diff options
Diffstat (limited to 'services')
12 files changed, 222 insertions, 75 deletions
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp index 5002099..48f7514 100644 --- a/services/audioflinger/AudioFlinger.cpp +++ b/services/audioflinger/AudioFlinger.cpp @@ -1416,6 +1416,7 @@ sp<IAudioRecord> AudioFlinger::openRecord( uint32_t sampleRate, audio_format_t format, audio_channel_mask_t channelMask, + const String16& opPackageName, size_t *frameCount, IAudioFlinger::track_flags_t *flags, pid_t tid, @@ -1435,7 +1436,7 @@ sp<IAudioRecord> AudioFlinger::openRecord( buffers.clear(); // check calling permissions - if (!recordingAllowed()) { + if (!recordingAllowed(opPackageName)) { ALOGE("openRecord() permission denied: recording not allowed"); lStatus = PERMISSION_DENIED; goto Exit; @@ -2447,6 +2448,7 @@ sp<IEffect> AudioFlinger::createEffect( int32_t priority, audio_io_handle_t io, int sessionId, + const String16& opPackageName, status_t *status, int *id, int *enabled) @@ -2543,7 +2545,7 @@ sp<IEffect> AudioFlinger::createEffect( // check recording permission for visualizer if ((memcmp(&desc.type, SL_IID_VISUALIZATION, sizeof(effect_uuid_t)) == 0) && - !recordingAllowed()) { + !recordingAllowed(opPackageName)) { lStatus = PERMISSION_DENIED; goto Exit; } diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h index e1ddcbc..3c4517f 100644 --- a/services/audioflinger/AudioFlinger.h +++ b/services/audioflinger/AudioFlinger.h @@ -120,6 +120,7 @@ public: uint32_t sampleRate, audio_format_t format, audio_channel_mask_t channelMask, + const String16& opPackageName, size_t *pFrameCount, IAudioFlinger::track_flags_t *flags, pid_t tid, @@ -216,6 +217,7 @@ public: int32_t priority, audio_io_handle_t io, int sessionId, + const String16& opPackageName, status_t *status /*non-NULL*/, int *id, int *enabled); diff --git a/services/audioflinger/ServiceUtilities.cpp b/services/audioflinger/ServiceUtilities.cpp index 8246fef..0a718fb 100644 --- a/services/audioflinger/ServiceUtilities.cpp +++ b/services/audioflinger/ServiceUtilities.cpp @@ -14,38 +14,97 @@ * limitations under the License. */ +#include <binder/AppOpsManager.h> #include <binder/IPCThreadState.h> #include <binder/IServiceManager.h> #include <binder/PermissionCache.h> #include "ServiceUtilities.h" +/* When performing permission checks we do not use permission cache for + * runtime permissions (protection level dangerous) as they may change at + * runtime. All other permissions (protection level normal and dangerous) + * can be cached as they never change. Of course all permission checked + * here are platform defined. + */ + namespace android { // Not valid until initialized by AudioFlinger constructor. It would have to be // re-initialized if the process containing AudioFlinger service forks (which it doesn't). pid_t getpid_cached; -bool recordingAllowed() { +bool recordingAllowed(const String16& opPackageName) { + // Note: We are getting the UID from the calling IPC thread state because all + // clients that perform recording create AudioRecord in their own processes + // and the system does not create AudioRecord objects on behalf of apps. This + // differs from playback where in some situations the system recreates AudioTrack + // instances associated with a client's MediaPlayer on behalf of this client. + // In the latter case we have to store the client UID and pass in along for + // security checks. + if (getpid_cached == IPCThreadState::self()->getCallingPid()) return true; static const String16 sRecordAudio("android.permission.RECORD_AUDIO"); - // don't use PermissionCache; this is not a system permission - bool ok = checkCallingPermission(sRecordAudio); - if (!ok) ALOGE("Request requires android.permission.RECORD_AUDIO"); - return ok; + + // IMPORTANT: Don't use PermissionCache - a runtime permission and may change. + const bool ok = checkCallingPermission(sRecordAudio); + if (!ok) { + ALOGE("Request requires android.permission.RECORD_AUDIO"); + return false; + } + + const uid_t uid = IPCThreadState::self()->getCallingUid(); + String16 checkedOpPackageName = opPackageName; + + // In some cases the calling code has no access to the package it runs under. + // For example, code using the wilhelm framework's OpenSL-ES APIs. In this + // case we will get the packages for the calling UID and pick the first one + // for attributing the app op. This will work correctly for runtime permissions + // as for legacy apps we will toggle the app op for all packages in the UID. + // The caveat is that the operation may be attributed to the wrong package and + // stats based on app ops may be slightly off. + if (checkedOpPackageName.size() <= 0) { + sp<IServiceManager> sm = defaultServiceManager(); + sp<IBinder> binder = sm->getService(String16("permission")); + if (binder == 0) { + ALOGE("Cannot get permission service"); + return false; + } + + sp<IPermissionController> permCtrl = interface_cast<IPermissionController>(binder); + Vector<String16> packages; + + permCtrl->getPackagesForUid(uid, packages); + + if (packages.isEmpty()) { + ALOGE("No packages for calling UID"); + return false; + } + checkedOpPackageName = packages[0]; + } + + AppOpsManager appOps; + if (appOps.noteOp(AppOpsManager::OP_RECORD_AUDIO, uid, opPackageName) + != AppOpsManager::MODE_ALLOWED) { + ALOGE("Request denied by app op OP_RECORD_AUDIO"); + return false; + } + + return true; } bool captureAudioOutputAllowed() { if (getpid_cached == IPCThreadState::self()->getCallingPid()) return true; static const String16 sCaptureAudioOutput("android.permission.CAPTURE_AUDIO_OUTPUT"); - // don't use PermissionCache; this is not a system permission - bool ok = checkCallingPermission(sCaptureAudioOutput); + // IMPORTANT: Use PermissionCache - not a runtime permission and may not change. + bool ok = PermissionCache::checkCallingPermission(sCaptureAudioOutput); if (!ok) ALOGE("Request requires android.permission.CAPTURE_AUDIO_OUTPUT"); return ok; } bool captureHotwordAllowed() { static const String16 sCaptureHotwordAllowed("android.permission.CAPTURE_AUDIO_HOTWORD"); - bool ok = checkCallingPermission(sCaptureHotwordAllowed); + // IMPORTANT: Use PermissionCache - not a runtime permission and may not change. + bool ok = PermissionCache::checkCallingPermission(sCaptureHotwordAllowed); if (!ok) ALOGE("android.permission.CAPTURE_AUDIO_HOTWORD"); return ok; } @@ -53,15 +112,16 @@ bool captureHotwordAllowed() { bool settingsAllowed() { if (getpid_cached == IPCThreadState::self()->getCallingPid()) return true; static const String16 sAudioSettings("android.permission.MODIFY_AUDIO_SETTINGS"); - // don't use PermissionCache; this is not a system permission - bool ok = checkCallingPermission(sAudioSettings); + // IMPORTANT: Use PermissionCache - not a runtime permission and may not change. + bool ok = PermissionCache::checkCallingPermission(sAudioSettings); if (!ok) ALOGE("Request requires android.permission.MODIFY_AUDIO_SETTINGS"); return ok; } bool modifyAudioRoutingAllowed() { static const String16 sModifyAudioRoutingAllowed("android.permission.MODIFY_AUDIO_ROUTING"); - bool ok = checkCallingPermission(sModifyAudioRoutingAllowed); + // IMPORTANT: Use PermissionCache - not a runtime permission and may not change. + bool ok = PermissionCache::checkCallingPermission(sModifyAudioRoutingAllowed); if (!ok) ALOGE("android.permission.MODIFY_AUDIO_ROUTING"); return ok; } @@ -69,7 +129,7 @@ bool modifyAudioRoutingAllowed() { bool dumpAllowed() { // don't optimize for same pid, since mediaserver never dumps itself static const String16 sDump("android.permission.DUMP"); - // OK to use PermissionCache; this is a system permission + // IMPORTANT: Use PermissionCache - not a runtime permission and may not change. bool ok = PermissionCache::checkCallingPermission(sDump); // convention is for caller to dump an error message to fd instead of logging here //if (!ok) ALOGE("Request requires android.permission.DUMP"); diff --git a/services/audioflinger/ServiceUtilities.h b/services/audioflinger/ServiceUtilities.h index df6f6f4..fba6dce 100644 --- a/services/audioflinger/ServiceUtilities.h +++ b/services/audioflinger/ServiceUtilities.h @@ -20,11 +20,10 @@ namespace android { extern pid_t getpid_cached; -bool recordingAllowed(); +bool recordingAllowed(const String16& opPackageName); bool captureAudioOutputAllowed(); bool captureHotwordAllowed(); bool settingsAllowed(); bool modifyAudioRoutingAllowed(); bool dumpAllowed(); - } diff --git a/services/audiopolicy/AudioPolicyInterface.h b/services/audiopolicy/AudioPolicyInterface.h index 58c65fa..9230750 100644 --- a/services/audiopolicy/AudioPolicyInterface.h +++ b/services/audiopolicy/AudioPolicyInterface.h @@ -133,6 +133,7 @@ public: audio_format_t format, audio_channel_mask_t channelMask, audio_input_flags_t flags, + audio_port_handle_t selectedDeviceId, input_type_t *inputType) = 0; // indicates to the audio policy manager that the input starts being used. virtual status_t startInput(audio_io_handle_t input, diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp index ba3fcaf..7de72de 100644 --- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp +++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp @@ -689,7 +689,7 @@ status_t AudioPolicyManager::getOutputForAttr(const audio_attributes_t *attr, break; } } - mOutputRoutes.addRoute(session, *stream, deviceDesc); + mOutputRoutes.addRoute(session, *stream, SessionRoute::SOURCE_TYPE_NA, deviceDesc); return NO_ERROR; } @@ -1226,6 +1226,7 @@ status_t AudioPolicyManager::getInputForAttr(const audio_attributes_t *attr, audio_format_t format, audio_channel_mask_t channelMask, audio_input_flags_t flags, + audio_port_handle_t selectedDeviceId, input_type_t *inputType) { ALOGV("getInputForAttr() source %d, samplingRate %d, format %d, channelMask %x," @@ -1247,6 +1248,16 @@ status_t AudioPolicyManager::getInputForAttr(const audio_attributes_t *attr, } halInputSource = inputSource; + // Explicit routing? + sp<DeviceDescriptor> deviceDesc; + 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); + if (inputSource == AUDIO_SOURCE_REMOTE_SUBMIX && strncmp(attr->tags, "addr=", strlen("addr=")) == 0) { status_t ret = mPolicyMixes.getInputMixForAttr(*attr, &policyMix); @@ -1378,6 +1389,7 @@ status_t AudioPolicyManager::getInputForAttr(const audio_attributes_t *attr, addInput(*input, inputDesc); mpClientInterface->onAudioPortListUpdate(); + return NO_ERROR; } @@ -1419,7 +1431,7 @@ status_t AudioPolicyManager::startInput(audio_io_handle_t input, } } - if (inputDesc->mRefCount == 0) { + if (inputDesc->mRefCount == 0 || mInputRoutes.hasRouteChanged(session)) { // if input maps to a dynamic policy with an activity listener, notify of state change if ((inputDesc->mPolicyMix != NULL) && ((inputDesc->mPolicyMix->mFlags & MIX_FLAG_NOTIFY_ACTIVITY) != 0)) { @@ -1427,6 +1439,9 @@ status_t AudioPolicyManager::startInput(audio_io_handle_t input, MIX_STATE_MIXING); } + // Routing? + mInputRoutes.incRouteActivity(session); + if (mInputs.activeInputsCount() == 0) { SoundTrigger::setCaptureState(true); } @@ -1479,6 +1494,10 @@ status_t AudioPolicyManager::stopInput(audio_io_handle_t input, } inputDesc->mRefCount--; + + // Routing? + mInputRoutes.decRouteActivity(session); + if (inputDesc->mRefCount == 0) { // if input maps to a dynamic policy with an activity listener, notify of state change if ((inputDesc->mPolicyMix != NULL) @@ -1521,6 +1540,10 @@ void AudioPolicyManager::releaseInput(audio_io_handle_t input, ALOGW("releaseInput() releasing unknown input %d", input); return; } + + // Routing + mInputRoutes.removeRoute(session); + sp<AudioInputDescriptor> inputDesc = mInputs.valueAt(index); ALOG_ASSERT(inputDesc != 0); @@ -3771,7 +3794,6 @@ audio_devices_t AudioPolicyManager::getNewInputDevice(audio_io_handle_t input) audio_devices_t device = getDeviceAndMixForInputSource(inputDesc->mInputSource); - ALOGV("getNewInputDevice() selected device %x", device); return device; } @@ -4291,7 +4313,15 @@ audio_devices_t AudioPolicyManager::getDeviceAndMixForInputSource(audio_source_t audio_devices_t AudioPolicyManager::getDeviceForInputSource(audio_source_t inputSource) { - return mEngine->getDeviceForInputSource(inputSource); + for (size_t routeIndex = 0; routeIndex < mInputRoutes.size(); routeIndex++) { + sp<SessionRoute> route = mInputRoutes.valueAt(routeIndex); + if (inputSource == route->mSource && route->mDeviceDescriptor != 0 + /*&& route->mActivityCount != 0*/) { + return route->mDeviceDescriptor->type(); + } + } + + return mEngine->getDeviceForInputSource(inputSource); } float AudioPolicyManager::computeVolume(audio_stream_type_t stream, @@ -4514,8 +4544,8 @@ void AudioPolicyManager::handleIncallSonification(audio_stream_type_t stream, // --- SessionRoute class implementation void AudioPolicyManager::SessionRoute::log(const char* prefix) { - ALOGI("%s[SessionRoute strm:0x%X, sess:0x%X, dev:0x%X refs:%d act:%d", - prefix, mStreamType, mSession, + ALOGI("%s[SessionRoute strm:0x%X, src:%d, sess:0x%X, dev:0x%X refs:%d act:%d", + prefix, mStreamType, mSource, mSession, mDeviceDescriptor != 0 ? mDeviceDescriptor->type() : AUDIO_DEVICE_NONE, mRefCount, mActivityCount); } @@ -4537,28 +4567,6 @@ bool AudioPolicyManager::SessionRouteMap::hasRouteChanged(audio_session_t sessio return false; } -void AudioPolicyManager::SessionRouteMap::addRoute(audio_session_t session, - audio_stream_type_t streamType, - sp<DeviceDescriptor> deviceDescriptor) -{ - sp<SessionRoute> route = indexOfKey(session) >= 0 ? valueFor(session) : 0; - if (route != NULL) { - if ((route->mDeviceDescriptor == 0 && deviceDescriptor != 0) || - (!route->mDeviceDescriptor->equals(deviceDescriptor))) { - route->mChanged = true; - } - route->mRefCount++; - route->mDeviceDescriptor = deviceDescriptor; - } else { - route = new AudioPolicyManager::SessionRoute(session, streamType, deviceDescriptor); - route->mRefCount++; - add(session, route); - if (deviceDescriptor != 0) { - route->mChanged = true; - } - } -} - void AudioPolicyManager::SessionRouteMap::removeRoute(audio_session_t session) { sp<SessionRoute> route = indexOfKey(session) >= 0 ? valueFor(session) : 0; @@ -4594,6 +4602,38 @@ void AudioPolicyManager::SessionRouteMap::log(const char* caption) { } } +void AudioPolicyManager::SessionRouteMap::addRoute(audio_session_t session, + audio_stream_type_t streamType, + audio_source_t source, + sp<DeviceDescriptor> descriptor) +{ + if (mMapType == MAPTYPE_INPUT && streamType != SessionRoute::STREAM_TYPE_NA) { + ALOGE("Adding Output Route to InputRouteMap"); + return; + } else if (mMapType == MAPTYPE_OUTPUT && source != SessionRoute::SOURCE_TYPE_NA) { + ALOGE("Adding Input Route to OutputRouteMap"); + return; + } + + sp<SessionRoute> route = indexOfKey(session) >= 0 ? valueFor(session) : 0; + + if (route != 0) { + if ((route->mDeviceDescriptor == 0 && descriptor != 0) || + (!route->mDeviceDescriptor->equals(descriptor))) { + route->mChanged = true; + } + route->mRefCount++; + route->mDeviceDescriptor = descriptor; + } else { + route = new AudioPolicyManager::SessionRoute(session, streamType, source, descriptor); + route->mRefCount++; + add(session, route); + if (descriptor != 0) { + route->mChanged = true; + } + } +} + void AudioPolicyManager::defaultAudioPolicyConfig(void) { sp<HwModule> module; diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.h b/services/audiopolicy/managerdefault/AudioPolicyManager.h index 521f6c4..b965411 100644 --- a/services/audiopolicy/managerdefault/AudioPolicyManager.h +++ b/services/audiopolicy/managerdefault/AudioPolicyManager.h @@ -131,6 +131,7 @@ public: audio_format_t format, audio_channel_mask_t channelMask, audio_input_flags_t flags, + audio_port_handle_t selectedDeviceId, input_type_t *inputType); // indicates to the audio policy manager that the input starts being used. @@ -233,45 +234,84 @@ public: routing_strategy getStrategy(audio_stream_type_t stream) const; protected: - class SessionRoute : public RefBase - { + class SessionRoute : public RefBase { public: - friend class SessionRouteMap; + // For Input (Source) routes, use STREAM_TYPE_NA ("NA" = "not applicable)for the + // streamType argument + static const audio_stream_type_t STREAM_TYPE_NA = AUDIO_STREAM_DEFAULT; + + // For Output (Sink) routes, use SOURCE_TYPE_NA ("NA" = "not applicable") for the + // source argument + + static const audio_source_t SOURCE_TYPE_NA = AUDIO_SOURCE_DEFAULT; + SessionRoute(audio_session_t session, audio_stream_type_t streamType, + audio_source_t source, sp<DeviceDescriptor> deviceDescriptor) - : mSession(session), - mStreamType(streamType), - mDeviceDescriptor(deviceDescriptor), - mRefCount(0), - mActivityCount(0), - mChanged(false) {} - - void log(const char* prefix); + : mSession(session), + mDeviceDescriptor(deviceDescriptor), + mRefCount(0), + mActivityCount(0), + mChanged(false), + mStreamType(streamType), + mSource(source) {} audio_session_t mSession; - audio_stream_type_t mStreamType; sp<DeviceDescriptor> mDeviceDescriptor; + void log(const char* prefix); + // "reference" counting int mRefCount; // +/- on references int mActivityCount; // +/- on start/stop bool mChanged; + + // for outputs + const audio_stream_type_t mStreamType; + + // for inputs + const audio_source_t mSource; }; - class SessionRouteMap: public KeyedVector<audio_session_t, sp<SessionRoute>> - { - public: + class SessionRouteMap: public KeyedVector<audio_session_t, sp<SessionRoute>> { + public: + // These constants identify the SessionRoutMap as holding EITHER input routes, + // or output routes. An error will occur if an attempt is made to add a SessionRoute + // object with mStreamType == STREAM_TYPE_NA (i.e. an input SessionRoute) to a + // SessionRoutMap that is marked for output (i.e. mMapType == SESSION_ROUTE_MAP_OUTPUT) + // and similarly for output SessionRoutes and Input SessionRouteMaps. + typedef enum { + MAPTYPE_INPUT = 0, + MAPTYPE_OUTPUT = 1 + } session_route_map_type_t; + + SessionRouteMap(session_route_map_type_t mapType) : + mMapType(mapType) { + } + bool hasRoute(audio_session_t session); - void addRoute(audio_session_t session, audio_stream_type_t streamType, - sp<DeviceDescriptor> deviceDescriptor); void removeRoute(audio_session_t session); int incRouteActivity(audio_session_t session); int decRouteActivity(audio_session_t session); bool hasRouteChanged(audio_session_t session); // also clears the changed flag void log(const char* caption); + + // Specify an Output(Sink) route by passing SessionRoute::SOURCE_TYPE_NA in the + // source argument. + // Specify an Input(Source) rout by passing SessionRoute::AUDIO_STREAM_DEFAULT + // in the streamType argument. + void addRoute(audio_session_t session, + audio_stream_type_t streamType, + audio_source_t source, + sp<DeviceDescriptor> deviceDescriptor); + + private: + // Used to mark a SessionRoute as for either inputs (mMapType == kSessionRouteMap_Input) + // or outputs (mMapType == kSessionRouteMap_Output) + const session_route_map_type_t mMapType; }; // From AudioPolicyManagerObserver @@ -535,8 +575,8 @@ protected: DeviceVector mAvailableOutputDevices; // all available output devices DeviceVector mAvailableInputDevices; // all available input devices - SessionRouteMap mOutputRoutes; - SessionRouteMap mInputRoutes; + SessionRouteMap mOutputRoutes = SessionRouteMap(SessionRouteMap::MAPTYPE_OUTPUT); + SessionRouteMap mInputRoutes = SessionRouteMap(SessionRouteMap::MAPTYPE_INPUT); StreamDescriptorCollection mStreams; // stream descriptors for volume control bool mLimitRingtoneVolume; // limit ringtone volume to music volume if headset connected diff --git a/services/audiopolicy/service/AudioPolicyEffects.cpp b/services/audiopolicy/service/AudioPolicyEffects.cpp index e6ace20..282ddeb 100644 --- a/services/audiopolicy/service/AudioPolicyEffects.cpp +++ b/services/audiopolicy/service/AudioPolicyEffects.cpp @@ -109,8 +109,8 @@ status_t AudioPolicyEffects::addInputEffects(audio_io_handle_t input, Vector <EffectDesc *> effects = mInputSources.valueAt(index)->mEffects; for (size_t i = 0; i < effects.size(); i++) { EffectDesc *effect = effects[i]; - sp<AudioEffect> fx = new AudioEffect(NULL, &effect->mUuid, -1, 0, 0, - audioSession, input); + sp<AudioEffect> fx = new AudioEffect(NULL, String16("android"), &effect->mUuid, -1, 0, + 0, audioSession, input); status_t status = fx->initCheck(); if (status != NO_ERROR && status != ALREADY_EXISTS) { ALOGW("addInputEffects(): failed to create Fx %s on source %d", @@ -254,7 +254,7 @@ status_t AudioPolicyEffects::addOutputSessionEffects(audio_io_handle_t output, Vector <EffectDesc *> effects = mOutputStreams.valueAt(index)->mEffects; for (size_t i = 0; i < effects.size(); i++) { EffectDesc *effect = effects[i]; - sp<AudioEffect> fx = new AudioEffect(NULL, &effect->mUuid, 0, 0, 0, + sp<AudioEffect> fx = new AudioEffect(NULL, String16("android"), &effect->mUuid, 0, 0, 0, audioSession, output); status_t status = fx->initCheck(); if (status != NO_ERROR && status != ALREADY_EXISTS) { diff --git a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp index e764eda..5ceb1cf 100644 --- a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp +++ b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp @@ -150,7 +150,7 @@ status_t AudioPolicyService::getOutputForAttr(const audio_attributes_t *attr, audio_format_t format, audio_channel_mask_t channelMask, audio_output_flags_t flags, - int mSelectedDeviceId, + audio_port_handle_t selectedDeviceId, const audio_offload_info_t *offloadInfo) { if (mAudioPolicyManager == NULL) { @@ -159,7 +159,7 @@ status_t AudioPolicyService::getOutputForAttr(const audio_attributes_t *attr, ALOGV("getOutput()"); Mutex::Autolock _l(mLock); return mAudioPolicyManager->getOutputForAttr(attr, output, session, stream, samplingRate, - format, channelMask, flags, mSelectedDeviceId, offloadInfo); + format, channelMask, flags, selectedDeviceId, offloadInfo); } status_t AudioPolicyService::startOutput(audio_io_handle_t output, @@ -251,7 +251,8 @@ status_t AudioPolicyService::getInputForAttr(const audio_attributes_t *attr, uint32_t samplingRate, audio_format_t format, audio_channel_mask_t channelMask, - audio_input_flags_t flags) + audio_input_flags_t flags, + audio_port_handle_t selectedDeviceId) { if (mAudioPolicyManager == NULL) { return NO_INIT; @@ -273,7 +274,7 @@ status_t AudioPolicyService::getInputForAttr(const audio_attributes_t *attr, // the audio_in_acoustics_t parameter is ignored by get_input() status = mAudioPolicyManager->getInputForAttr(attr, input, session, samplingRate, format, channelMask, - flags, &inputType); + flags, selectedDeviceId, &inputType); audioPolicyEffects = mAudioPolicyEffects; if (status == NO_ERROR) { diff --git a/services/audiopolicy/service/AudioPolicyInterfaceImplLegacy.cpp b/services/audiopolicy/service/AudioPolicyInterfaceImplLegacy.cpp index f783437..433e712 100644 --- a/services/audiopolicy/service/AudioPolicyInterfaceImplLegacy.cpp +++ b/services/audiopolicy/service/AudioPolicyInterfaceImplLegacy.cpp @@ -237,7 +237,8 @@ status_t AudioPolicyService::getInputForAttr(const audio_attributes_t *attr, uint32_t samplingRate, audio_format_t format, audio_channel_mask_t channelMask, - audio_input_flags_t flags __unused) + audio_input_flags_t flags __unused, + audio_port_handle_t selectedDeviceId __unused) { if (mpAudioPolicy == NULL) { return NO_INIT; @@ -568,7 +569,7 @@ status_t AudioPolicyService::getOutputForAttr(const audio_attributes_t *attr, audio_format_t format, audio_channel_mask_t channelMask, audio_output_flags_t flags, - int selectedDeviceId __unused, + audio_port_handle_t selectedDeviceId __unused, const audio_offload_info_t *offloadInfo) { if (attr != NULL) { diff --git a/services/audiopolicy/service/AudioPolicyService.h b/services/audiopolicy/service/AudioPolicyService.h index 4e25d33..07ea96b 100644 --- a/services/audiopolicy/service/AudioPolicyService.h +++ b/services/audiopolicy/service/AudioPolicyService.h @@ -84,7 +84,7 @@ public: audio_format_t format = AUDIO_FORMAT_DEFAULT, audio_channel_mask_t channelMask = 0, audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE, - int selectedDeviceId = AUDIO_PORT_HANDLE_NONE, + audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE, const audio_offload_info_t *offloadInfo = NULL); virtual status_t startOutput(audio_io_handle_t output, audio_stream_type_t stream, @@ -101,7 +101,8 @@ public: uint32_t samplingRate, audio_format_t format, audio_channel_mask_t channelMask, - audio_input_flags_t flags); + audio_input_flags_t flags, + audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE); virtual status_t startInput(audio_io_handle_t input, audio_session_t session); virtual status_t stopInput(audio_io_handle_t input, diff --git a/services/camera/libcameraservice/api1/client2/CallbackProcessor.cpp b/services/camera/libcameraservice/api1/client2/CallbackProcessor.cpp index 5c8f750..88c5811 100644 --- a/services/camera/libcameraservice/api1/client2/CallbackProcessor.cpp +++ b/services/camera/libcameraservice/api1/client2/CallbackProcessor.cpp @@ -395,7 +395,7 @@ status_t CallbackProcessor::processNewCallback(sp<Camera2Client> &client) { heapIdx = mCallbackHeapHead; - mCallbackHeapHead = (mCallbackHeapHead + 1) & kCallbackHeapCount; + mCallbackHeapHead = (mCallbackHeapHead + 1) % kCallbackHeapCount; mCallbackHeapFree--; // TODO: Get rid of this copy by passing the gralloc queue all the way |