CEC: Move finishWithCallback method to FeatureAction

Bug: 159901363
Test: None
Change-Id: Idd30ec162136c8b32e8cee1181c6e3e733aa9966
Merged-In: Idd30ec162136c8b32e8cee1181c6e3e733aa9966
diff --git a/services/core/java/com/android/server/hdmi/DevicePowerStatusAction.java b/services/core/java/com/android/server/hdmi/DevicePowerStatusAction.java
index b52ab76..313e9dfe 100644
--- a/services/core/java/com/android/server/hdmi/DevicePowerStatusAction.java
+++ b/services/core/java/com/android/server/hdmi/DevicePowerStatusAction.java
@@ -20,11 +20,8 @@
 import android.hardware.hdmi.HdmiPlaybackClient;
 import android.hardware.hdmi.HdmiPlaybackClient.DisplayStatusCallback;
 import android.hardware.hdmi.IHdmiControlCallback;
-import android.os.RemoteException;
 import android.util.Slog;
 
-import java.util.ArrayList;
-import java.util.List;
 
 /**
  * Feature action that queries the power status of other device. This action is initiated via
@@ -40,7 +37,6 @@
     private static final int STATE_WAITING_FOR_REPORT_POWER_STATUS = 1;
 
     private final int mTargetAddress;
-    private final List<IHdmiControlCallback> mCallbacks = new ArrayList<>();
 
     static DevicePowerStatusAction create(HdmiCecLocalDevice source,
             int targetAddress, IHdmiControlCallback callback) {
@@ -53,9 +49,8 @@
 
     private DevicePowerStatusAction(HdmiCecLocalDevice localDevice,
             int targetAddress, IHdmiControlCallback callback) {
-        super(localDevice);
+        super(localDevice, callback);
         mTargetAddress = targetAddress;
-        addCallback(callback);
     }
 
     @Override
@@ -79,8 +74,7 @@
         }
         if (cmd.getOpcode() == Constants.MESSAGE_REPORT_POWER_STATUS) {
             int status = cmd.getParams()[0];
-            invokeCallback(status);
-            finish();
+            finishWithCallback(status);
             return true;
         }
         return false;
@@ -93,22 +87,7 @@
         }
         if (state == STATE_WAITING_FOR_REPORT_POWER_STATUS) {
             // Got no response from TV. Report status 'unknown'.
-            invokeCallback(HdmiControlManager.POWER_STATUS_UNKNOWN);
-            finish();
-        }
-    }
-
-    public void addCallback(IHdmiControlCallback callback) {
-        mCallbacks.add(callback);
-    }
-
-    private void invokeCallback(int result) {
-        try {
-            for (IHdmiControlCallback callback : mCallbacks) {
-                callback.onComplete(result);
-            }
-        } catch (RemoteException e) {
-            Slog.e(TAG, "Callback failed:" + e);
+            finishWithCallback(HdmiControlManager.POWER_STATUS_UNKNOWN);
         }
     }
 }
diff --git a/services/core/java/com/android/server/hdmi/DeviceSelectAction.java b/services/core/java/com/android/server/hdmi/DeviceSelectAction.java
index c684a56..24b99cd 100644
--- a/services/core/java/com/android/server/hdmi/DeviceSelectAction.java
+++ b/services/core/java/com/android/server/hdmi/DeviceSelectAction.java
@@ -21,8 +21,8 @@
 import android.hardware.hdmi.HdmiTvClient;
 import android.hardware.hdmi.IHdmiControlCallback;
 import android.hardware.tv.cec.V1_0.SendMessageResult;
-import android.os.RemoteException;
 import android.util.Slog;
+
 import com.android.server.hdmi.HdmiControlService.SendMessageCallback;
 
 /**
@@ -59,7 +59,6 @@
     private static final int STATE_WAIT_FOR_DEVICE_POWER_ON = 3;
 
     private final HdmiDeviceInfo mTarget;
-    private final IHdmiControlCallback mCallback;
     private final HdmiCecMessage mGivePowerStatus;
 
     private int mPowerStatusCounter = 0;
@@ -73,8 +72,7 @@
      */
     public DeviceSelectAction(HdmiCecLocalDeviceTv source,
             HdmiDeviceInfo target, IHdmiControlCallback callback) {
-        super(source);
-        mCallback = callback;
+        super(source, callback);
         mTarget = target;
         mGivePowerStatus = HdmiCecMessageBuilder.buildGiveDevicePowerStatus(
                 getSourceAddress(), getTargetAddress());
@@ -92,16 +90,17 @@
     }
 
     private void queryDevicePowerStatus() {
-        sendCommand(mGivePowerStatus, new SendMessageCallback() {
-            @Override
-            public void onSendCompleted(int error) {
-                if (error != SendMessageResult.SUCCESS) {
-                    invokeCallback(HdmiControlManager.RESULT_COMMUNICATION_FAILED);
-                    finish();
-                    return;
-                }
-            }
-        });
+        sendCommand(
+                mGivePowerStatus,
+                new SendMessageCallback() {
+                    @Override
+                    public void onSendCompleted(int error) {
+                        if (error != SendMessageResult.SUCCESS) {
+                            finishWithCallback(HdmiControlManager.RESULT_COMMUNICATION_FAILED);
+                            return;
+                        }
+                    }
+                });
         mState = STATE_WAIT_FOR_REPORT_POWER_STATUS;
         addTimer(mState, HdmiConfig.TIMEOUT_MS);
     }
