1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107
|
// Copyright 2018 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ash/system/audio/display_speaker_controller.h"
#include "ash/shell.h"
#include "chromeos/ash/components/audio/cras_audio_handler.h"
#include "third_party/cros_system_api/dbus/service_constants.h"
#include "ui/display/manager/display_manager.h"
#include "ui/display/manager/managed_display_info.h"
#include "ui/display/util/display_util.h"
inline cras::DisplayRotation ToCRASDisplayRotation(
display::Display::Rotation rotation) {
switch (rotation) {
case display::Display::ROTATE_0:
return cras::DisplayRotation::ROTATE_0;
case display::Display::ROTATE_90:
return cras::DisplayRotation::ROTATE_90;
case display::Display::ROTATE_180:
return cras::DisplayRotation::ROTATE_180;
case display::Display::ROTATE_270:
return cras::DisplayRotation::ROTATE_270;
};
}
namespace ash {
DisplaySpeakerController::DisplaySpeakerController() {
chromeos::PowerManagerClient::Get()->AddObserver(this);
}
DisplaySpeakerController::~DisplaySpeakerController() {
chromeos::PowerManagerClient::Get()->RemoveObserver(this);
}
void DisplaySpeakerController::OnDisplayAdded(
const display::Display& new_display) {
if (!new_display.IsInternal())
return;
UpdateInternalSpeakerForDisplayRotation();
// This event will be triggered when the lid of the device is opened to exit
// the docked mode, we should always start or re-start HDMI re-discovering
// grace period right after this event.
CrasAudioHandler::Get()->SetActiveHDMIOutoutRediscoveringIfNecessary(true);
}
void DisplaySpeakerController::OnDisplaysRemoved(
const display::Displays& removed_displays) {
for (const auto& display : removed_displays) {
if (display.IsInternal()) {
UpdateInternalSpeakerForDisplayRotation();
// This event will be triggered when the lid of the device is closed to
// enter the docked mode, we should always start or re-start HDMI
// re-discovering grace period right after this event.
CrasAudioHandler::Get()->SetActiveHDMIOutoutRediscoveringIfNecessary(
true);
break;
}
}
}
void DisplaySpeakerController::OnDisplayMetricsChanged(
const display::Display& display,
uint32_t changed_metrics) {
if (!display.IsInternal())
return;
if (changed_metrics & display::DisplayObserver::DISPLAY_METRIC_ROTATION) {
UpdateInternalSpeakerForDisplayRotation();
}
// The event could be triggered multiple times during the HDMI display
// transition, we don't need to restart HDMI re-discovering grace period
// it is already started earlier.
CrasAudioHandler::Get()->SetActiveHDMIOutoutRediscoveringIfNecessary(false);
}
void DisplaySpeakerController::SuspendDone(base::TimeDelta sleep_duration) {
// This event is triggered when the device resumes after earlier suspension,
// we should always start or re-start HDMI re-discovering
// grace period right after this event.
CrasAudioHandler::Get()->SetActiveHDMIOutoutRediscoveringIfNecessary(true);
}
void DisplaySpeakerController::UpdateInternalSpeakerForDisplayRotation() {
// Swap left/right channel only if it is in Yoga mode.
bool swap = false;
if (display::HasInternalDisplay()) {
const display::ManagedDisplayInfo& display_info =
Shell::Get()->display_manager()->GetDisplayInfo(
display::Display::InternalDisplayId());
display::Display::Rotation rotation = display_info.GetActiveRotation();
if (rotation == display::Display::ROTATE_180)
swap = true;
CrasAudioHandler::Get()->SetDisplayRotation(
ToCRASDisplayRotation(rotation));
}
CrasAudioHandler::Get()->SwapInternalSpeakerLeftRightChannel(swap);
}
} // namespace ash
|