blob: 1f50c0d35f6eac669be4a65581f6e5785171ccf0 [file] [log] [blame]
// Copyright 2016 Google Inc. All Rights Reserved.
//
// 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.
#include "cobalt/speech/url_fetcher_fake.h"
#if defined(ENABLE_FAKE_MICROPHONE)
#include "base/basictypes.h"
#include "base/sys_byteorder.h"
#include "cobalt/speech/google_streaming_api.pb.h"
#include "net/url_request/url_fetcher_delegate.h"
#include "starboard/log.h"
namespace cobalt {
namespace speech {
namespace {
const int kDownloadTimerInterval = 100;
struct RecognitionAlternative {
const char* transcript;
float confidence;
};
const RecognitionAlternative kAlternatives_1[] = {
{"tube", 0.0f},
};
const RecognitionAlternative kAlternatives_2[] = {
{"to be", 0.0f},
};
const RecognitionAlternative kAlternatives_3[] = {
{" or not", 0.0f},
};
const RecognitionAlternative kAlternatives_4[] = {
{" or not to be", 0.0f}, {"to be", 0.0f},
};
const RecognitionAlternative kAlternatives_5[] = {
{"to be or not to be", 0.728f}, {"2 B or not to be", 0.0f},
};
const RecognitionAlternative kAlternatives_6[] = {
{"that", 0.0f}, {"is the", 0.0f},
};
const RecognitionAlternative kAlternatives_7[] = {
{"that", 0.0f}, {"is the question", 0.0f},
};
const RecognitionAlternative kAlternatives_8[] = {
{"that is", 0.0f}, {"the question", 0.0f},
};
const RecognitionAlternative kAlternatives_9[] = {
{"that is the question", 0.8577f}, {"that is a question", 0.0f},
};
struct RecognitionResult {
const RecognitionAlternative* alternatives;
bool final;
size_t number_of_alternatives;
};
const RecognitionResult kRecognitionResults[] = {
{kAlternatives_1, false, SB_ARRAY_SIZE_INT(kAlternatives_1)},
{kAlternatives_2, false, SB_ARRAY_SIZE_INT(kAlternatives_2)},
{kAlternatives_3, false, SB_ARRAY_SIZE_INT(kAlternatives_3)},
{kAlternatives_4, false, SB_ARRAY_SIZE_INT(kAlternatives_4)},
{kAlternatives_5, true, SB_ARRAY_SIZE_INT(kAlternatives_5)},
{kAlternatives_6, false, SB_ARRAY_SIZE_INT(kAlternatives_6)},
{kAlternatives_7, false, SB_ARRAY_SIZE_INT(kAlternatives_7)},
{kAlternatives_8, false, SB_ARRAY_SIZE_INT(kAlternatives_8)},
{kAlternatives_9, true, SB_ARRAY_SIZE_INT(kAlternatives_9)},
};
std::string GetMockProtoResult(int index) {
proto::SpeechRecognitionEvent proto_event;
proto_event.set_status(proto::SpeechRecognitionEvent::STATUS_SUCCESS);
proto::SpeechRecognitionResult* proto_result = proto_event.add_result();
proto_result->set_final(kRecognitionResults[index].final);
const RecognitionAlternative* recognition_alternatives =
kRecognitionResults[index].alternatives;
for (size_t i = 0; i < kRecognitionResults[index].number_of_alternatives;
++i) {
proto::SpeechRecognitionAlternative* proto_alternative =
proto_result->add_alternative();
proto_alternative->set_confidence(recognition_alternatives[i].confidence);
proto_alternative->set_transcript(recognition_alternatives[i].transcript);
}
std::string response_string;
proto_event.SerializeToString(&response_string);
// Prepend 4 byte prefix length indication to the protobuf message as
// envisaged by the google streaming recognition webservice protocol.
uint32_t prefix =
base::HostToNet32(static_cast<uint32_t>(response_string.size()));
response_string.insert(0, reinterpret_cast<char*>(&prefix), sizeof(prefix));
return response_string;
}
} // namespace
URLFetcherFake::URLFetcherFake(const GURL& url,
net::URLFetcher::RequestType /*request_type*/,
net::URLFetcherDelegate* delegate)
: original_url_(url),
delegate_(delegate),
is_chunked_upload_(false),
download_index_(0) {}
URLFetcherFake::~URLFetcherFake() {}
void URLFetcherFake::SetChunkedUpload(
const std::string& /*upload_content_type*/) {
is_chunked_upload_ = true;
}
void URLFetcherFake::AppendChunkToUpload(const std::string& /*data*/,
bool /*is_last_chunk*/) {
SB_DCHECK(is_chunked_upload_);
// no-op.
}
void URLFetcherFake::SetRequestContext(
net::URLRequestContextGetter* /*request_context_getter*/) {
// no-op.
}
void URLFetcherFake::Start() {
if (!is_chunked_upload_) {
download_timer_.emplace();
download_timer_->Start(
FROM_HERE, base::TimeDelta::FromMilliseconds(kDownloadTimerInterval),
this, &URLFetcherFake::OnURLFetchDownloadData);
}
}
const net::URLRequestStatus& URLFetcherFake::GetStatus() const {
return fake_status_;
}
int URLFetcherFake::GetResponseCode() const { return 200; }
void URLFetcherFake::OnURLFetchDownloadData() {
SB_DCHECK(!is_chunked_upload_);
std::string result = GetMockProtoResult(download_index_);
delegate_->OnURLFetchDownloadData(
this, make_scoped_ptr<std::string>(new std::string(result)));
download_index_++;
if (download_index_ ==
static_cast<int>(SB_ARRAY_SIZE_INT(kRecognitionResults))) {
download_index_ = 0;
download_timer_->Stop();
}
}
} // namespace speech
} // namespace cobalt
#endif // defined(ENABLE_FAKE_MICROPHONE)