@@ -174,8 +173,7 @@
         tv().setActivePath(mTarget.getPhysicalAddress());
         sendCommand(HdmiCecMessageBuilder.buildSetStreamPath(
                 getSourceAddress(), mTarget.getPhysicalAddress()));
-        invokeCallback(HdmiControlManager.RESULT_SUCCESS);
-        finish();
+        finishWithCallback(HdmiControlManager.RESULT_SUCCESS);
     }
 
     @Override
@@ -187,8 +185,7 @@
         switch (mState) {
             case STATE_WAIT_FOR_REPORT_POWER_STATUS:
                 if (tv().isPowerStandbyOrTransient()) {
-                    invokeCallback(HdmiControlManager.RESULT_INCORRECT_MODE);
-                    finish();
+                    finishWithCallback(HdmiControlManager.RESULT_INCORRECT_MODE);
                     return;
                 }
                 sendSetStreamPath();
@@ -200,15 +197,4 @@
                 break;
         }
     }
-
-    private void invokeCallback(int result) {
-        if (mCallback == null) {
-            return;
-        }
-        try {
-            mCallback.onComplete(result);
-        } catch (RemoteException e) {
-            Slog.e(TAG, "Callback failed:" + e);
-        }
-    }
 }
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecFeatureAction.java b/services/core/java/com/android/server/hdmi/HdmiCecFeatureAction.java
index 2da698b..2e1ff03 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecFeatureAction.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecFeatureAction.java
@@ -15,9 +15,11 @@
  */
 package com.android.server.hdmi;
 
+import android.hardware.hdmi.IHdmiControlCallback;
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Message;
+import android.os.RemoteException;
 import android.util.Pair;
 import android.util.Slog;
 
@@ -25,6 +27,7 @@
 import com.android.server.hdmi.HdmiControlService.DevicePollingCallback;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.List;
 
 /**
@@ -61,7 +64,20 @@
 
     private ArrayList<Pair<HdmiCecFeatureAction, Runnable>> mOnFinishedCallbacks;
 
+    final List<IHdmiControlCallback> mCallbacks = new ArrayList<>();
+
     HdmiCecFeatureAction(HdmiCecLocalDevice source) {
+        this(source, new ArrayList<>());
+    }
+
+    HdmiCecFeatureAction(HdmiCecLocalDevice source, IHdmiControlCallback callback) {
+        this(source, Arrays.asList(callback));
+    }
+
+    HdmiCecFeatureAction(HdmiCecLocalDevice source, List<IHdmiControlCallback> callbacks) {
+        for (IHdmiControlCallback callback : callbacks) {
+            addCallback(callback);
+        }
         mSource = source;
         mService = mSource.getService();
         mActionTimer = createActionTimer(mService.getServiceLooper());
@@ -282,4 +298,26 @@
         }
         mOnFinishedCallbacks.add(Pair.create(action, runnable));
     }
+
+    protected void finishWithCallback(int returnCode) {
+        invokeCallback(returnCode);
+        finish();
+    }
+
+    public void addCallback(IHdmiControlCallback callback) {
+        mCallbacks.add(callback);
+    }
+
+    private void invokeCallback(int result) {
+        try {
+            for (IHdmiControlCallback callback : mCallbacks) {
+                if (callback == null) {
+                    continue;
+                }
+                callback.onComplete(result);
+            }
+        } catch (RemoteException e) {
+            Slog.e(TAG, "Callback failed:" + e);
+        }
+    }
 }
diff --git a/services/core/java/com/android/server/hdmi/OneTouchPlayAction.java b/services/core/java/com/android/server/hdmi/OneTouchPlayAction.java
index 4962af1..083aecd 100644
--- a/services/core/java/com/android/server/hdmi/OneTouchPlayAction.java
+++ b/services/core/java/com/android/server/hdmi/OneTouchPlayAction.java
@@ -18,11 +18,8 @@
 import android.hardware.hdmi.HdmiControlManager;
 import android.hardware.hdmi.HdmiPlaybackClient.OneTouchPlayCallback;
 import android.hardware.hdmi.IHdmiControlCallback;
-import android.os.RemoteException;
 import android.util.Slog;
 
-import java.util.ArrayList;
-import java.util.List;
 
 /**
  * Feature action that performs one touch play against TV/Display device. This action is initiated
@@ -50,7 +47,6 @@
     private static final int LOOP_COUNTER_MAX = 10;
 
     private final int mTargetAddress;
-    private final List<IHdmiControlCallback> mCallbacks = new ArrayList<>();
 
     private int mPowerStatusCounter = 0;
 
@@ -67,9 +63,8 @@
 
     private OneTouchPlayAction(HdmiCecLocalDevice localDevice, int targetAddress,
             IHdmiControlCallback callback) {
-        super(localDevice);
+        super(localDevice, callback);
         mTargetAddress = targetAddress;
-        addCallback(callback);
     }
 
     @Override
@@ -113,8 +108,7 @@
             int status = cmd.getParams()[0];
             if (status == HdmiControlManager.POWER_STATUS_ON) {
                 broadcastActiveSource();
-                invokeCallback(HdmiControlManager.RESULT_SUCCESS);
-                finish();
+                finishWithCallback(HdmiControlManager.RESULT_SUCCESS);
             }
             return true;
         }
@@ -132,23 +126,8 @@
                 addTimer(mState, HdmiConfig.TIMEOUT_MS);
             } else {
                 // Couldn't wake up the TV for whatever reason. Report failure.
-                invokeCallback(HdmiControlManager.RESULT_TIMEOUT);
-                finish();
+                finishWithCallback(HdmiControlManager.RESULT_TIMEOUT);
             }
         }
     }
-
-    public void addCallback(IHdmiControlCallback callback) {
-        mCallbacks.add(callback);
-    }
-
-    private void invokeCallback(int result) {
-        try {
-            for (IHdmiControlCallback callback : mCallbacks) {
-                callback.onComplete(result);
-            }
-        } catch (RemoteException e) {
-            Slog.e(TAG, "Callback failed:" + e);
-        }
-    }
 }
diff --git a/services/core/java/com/android/server/hdmi/RoutingControlAction.java b/services/core/java/com/android/server/hdmi/RoutingControlAction.java
index 9a52c19..aff9630 100644
--- a/services/core/java/com/android/server/hdmi/RoutingControlAction.java
+++ b/services/core/java/com/android/server/hdmi/RoutingControlAction.java
@@ -16,11 +16,9 @@
 
 package com.android.server.hdmi;
 
-import android.annotation.Nullable;
 import android.hardware.hdmi.HdmiControlManager;
 import android.hardware.hdmi.HdmiDeviceInfo;
 import android.hardware.hdmi.IHdmiControlCallback;
-import android.os.RemoteException;
 import android.util.Slog;
 
 import com.android.server.hdmi.HdmiControlService.SendMessageCallback;
@@ -66,15 +64,12 @@
     // <Inactive Source> command.
     private final boolean mNotifyInputChange;
 
-    @Nullable private final IHdmiControlCallback mCallback;
-
     // The latest routing path. Updated by each <Routing Information> from CEC switches.
     private int mCurrentRoutingPath;
 
     RoutingControlAction(HdmiCecLocalDevice localDevice, int path, boolean queryDevicePowerStatus,
             IHdmiControlCallback callback) {
-        super(localDevice);
-        mCallback = callback;
+        super(localDevice, callback);
         mCurrentRoutingPath = path;
         mQueryDevicePowerStatus = queryDevicePowerStatus;
         // Callback is non-null when routing control action is brought up by binder API. Use
@@ -147,11 +142,6 @@
                 mCurrentRoutingPath));
     }
 
-    private void finishWithCallback(int result) {
-        invokeCallback(result);
-        finish();
-    }
-
     @Override
     public void handleTimerEvent(int timeoutState) {
         if (mState != timeoutState || mState == STATE_NONE) {
@@ -200,15 +190,4 @@
             finishWithCallback(HdmiControlManager.RESULT_SUCCESS);
         }
     }
-
-    private void invokeCallback(int result) {
-        if (mCallback == null) {
-            return;
-        }
-        try {
-            mCallback.onComplete(result);
-        } catch (RemoteException e) {
-            // Do nothing.
-        }
-    }
 }
diff --git a/services/core/java/com/android/server/hdmi/SystemAudioAction.java b/services/core/java/com/android/server/hdmi/SystemAudioAction.java
index a5477e8..978c25d 100644
--- a/services/core/java/com/android/server/hdmi/SystemAudioAction.java
+++ b/services/core/java/com/android/server/hdmi/SystemAudioAction.java
@@ -16,13 +16,11 @@
 
 package com.android.server.hdmi;
 
-import android.annotation.Nullable;
 import android.hardware.hdmi.HdmiControlManager;
 import android.hardware.hdmi.HdmiDeviceInfo;
 import android.hardware.hdmi.IHdmiControlCallback;
 import android.hardware.tv.cec.V1_0.SendMessageResult;
-import android.os.RemoteException;
-import android.util.Slog;
+
 import java.util.List;
 
 /**
@@ -49,8 +47,6 @@
     // The target audio status of the action, whether to enable the system audio mode or not.
     protected boolean mTargetAudioStatus;
 
-    @Nullable private final IHdmiControlCallback mCallback;
-
     private int mSendRetryCount = 0;
 
     /**
@@ -64,11 +60,10 @@
      */
     SystemAudioAction(HdmiCecLocalDevice source, int avrAddress, boolean targetStatus,
             IHdmiControlCallback callback) {
-        super(source);
+        super(source, callback);
         HdmiUtils.verifyAddressType(avrAddress, HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM);
         mAvrLogicalAddress = avrAddress;
         mTargetAudioStatus = targetStatus;
-        mCallback = callback;
     }
 
     // Seq #27
