Commit 6fd1fb81 authored by Xiaohui Chen's avatar Xiaohui Chen Committed by Commit Bot

assistant: refactor old methods to use ensure style

Bug: None
Test: locally build and run
Change-Id: I843f45f2056e5fb8b61ccf5f27e6ff8f25595c12
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1876795
Commit-Queue: Xiaohui Chen <xiaohuic@chromium.org>
Reviewed-by: default avatarTao Wu <wutao@chromium.org>
Cr-Commit-Position: refs/heads/master@{#709528}
parent 0b3c319b
......@@ -11,6 +11,7 @@
#include "ash/public/cpp/assistant/assistant_state_base.h"
#include "base/barrier_closure.h"
#include "base/bind.h"
#include "base/callback_forward.h"
#include "base/feature_list.h"
#include "base/i18n/rtl.h"
#include "base/logging.h"
......@@ -310,13 +311,17 @@ void AssistantManagerServiceImpl::RegisterAlarmsTimersListener() {
if (!alarm_timer_manager)
return;
alarm_timer_manager->RegisterRingingStateListener([this]() {
main_task_runner()->PostTask(
FROM_HERE,
base::BindOnce(
&AssistantManagerServiceImpl::OnAlarmTimerStateChangedOnMainThread,
auto listener_callback = base::BindRepeating(
[](scoped_refptr<base::SequencedTaskRunner> task_runner,
base::RepeatingClosure task) {
task_runner->PostTask(FROM_HERE, task);
},
main_task_runner(),
base::BindRepeating(
&AssistantManagerServiceImpl::OnAlarmTimerStateChanged,
weak_factory_.GetWeakPtr()));
});
alarm_timer_manager->RegisterRingingStateListener(
[listener = std::move(listener_callback)] { listener.Run(); });
}
void AssistantManagerServiceImpl::EnableListening(bool enable) {
......@@ -530,20 +535,93 @@ void AssistantManagerServiceImpl::DismissNotification(
void AssistantManagerServiceImpl::OnConversationTurnStartedInternal(
const assistant_client::ConversationTurnMetadata& metadata) {
main_task_runner()->PostTask(
FROM_HERE,
base::BindOnce(
&AssistantManagerServiceImpl::OnConversationTurnStartedOnMainThread,
weak_factory_.GetWeakPtr(), metadata));
ENSURE_MAIN_THREAD(
&AssistantManagerServiceImpl::OnConversationTurnStartedInternal,
metadata);
platform_api_->OnConversationTurnStarted();
// Retrieve the cached interaction metadata associated with this conversation
// turn or construct a new instance if there's no match in the cache.
mojom::AssistantInteractionMetadataPtr metadata_ptr;
auto it = pending_interactions_.find(metadata.id);
if (it != pending_interactions_.end()) {
metadata_ptr = std::move(it->second);
pending_interactions_.erase(it);
} else {
metadata_ptr = mojom::AssistantInteractionMetadata::New();
metadata_ptr->type = metadata.is_mic_open
? mojom::AssistantInteractionType::kVoice
: mojom::AssistantInteractionType::kText;
metadata_ptr->source = mojom::AssistantQuerySource::kLibAssistantInitiated;
}
for (auto& it : interaction_subscribers_)
it->OnInteractionStarted(metadata_ptr->Clone());
}
void AssistantManagerServiceImpl::OnConversationTurnFinished(
Resolution resolution) {
main_task_runner()->PostTask(
FROM_HERE,
base::BindOnce(
&AssistantManagerServiceImpl::OnConversationTurnFinishedOnMainThread,
weak_factory_.GetWeakPtr(), resolution));
ENSURE_MAIN_THREAD(&AssistantManagerServiceImpl::OnConversationTurnFinished,
resolution);
// TODO(updowndota): Find a better way to handle the edge cases.
if (resolution != Resolution::NORMAL_WITH_FOLLOW_ON &&
resolution != Resolution::CANCELLED &&
resolution != Resolution::BARGE_IN) {
platform_api_->SetMicState(false);
}
platform_api_->OnConversationTurnFinished();
switch (resolution) {
// Interaction ended normally.
case Resolution::NORMAL:
case Resolution::NORMAL_WITH_FOLLOW_ON:
case Resolution::NO_RESPONSE:
for (auto& it : interaction_subscribers_) {
it->OnInteractionFinished(
mojom::AssistantInteractionResolution::kNormal);
}
RecordQueryResponseTypeUMA();
break;
// Interaction ended due to interruption.
case Resolution::BARGE_IN:
case Resolution::CANCELLED:
for (auto& it : interaction_subscribers_) {
it->OnInteractionFinished(
mojom::AssistantInteractionResolution::kInterruption);
}
if (receive_inline_response_ || receive_modify_settings_proto_response_ ||
!receive_url_response_.empty()) {
RecordQueryResponseTypeUMA();
}
break;
// Interaction ended due to mic timeout.
case Resolution::TIMEOUT:
for (auto& it : interaction_subscribers_) {
it->OnInteractionFinished(
mojom::AssistantInteractionResolution::kMicTimeout);
}
break;
// Interaction ended due to error.
case Resolution::COMMUNICATION_ERROR:
for (auto& it : interaction_subscribers_) {
it->OnInteractionFinished(
mojom::AssistantInteractionResolution::kError);
}
break;
// Interaction ended because the device was not selected to produce a
// response. This occurs due to multi-device hotword loss.
case Resolution::DEVICE_NOT_SELECTED:
for (auto& it : interaction_subscribers_) {
it->OnInteractionFinished(
mojom::AssistantInteractionResolution::kMultiDeviceHotwordLoss);
}
break;
}
}
void AssistantManagerServiceImpl::OnScheduleWait(int id, int time_ms) {
......@@ -572,12 +650,8 @@ void AssistantManagerServiceImpl::OnScheduleWait(int id, int time_ms) {
// TODO(b/113541754): Deprecate this API when the server provides a fallback.
void AssistantManagerServiceImpl::OnShowContextualQueryFallback() {
// Show fallback text.
main_task_runner()->PostTask(
FROM_HERE,
base::BindOnce(&AssistantManagerServiceImpl::OnShowTextOnMainThread,
weak_factory_.GetWeakPtr(),
l10n_util::GetStringUTF8(
IDS_ASSISTANT_SCREEN_CONTEXT_QUERY_FALLBACK_TEXT)));
OnShowText(l10n_util::GetStringUTF8(
IDS_ASSISTANT_SCREEN_CONTEXT_QUERY_FALLBACK_TEXT));
// Construct a fallback card.
std::stringstream html;
......@@ -608,22 +682,24 @@ void AssistantManagerServiceImpl::OnShowContextualQueryFallback() {
<< "</div></body></html>";
// Show fallback card.
main_task_runner()->PostTask(
FROM_HERE,
base::BindOnce(&AssistantManagerServiceImpl::OnShowHtmlOnMainThread,
weak_factory_.GetWeakPtr(), html.str(), /*fallback=*/""));
OnShowHtml(html.str(), /*fallback=*/"");
}
void AssistantManagerServiceImpl::OnShowHtml(const std::string& html,
const std::string& fallback) {
main_task_runner()->PostTask(
FROM_HERE,
base::BindOnce(&AssistantManagerServiceImpl::OnShowHtmlOnMainThread,
weak_factory_.GetWeakPtr(), html, fallback));
ENSURE_MAIN_THREAD(&AssistantManagerServiceImpl::OnShowHtml, html, fallback);
receive_inline_response_ = true;
for (auto& it : interaction_subscribers_)
it->OnHtmlResponse(html, fallback);
}
void AssistantManagerServiceImpl::OnShowSuggestions(
const std::vector<action::Suggestion>& suggestions) {
ENSURE_MAIN_THREAD(&AssistantManagerServiceImpl::OnShowSuggestions,
suggestions);
// Convert to mojom struct for IPC.
std::vector<mojom::AssistantSuggestionPtr> ptrs;
for (const action::Suggestion& suggestion : suggestions) {
......@@ -634,30 +710,36 @@ void AssistantManagerServiceImpl::OnShowSuggestions(
ptrs.push_back(std::move(ptr));
}
main_task_runner()->PostTask(
FROM_HERE,
base::BindOnce(
&AssistantManagerServiceImpl::OnShowSuggestionsOnMainThread,
weak_factory_.GetWeakPtr(), std::move(ptrs)));
for (auto& it : interaction_subscribers_)
it->OnSuggestionsResponse(mojo::Clone(ptrs));
}
void AssistantManagerServiceImpl::OnShowText(const std::string& text) {
main_task_runner()->PostTask(
FROM_HERE,
base::BindOnce(&AssistantManagerServiceImpl::OnShowTextOnMainThread,
weak_factory_.GetWeakPtr(), text));
ENSURE_MAIN_THREAD(&AssistantManagerServiceImpl::OnShowText, text);
receive_inline_response_ = true;
for (auto& it : interaction_subscribers_)
it->OnTextResponse(text);
}
void AssistantManagerServiceImpl::OnOpenUrl(const std::string& url,
bool is_background) {
main_task_runner()->PostTask(
FROM_HERE,
base::BindOnce(&AssistantManagerServiceImpl::OnOpenUrlOnMainThread,
weak_factory_.GetWeakPtr(), url, is_background));
ENSURE_MAIN_THREAD(&AssistantManagerServiceImpl::OnOpenUrl, url,
is_background);
receive_url_response_ = url;
const GURL gurl = GURL(url);
for (auto& it : interaction_subscribers_)
it->OnOpenUrlResponse(gurl, is_background);
}
void AssistantManagerServiceImpl::OnShowNotification(
const action::Notification& notification) {
ENSURE_MAIN_THREAD(&AssistantManagerServiceImpl::OnShowNotification,
notification);
mojom::AssistantNotificationPtr notification_ptr =
mojom::AssistantNotification::New();
notification_ptr->title = notification.title;
......@@ -686,11 +768,8 @@ void AssistantManagerServiceImpl::OnShowNotification(
button.label, GURL(button.action_url)));
}
main_task_runner()->PostTask(
FROM_HERE,
base::BindOnce(
&AssistantManagerServiceImpl::OnShowNotificationOnMainThread,
weak_factory_.GetWeakPtr(), std::move(notification_ptr)));
assistant_notification_controller()->AddOrUpdateNotification(
notification_ptr.Clone());
}
void AssistantManagerServiceImpl::OnOpenAndroidApp(
......@@ -727,9 +806,11 @@ void AssistantManagerServiceImpl::OnVerifyAndroidApp(
weak_factory_.GetWeakPtr(), interaction));
}
void AssistantManagerServiceImpl::OnOpenMediaAndroidIntentOnMainThread(
void AssistantManagerServiceImpl::OnOpenMediaAndroidIntent(
const std::string play_media_args_proto,
action::AndroidAppInfo* android_app_info) {
DCHECK(main_task_runner()->RunsTasksInCurrentSequence());
// Handle android media playback intent.
mojom::AndroidAppInfoPtr app_info_ptr = mojom::AndroidAppInfo::New();
app_info_ptr->package_name = android_app_info->package_name;
......@@ -759,13 +840,12 @@ void AssistantManagerServiceImpl::OnPlayMedia(
std::unique_ptr<action::AndroidAppInfo> android_app_info =
GetAndroidAppInfoFromMediaArgs(play_media_args_proto);
if (android_app_info) {
OnOpenMediaAndroidIntentOnMainThread(play_media_args_proto,
android_app_info.get());
OnOpenMediaAndroidIntent(play_media_args_proto, android_app_info.get());
} else {
std::string url = GetWebUrlFromMediaArgs(play_media_args_proto);
// Fallack to web URL.
if (!url.empty())
OnOpenUrlOnMainThread(url, /*in_background=*/false);
OnOpenUrl(url, /*in_background=*/false);
}
}
......@@ -806,28 +886,52 @@ void AssistantManagerServiceImpl::OnRecognitionStateChanged(
assistant_client::ConversationStateListener::RecognitionState state,
const assistant_client::ConversationStateListener::RecognitionResult&
recognition_result) {
main_task_runner()->PostTask(
FROM_HERE,
base::BindOnce(
&AssistantManagerServiceImpl::OnRecognitionStateChangedOnMainThread,
weak_factory_.GetWeakPtr(), state, recognition_result));
ENSURE_MAIN_THREAD(&AssistantManagerServiceImpl::OnRecognitionStateChanged,
state, recognition_result);
switch (state) {
case assistant_client::ConversationStateListener::RecognitionState::STARTED:
for (auto& it : interaction_subscribers_)
it->OnSpeechRecognitionStarted();
break;
case assistant_client::ConversationStateListener::RecognitionState::
INTERMEDIATE_RESULT:
for (auto& it : interaction_subscribers_) {
it->OnSpeechRecognitionIntermediateResult(
recognition_result.high_confidence_text,
recognition_result.low_confidence_text);
}
break;
case assistant_client::ConversationStateListener::RecognitionState::
END_OF_UTTERANCE:
for (auto& it : interaction_subscribers_)
it->OnSpeechRecognitionEndOfUtterance();
break;
case assistant_client::ConversationStateListener::RecognitionState::
FINAL_RESULT:
for (auto& it : interaction_subscribers_) {
it->OnSpeechRecognitionFinalResult(
recognition_result.recognized_speech);
}
break;
}
}
void AssistantManagerServiceImpl::OnRespondingStarted(bool is_error_response) {
main_task_runner()->PostTask(
FROM_HERE,
base::BindOnce(
&AssistantManagerServiceImpl::OnRespondingStartedOnMainThread,
weak_factory_.GetWeakPtr(), is_error_response));
ENSURE_MAIN_THREAD(&AssistantManagerServiceImpl::OnRespondingStarted,
is_error_response);
for (auto& it : interaction_subscribers_)
it->OnTtsStarted(is_error_response);
}
void AssistantManagerServiceImpl::OnSpeechLevelUpdated(
const float speech_level) {
main_task_runner()->PostTask(
FROM_HERE,
base::BindOnce(
&AssistantManagerServiceImpl::OnSpeechLevelUpdatedOnMainThread,
weak_factory_.GetWeakPtr(), speech_level));
ENSURE_MAIN_THREAD(&AssistantManagerServiceImpl::OnSpeechLevelUpdated,
speech_level);
for (auto& it : interaction_subscribers_)
it->OnSpeechLevelUpdated(speech_level);
}
void LogUnsupportedChange(api::client_op::ModifySettingArgs args) {
......@@ -1019,19 +1123,28 @@ bool AssistantManagerServiceImpl::SupportsModifySettings() {
void AssistantManagerServiceImpl::OnNotificationRemoved(
const std::string& grouping_key) {
main_task_runner()->PostTask(
FROM_HERE,
base::BindOnce(
&AssistantManagerServiceImpl::OnNotificationRemovedOnMainThread,
weak_factory_.GetWeakPtr(), grouping_key));
ENSURE_MAIN_THREAD(&AssistantManagerServiceImpl::OnNotificationRemoved,
grouping_key);
if (grouping_key.empty()) {
assistant_notification_controller()->RemoveAllNotifications(
/*from_server=*/true);
} else {
assistant_notification_controller()->RemoveNotificationByGroupingKey(
grouping_key, /*from_server=*/
true);
}
}
void AssistantManagerServiceImpl::OnCommunicationError(int error_code) {
main_task_runner()->PostTask(
FROM_HERE,
base::BindOnce(
&AssistantManagerServiceImpl::OnCommunicationErrorOnMainThread,
weak_factory_.GetWeakPtr(), error_code));
ENSURE_MAIN_THREAD(&AssistantManagerServiceImpl::OnCommunicationError,
error_code);
CommunicationErrorType type =
CommunicationErrorTypeFromLibassistantErrorCode(error_code);
for (auto& observer : error_observers_)
observer.OnCommunicationError(type);
}
void AssistantManagerServiceImpl::StartAssistantInternal(
......@@ -1245,121 +1358,6 @@ void AssistantManagerServiceImpl::MediaSessionMetadataChanged(
UpdateMediaState();
}
void AssistantManagerServiceImpl::OnConversationTurnStartedOnMainThread(
const assistant_client::ConversationTurnMetadata& metadata) {
platform_api_->OnConversationTurnStarted();
// Retrieve the cached interaction metadata associated with this conversation
// turn or construct a new instance if there's no match in the cache.
mojom::AssistantInteractionMetadataPtr metadata_ptr;
auto it = pending_interactions_.find(metadata.id);
if (it != pending_interactions_.end()) {
metadata_ptr = std::move(it->second);
pending_interactions_.erase(it);
} else {
metadata_ptr = mojom::AssistantInteractionMetadata::New();
metadata_ptr->type = metadata.is_mic_open
? mojom::AssistantInteractionType::kVoice
: mojom::AssistantInteractionType::kText;
metadata_ptr->source = mojom::AssistantQuerySource::kLibAssistantInitiated;
}
for (auto& it : interaction_subscribers_)
it->OnInteractionStarted(metadata_ptr->Clone());
}
void AssistantManagerServiceImpl::OnConversationTurnFinishedOnMainThread(
assistant_client::ConversationStateListener::Resolution resolution) {
// TODO(updowndota): Find a better way to handle the edge cases.
if (resolution != Resolution::NORMAL_WITH_FOLLOW_ON &&
resolution != Resolution::CANCELLED &&
resolution != Resolution::BARGE_IN) {
platform_api_->SetMicState(false);
}
platform_api_->OnConversationTurnFinished();
switch (resolution) {
// Interaction ended normally.
case Resolution::NORMAL:
case Resolution::NORMAL_WITH_FOLLOW_ON:
case Resolution::NO_RESPONSE:
for (auto& it : interaction_subscribers_) {
it->OnInteractionFinished(
mojom::AssistantInteractionResolution::kNormal);
}
RecordQueryResponseTypeUMA();
break;
// Interaction ended due to interruption.
case Resolution::BARGE_IN:
case Resolution::CANCELLED:
for (auto& it : interaction_subscribers_) {
it->OnInteractionFinished(
mojom::AssistantInteractionResolution::kInterruption);
}
if (receive_inline_response_ || receive_modify_settings_proto_response_ ||
!receive_url_response_.empty()) {
RecordQueryResponseTypeUMA();
}
break;
// Interaction ended due to mic timeout.
case Resolution::TIMEOUT:
for (auto& it : interaction_subscribers_) {
it->OnInteractionFinished(
mojom::AssistantInteractionResolution::kMicTimeout);
}
break;
// Interaction ended due to error.
case Resolution::COMMUNICATION_ERROR:
for (auto& it : interaction_subscribers_) {
it->OnInteractionFinished(
mojom::AssistantInteractionResolution::kError);
}
break;
// Interaction ended because the device was not selected to produce a
// response. This occurs due to multi-device hotword loss.
case Resolution::DEVICE_NOT_SELECTED:
for (auto& it : interaction_subscribers_) {
it->OnInteractionFinished(
mojom::AssistantInteractionResolution::kMultiDeviceHotwordLoss);
}
break;
}
}
void AssistantManagerServiceImpl::OnShowHtmlOnMainThread(
const std::string& html,
const std::string& fallback) {
receive_inline_response_ = true;
for (auto& it : interaction_subscribers_)
it->OnHtmlResponse(html, fallback);
}
void AssistantManagerServiceImpl::OnShowSuggestionsOnMainThread(
const std::vector<mojom::AssistantSuggestionPtr>& suggestions) {
for (auto& it : interaction_subscribers_)
it->OnSuggestionsResponse(mojo::Clone(suggestions));
}
void AssistantManagerServiceImpl::OnShowTextOnMainThread(
const std::string& text) {
receive_inline_response_ = true;
for (auto& it : interaction_subscribers_)
it->OnTextResponse(text);
}
void AssistantManagerServiceImpl::OnOpenUrlOnMainThread(const std::string& url,
bool in_background) {
receive_url_response_ = url;
const GURL gurl = GURL(url);
for (auto& it : interaction_subscribers_)
it->OnOpenUrlResponse(gurl, in_background);
}
void AssistantManagerServiceImpl::OnPlaybackStateChange(
const MediaStatus& status) {
......@@ -1367,78 +1365,8 @@ void AssistantManagerServiceImpl::OnPlaybackStateChange(
media_session_->NotifyMediaSessionMetadataChanged(status);
}
void AssistantManagerServiceImpl::OnShowNotificationOnMainThread(
const mojom::AssistantNotificationPtr& notification) {
assistant_notification_controller()->AddOrUpdateNotification(
notification.Clone());
}
void AssistantManagerServiceImpl::OnNotificationRemovedOnMainThread(
const std::string& grouping_key) {
if (grouping_key.empty()) {
assistant_notification_controller()->RemoveAllNotifications(
/*from_server=*/true);
} else {
assistant_notification_controller()->RemoveNotificationByGroupingKey(
grouping_key, /*from_server=*/
true);
}
}
void AssistantManagerServiceImpl::OnCommunicationErrorOnMainThread(
int error_code) {
CommunicationErrorType type =
CommunicationErrorTypeFromLibassistantErrorCode(error_code);
for (auto& observer : error_observers_)
observer.OnCommunicationError(type);
}
void AssistantManagerServiceImpl::OnRecognitionStateChangedOnMainThread(
assistant_client::ConversationStateListener::RecognitionState state,
const assistant_client::ConversationStateListener::RecognitionResult&
recognition_result) {
switch (state) {
case assistant_client::ConversationStateListener::RecognitionState::STARTED:
for (auto& it : interaction_subscribers_)
it->OnSpeechRecognitionStarted();
break;
case assistant_client::ConversationStateListener::RecognitionState::
INTERMEDIATE_RESULT:
for (auto& it : interaction_subscribers_) {
it->OnSpeechRecognitionIntermediateResult(
recognition_result.high_confidence_text,
recognition_result.low_confidence_text);
}
break;
case assistant_client::ConversationStateListener::RecognitionState::
END_OF_UTTERANCE:
for (auto& it : interaction_subscribers_)
it->OnSpeechRecognitionEndOfUtterance();
break;
case assistant_client::ConversationStateListener::RecognitionState::
FINAL_RESULT:
for (auto& it : interaction_subscribers_) {
it->OnSpeechRecognitionFinalResult(
recognition_result.recognized_speech);
}
break;
}
}
void AssistantManagerServiceImpl::OnRespondingStartedOnMainThread(
bool is_error_response) {
for (auto& it : interaction_subscribers_)
it->OnTtsStarted(is_error_response);
}
void AssistantManagerServiceImpl::OnSpeechLevelUpdatedOnMainThread(
const float speech_level) {
for (auto& it : interaction_subscribers_)
it->OnSpeechLevelUpdated(speech_level);
}
void AssistantManagerServiceImpl::OnAlarmTimerStateChangedOnMainThread() {
void AssistantManagerServiceImpl::OnAlarmTimerStateChanged() {
ENSURE_MAIN_THREAD(&AssistantManagerServiceImpl::OnAlarmTimerStateChanged);
// Currently, we only handle ringing events here. After some AlarmTimerManager
// API improvement, we will be handling other alarm/timer events.
auto* alarm_timer_manager =
......
......@@ -11,6 +11,7 @@
#include <vector>
#include "ash/public/mojom/assistant_controller.mojom.h"
#include "base/memory/scoped_refptr.h"
#include "base/synchronization/lock.h"
#include "base/threading/thread.h"
#include "chromeos/assistant/internal/action/cros_action_module.h"
......@@ -248,30 +249,9 @@ class COMPONENT_EXPORT(ASSISTANT_SERVICE) AssistantManagerServiceImpl
void HandleLaunchMediaIntentResponse(bool app_opened);
void OnConversationTurnStartedOnMainThread(
const assistant_client::ConversationTurnMetadata& metadata);
void OnConversationTurnFinishedOnMainThread(
assistant_client::ConversationStateListener::Resolution resolution);
void OnShowHtmlOnMainThread(const std::string& html,
const std::string& fallback);
void OnShowSuggestionsOnMainThread(
const std::vector<mojom::AssistantSuggestionPtr>& suggestions);
void OnShowTextOnMainThread(const std::string& text);
void OnOpenUrlOnMainThread(const std::string& url, bool in_background);
void OnShowNotificationOnMainThread(
const mojom::AssistantNotificationPtr& notification);
void OnNotificationRemovedOnMainThread(const std::string& grouping_id);
void OnCommunicationErrorOnMainThread(int error_code);
void OnRecognitionStateChangedOnMainThread(
assistant_client::ConversationStateListener::RecognitionState state,
const assistant_client::ConversationStateListener::RecognitionResult&
recognition_result);
void OnRespondingStartedOnMainThread(bool is_error_response);
void OnSpeechLevelUpdatedOnMainThread(const float speech_level);
void OnAlarmTimerStateChangedOnMainThread();
void OnAlarmTimerStateChanged();
void OnModifySettingsAction(const std::string& modify_setting_args_proto);
void OnOpenMediaAndroidIntentOnMainThread(
const std::string play_media_args_proto,
void OnOpenMediaAndroidIntent(const std::string play_media_args_proto,
action::AndroidAppInfo* android_app_info);
void OnPlayMedia(const std::string play_media_args_proto);
void OnMediaControlAction(const std::string& action_name,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment