audiohal: Avoid making unneeded calls to HIDL inteface's ::castFrom

Instead of calling '::castFrom' every time a conversion from
IDevice to IPrimaryDevice is needed, make this conversion at
initialization.

This is to avoid additional IPC calls that are required
for 'castFrom'.

Bug: 63142881
Change-Id: Ic4192c729011ce2653772847e83da426116f9e94
Test: audio works
diff --git a/media/libaudiohal/DeviceHalHidl.cpp b/media/libaudiohal/DeviceHalHidl.cpp
index 71fbd98..49ef991 100644
--- a/media/libaudiohal/DeviceHalHidl.cpp
+++ b/media/libaudiohal/DeviceHalHidl.cpp
@@ -98,7 +98,8 @@
 }  // namespace
 
 DeviceHalHidl::DeviceHalHidl(const sp<IDevice>& device)
-        : ConversionHelperHidl("Device"), mDevice(device) {
+        : ConversionHelperHidl("Device"), mDevice(device),
+          mPrimaryDevice(IPrimaryDevice::castFrom(device)) {
 }
 
 DeviceHalHidl::~DeviceHalHidl() {
@@ -120,24 +121,21 @@
 
 status_t DeviceHalHidl::setVoiceVolume(float volume) {
     if (mDevice == 0) return NO_INIT;
-    sp<IPrimaryDevice> primaryDev = IPrimaryDevice::castFrom(mDevice);
-    if (primaryDev == 0) return INVALID_OPERATION;
-    return processReturn("setVoiceVolume", primaryDev->setVoiceVolume(volume));
+    if (mPrimaryDevice == 0) return INVALID_OPERATION;
+    return processReturn("setVoiceVolume", mPrimaryDevice->setVoiceVolume(volume));
 }
 
 status_t DeviceHalHidl::setMasterVolume(float volume) {
     if (mDevice == 0) return NO_INIT;
-    sp<IPrimaryDevice> primaryDev = IPrimaryDevice::castFrom(mDevice);
-    if (primaryDev == 0) return INVALID_OPERATION;
-    return processReturn("setMasterVolume", primaryDev->setMasterVolume(volume));
+    if (mPrimaryDevice == 0) return INVALID_OPERATION;
+    return processReturn("setMasterVolume", mPrimaryDevice->setMasterVolume(volume));
 }
 
 status_t DeviceHalHidl::getMasterVolume(float *volume) {
     if (mDevice == 0) return NO_INIT;
-    sp<IPrimaryDevice> primaryDev = IPrimaryDevice::castFrom(mDevice);
-    if (primaryDev == 0) return INVALID_OPERATION;
+    if (mPrimaryDevice == 0) return INVALID_OPERATION;
     Result retval;
-    Return<void> ret = primaryDev->getMasterVolume(
+    Return<void> ret = mPrimaryDevice->getMasterVolume(
             [&](Result r, float v) {
                 retval = r;
                 if (retval == Result::OK) {
@@ -149,9 +147,8 @@
 
 status_t DeviceHalHidl::setMode(audio_mode_t mode) {
     if (mDevice == 0) return NO_INIT;
-    sp<IPrimaryDevice> primaryDev = IPrimaryDevice::castFrom(mDevice);
-    if (primaryDev == 0) return INVALID_OPERATION;
-    return processReturn("setMode", primaryDev->setMode(AudioMode(mode)));
+    if (mPrimaryDevice == 0) return INVALID_OPERATION;
+    return processReturn("setMode", mPrimaryDevice->setMode(AudioMode(mode)));
 }
 
 status_t DeviceHalHidl::setMicMute(bool state) {
diff --git a/media/libaudiohal/DeviceHalHidl.h b/media/libaudiohal/DeviceHalHidl.h
index 9da02a4..8651b51 100644
--- a/media/libaudiohal/DeviceHalHidl.h
+++ b/media/libaudiohal/DeviceHalHidl.h
@@ -18,11 +18,13 @@
 #define ANDROID_HARDWARE_DEVICE_HAL_HIDL_H
 
 #include <android/hardware/audio/2.0/IDevice.h>
+#include <android/hardware/audio/2.0/IPrimaryDevice.h>
 #include <media/audiohal/DeviceHalInterface.h>
 
 #include "ConversionHelperHidl.h"
 
 using ::android::hardware::audio::V2_0::IDevice;
+using ::android::hardware::audio::V2_0::IPrimaryDevice;
 using ::android::hardware::Return;
 
 namespace android {
@@ -110,6 +112,7 @@
   private:
     friend class DevicesFactoryHalHidl;
     sp<IDevice> mDevice;
+    sp<IPrimaryDevice> mPrimaryDevice;  // Null if it's not a primary device.
 
     // Can not be constructed directly by clients.
     explicit DeviceHalHidl(const sp<IDevice>& device);