Set initial audio device for AudioTrack and AudioRecord

Bug: 62090113
Test: run AAudio test and verify a valid device is reported just
after opening playback or capture streams in legacy mode.

Merged-In: Ic8be42e1735690eb00c811ef0cb8b5abb36172d6

Change-Id: Ic8be42e1735690eb00c811ef0cb8b5abb36172d6
diff --git a/media/libaaudio/examples/input_monitor/src/input_monitor.cpp b/media/libaaudio/examples/input_monitor/src/input_monitor.cpp
index 715c5f8..892792d 100644
--- a/media/libaaudio/examples/input_monitor/src/input_monitor.cpp
+++ b/media/libaaudio/examples/input_monitor/src/input_monitor.cpp
@@ -22,6 +22,7 @@
 #include <stdlib.h>
 #include <math.h>
 #include <aaudio/AAudio.h>
+#include <aaudio/AAudioTesting.h>
 #include "AAudioExampleUtils.h"
 #include "AAudioSimpleRecorder.h"
 
@@ -42,7 +43,7 @@
     const aaudio_format_t requestedDataFormat = AAUDIO_FORMAT_PCM_I16;
     aaudio_format_t actualDataFormat;
 
-    const int requestedInputChannelCount = 1; // Can affect whether we get a FAST path.
+    const int requestedInputChannelCount = 2; // Can affect whether we get a FAST path.
 
     //aaudio_performance_mode_t requestedPerformanceMode = AAUDIO_PERFORMANCE_MODE_NONE;
     const aaudio_performance_mode_t requestedPerformanceMode = AAUDIO_PERFORMANCE_MODE_LOW_LATENCY;
@@ -61,6 +62,7 @@
     int16_t *data = nullptr;
     float peakLevel = 0.0;
     int loopCounter = 0;
+    int32_t deviceId;
 
     // Make printf print immediately so that debug info is not stuck
     // in a buffer if we hang or crash.
@@ -68,6 +70,8 @@
 
     printf("%s - Monitor input level using AAudio\n", argv[0]);
 
+//    AAudio_setMMapPolicy(AAUDIO_POLICY_ALWAYS);
+
     recorder.setPerformanceMode(requestedPerformanceMode);
     recorder.setSharingMode(requestedSharingMode);
 
@@ -79,6 +83,9 @@
     }
     aaudioStream = recorder.getStream();
 
+    deviceId = AAudioStream_getDeviceId(aaudioStream);
+    printf("deviceId = %d\n", deviceId);
+
     actualSamplesPerFrame = AAudioStream_getSamplesPerFrame(aaudioStream);
     printf("SamplesPerFrame = %d\n", actualSamplesPerFrame);
     actualSampleRate = AAudioStream_getSampleRate(aaudioStream);
