audio policy: support platforms with no audio devices

Remove requirement to declare an AUDIO_DEVICE_OUT_SPEAKER device
for platforms without audio output.

By convention:
- platforms without audio output should declare a single output
device of type AUDIO_DEVICE_OUT_STUB also declared as default
output device
- platforms without audio input should declare a single input
device of type AUDIO_DEVICE_IN_STUB

Platforms with no audio at all can use stub audio policy configuration
file and audio HAL with the following instructions in device.mk file:

USE_XML_AUDIO_POLICY_CONF := 1
PRODUCT_PACKAGES += \
    audio.stub.default
PRODUCT_COPY_FILES += \
    frameworks/av/services/audiopolicy/config/audio_policy_configuration_stub.xml:system/etc/audio_policy_configuration.xml

Bug: 25075342
Change-Id: Id700978559427edd3c7cc38d98f2fd52928367ed
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index fac2342..29ab262 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -1847,8 +1847,8 @@
     // the requested device
     // - For non default requested device, currently selected device on the output is either the
     // requested device or one of the devices selected by the strategy
-    // - For default requested device (AUDIO_DEVICE_OUT_DEFAULT), apply volume only if no specific
-    // device volume value exists for currently selected device.
+    // - For default requested device (AUDIO_DEVICE_OUT_DEFAULT_FOR_VOLUME), apply volume only if
+    // no specific device volume value exists for currently selected device.
     status_t status = NO_ERROR;
     for (size_t i = 0; i < mOutputs.size(); i++) {
         sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
@@ -1866,7 +1866,7 @@
                 continue;
             }
             bool applyDefault = false;
-            if (device != AUDIO_DEVICE_OUT_DEFAULT) {
+            if (device != AUDIO_DEVICE_OUT_DEFAULT_FOR_VOLUME) {
                 curStreamDevice |= device;
             } else if (!mVolumeCurves->hasVolumeIndexForDevice(
                     stream, Volume::getDeviceForVolume(curStreamDevice))) {
@@ -1895,9 +1895,9 @@
     if (!audio_is_output_device(device)) {
         return BAD_VALUE;
     }
-    // if device is AUDIO_DEVICE_OUT_DEFAULT, return volume for device corresponding to
+    // if device is AUDIO_DEVICE_OUT_DEFAULT_FOR_VOLUME, return volume for device corresponding to
     // the strategy the stream belongs to.
-    if (device == AUDIO_DEVICE_OUT_DEFAULT) {
+    if (device == AUDIO_DEVICE_OUT_DEFAULT_FOR_VOLUME) {
         device = getDeviceForStrategy(getStrategy(stream), true /*fromCache*/);
     }
     device = Volume::getDeviceForVolume(device);
@@ -2331,19 +2331,29 @@
     size_t portsMax = *num_ports;
     *num_ports = 0;
     if (type == AUDIO_PORT_TYPE_NONE || type == AUDIO_PORT_TYPE_DEVICE) {
+        // do not report devices with type AUDIO_DEVICE_IN_STUB or AUDIO_DEVICE_OUT_STUB
+        // as they are used by stub HALs by convention
         if (role == AUDIO_PORT_ROLE_SINK || role == AUDIO_PORT_ROLE_NONE) {
-            for (size_t i = 0;
-                    i  < mAvailableOutputDevices.size() && portsWritten < portsMax; i++) {
-                mAvailableOutputDevices[i]->toAudioPort(&ports[portsWritten++]);
+            for (size_t i = 0; i < mAvailableOutputDevices.size(); i++) {
+                if (mAvailableOutputDevices[i]->type() == AUDIO_DEVICE_OUT_STUB) {
+                    continue;
+                }
+                if (portsWritten < portsMax) {
+                    mAvailableOutputDevices[i]->toAudioPort(&ports[portsWritten++]);
+                }
+                (*num_ports)++;
             }
-            *num_ports += mAvailableOutputDevices.size();
         }
         if (role == AUDIO_PORT_ROLE_SOURCE || role == AUDIO_PORT_ROLE_NONE) {
-            for (size_t i = 0;
-                    i  < mAvailableInputDevices.size() && portsWritten < portsMax; i++) {
-                mAvailableInputDevices[i]->toAudioPort(&ports[portsWritten++]);
+            for (size_t i = 0; i < mAvailableInputDevices.size(); i++) {
+                if (mAvailableInputDevices[i]->type() == AUDIO_DEVICE_IN_STUB) {
+                    continue;
+                }
+                if (portsWritten < portsMax) {
+                    mAvailableInputDevices[i]->toAudioPort(&ports[portsWritten++]);
+                }
+                (*num_ports)++;
             }
-            *num_ports += mAvailableInputDevices.size();
         }
     }
     if (type == AUDIO_PORT_TYPE_NONE || type == AUDIO_PORT_TYPE_MIX) {