blob: 438801701e92aca9130071a6e92c3b8b2cc4be2d [file] [log] [blame]
// Copyright 2021 The Cobalt Authors. 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 "starboard/linux/shared/soft_mic_platform_service.h"
#include <memory>
#include <string>
#include "starboard/common/log.h"
#include "starboard/common/string.h"
#include "starboard/configuration.h"
#include "starboard/linux/shared/platform_service.h"
#include "starboard/shared/starboard/application.h"
// Omit namespace linux due to symbol name conflict.
namespace starboard {
namespace shared {
namespace {
typedef struct SoftMicPlatformServiceImpl : public PlatformServiceImpl {
// Define additional data field.
// variable_1, variable_2,...
SoftMicPlatformServiceImpl(void* context,
ReceiveMessageCallback receive_callback)
: PlatformServiceImpl(context, receive_callback) {}
// Default constructor.
SoftMicPlatformServiceImpl() = default;
} SoftMicPlatformServiceImpl;
const char kGetMicSupport[] = "\"getMicSupport\"";
const char kNotifySearchActive[] = "\"notifySearchActive\"";
const char kNotifySearchInactive[] = "\"notifySearchInactive\"";
const char kHasHardMicSupport[] = "has_hard_mic_support";
const char kHasSoftMicSupport[] = "has_soft_mic_support";
const char kMicGesture[] = "mic_gesture";
const char kJSONTrue[] = "true";
const char kJSONFalse[] = "false";
bool Has(const char* name) {
// Check if platform has service name.
return strcmp(name, kSoftMicPlatformServiceName) == 0;
}
PlatformServiceImpl* Open(void* context,
ReceiveMessageCallback receive_callback) {
SB_DCHECK(context);
SB_LOG(INFO) << "Open() service created: " << kSoftMicPlatformServiceName;
return new SoftMicPlatformServiceImpl(context, receive_callback);
}
void Close(PlatformServiceImpl* service) {
// Function Close shouldn't manually delete PlatformServiceImpl pointer,
// because it is managed by unique_ptr in Platform Service.
SB_LOG(INFO) << "Perform actions before gracefully shutting down the service";
}
void* Send(PlatformServiceImpl* service,
void* data,
uint64_t length,
uint64_t* output_length,
bool* invalid_state) {
SB_DCHECK(service);
SB_DCHECK(data);
SB_DCHECK(output_length);
// This bool flag is set to true if the data argument
// is successfully parsed as a known web app request,
// false otherwise. It is then sent as a synchronous
// response to the web app indicating this success or
// failure.
auto valid_message_received = false;
char message[length + 1];
std::memcpy(message, data, length);
message[length] = '\0';
SB_LOG(INFO) << "Send() message: " << message;
if (strcmp(message, kGetMicSupport) == 0) {
// Process "getMicSupport" web app message.
SB_LOG(INFO) << "Send() kGetMicSupport message received.";
auto has_hard_mic = false;
auto has_soft_mic = true;
auto mic_gesture_hold = false;
auto mic_gesture_tap = false;
#if !defined(COBALT_BUILD_TYPE_GOLD)
using shared::starboard::Application;
// Check for explicit true or false switch value for kHasHardMicSupport,
// kHasSoftMicSupport, kMicGestureHold, and kMicGestureTap optional target
// params. Use default values if none are set.
auto command_line = Application::Get()->GetCommandLine();
auto hard_mic_switch_value =
command_line->GetSwitchValue(kHasHardMicSupport);
if (hard_mic_switch_value == kJSONTrue) {
has_hard_mic = true;
} else if (hard_mic_switch_value == kJSONFalse) {
has_hard_mic = false;
}
auto soft_mic_switch_value =
command_line->GetSwitchValue(kHasSoftMicSupport);
if (soft_mic_switch_value == kJSONTrue) {
has_soft_mic = true;
} else if (soft_mic_switch_value == kJSONFalse) {
has_soft_mic = false;
}
auto mic_gesture_switch_value = command_line->GetSwitchValue(kMicGesture);
mic_gesture_hold = mic_gesture_switch_value == "hold";
mic_gesture_tap = mic_gesture_switch_value == "tap";
#endif // !defined(COBALT_BUILD_TYPE_GOLD)
auto mic_gesture = "null";
if (mic_gesture_hold)
mic_gesture = "\"HOLD\"";
else if (mic_gesture_tap)
mic_gesture = "\"TAP\"";
auto response = FormatString(
"{\"hasHardMicSupport\": %s, \"hasSoftMicSupport\": %s, "
"\"micGesture\": %s}",
(has_hard_mic ? kJSONTrue : kJSONFalse),
(has_soft_mic ? kJSONTrue : kJSONFalse), mic_gesture);
SB_LOG(INFO) << "Send() kGetMicSupport response: " << response;
// Here we are synchronously calling the receive_callback() from within
// Send() which is unnecessary. Implementations should prioritize
// returning from Send() ASAP to avoid blocking the JavaScript thread.
static_cast<PlatformServiceImpl*>(service)->receive_callback(
service->context, static_cast<const void*>(response.c_str()),
response.length());
valid_message_received = true;
} else if (strcmp(message, kNotifySearchActive) == 0) {
// Process "notifySearchActive" web app message.
SB_LOG(INFO) << "Send() kNotifySearchActive message received";
valid_message_received = true;
} else if (strcmp(message, kNotifySearchInactive) == 0) {
// Process "notifySearchInactive" web app message.
SB_LOG(INFO) << "Send() kNotifySearchInactive message received";
valid_message_received = true;
}
// Synchronous bool response to the web app confirming the message
// has been successfully parsed by the platform. Response needs
// to be allocated with malloc() as the caller of Send()
// in cobalt/h5vcc/h5vcc_platform_service.cc Send() uses
// free().
bool* ptr = reinterpret_cast<bool*>(malloc(sizeof(bool)));
*ptr = valid_message_received;
*output_length = sizeof(bool);
return static_cast<void*>(ptr);
}
const CobaltPlatformServiceApi kSoftMicPlatformServiceApi = {
kSoftMicPlatformServiceName,
1, // API version that's implemented.
&Has,
&Open,
&Close,
&Send};
} // namespace
const void* GetSoftMicPlatformServiceApi() {
return &kSoftMicPlatformServiceApi;
}
} // namespace shared
} // namespace starboard