@@ -133,7 +140,7 @@
     framesLeft = framesToRecord;
     while (framesLeft > 0) {
         // Read audio data from the stream.
-        const int64_t timeoutNanos = 100 * NANOS_PER_MILLISECOND;
+        const int64_t timeoutNanos = 1000 * NANOS_PER_MILLISECOND;
         int minFrames = (framesToRecord < framesPerRead) ? framesToRecord : framesPerRead;
         int actual = AAudioStream_read(aaudioStream, data, minFrames, timeoutNanos);
         if (actual < 0) {
diff --git a/media/libaaudio/examples/write_sine/src/write_sine.cpp b/media/libaaudio/examples/write_sine/src/write_sine.cpp
index 6522ba4..3a00f51 100644
--- a/media/libaaudio/examples/write_sine/src/write_sine.cpp
+++ b/media/libaaudio/examples/write_sine/src/write_sine.cpp
@@ -64,6 +64,7 @@
     int32_t  xRunCount = 0;
     float   *floatData = nullptr;
     int16_t *shortData = nullptr;
+    int32_t deviceId;
 
     // Make printf print immediately so that debug info is not stuck
     // in a buffer if we hang or crash.
@@ -86,6 +87,9 @@
     aaudioStream = player.getStream();
     // Request stream properties.
 
+    deviceId = AAudioStream_getDeviceId(aaudioStream);
+    printf("deviceId = %d\n", deviceId);
+
     state = AAudioStream_getState(aaudioStream);
     printf("after open, state = %s\n", AAudio_convertStreamStateToText(state));
 
diff --git a/media/libaudioclient/AudioRecord.cpp b/media/libaudioclient/AudioRecord.cpp
index d29aa74..b96adc7 100644
--- a/media/libaudioclient/AudioRecord.cpp
+++ b/media/libaudioclient/AudioRecord.cpp
@@ -69,7 +69,8 @@
     : mActive(false), mStatus(NO_INIT), mOpPackageName(opPackageName),
       mSessionId(AUDIO_SESSION_ALLOCATE),
       mPreviousPriority(ANDROID_PRIORITY_NORMAL), mPreviousSchedulingGroup(SP_DEFAULT),
-      mSelectedDeviceId(AUDIO_PORT_HANDLE_NONE), mPortId(AUDIO_PORT_HANDLE_NONE)
+      mSelectedDeviceId(AUDIO_PORT_HANDLE_NONE), mRoutedDeviceId(AUDIO_PORT_HANDLE_NONE),
+      mPortId(AUDIO_PORT_HANDLE_NONE)
 {
 }
 
@@ -503,7 +504,14 @@
     if (mInput == AUDIO_IO_HANDLE_NONE) {
         return AUDIO_PORT_HANDLE_NONE;
     }
-    return AudioSystem::getDeviceIdForIo(mInput);
+    // if the input stream does not have an active audio patch, use either the device initially
+    // selected by audio policy manager or the last routed device
+    audio_port_handle_t deviceId = AudioSystem::getDeviceIdForIo(mInput);
+    if (deviceId == AUDIO_PORT_HANDLE_NONE) {
+        deviceId = mRoutedDeviceId;
+    }
+    mRoutedDeviceId = deviceId;
+    return deviceId;
 }
 
 // -------------------------------------------------------------------------
@@ -538,13 +546,14 @@
             .channel_mask = mChannelMask,
             .format = mFormat
         };
