diff options
Diffstat (limited to 'services/audioflinger')
| -rw-r--r-- | services/audioflinger/AudioFlinger.cpp | 28 | ||||
| -rw-r--r-- | services/audioflinger/AudioFlinger.h | 3 | ||||
| -rw-r--r-- | services/audioflinger/Threads.cpp | 27 | ||||
| -rw-r--r-- | services/audioflinger/Threads.h | 20 | 
4 files changed, 42 insertions, 36 deletions
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp index 52fce34..8f1e050 100644 --- a/services/audioflinger/AudioFlinger.cpp +++ b/services/audioflinger/AudioFlinger.cpp @@ -1252,11 +1252,9 @@ void AudioFlinger::registerClient(const sp<IAudioFlingerClient>& client)      if (client == 0) {          return;      } -    bool clientAdded = false; +    pid_t pid = IPCThreadState::self()->getCallingPid();      {          Mutex::Autolock _cl(mClientLock); - -        pid_t pid = IPCThreadState::self()->getCallingPid();          if (mNotificationClients.indexOfKey(pid) < 0) {              sp<NotificationClient> notificationClient = new NotificationClient(this,                                                                                  client, @@ -1267,22 +1265,19 @@ void AudioFlinger::registerClient(const sp<IAudioFlingerClient>& client)              sp<IBinder> binder = IInterface::asBinder(client);              binder->linkToDeath(notificationClient); -            clientAdded = true;          }      }      // mClientLock should not be held here because ThreadBase::sendIoConfigEvent() will lock the      // ThreadBase mutex and the locking order is ThreadBase::mLock then AudioFlinger::mClientLock. -    if (clientAdded) { -        // the config change is always sent from playback or record threads to avoid deadlock -        // with AudioSystem::gLock -        for (size_t i = 0; i < mPlaybackThreads.size(); i++) { -            mPlaybackThreads.valueAt(i)->sendIoConfigEvent(AUDIO_OUTPUT_OPENED); -        } +    // the config change is always sent from playback or record threads to avoid deadlock +    // with AudioSystem::gLock +    for (size_t i = 0; i < mPlaybackThreads.size(); i++) { +        mPlaybackThreads.valueAt(i)->sendIoConfigEvent(AUDIO_OUTPUT_OPENED, pid); +    } -        for (size_t i = 0; i < mRecordThreads.size(); i++) { -            mRecordThreads.valueAt(i)->sendIoConfigEvent(AUDIO_INPUT_OPENED); -        } +    for (size_t i = 0; i < mRecordThreads.size(); i++) { +        mRecordThreads.valueAt(i)->sendIoConfigEvent(AUDIO_INPUT_OPENED, pid);      }  } @@ -1316,12 +1311,15 @@ void AudioFlinger::removeNotificationClient(pid_t pid)  }  void AudioFlinger::ioConfigChanged(audio_io_config_event event, -                                   const sp<AudioIoDescriptor>& ioDesc) +                                   const sp<AudioIoDescriptor>& ioDesc, +                                   pid_t pid)  {      Mutex::Autolock _l(mClientLock);      size_t size = mNotificationClients.size();      for (size_t i = 0; i < size; i++) { -        mNotificationClients.valueAt(i)->audioFlingerClient()->ioConfigChanged(event, ioDesc); +        if ((pid == 0) || (mNotificationClients.keyAt(i) == pid)) { +            mNotificationClients.valueAt(i)->audioFlingerClient()->ioConfigChanged(event, ioDesc); +        }      }  } diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h index d087ced..4f7e27d 100644 --- a/services/audioflinger/AudioFlinger.h +++ b/services/audioflinger/AudioFlinger.h @@ -559,7 +559,8 @@ private:                float streamVolume_l(audio_stream_type_t stream) const                                  { return mStreamTypes[stream].volume; }                void ioConfigChanged(audio_io_config_event event, -                                   const sp<AudioIoDescriptor>& ioDesc); +                                   const sp<AudioIoDescriptor>& ioDesc, +                                   pid_t pid = 0);                // Allocate an audio_io_handle_t, session ID, effect ID, or audio_module_handle_t.                // They all share the same ID space, but the namespaces are actually independent diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp index d3ea9d8..0880c5d 100644 --- a/services/audioflinger/Threads.cpp +++ b/services/audioflinger/Threads.cpp @@ -532,7 +532,8 @@ AudioFlinger::ThreadBase::ThreadBase(const sp<AudioFlinger>& audioFlinger, audio          // RecordThread::readInputParameters_l()          //FIXME: mStandby should be true here. Is this some kind of hack?          mStandby(false), mOutDevice(outDevice), mInDevice(inDevice), -        mPrevInDevice(AUDIO_DEVICE_NONE), mAudioSource(AUDIO_SOURCE_DEFAULT), mId(id), +        mPrevOutDevice(AUDIO_DEVICE_NONE), mPrevInDevice(AUDIO_DEVICE_NONE), +        mAudioSource(AUDIO_SOURCE_DEFAULT), mId(id),          // mName will be set by concrete (non-virtual) subclass          mDeathRecipient(new PMDeathRecipient(this)),          mSystemReady(systemReady) @@ -627,16 +628,16 @@ status_t AudioFlinger::ThreadBase::sendConfigEvent_l(sp<ConfigEvent>& event)      return status;  } -void AudioFlinger::ThreadBase::sendIoConfigEvent(audio_io_config_event event) +void AudioFlinger::ThreadBase::sendIoConfigEvent(audio_io_config_event event, pid_t pid)  {      Mutex::Autolock _l(mLock); -    sendIoConfigEvent_l(event); +    sendIoConfigEvent_l(event, pid);  }  // sendIoConfigEvent_l() must be called with ThreadBase::mLock held -void AudioFlinger::ThreadBase::sendIoConfigEvent_l(audio_io_config_event event) +void AudioFlinger::ThreadBase::sendIoConfigEvent_l(audio_io_config_event event, pid_t pid)  { -    sp<ConfigEvent> configEvent = (ConfigEvent *)new IoConfigEvent(event); +    sp<ConfigEvent> configEvent = (ConfigEvent *)new IoConfigEvent(event, pid);      sendConfigEvent_l(configEvent);  } @@ -706,7 +707,7 @@ void AudioFlinger::ThreadBase::processConfigEvents_l()          } break;          case CFG_EVENT_IO: {              IoConfigEventData *data = (IoConfigEventData *)event->mData.get(); -            ioConfigChanged(data->mEvent); +            ioConfigChanged(data->mEvent, data->mPid);          } break;          case CFG_EVENT_SET_PARAMETER: {              SetParameterConfigEventData *data = (SetParameterConfigEventData *)event->mData.get(); @@ -1999,7 +2000,7 @@ String8 AudioFlinger::PlaybackThread::getParameters(const String8& keys)      return out_s8;  } -void AudioFlinger::PlaybackThread::ioConfigChanged(audio_io_config_event event) { +void AudioFlinger::PlaybackThread::ioConfigChanged(audio_io_config_event event, pid_t pid) {      sp<AudioIoDescriptor> desc = new AudioIoDescriptor();      ALOGV("PlaybackThread::ioConfigChanged, thread %p, event %d", this, event); @@ -2021,7 +2022,7 @@ void AudioFlinger::PlaybackThread::ioConfigChanged(audio_io_config_event event)      default:          break;      } -    mAudioFlinger->ioConfigChanged(event, desc); +    mAudioFlinger->ioConfigChanged(event, desc, pid);  }  void AudioFlinger::PlaybackThread::writeCallback() @@ -3133,7 +3134,10 @@ status_t AudioFlinger::PlaybackThread::createAudioPatch_l(const struct audio_pat      for (size_t i = 0; i < mEffectChains.size(); i++) {          mEffectChains[i]->setDevice_l(type);      } -    bool configChanged = mOutDevice != type; + +    // mPrevOutDevice is the latest device set by createAudioPatch_l(). It is not set when +    // the thread is created so that the first patch creation triggers an ioConfigChanged callback +    bool configChanged = mPrevOutDevice != type;      mOutDevice = type;      mPatch = *patch; @@ -3163,6 +3167,7 @@ status_t AudioFlinger::PlaybackThread::createAudioPatch_l(const struct audio_pat          *handle = AUDIO_PATCH_HANDLE_NONE;      }      if (configChanged) { +        mPrevOutDevice = type;          sendIoConfigEvent_l(AUDIO_OUTPUT_CONFIG_CHANGED);      }      return status; @@ -6868,7 +6873,7 @@ String8 AudioFlinger::RecordThread::getParameters(const String8& keys)      return out_s8;  } -void AudioFlinger::RecordThread::ioConfigChanged(audio_io_config_event event) { +void AudioFlinger::RecordThread::ioConfigChanged(audio_io_config_event event, pid_t pid) {      sp<AudioIoDescriptor> desc = new AudioIoDescriptor();      desc->mIoHandle = mId; @@ -6888,7 +6893,7 @@ void AudioFlinger::RecordThread::ioConfigChanged(audio_io_config_event event) {      default:          break;      } -    mAudioFlinger->ioConfigChanged(event, desc); +    mAudioFlinger->ioConfigChanged(event, desc, pid);  }  void AudioFlinger::RecordThread::readInputParameters_l() diff --git a/services/audioflinger/Threads.h b/services/audioflinger/Threads.h index 0783371..46ac300 100644 --- a/services/audioflinger/Threads.h +++ b/services/audioflinger/Threads.h @@ -104,21 +104,22 @@ public:      class IoConfigEventData : public ConfigEventData {      public: -        IoConfigEventData(audio_io_config_event event) : -            mEvent(event) {} +        IoConfigEventData(audio_io_config_event event, pid_t pid) : +            mEvent(event), mPid(pid) {}          virtual  void dump(char *buffer, size_t size) {              snprintf(buffer, size, "IO event: event %d\n", mEvent);          }          const audio_io_config_event mEvent; +        const pid_t                 mPid;      };      class IoConfigEvent : public ConfigEvent {      public: -        IoConfigEvent(audio_io_config_event event) : +        IoConfigEvent(audio_io_config_event event, pid_t pid) :              ConfigEvent(CFG_EVENT_IO) { -            mData = new IoConfigEventData(event); +            mData = new IoConfigEventData(event, pid);          }          virtual ~IoConfigEvent() {}      }; @@ -255,13 +256,13 @@ public:                                                      status_t& status) = 0;      virtual     status_t    setParameters(const String8& keyValuePairs);      virtual     String8     getParameters(const String8& keys) = 0; -    virtual     void        ioConfigChanged(audio_io_config_event event) = 0; +    virtual     void        ioConfigChanged(audio_io_config_event event, pid_t pid = 0) = 0;                  // sendConfigEvent_l() must be called with ThreadBase::mLock held                  // Can temporarily release the lock if waiting for a reply from                  // processConfigEvents_l().                  status_t    sendConfigEvent_l(sp<ConfigEvent>& event); -                void        sendIoConfigEvent(audio_io_config_event event); -                void        sendIoConfigEvent_l(audio_io_config_event event); +                void        sendIoConfigEvent(audio_io_config_event event, pid_t pid = 0); +                void        sendIoConfigEvent_l(audio_io_config_event event, pid_t pid = 0);                  void        sendPrioConfigEvent(pid_t pid, pid_t tid, int32_t prio);                  void        sendPrioConfigEvent_l(pid_t pid, pid_t tid, int32_t prio);                  status_t    sendSetParameterConfigEvent_l(const String8& keyValuePair); @@ -436,6 +437,7 @@ protected:                  bool                    mStandby;     // Whether thread is currently in standby.                  audio_devices_t         mOutDevice;   // output device                  audio_devices_t         mInDevice;    // input device +                audio_devices_t         mPrevOutDevice;   // previous output device                  audio_devices_t         mPrevInDevice;    // previous input device                  struct audio_patch      mPatch;                  audio_source_t          mAudioSource; @@ -572,7 +574,7 @@ public:                                  { return android_atomic_acquire_load(&mSuspended) > 0; }      virtual     String8     getParameters(const String8& keys); -    virtual     void        ioConfigChanged(audio_io_config_event event); +    virtual     void        ioConfigChanged(audio_io_config_event event, pid_t pid = 0);                  status_t    getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames);                  // FIXME rename mixBuffer() to sinkBuffer() and remove int16_t* dependency.                  // Consider also removing and passing an explicit mMainBuffer initialization @@ -1254,7 +1256,7 @@ public:                                                 status_t& status);      virtual void        cacheParameters_l() {}      virtual String8     getParameters(const String8& keys); -    virtual void        ioConfigChanged(audio_io_config_event event); +    virtual void        ioConfigChanged(audio_io_config_event event, pid_t pid = 0);      virtual status_t    createAudioPatch_l(const struct audio_patch *patch,                                             audio_patch_handle_t *handle);      virtual status_t    releaseAudioPatch_l(const audio_patch_handle_t handle);  | 
