C++程序  |  173行  |  6.31 KB

/*
 * Copyright (C) 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#define LOG_TAG "ATVAudioPolicyManager"
//#define LOG_NDEBUG 0
#include <media/AudioParameter.h>
#include <media/mediarecorder.h>
#include <utils/Log.h>
#include <utils/String16.h>
#include <utils/String8.h>
#include <utils/StrongPointer.h>

#include "AudioHardwareOutput.h"
#include "ATVAudioPolicyManager.h"

#ifdef REMOTE_CONTROL_INTERFACE
#include <IRemoteControlService.h>
#endif


namespace android {
extern AudioHardwareOutput gAudioHardwareOutput;

// ----------------------------------------------------------------------------
// Common audio policy manager code is implemented in AudioPolicyManager class
// ----------------------------------------------------------------------------

// ---  class factory


extern "C" AudioPolicyInterface* createAudioPolicyManager(
        AudioPolicyClientInterface *clientInterface)
{
    return new ATVAudioPolicyManager(clientInterface);
}

extern "C" void destroyAudioPolicyManager(AudioPolicyInterface *interface)
{
    delete interface;
}

ATVAudioPolicyManager::ATVAudioPolicyManager(
        AudioPolicyClientInterface *clientInterface)
    : AudioPolicyManager(clientInterface), mForceSubmixInputSelection(false)
{
}

float ATVAudioPolicyManager::computeVolume(audio_stream_type_t stream,
                                           int index,
                                           audio_devices_t device)
{
    // We only use master volume, so all audio flinger streams
    // should be set to maximum
    (void)stream;
    (void)index;
    (void)device;
    return 0.0; // no attenuation == 0.0dB
}

status_t ATVAudioPolicyManager::setDeviceConnectionState(audio_devices_t device,
                                                         audio_policy_dev_state_t state,
                                                         const char *device_address,
                                                         const char *device_name)
{
    audio_devices_t tmp = AUDIO_DEVICE_NONE;;
    ALOGE("setDeviceConnectionState %08x %x %s", device, state,
          device_address ? device_address : "(null)");

    // If the input device is the remote submix and an address starting with "force=" was
    // specified, enable "force=1" / disable "force=0" the forced selection of the remote submix
    // input device over hardware input devices (e.g RemoteControl).
    if (device == AUDIO_DEVICE_IN_REMOTE_SUBMIX && device_address) {
        AudioParameter parameters = AudioParameter(String8(device_address));
        int forceValue;
        if (parameters.getInt(String8("force"), forceValue) == OK) {
            mForceSubmixInputSelection = forceValue != 0;
        }
    }

    if (audio_is_output_device(device)) {
      switch (state) {
          case AUDIO_POLICY_DEVICE_STATE_AVAILABLE:
              tmp = mAvailableOutputDevices.types() | device;
              break;

          case AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE:
              tmp = mAvailableOutputDevices.types() & ~device;
              break;
          default:
              ALOGE("setDeviceConnectionState() invalid state: %x", state);
              return BAD_VALUE;
      }

      gAudioHardwareOutput.updateRouting(tmp);
      tmp = mAvailableOutputDevices.types();
    }

    status_t ret = 0;
    if (device != AUDIO_DEVICE_IN_REMOTE_SUBMIX) {
      ret = AudioPolicyManager::setDeviceConnectionState(
                    device, state, device_address, device_name);
    }

    if (audio_is_output_device(device)) {
      if (tmp != mAvailableOutputDevices.types())
          gAudioHardwareOutput.updateRouting(mAvailableOutputDevices.types());
    }

    return ret;
}

audio_devices_t ATVAudioPolicyManager::getDeviceForInputSource(audio_source_t inputSource)
{
    uint32_t device = AUDIO_DEVICE_NONE;
    bool usePhysRemote = true;

    if (inputSource == AUDIO_SOURCE_VOICE_RECOGNITION) {
#ifdef REMOTE_CONTROL_INTERFACE
      ALOGI("Using REMOTE_CONTROL_INTERFACE.");
      // Check if remote is actually connected or we should move on
      sp<IRemoteControlService> service = IRemoteControlService::getInstance();
      if (service == NULL) {
          ALOGV("getDeviceForInputSource No RemoteControl service detected, ignoring");
          usePhysRemote = false;
      } else if (!service->hasActiveRemote()) {
          if (mForceSubmixInputSelection == false && service->hasConnectedRemotes()) {
              ALOGV("getDeviceForInputSource connected remote and submix not forced");
              usePhysRemote = true;
          } else {
              ALOGV("getDeviceForInputSource No active connected device, passing onto submix");
              usePhysRemote = false;
          }
      }
#endif
      ALOGV("getDeviceForInputSource %s %s", usePhysRemote ? "use physical" : "",
          mForceSubmixInputSelection ? "use virtual" : "");
      audio_devices_t availableDeviceTypes = mAvailableInputDevices.types() &
                                                ~AUDIO_DEVICE_BIT_IN;
      if (availableDeviceTypes & AUDIO_DEVICE_IN_WIRED_HEADSET &&
            usePhysRemote) {
          // User a wired headset (physical remote) if available, connected and active
          ALOGV("Wired Headset available");
          device = AUDIO_DEVICE_IN_WIRED_HEADSET;
      } else if (availableDeviceTypes & AUDIO_DEVICE_IN_REMOTE_SUBMIX &&
            mForceSubmixInputSelection) {
          // REMOTE_SUBMIX should always be avaible, let's make sure it's being forced at the moment
          ALOGV("Virtual remote available");
          device = AUDIO_DEVICE_IN_REMOTE_SUBMIX;
      } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_DEVICE) {
          ALOGV("Use USB audio input");
          device = AUDIO_DEVICE_IN_USB_DEVICE;
      }
    }

    ALOGV("getDeviceForInputSource() input source %d, device %08x", inputSource, device);
    return device;
}

}  // namespace android