+    mRoutedDeviceId = mSelectedDeviceId;
     status = AudioSystem::getInputForAttr(&mAttributes, &input,
                                         mSessionId,
                                         // FIXME compare to AudioTrack
                                         mClientPid,
                                         mClientUid,
                                         &config,
-                                        mFlags, mSelectedDeviceId, &mPortId);
+                                        mFlags, &mRoutedDeviceId, &mPortId);
 
     if (status != NO_ERROR || input == AUDIO_IO_HANDLE_NONE) {
         ALOGE("Could not get audio input for session %d, record source %d, sample rate %u, "
diff --git a/media/libaudioclient/AudioSystem.cpp b/media/libaudioclient/AudioSystem.cpp
index ed1e6d1..2f710bd 100644
--- a/media/libaudioclient/AudioSystem.cpp
+++ b/media/libaudioclient/AudioSystem.cpp
@@ -819,7 +819,7 @@
                                         uid_t uid,
                                         const audio_config_t *config,
                                         audio_output_flags_t flags,
-                                        audio_port_handle_t selectedDeviceId,
+                                        audio_port_handle_t *selectedDeviceId,
                                         audio_port_handle_t *portId)
 {
     const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
@@ -863,7 +863,7 @@
                                 uid_t uid,
                                 const audio_config_base_t *config,
                                 audio_input_flags_t flags,
-                                audio_port_handle_t selectedDeviceId,
+                                audio_port_handle_t *selectedDeviceId,
                                 audio_port_handle_t *portId)
 {
     const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
diff --git a/media/libaudioclient/AudioTrack.cpp b/media/libaudioclient/AudioTrack.cpp
index 98ec7d7..c614b6c 100644
--- a/media/libaudioclient/AudioTrack.cpp
+++ b/media/libaudioclient/AudioTrack.cpp
@@ -184,6 +184,7 @@
       mPreviousSchedulingGroup(SP_DEFAULT),
       mPausedPosition(0),
       mSelectedDeviceId(AUDIO_PORT_HANDLE_NONE),
+      mRoutedDeviceId(AUDIO_PORT_HANDLE_NONE),
       mPortId(AUDIO_PORT_HANDLE_NONE)
 {
     mAttributes.content_type = AUDIO_CONTENT_TYPE_UNKNOWN;
@@ -1226,7 +1227,14 @@
     if (mOutput == AUDIO_IO_HANDLE_NONE) {
         return AUDIO_PORT_HANDLE_NONE;
     }
-    return AudioSystem::getDeviceIdForIo(mOutput);
+    // if the output stream does not have an active audio patch, use either the device initially
+    // selected by audio policy manager or the last routed device
+    audio_port_handle_t deviceId = AudioSystem::getDeviceIdForIo(mOutput);
+    if (deviceId == AUDIO_PORT_HANDLE_NONE) {
+        deviceId = mRoutedDeviceId;
+    }
+    mRoutedDeviceId = deviceId;
+    return deviceId;
 }
 
 status_t AudioTrack::attachAuxEffect(int effectId)
@@ -1292,10 +1300,11 @@
     config.channel_mask = mChannelMask;
     config.format = mFormat;
     config.offload_info = mOffloadInfoCopy;
+    mRoutedDeviceId = mSelectedDeviceId;
     status = AudioSystem::getOutputForAttr(attr, &output,
                                            mSessionId, &streamType, mClientUid,
                                            &config,
-                                           mFlags, mSelectedDeviceId, &mPortId);
+                                           mFlags, &mRoutedDeviceId, &mPortId);
 
     if (status != NO_ERROR || output == AUDIO_IO_HANDLE_NONE) {
         ALOGE("Could not get audio output for session %d, stream type %d, usage %d, sample rate %u,"
diff --git a/media/libaudioclient/IAudioPolicyService.cpp b/media/libaudioclient/IAudioPolicyService.cpp
index b72047b..d320320 100644
--- a/media/libaudioclient/IAudioPolicyService.cpp
+++ b/media/libaudioclient/IAudioPolicyService.cpp
@@ -193,7 +193,7 @@
                                         uid_t uid,
                                         const audio_config_t *config,
                                         audio_output_flags_t flags,
-                                        audio_port_handle_t selectedDeviceId,
+                                        audio_port_handle_t *selectedDeviceId,
                                         audio_port_handle_t *portId)
         {
             Parcel data, reply;
@@ -212,6 +212,10 @@
                 ALOGE("getOutputForAttr NULL output - shouldn't happen");
                 return BAD_VALUE;
             }
+            if (selectedDeviceId == NULL) {
+                ALOGE("getOutputForAttr NULL selectedDeviceId - shouldn't happen");
+                return BAD_VALUE;
+            }
             if (portId == NULL) {
                 ALOGE("getOutputForAttr NULL portId - shouldn't happen");
                 return BAD_VALUE;
@@ -232,7 +236,7 @@
             data.writeInt32(uid);
             data.write(config, sizeof(audio_config_t));
             data.writeInt32(static_cast <uint32_t>(flags));
-            data.writeInt32(selectedDeviceId);
+            data.writeInt32(*selectedDeviceId);
             data.writeInt32(*portId);
             status_t status = remote()->transact(GET_OUTPUT_FOR_ATTR, data, &reply);
             if (status != NO_ERROR) {
@@ -247,6 +251,7 @@
             if (stream != NULL) {
                 *stream = lStream;
             }
+            *selectedDeviceId = (audio_port_handle_t)reply.readInt32();
             *portId = (audio_port_handle_t)reply.readInt32();
             return status;
         }
@@ -296,7 +301,7 @@
                                      uid_t uid,
                                      const audio_config_base_t *config,
                                      audio_input_flags_t flags,
-                                     audio_port_handle_t selectedDeviceId,
+                                     audio_port_handle_t *selectedDeviceId,
                                      audio_port_handle_t *portId)
     {
         Parcel data, reply;
@@ -309,6 +314,10 @@
             ALOGE("getInputForAttr NULL input - shouldn't happen");
             return BAD_VALUE;
         }
+        if (selectedDeviceId == NULL) {
+            ALOGE("getInputForAttr NULL selectedDeviceId - shouldn't happen");
+            return BAD_VALUE;
+        }
         if (portId == NULL) {
             ALOGE("getInputForAttr NULL portId - shouldn't happen");
             return BAD_VALUE;
@@ -319,7 +328,7 @@
         data.writeInt32(uid);
         data.write(config, sizeof(audio_config_base_t));
         data.writeInt32(flags);
-        data.writeInt32(selectedDeviceId);
+        data.writeInt32(*selectedDeviceId);
         data.writeInt32(*portId);
         status_t status = remote()->transact(GET_INPUT_FOR_ATTR, data, &reply);
         if (status != NO_ERROR) {
@@ -330,6 +339,7 @@
             return status;
         }
         *input = (audio_io_handle_t)reply.readInt32();
+        *selectedDeviceId = (audio_port_handle_t)reply.readInt32();
         *portId = (audio_port_handle_t)reply.readInt32();
         return NO_ERROR;
     }
@@ -968,10 +978,11 @@
             status_t status = getOutputForAttr(hasAttributes ? &attr : NULL,
                     &output, session, &stream, uid,
                     &config,
-                    flags, selectedDeviceId, &portId);
+                    flags, &selectedDeviceId, &portId);
             reply->writeInt32(status);
             reply->writeInt32(output);
             reply->writeInt32(stream);
+            reply->writeInt32(selectedDeviceId);
             reply->writeInt32(portId);
             return NO_ERROR;
         } break;
