status_t BufferQueue::disconnect(int api) { ATRACE_CALL(); ST_LOGV("disconnect: api=%d", api); int err = NO_ERROR; sp<ConsumerListener> listener; { // Scope for the lock Mutex::Autolock lock(mMutex); if (mAbandoned) { // it is not really an error to disconnect after the surface // has been abandoned, it should just be a no-op. return NO_ERROR; } switch (api) { case NATIVE_WINDOW_API_EGL: case NATIVE_WINDOW_API_CPU: case NATIVE_WINDOW_API_MEDIA: case NATIVE_WINDOW_API_CAMERA: if (mConnectedApi == api) { drainQueueAndFreeBuffersLocked(); mConnectedApi = NO_CONNECTED_API; mDequeueCondition.broadcast(); listener = mConsumerListener; } else { ST_LOGE("disconnect: connected to another api (cur=%d, req=%d)", mConnectedApi, api); err = -EINVAL; } break; default: ST_LOGE("disconnect: unknown API %d", api); err = -EINVAL; break; } } if (listener != NULL) { listener->onBuffersReleased(); } return err; }
status_t SurfaceTexture::disconnect(int api) { ST_LOGV("disconnect: api=%d", api); Mutex::Autolock lock(mMutex); if (mAbandoned) { // it is not really an error to disconnect after the surface // has been abandoned, it should just be a no-op. return NO_ERROR; } int err = NO_ERROR; switch (api) { case NATIVE_WINDOW_API_EGL: case NATIVE_WINDOW_API_CPU: case NATIVE_WINDOW_API_MEDIA: case NATIVE_WINDOW_API_CAMERA: if (mConnectedApi == api) { drainQueueAndFreeBuffersLocked(); mConnectedApi = NO_CONNECTED_API; mNextCrop.makeInvalid(); mNextScalingMode = NATIVE_WINDOW_SCALING_MODE_FREEZE; mNextTransform = 0; mDequeueCondition.signal(); } else { ST_LOGE("disconnect: connected to another api (cur=%d, req=%d)", mConnectedApi, api); err = -EINVAL; } break; default: ST_LOGE("disconnect: unknown API %d", api); err = -EINVAL; break; } return err; }