audiopolicymanagertest-AudioPatchの作成

11215 ワード

audiopolicymanagertest TEST_F(…)学習
要約
audiopolicymanagertest.cppでgtestフレームワークを使用して、コード呼び出しRUN_ALL_TESTS()の場合、TEST_F(…)の主な流れは以下の通りである.
  • はtestsuiteクラスSetUp()を呼び出してベースの初期化作業を行う.
  • TEST_を実行Fコードブロック内のコード.
  • testsuiteクラスTearDown)を呼び出して破棄作業を行う.

  • AudioPolicyManagerTest::SetUp()分析
    コードは次のとおりです.
    void AudioPolicyManagerTest::SetUp() {
        mClient.reset(new AudioPolicyManagerTestClient);
        mManager.reset(new AudioPolicyTestManager(mClient.get()));
        mManager->getConfig().setDefault();
        ASSERT_EQ(NO_ERROR, mManager->initialize());
        ASSERT_EQ(NO_ERROR, mManager->initCheck());
    }
    
  • は、AudioPolicyManagerTestClientAudioPolicyTestManagerの2つのオブジェクトを作成します.AudioPolicyTestManagerを作成すると、前に作成したクライアントが登録され、サウンドカーブmVolumeCurvesaudioPolicyConfigのオブジェクトが作成されます.
  •     mpClientInterface(clientInterface),
    ...
        mVolumeCurves(new StreamDescriptorCollection()),
        mConfig(mHwModulesAll, mAvailableOutputDevices, mAvailableInputDevices,
                mDefaultOutputDevice),
    ...
    
  • audiopolicyconfigのデフォルト構成
  • を設定する
  • DeviceDescriptor型の入出力デバイスを作成し、mTypeはいずれも:AUDIO_PORT_TYPE_DEVICEである.DeviceVector型の配列にそれぞれ加えた.
  • は、「primary」という名前のHwModuleモジュールを作成します.
  • は、mTypeがOutputProfileであるAUDIO_PORT_TYPE_MIXのオブジェクトを作成します.mModuleを2に向ける.作成されたHwModuleモジュール.
  • は、AudioProfileオブジェクトを作成し、そのオブジェクトのオーディオフォーマット、チャネル数、サンプリングフォーマットなどを初期化し、最後に作成したAudioProfileオブジェクトをOutputProfileオブジェクトの配列メンバーに追加する(mProfiles).
  • DeviceVectorタイプの出力デバイス配列をOutputProfileオブジェクトに追加し、出力シーンのFlagを設定します.
  • 入力シーンを作成し、HwModuleを入力シーンに関連付け、オーディオシーンを作成して入力シーンに追加し、デフォルトの入力デバイス配列を入力シーンでサポートされている配列に追加します.
  • は最後に、入出力シーンをHwModuleに登録し、HwModulemHwModulesリストに追加する.
  • AudioPolicyTestManager初期化
  • は、各ストリームに対応するポリシーの音量曲線を初期化する.
  • // VolumeProfiles    :
        // default volume curves per stream and device category. See initializeVolumeCurves()
       static const VolumeCurvePoint *sVolumeProfiles[AUDIO_STREAM_CNT][DEVICE_CATEGORY_CNT];
    //          :
    const VolumeCurvePoint *Gains::sVolumeProfiles[AUDIO_STREAM_CNT]
                                                     [DEVICE_CATEGORY_CNT] = {
       { // AUDIO_STREAM_VOICE_CALL
           Gains::sDefaultVoiceVolumeCurve, // DEVICE_CATEGORY_HEADSET
           Gains::sSpeakerVoiceVolumeCurve, // DEVICE_CATEGORY_SPEAKER
           Gains::sSpeakerVoiceVolumeCurve, // DEVICE_CATEGORY_EARPIECE
           Gains::sDefaultMediaVolumeCurve, // DEVICE_CATEGORY_EXT_MEDIA
           Gains::sHearingAidVolumeCurve     // DEVICE_CATEGORY_HEARING_AID
       },
       ...
    }
    // VolumeCurvePoint      :
    const VolumeCurvePoint
    Gains::sDefaultVoiceVolumeCurve[Volume::VOLCNT] = {
       {0, -42.0f}, {33, -28.0f}, {66, -14.0f}, {100, 0.0f}
    };
    //   VolumeCurvePoint        ,mIndex(  ),mDBAttenuation(DB    )
    
  • Engineエンジンを作成します.
  • は、現在有効な入出力デバイスタイプを取得する.
  •     // mAvailableOutputDevices and mAvailableInputDevices now contain all attached devices
       // open all output streams needed to access attached devices
       audio_devices_t outputDeviceTypes = mAvailableOutputDevices.types();
       audio_devices_t inputDeviceTypes = mAvailableInputDevices.types() & ~AUDIO_DEVICE_BIT_IN;
       
       //           :
       void DeviceVector::refreshTypes()
       {
           mDeviceTypes = AUDIO_DEVICE_NONE;
           for (size_t i = 0; i < size(); i++) {
               mDeviceTypes |= itemAt(i)->type();
           }
           ALOGV("DeviceVector::refreshTypes() mDeviceTypes %08x", mDeviceTypes);
       }
    
  • は、mHwModulesAllを巡回し、各HwModuleオブジェクトを初期化する.まずhwModuleが指定したハードウェアライブラリをロードし、ロードしたハンドルをHwModuleのmHandleメンバー変数に戻し、次にHwModuleが対応する出力シーンを順次巡回し、出力ストリームを開くなどの操作を行い、最後にHwModuleが対応する入力シーンを巡回し、入力ストリームを開く/閉じるなどの操作を行う.
  •     for (const auto& hwModule : mHwModulesAll) {
           hwModule->setHandle(mpClientInterface->loadHwModule(hwModule->getName()));
           if (hwModule->getHandle() == AUDIO_MODULE_HANDLE_NONE) {
               ALOGW("could not open HW module %s", hwModule->getName());
               continue;
           }
           mHwModules.push_back(hwModule);
           // open all output streams needed to access attached devices
           // except for direct output streams that are only opened when they are actually
           // required by an app.
           // This also validates mAvailableOutputDevices list
           for (const auto& outProfile : hwModule->getOutputProfiles()) {
                 ...
             }
           // open input streams needed to access attached devices to validate
           // mAvailableInputDevices list
           for (const auto& inProfile : hwModule->getInputProfiles()) {
                 ...
           }
       }
    
  • HwModuleの出力シーンを巡ります.OutputProfileでサポートされているデバイスタイプを取得し、SwAudioOutputDescriptorインスタンスを作成し、OutputProfileおよびmpClientInterfaceを登録します.OutputProfile以前に登録されたオーディオフォーマット、チャネル数、サンプリングレートをmPortによって取得し、それぞれに対応するメンバー変数を初期化する.その後、OutputProfileのFlagを取得し、mFlagに設定する.OutputProfileの構成(デバイス)タイプを取得し、各OutputProfileはprofileTypeに対応する.サポートされているデバイス配列では、profileTypeによって対応するDeviceDescriptorデバイス配列を検索し、最初のDeviceDescriptorのaddressを取得します.SwAudioOutputDescriptorのopenを呼び出してoutputstreamを開きます.現在のHwModuleをmAvailableOutputDevicesに関連付けて、mAvailableOutputDevices接続ステータスを更新します.SwAudioOutputDescriptorをmPrimaryOutputに登録します.outputとSwAudioOutputDescriptorのキー値のペアをmOutputsに追加します.SwAudioOutputDescriptorオブジェクトの各ストリームのカーブボリュームを設定します.現在有効な出力をmMusicEffectOutputに設定します.出力デバイスを設定し、SwAudioOutputDescriptorオブジェクトのpatchを構成し、mpClientInterface->createAudioPatchを呼び出してpatchを作成し、streamボリュームを適用します.
  • // open all output streams needed to access attached devices
    // except for direct output streams that are only opened when they are actually
    // required by an app.
    // This also validates mAvailableOutputDevices list
    for (const auto& outProfile : hwModule->getOutputProfiles()) {
    ...
      audio_devices_t profileType = outProfile->getSupportedDevicesType();
      if ((profileType & mDefaultOutputDevice->type()) != AUDIO_DEVICE_NONE) {
          profileType = mDefaultOutputDevice->type();
      } else {
          // chose first device present in profile's SupportedDevices also part of
          // outputDeviceTypes
          profileType = outProfile->getSupportedDeviceForType(outputDeviceTypes);
      } 
      sp outputDesc = new SwAudioOutputDescriptor(outProfile,
                                                                                   mpClientInterface);
      const DeviceVector &supportedDevices = outProfile->getSupportedDevices();
      const DeviceVector &devicesForType = supportedDevices.getDevicesFromType(profileType);
      String8 address = devicesForType.size() > 0 ? devicesForType.itemAt(0)->mAddress
                      : String8("");
      audio_io_handle_t output = AUDIO_IO_HANDLE_NONE;
      status_t status = outputDesc->open(nullptr, profileType, address,
                                             AUDIO_STREAM_DEFAULT, AUDIO_OUTPUT_FLAG_NONE, &output);
    
      if (status != NO_ERROR) {
          ALOGW("Cannot open output stream for device %08x on hw module %s",
                        outputDesc->mDevice,
                        hwModule->getName());
      } else {
          for (const auto& dev : supportedDevices) {
              ssize_t index = mAvailableOutputDevices.indexOf(dev);
              // give a valid ID to an attached device once confirmed it is reachable
              if (index >= 0 && !mAvailableOutputDevices[index]->isAttached()) {
                  mAvailableOutputDevices[index]->attach(hwModule);
              }
          }
          if (mPrimaryOutput == 0 &&
                          outProfile->getFlags() & AUDIO_OUTPUT_FLAG_PRIMARY) {
              mPrimaryOutput = outputDesc;
          }
          addOutput(output, outputDesc);
          setOutputDevice(outputDesc,
                                  profileType,
                                  true,
                                  0,
                                  NULL,
                                  address);
          }
     }
    
  • HwModuleの入力シーンを巡回します.InputProfileから、mAvailableInputDevicesがサポートするデバイスタイプが見つかりました.AudioInputDescriptorオブジェクトを作成し、InputProfileおよびmpClientInterfaceをそのオブジェクトのmProfileおよびmClientInterfaceに登録し、InputProfileによってオーディオフォーマット、チャネル数、サンプリングレートをmSamplingRate、mChannelMask、mFormatにそれぞれ割り当てます.サポートされている入力デバイスのリストは、現在のシーンでサポートされているタイプprofileTypeによって検索される.デバイスリストを入力してaddressを取得します.最後にopenを呼び出して入力デバイスを開き、入力デバイスハンドルに戻ります.mAvailableInputDevicesの対応するデバイスをHwModuleに関連付ける.inputprofileを特定のデバイスに導入します.最後に入力デバイスを閉じます.
  • updateDevicesAndOutputs()
  • 断言処理
  • ASSERT_EQ(NO_ERROR,mManager->initCheck()は,コードによって真と断言する.
  • status_t AudioPolicyManager::initCheck()
    {
       return hasPrimaryOutput() ? NO_ERROR : NO_INIT;
    }
    

    TEST_Fコードセグメント
  • createAudioPatchパラメータ断言
  • // patch    
    ASSERT_EQ(BAD_VALUE, mManager->createAudioPatch(nullptr, &handle, 0));
    // handle    
    ASSERT_EQ(BAD_VALUE, mManager->createAudioPatch(&patch, nullptr, 0));
    // patch num_sources==0   
    ASSERT_EQ(BAD_VALUE, mManager->createAudioPatch(&patch, &handle, 0));
    // patch num_source  1  
    patch.num_sources = AUDIO_PATCH_PORTS_MAX + 1;
    patch.num_sinks = 1;
    ASSERT_EQ(BAD_VALUE, mManager->createAudioPatch(&patch, &handle, 0));
    // patch num_sinks  16  
    patch.num_sources = 1;
    patch.num_sinks = AUDIO_PATCH_PORTS_MAX + 1;
    ASSERT_EQ(BAD_VALUE, mManager->createAudioPatch(&patch, &handle, 0))
    patch num_source  1  
    patch.num_sources = 2;
    patch.num_sinks = 1;
    ASSERT_EQ(INVALID_OPERATION, mManager->createAudioPatch(&patch, &handle, 0));
    //patch sources[0].role  AUDIO_PORT_ROLE_SINK   
    patch = {};
    patch.num_sources = 1;
    patch.sources[0].role = AUDIO_PORT_ROLE_SINK;
    patch.num_sinks = 1;
    patch.sinks[0].role = AUDIO_PORT_ROLE_SINK;
    ASSERT_EQ(INVALID_OPERATION, mManager->createAudioPatch(&patch, &handle, 0));
    // patch sinks[0].role  AUDIO_PORT_ROLE_SOURCE   
    patch = {};
    patch.num_sources = 1;
    patch.sources[0].role = AUDIO_PORT_ROLE_SOURCE;
    patch.num_sinks = 1;
    patch.sinks[0].role = AUDIO_PORT_ROLE_SOURCE;
    ASSERT_EQ(INVALID_OPERATION, mManager->createAudioPatch(&patch, &handle, 0));
    // Verify that the handle is left unchanged.
    ASSERT_EQ(AUDIO_PATCH_HANDLE_NONE, handle);
    ASSERT_EQ(patchCountBefore, mClient->getActivePatchesCount());
    

    AudioPolicyManagerTest::TearDown()分析
    void AudioPolicyManagerTest::TearDown() {
        mManager.reset();
        mClient.reset();
    }