@@ -1025,10 +1036,11 @@
             audio_io_handle_t input = AUDIO_IO_HANDLE_NONE;
             status_t status = getInputForAttr(&attr, &input, session, pid, uid,
                                               &config,
-                                              flags, selectedDeviceId, &portId);
+                                              flags, &selectedDeviceId, &portId);
             reply->writeInt32(status);
             if (status == NO_ERROR) {
                 reply->writeInt32(input);
+                reply->writeInt32(selectedDeviceId);
                 reply->writeInt32(portId);
             }
             return NO_ERROR;
diff --git a/media/libaudioclient/include/media/AudioRecord.h b/media/libaudioclient/include/media/AudioRecord.h
index 1b034b5..32757d3 100644
--- a/media/libaudioclient/include/media/AudioRecord.h
+++ b/media/libaudioclient/include/media/AudioRecord.h
@@ -655,7 +655,10 @@
 
     // For Device Selection API
     //  a value of AUDIO_PORT_HANDLE_NONE indicated default (AudioPolicyManager) routing.
-    audio_port_handle_t    mSelectedDeviceId;
+    audio_port_handle_t     mSelectedDeviceId; // Device requested by the application.
+    audio_port_handle_t     mRoutedDeviceId;   // Device actually selected by audio policy manager:
+                                              // May not match the app selection depending on other
+                                              // activity and connected devices
     sp<AudioSystem::AudioDeviceCallback> mDeviceCallback;
     audio_port_handle_t    mPortId;  // unique ID allocated by audio policy
 
diff --git a/media/libaudioclient/include/media/AudioSystem.h b/media/libaudioclient/include/media/AudioSystem.h
index 2875794..2e39d23 100644
--- a/media/libaudioclient/include/media/AudioSystem.h
+++ b/media/libaudioclient/include/media/AudioSystem.h
@@ -224,7 +224,7 @@
                                      uid_t uid,
                                      const audio_config_t *config,
                                      audio_output_flags_t flags,
-                                     audio_port_handle_t selectedDeviceId,
+                                     audio_port_handle_t *selectedDeviceId,
                                      audio_port_handle_t *portId);
     static status_t startOutput(audio_io_handle_t output,
                                 audio_stream_type_t stream,
@@ -245,7 +245,7 @@
                                     uid_t uid,
                                     const audio_config_base_t *config,
                                     audio_input_flags_t flags,
-                                    audio_port_handle_t selectedDeviceId,
+                                    audio_port_handle_t *selectedDeviceId,
                                     audio_port_handle_t *portId);
 
     static status_t startInput(audio_io_handle_t input,
diff --git a/media/libaudioclient/include/media/AudioTrack.h b/media/libaudioclient/include/media/AudioTrack.h
index 5d73df3..3f9037f 100644
--- a/media/libaudioclient/include/media/AudioTrack.h
+++ b/media/libaudioclient/include/media/AudioTrack.h
@@ -1135,7 +1135,10 @@
 
     // For Device Selection API
     //  a value of AUDIO_PORT_HANDLE_NONE indicated default (AudioPolicyManager) routing.
-    audio_port_handle_t     mSelectedDeviceId;
+    audio_port_handle_t    mSelectedDeviceId; // Device requested by the application.
+    audio_port_handle_t    mRoutedDeviceId;   // Device actually selected by audio policy manager:
+                                              // May not match the app selection depending on other
+                                              // activity and connected devices.
 
     sp<VolumeHandler>       mVolumeHandler;
 
diff --git a/media/libaudioclient/include/media/IAudioPolicyService.h b/media/libaudioclient/include/media/IAudioPolicyService.h
index ac71873..9b3e35e 100644
--- a/media/libaudioclient/include/media/IAudioPolicyService.h
+++ b/media/libaudioclient/include/media/IAudioPolicyService.h
@@ -68,7 +68,7 @@
                                       uid_t uid,
                                       const audio_config_t *config,
                                       audio_output_flags_t flags,
-                                      audio_port_handle_t selectedDeviceId,
+                                      audio_port_handle_t *selectedDeviceId,
                                       audio_port_handle_t *portId) = 0;
     virtual status_t startOutput(audio_io_handle_t output,
                                  audio_stream_type_t stream,
@@ -86,7 +86,7 @@
                               uid_t uid,
                               const audio_config_base_t *config,
                               audio_input_flags_t flags,
-                              audio_port_handle_t selectedDeviceId,
+                              audio_port_handle_t *selectedDeviceId,
                               audio_port_handle_t *portId) = 0;
     virtual status_t startInput(audio_io_handle_t input,
                                 audio_session_t session) = 0;
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index c379c89..d850aa9 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -306,14 +306,14 @@
                                             &fullConfig,
                                             (audio_output_flags_t)(AUDIO_OUTPUT_FLAG_MMAP_NOIRQ |
                                                     AUDIO_OUTPUT_FLAG_DIRECT),
-                                            *deviceId, &portId);
+                                            deviceId, &portId);
     } else {
         ret = AudioSystem::getInputForAttr(attr, &io,
                                               sessionId,
                                               client.clientPid,
                                               client.clientUid,
                                               config,
-                                              AUDIO_INPUT_FLAG_MMAP_NOIRQ, *deviceId, &portId);
+                                              AUDIO_INPUT_FLAG_MMAP_NOIRQ, deviceId, &portId);
     }
     if (ret != NO_ERROR) {
         return ret;
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index df10d23..085be00 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -7650,26 +7650,28 @@
             audio_stream_type_t stream = streamType();
             audio_output_flags_t flags =
                     (audio_output_flags_t)(AUDIO_OUTPUT_FLAG_MMAP_NOIRQ | AUDIO_OUTPUT_FLAG_DIRECT);
+            audio_port_handle_t deviceId = AUDIO_PORT_HANDLE_NONE;
             ret = AudioSystem::getOutputForAttr(&mAttr, &io,
                                                 sessionId,
                                                 &stream,
                                                 client.clientUid,
                                                 &config,
                                                 flags,
-                                                AUDIO_PORT_HANDLE_NONE,
+                                                &deviceId,
                                                 &portId);
         } else {
             audio_config_base_t config;
             config.sample_rate = mSampleRate;
             config.channel_mask = mChannelMask;
             config.format = mFormat;
+            audio_port_handle_t deviceId = AUDIO_PORT_HANDLE_NONE;
             ret = AudioSystem::getInputForAttr(&mAttr, &io,
                                                   sessionId,
                                                   client.clientPid,
                                                   client.clientUid,
                                                   &config,
                                                   AUDIO_INPUT_FLAG_MMAP_NOIRQ,
-                                                  AUDIO_PORT_HANDLE_NONE,
+                                                  &deviceId,
                                                   &portId);
         }
         // APM should not chose a different input or output stream for the same set of attributes