@@ -174,7 +169,7 @@
     }
 
     protected void startAudioStatusAction() {
-        addAndStartAction(new SystemAudioStatusAction(tv(), mAvrLogicalAddress, mCallback));
+        addAndStartAction(new SystemAudioStatusAction(tv(), mAvrLogicalAddress, mCallbacks));
         finish();
     }
 
@@ -194,17 +189,4 @@
                 return;
         }
     }
-
-    // TODO: if IHdmiControlCallback is general to other FeatureAction,
-    //       move it into FeatureAction.
-    protected void finishWithCallback(int returnCode) {
-        if (mCallback != null) {
-            try {
-                mCallback.onComplete(returnCode);
-            } catch (RemoteException e) {
-                Slog.e(TAG, "Failed to invoke callback.", e);
-            }
-        }
-        finish();
-    }
 }
diff --git a/services/core/java/com/android/server/hdmi/SystemAudioStatusAction.java b/services/core/java/com/android/server/hdmi/SystemAudioStatusAction.java
index 5d913d1..b4af540 100644
--- a/services/core/java/com/android/server/hdmi/SystemAudioStatusAction.java
+++ b/services/core/java/com/android/server/hdmi/SystemAudioStatusAction.java
@@ -16,14 +16,14 @@
 
 package com.android.server.hdmi;
 
-import android.annotation.Nullable;
 import android.hardware.hdmi.HdmiControlManager;
 import android.hardware.hdmi.IHdmiControlCallback;
 import android.hardware.tv.cec.V1_0.SendMessageResult;
-import android.os.RemoteException;
-import android.util.Slog;
+
 import com.android.server.hdmi.HdmiControlService.SendMessageCallback;
 
+import java.util.List;
+
 /**
  * Action to update audio status (volume or mute) of audio amplifier
  */
@@ -34,13 +34,17 @@
     private static final int STATE_WAIT_FOR_REPORT_AUDIO_STATUS = 1;
 
     private final int mAvrAddress;
-    @Nullable private final IHdmiControlCallback mCallback;
+
+    SystemAudioStatusAction(
+            HdmiCecLocalDevice source, int avrAddress, List<IHdmiControlCallback> callbacks) {
+        super(source, callbacks);
+        mAvrAddress = avrAddress;
+    }
 
     SystemAudioStatusAction(HdmiCecLocalDevice source, int avrAddress,
             IHdmiControlCallback callback) {
-        super(source);
+        super(source, callback);
         mAvrAddress = avrAddress;
-        mCallback = callback;
     }
 
     @Override
@@ -97,17 +101,6 @@
         finishWithCallback(HdmiControlManager.RESULT_SUCCESS);
     }
 
-    private void finishWithCallback(int returnCode) {
-        if (mCallback != null) {
-            try {
-                mCallback.onComplete(returnCode);
-            } catch (RemoteException e) {
-                Slog.e(TAG, "Failed to invoke callback.", e);
-            }
-        }
-        finish();
-    }
-
     @Override
     void handleTimerEvent(int state) {
         if (mState != state) {