forked from chromium/chromium
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
chromeos: Microphone mute notifications
Show a notification if an app is trying to access the microphone while the microphone is muted. Notification logic resides in MicrophoneMutNotificationController. Logic for determining whether a microphone-using app is running (and the name of said app) resides in MediaNotificationModel, an abstract, singleton-providing interface under ash/public/cpp/ with a concrete implementation under chrome/browser/ui/ash/. Notification strings added to ash_strings.grd. Guard notifications with base::Feature kMicMuteNotifications. Add method to the FakeCrasAudioClient API for setting client-type/number-of-active-input-streams-with-permission map, for testing. In MicGainSliderView::OnThemeChanged(), call into the superclass at the top. This change courtesy of tbarzic, which fixes unit test failures from Chromium LUCI CQ. Bug: 1201371 Change-Id: Ic89d117ba788e411cf0275adfdf4379a6e1907fd Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2860331 Commit-Queue: Roger Tinkoff <rtinkoff@google.com> Reviewed-by: Ahmed Mehfooz <amehfooz@chromium.org> Reviewed-by: James Cook <jamescook@chromium.org> Reviewed-by: Toni Baržić <tbarzic@chromium.org> Cr-Commit-Position: refs/heads/master@{#882580}
- Loading branch information
1 parent
f3c449b
commit 4a008a2
Showing
24 changed files
with
717 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
1 change: 1 addition & 0 deletions
1
ash/ash_strings_grd/IDS_MICROPHONE_MUTE_SWITCH_ON_NOTIFICATION_MESSAGE.png.sha1
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
9c446eb6a1dad02fe31d366910b57b4942c684f7 |
1 change: 1 addition & 0 deletions
1
...ash_strings_grd/IDS_MICROPHONE_MUTE_SWITCH_ON_NOTIFICATION_MESSAGE_WITH_APP_NAME.png.sha1
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
e7b83d22230b704fa74103296c0151d9b263be81 |
1 change: 1 addition & 0 deletions
1
ash/ash_strings_grd/IDS_MICROPHONE_MUTE_SWITCH_ON_NOTIFICATION_TITLE.png.sha1
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
e7b83d22230b704fa74103296c0151d9b263be81 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
// Copyright 2021 The Chromium Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
#include "ash/public/cpp/microphone_mute_notification_delegate.h" | ||
|
||
#include "base/check.h" | ||
#include "base/check_op.h" | ||
|
||
namespace ash { | ||
|
||
namespace { | ||
|
||
MicrophoneMuteNotificationDelegate* g_instance = nullptr; | ||
|
||
} // namespace | ||
|
||
// static | ||
MicrophoneMuteNotificationDelegate* MicrophoneMuteNotificationDelegate::Get() { | ||
return g_instance; | ||
} | ||
|
||
MicrophoneMuteNotificationDelegate::MicrophoneMuteNotificationDelegate() { | ||
DCHECK(!g_instance); | ||
g_instance = this; | ||
} | ||
|
||
MicrophoneMuteNotificationDelegate::~MicrophoneMuteNotificationDelegate() { | ||
DCHECK_EQ(this, g_instance); | ||
g_instance = nullptr; | ||
} | ||
|
||
} // namespace ash |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
// Copyright 2021 The Chromium Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
#ifndef ASH_PUBLIC_CPP_MICROPHONE_MUTE_NOTIFICATION_DELEGATE_H_ | ||
#define ASH_PUBLIC_CPP_MICROPHONE_MUTE_NOTIFICATION_DELEGATE_H_ | ||
|
||
#include <string> | ||
|
||
#include "ash/public/cpp/ash_public_export.h" | ||
#include "base/optional.h" | ||
|
||
namespace ash { | ||
|
||
// This delegate exists so that code relevant to microphone mute notifications | ||
// under //ash can call back into //chrome. The actual delegate instance is | ||
// owned and constructed by code in //chrome during startup. | ||
class ASH_PUBLIC_EXPORT MicrophoneMuteNotificationDelegate { | ||
public: | ||
static MicrophoneMuteNotificationDelegate* Get(); | ||
|
||
// Returns an optional string with: | ||
// | ||
// No value, if no app is accessing the mic | ||
// Empty value, if an app is accessing the mic but no name could be determined | ||
// Non-empty value, if an app is accessing the mic and a name could be | ||
// determined | ||
virtual base::Optional<std::u16string> GetAppAccessingMicrophone() = 0; | ||
|
||
protected: | ||
MicrophoneMuteNotificationDelegate(); | ||
virtual ~MicrophoneMuteNotificationDelegate(); | ||
}; | ||
|
||
} // namespace ash | ||
|
||
#endif // ASH_PUBLIC_CPP_MICROPHONE_MUTE_NOTIFICATION_DELEGATE_H_ |
105 changes: 105 additions & 0 deletions
105
ash/system/microphone_mute/microphone_mute_notification_controller.cc
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
// Copyright 2021 The Chromium Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
#include "ash/system/microphone_mute/microphone_mute_notification_controller.h" | ||
|
||
#include <cstdint> | ||
#include <string> | ||
|
||
#include "ash/public/cpp/microphone_mute_notification_delegate.h" | ||
#include "ash/public/cpp/notification_utils.h" | ||
#include "ash/strings/grit/ash_strings.h" | ||
#include "base/strings/utf_string_conversions.h" | ||
#include "components/vector_icons/vector_icons.h" | ||
#include "ui/base/l10n/l10n_util.h" | ||
#include "ui/message_center/message_center.h" | ||
#include "ui/message_center/public/cpp/notification.h" | ||
|
||
namespace ash { | ||
|
||
// static | ||
const char MicrophoneMuteNotificationController::kNotificationId[] = | ||
"ash://microphone_mute"; | ||
|
||
MicrophoneMuteNotificationController::MicrophoneMuteNotificationController() { | ||
audio_observation_.Observe(CrasAudioHandler::Get()); | ||
} | ||
|
||
MicrophoneMuteNotificationController::~MicrophoneMuteNotificationController() = | ||
default; | ||
|
||
void MicrophoneMuteNotificationController::OnInputMuteChanged(bool mute_on) { | ||
// Catches the case where the mic is muted while a mic-using app is running. | ||
mic_mute_on_ = mute_on; | ||
MaybeShowNotification(); | ||
} | ||
|
||
void MicrophoneMuteNotificationController::MaybeShowNotification() { | ||
if (mic_mute_on_) { | ||
base::Optional<std::u16string> app_name = | ||
MicrophoneMuteNotificationDelegate::Get()->GetAppAccessingMicrophone(); | ||
if (app_name.has_value() || HaveActiveInputStreams()) { | ||
GenerateMicrophoneMuteNotification(app_name); | ||
return; | ||
} | ||
} | ||
|
||
RemoveMicrophoneMuteNotification(); | ||
} | ||
|
||
void MicrophoneMuteNotificationController::GenerateMicrophoneMuteNotification( | ||
const base::Optional<std::u16string>& app_name) { | ||
std::unique_ptr<message_center::Notification> notification = | ||
CreateSystemNotification( | ||
message_center::NOTIFICATION_TYPE_SIMPLE, kNotificationId, | ||
GetNotificationTitle(), GetNotificationMessage(app_name), | ||
/*display_source=*/std::u16string(), GURL(), | ||
message_center::NotifierId( | ||
message_center::NotifierType::SYSTEM_COMPONENT, kNotificationId), | ||
message_center::RichNotificationData(), nullptr, | ||
vector_icons::kSettingsIcon, | ||
message_center::SystemNotificationWarningLevel::NORMAL); | ||
|
||
message_center::MessageCenter::Get()->AddNotification( | ||
std::move(notification)); | ||
} | ||
|
||
std::u16string MicrophoneMuteNotificationController::GetNotificationMessage( | ||
const base::Optional<std::u16string>& app_name) const { | ||
return !app_name.value_or(u"").empty() | ||
? l10n_util::GetStringFUTF16( | ||
IDS_MICROPHONE_MUTE_SWITCH_ON_NOTIFICATION_MESSAGE_WITH_APP_NAME, | ||
app_name.value()) | ||
: l10n_util::GetStringUTF16( | ||
IDS_MICROPHONE_MUTE_SWITCH_ON_NOTIFICATION_MESSAGE); | ||
} | ||
|
||
std::u16string MicrophoneMuteNotificationController::GetNotificationTitle() | ||
const { | ||
return l10n_util::GetStringUTF16( | ||
IDS_MICROPHONE_MUTE_SWITCH_ON_NOTIFICATION_TITLE); | ||
} | ||
|
||
void MicrophoneMuteNotificationController::RemoveMicrophoneMuteNotification() { | ||
message_center::MessageCenter::Get()->RemoveNotification(kNotificationId, | ||
/*by_user=*/false); | ||
} | ||
|
||
bool MicrophoneMuteNotificationController::HaveActiveInputStreams() { | ||
base::flat_map<CrasAudioHandler::ClientType, uint32_t> input_streams = | ||
CrasAudioHandler::Get()->GetNumberOfInputStreamsWithPermission(); | ||
for (auto& per_client_type_count : input_streams) { | ||
if (per_client_type_count.second > 0) | ||
return true; | ||
} | ||
return false; | ||
} | ||
|
||
void MicrophoneMuteNotificationController:: | ||
OnNumberOfInputStreamsWithPermissionChanged() { | ||
// Catches the case where a mic-using app is launched while the mic is muted. | ||
MaybeShowNotification(); | ||
} | ||
|
||
} // namespace ash |
79 changes: 79 additions & 0 deletions
79
ash/system/microphone_mute/microphone_mute_notification_controller.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
// Copyright 2021 The Chromium Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
#ifndef ASH_SYSTEM_MICROPHONE_MUTE_MICROPHONE_MUTE_NOTIFICATION_CONTROLLER_H_ | ||
#define ASH_SYSTEM_MICROPHONE_MUTE_MICROPHONE_MUTE_NOTIFICATION_CONTROLLER_H_ | ||
|
||
#include <string> | ||
|
||
#include "ash/ash_export.h" | ||
#include "ash/components/audio/cras_audio_handler.h" | ||
#include "base/macros.h" | ||
#include "base/memory/weak_ptr.h" | ||
#include "base/scoped_observation.h" | ||
|
||
namespace ash { | ||
|
||
// Controller class to manage microphone mute notifications. This | ||
// notification shows up when the user launches an app that uses the microphone | ||
// while the microphone is muted. | ||
class ASH_EXPORT MicrophoneMuteNotificationController | ||
: public ash::CrasAudioHandler::AudioObserver { | ||
public: | ||
MicrophoneMuteNotificationController(); | ||
MicrophoneMuteNotificationController( | ||
const MicrophoneMuteNotificationController&) = delete; | ||
MicrophoneMuteNotificationController& operator=( | ||
const MicrophoneMuteNotificationController&) = delete; | ||
~MicrophoneMuteNotificationController() override; | ||
|
||
// Shows the microphone muted notification if it needs to be shown. | ||
void MaybeShowNotification(); | ||
|
||
// ash::CrasAudioHandler::AudioObserver: | ||
void OnInputMuteChanged(bool mute_on) override; | ||
void OnNumberOfInputStreamsWithPermissionChanged() override; | ||
|
||
private: | ||
friend class MicrophoneMuteNotificationControllerTest; | ||
|
||
// Creates a notification for telling the user they're attempting to use the | ||
// mic while the mis is muted. | ||
void GenerateMicrophoneMuteNotification( | ||
const base::Optional<std::u16string>& app_name); | ||
|
||
// Mic mute notification title. | ||
std::u16string GetNotificationTitle() const; | ||
|
||
// Mic mute notification body. | ||
std::u16string GetNotificationMessage( | ||
const base::Optional<std::u16string>& app_name) const; | ||
|
||
// Takes down the mic mute notification. | ||
void RemoveMicrophoneMuteNotification(); | ||
|
||
// Returns true if we have any active input stream with permission, of any | ||
// client type. See | ||
// ash::CrasAudioClient::NumberOfInputStreamsWithPermissionChanged() for more | ||
// details. | ||
bool HaveActiveInputStreams(); | ||
|
||
static const char kNotificationId[]; | ||
|
||
// A value of true means the mic is muted. | ||
bool mic_mute_on_ = false; | ||
|
||
base::ScopedObservation<ash::CrasAudioHandler, | ||
AudioObserver, | ||
&ash::CrasAudioHandler::AddAudioObserver, | ||
&ash::CrasAudioHandler::RemoveAudioObserver> | ||
audio_observation_{this}; | ||
|
||
base::WeakPtrFactory<MicrophoneMuteNotificationController> weak_ptr_factory_{ | ||
this}; | ||
}; | ||
|
||
} // namespace ash | ||
|
||
#endif // ASH_SYSTEM_MICROPHONE_MUTE_MICROPHONE_MUTE_NOTIFICATION_CONTROLLER_H_ |
Oops, something went wrong.