diff --git a/services/audiopolicy/AudioPolicyInterface.h b/services/audiopolicy/AudioPolicyInterface.h
index 84e9426..c868206 100644
--- a/services/audiopolicy/AudioPolicyInterface.h
+++ b/services/audiopolicy/AudioPolicyInterface.h
@@ -122,7 +122,7 @@
                                         uid_t uid,
                                         const audio_config_t *config,
                                         audio_output_flags_t flags,
-                                        int selectedDeviceId,
+                                        audio_port_handle_t *selectedDeviceId,
                                         audio_port_handle_t *portId) = 0;
     // indicates to the audio policy manager that the output starts being used by corresponding stream.
     virtual status_t startOutput(audio_io_handle_t output,
@@ -144,7 +144,7 @@
                                      uid_t uid,
                                      const audio_config_base_t *config,
                                      audio_input_flags_t flags,
-                                     audio_port_handle_t selectedDeviceId,
+                                     audio_port_handle_t *selectedDeviceId,
                                      input_type_t *inputType,
                                      audio_port_handle_t *portId) = 0;
     // indicates to the audio policy manager that the input starts being used.
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index 732f711..194609f 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -769,7 +769,7 @@
                                               uid_t uid,
                                               const audio_config_t *config,
                                               audio_output_flags_t flags,
-                                              audio_port_handle_t selectedDeviceId,
+                                              audio_port_handle_t *selectedDeviceId,
                                               audio_port_handle_t *portId)
 {
     audio_attributes_t attributes;
@@ -813,16 +813,18 @@
     ALOGV("getOutputForAttr() usage=%d, content=%d, tag=%s flags=%08x"
             " session %d selectedDeviceId %d",
             attributes.usage, attributes.content_type, attributes.tags, attributes.flags,
-            session, selectedDeviceId);
+            session, *selectedDeviceId);
 
     *stream = streamTypefromAttributesInt(&attributes);
 
     // Explicit routing?
     sp<DeviceDescriptor> deviceDesc;
-    for (size_t i = 0; i < mAvailableOutputDevices.size(); i++) {
-        if (mAvailableOutputDevices[i]->getId() == selectedDeviceId) {
-            deviceDesc = mAvailableOutputDevices[i];
-            break;
+    if (*selectedDeviceId != AUDIO_PORT_HANDLE_NONE) {
+        for (size_t i = 0; i < mAvailableOutputDevices.size(); i++) {
+            if (mAvailableOutputDevices[i]->getId() == *selectedDeviceId) {
+                deviceDesc = mAvailableOutputDevices[i];
+                break;
+            }
         }
     }
     mOutputRoutes.addRoute(session, *stream, SessionRoute::SOURCE_TYPE_NA, deviceDesc, uid);
@@ -845,6 +847,12 @@
         return INVALID_OPERATION;
     }
 
+    DeviceVector outputDevices = mAvailableOutputDevices.getDevicesFromType(device);
+    *selectedDeviceId = outputDevices.size() > 0 ? outputDevices.itemAt(0)->getId()
+            : AUDIO_PORT_HANDLE_NONE;
+
+    ALOGV("  getOutputForAttr() returns output %d selectedDeviceId %d", *output, *selectedDeviceId);
+
     return NO_ERROR;
 }
 
@@ -1085,8 +1093,6 @@
     ALOGW_IF((output == 0), "getOutput() could not find output for stream %d, samplingRate %d,"
             "format %d, channels %x, flags %x", stream, samplingRate, format, channelMask, flags);
 
-    ALOGV("  getOutputForDevice() returns output %d", output);
-
     return output;
 }
 
@@ -1481,7 +1487,7 @@
                                              uid_t uid,
                                              const audio_config_base_t *config,
                                              audio_input_flags_t flags,
-                                             audio_port_handle_t selectedDeviceId,
+                                             audio_port_handle_t *selectedDeviceId,
                                              input_type_t *inputType,
                                              audio_port_handle_t *portId)
 {
@@ -1511,10 +1517,12 @@
 
     // Explicit routing?
     sp<DeviceDescriptor> deviceDesc;
-    for (size_t i = 0; i < mAvailableInputDevices.size(); i++) {
-        if (mAvailableInputDevices[i]->getId() == selectedDeviceId) {
-            deviceDesc = mAvailableInputDevices[i];
-            break;
+    if (*selectedDeviceId != AUDIO_PORT_HANDLE_NONE) {
+        for (size_t i = 0; i < mAvailableInputDevices.size(); i++) {
+            if (mAvailableInputDevices[i]->getId() == *selectedDeviceId) {
+                deviceDesc = mAvailableInputDevices[i];
+                break;
+            }
         }
     }
     mInputRoutes.addRoute(session, SessionRoute::STREAM_TYPE_NA, inputSource, deviceDesc, uid);
@@ -1565,7 +1573,13 @@
         return INVALID_OPERATION;
     }
 
-    ALOGV("getInputForAttr() returns input type = %d", *inputType);
+    DeviceVector inputDevices = mAvailableInputDevices.getDevicesFromType(device);
+    *selectedDeviceId = inputDevices.size() > 0 ? inputDevices.itemAt(0)->getId()
+            : AUDIO_PORT_HANDLE_NONE;
+
+    ALOGV("getInputForAttr() returns input %d type %d selectedDeviceId %d",
+            *input, *inputType, *selectedDeviceId);
+
     return NO_ERROR;
 }
 
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.h b/services/audiopolicy/managerdefault/AudioPolicyManager.h
index c62ba25..e8cae79 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.h
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.h
@@ -116,7 +116,7 @@
                                           uid_t uid,
                                           const audio_config_t *config,
                                           audio_output_flags_t flags,
-                                          audio_port_handle_t selectedDeviceId,
+                                          audio_port_handle_t *selectedDeviceId,
                                           audio_port_handle_t *portId);
         virtual status_t startOutput(audio_io_handle_t output,
                                      audio_stream_type_t stream,
@@ -133,7 +133,7 @@
                                          uid_t uid,
                                          const audio_config_base_t *config,
                                          audio_input_flags_t flags,
-                                         audio_port_handle_t selectedDeviceId,
+                                         audio_port_handle_t *selectedDeviceId,
                                          input_type_t *inputType,
                                          audio_port_handle_t *portId);
 
diff --git a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
index 8a2f1dc..7d7cd93 100644
--- a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
+++ b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
@@ -167,7 +167,7 @@
                                               uid_t uid,
                                               const audio_config_t *config,
                                               audio_output_flags_t flags,
-                                              audio_port_handle_t selectedDeviceId,
+                                              audio_port_handle_t *selectedDeviceId,
                                               audio_port_handle_t *portId)
 {
     if (mAudioPolicyManager == NULL) {
@@ -277,7 +277,7 @@
                                              uid_t uid,
                                              const audio_config_base_t *config,
                                              audio_input_flags_t flags,
-                                             audio_port_handle_t selectedDeviceId,
+                                             audio_port_handle_t *selectedDeviceId,
                                              audio_port_handle_t *portId)
 {
     if (mAudioPolicyManager == NULL) {
diff --git a/services/audiopolicy/service/AudioPolicyService.h b/services/audiopolicy/service/AudioPolicyService.h
index 2cd26ac..35542f1 100644
--- a/services/audiopolicy/service/AudioPolicyService.h
+++ b/services/audiopolicy/service/AudioPolicyService.h
@@ -82,7 +82,7 @@
                                       uid_t uid,
                                       const audio_config_t *config,
                                       audio_output_flags_t flags,
-                                      audio_port_handle_t selectedDeviceId,
+                                      audio_port_handle_t *selectedDeviceId,
                                       audio_port_handle_t *portId);
     virtual status_t startOutput(audio_io_handle_t output,
                                  audio_stream_type_t stream,
@@ -100,7 +100,7 @@
                                      uid_t uid,
                                      const audio_config_base_t *config,
                                      audio_input_flags_t flags,
-                                     audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE,
+                                     audio_port_handle_t *selectedDeviceId = NULL,
                                      audio_port_handle_t *portId = NULL);
     virtual status_t startInput(audio_io_handle_t input,
                                 audio_session_t session);