Commit 2a9aa012 authored by Mitsuru Oshima's avatar Mitsuru Oshima Committed by Commit Bot

DefaultScaleFactor retriever

This class allows an ash client to get default scale factor.

Bug: b:66995734
Test: covered by unit test
Change-Id: Ie552284aa875976079ae67b48d0b87a8900f6b32
Reviewed-on: https://chromium-review.googlesource.com/1213477
Commit-Queue: Mitsuru Oshima <oshima@chromium.org>
Reviewed-by: default avatarVladislav Kaznacheev <kaznacheev@chromium.org>
Cr-Commit-Position: refs/heads/master@{#589759}
parent 7585ab55
...@@ -45,6 +45,8 @@ component("cpp") { ...@@ -45,6 +45,8 @@ component("cpp") {
"ash_typography.cc", "ash_typography.cc",
"ash_typography.h", "ash_typography.h",
"ash_view_ids.h", "ash_view_ids.h",
"default_scale_factor_retriever.cc",
"default_scale_factor_retriever.h",
"frame_utils.cc", "frame_utils.cc",
"frame_utils.h", "frame_utils.h",
"immersive/immersive_context.cc", "immersive/immersive_context.cc",
...@@ -143,6 +145,7 @@ mojom("test_interfaces") { ...@@ -143,6 +145,7 @@ mojom("test_interfaces") {
source_set("unit_tests") { source_set("unit_tests") {
testonly = true testonly = true
sources = [ sources = [
"default_scale_factor_retriever_unittest.cc",
"menu_utils_unittest.cc", "menu_utils_unittest.cc",
"power_utils_unittest.cc", "power_utils_unittest.cc",
"shelf_model_unittest.cc", "shelf_model_unittest.cc",
......
// Copyright 2018 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/default_scale_factor_retriever.h"
#include "ash/public/interfaces/constants.mojom.h"
namespace ash {
DefaultScaleFactorRetriever::DefaultScaleFactorRetriever()
: weak_ptr_factory_(this) {}
void DefaultScaleFactorRetriever::Start(
ash::mojom::CrosDisplayConfigControllerPtr cros_display_config) {
cros_display_config_ = std::move(cros_display_config);
auto callback = base::BindOnce(
&DefaultScaleFactorRetriever::OnDefaultScaleFactorRetrieved,
weak_ptr_factory_.GetWeakPtr());
cros_display_config_->GetDisplayUnitInfoList(
/*single_unified=*/false,
base::BindOnce(
[](GetDefaultScaleFactorCallback callback,
std::vector<ash::mojom::DisplayUnitInfoPtr> info_list) {
// TODO(oshima): This does not return correct value in docked
// mode.
for (const ash::mojom::DisplayUnitInfoPtr& info : info_list) {
if (info->is_internal) {
DCHECK(info->available_display_modes.size());
std::move(callback).Run(
info->available_display_modes[0]->device_scale_factor);
return;
}
}
std::move(callback).Run(1.0f);
},
std::move(callback)));
}
DefaultScaleFactorRetriever::~DefaultScaleFactorRetriever() = default;
void DefaultScaleFactorRetriever::GetDefaultScaleFactor(
GetDefaultScaleFactorCallback callback) {
if (display::Display::HasForceDeviceScaleFactor()) {
return std::move(callback).Run(
display::Display::GetForcedDeviceScaleFactor());
}
if (default_scale_factor_ > 0) {
std::move(callback).Run(default_scale_factor_);
return;
}
callback_ = std::move(callback);
}
void DefaultScaleFactorRetriever::CancelCallback() {
callback_.Reset();
}
void DefaultScaleFactorRetriever::SetDefaultScaleFactorForTest(
float scale_factor) {
default_scale_factor_ = scale_factor;
}
void DefaultScaleFactorRetriever::OnDefaultScaleFactorRetrieved(
float scale_factor) {
DCHECK_GT(scale_factor, 0.f);
default_scale_factor_ = scale_factor;
if (!callback_.is_null())
std::move(callback_).Run(scale_factor);
}
} // namespace ash
// Copyright 2018 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_DEFAULT_SCALE_FACTOR_RETRIEVER_H_
#define ASH_PUBLIC_CPP_DEFAULT_SCALE_FACTOR_RETRIEVER_H_
#include "ash/public/cpp/ash_public_export.h"
#include "ash/public/interfaces/cros_display_config.mojom.h"
#include "base/callback.h"
#include "base/memory/weak_ptr.h"
#include "base/time/time.h"
namespace ash {
// A utility class to retrieve default scale factor from ash shell
// asynchronously. It consists of two steps to minimize the
// latency.
// 1) Start querying by passing a CrosDisplayController.
// 2) Pass callback which will be called when the default
// scale factor is obtained.
class ASH_PUBLIC_EXPORT DefaultScaleFactorRetriever {
public:
using GetDefaultScaleFactorCallback = base::OnceCallback<void(float)>;
DefaultScaleFactorRetriever();
~DefaultScaleFactorRetriever();
// Start the query process.
void Start(mojom::CrosDisplayConfigControllerPtr cros_display_config);
// Get the default scale factor. The scale factor will be passed
// as an argument to the |callback|. The callback may be call synchronously
// if the scale factor is already available, or may be called
// asynchronously if the query is still in progress.
// This will automatically cancel the pending callback if any.
void GetDefaultScaleFactor(GetDefaultScaleFactorCallback callback);
// Cancels pending callback if any.
void CancelCallback();
void SetDefaultScaleFactorForTest(float scale_factor);
private:
void OnDefaultScaleFactorRetrieved(float scale_factor);
float default_scale_factor_ = -1.f;
mojom::CrosDisplayConfigControllerPtr cros_display_config_;
GetDefaultScaleFactorCallback callback_;
// WeakPtrFactory to use callbacks.
base::WeakPtrFactory<DefaultScaleFactorRetriever> weak_ptr_factory_;
};
} // namespace ash
#endif // ASH_PUBLIC_CPP_DEFAULT_SCALE_FACTOR_RETRIEVER_H_
// Copyright 2018 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/default_scale_factor_retriever.h"
#include "ash/public/interfaces/cros_display_config.mojom.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "mojo/public/cpp/bindings/binding.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/display/display.h"
namespace ash {
namespace {
class TestCrosDisplayConfig : public ash::mojom::CrosDisplayConfigController {
public:
static constexpr int64_t kFakeDisplayId = 1;
TestCrosDisplayConfig() : binding_(this) {}
ash::mojom::CrosDisplayConfigControllerPtr CreateInterfacePtrAndBind() {
ash::mojom::CrosDisplayConfigControllerPtr ptr;
binding_.Bind(mojo::MakeRequest(&ptr));
return ptr;
}
// ash::mojom::CrosDisplayConfigController:
void AddObserver(ash::mojom::CrosDisplayConfigObserverAssociatedPtrInfo
observer) override {}
void GetDisplayLayoutInfo(GetDisplayLayoutInfoCallback callback) override {}
void SetDisplayLayoutInfo(ash::mojom::DisplayLayoutInfoPtr info,
SetDisplayLayoutInfoCallback callback) override {}
void GetDisplayUnitInfoList(
bool single_unified,
GetDisplayUnitInfoListCallback callback) override {
std::vector<ash::mojom::DisplayUnitInfoPtr> info_list;
auto info = ash::mojom::DisplayUnitInfo::New();
info->id = kFakeDisplayId;
info->is_internal = true;
auto mode = ash::mojom::DisplayMode::New();
mode->device_scale_factor = 2.f;
info->available_display_modes.emplace_back(std::move(mode));
info_list.push_back(std::move(info));
std::move(callback).Run(std::move(info_list));
}
void SetDisplayProperties(const std::string& id,
ash::mojom::DisplayConfigPropertiesPtr properties,
SetDisplayPropertiesCallback callback) override {}
void SetUnifiedDesktopEnabled(bool enabled) override {}
void OverscanCalibration(const std::string& display_id,
ash::mojom::DisplayConfigOperation op,
const base::Optional<gfx::Insets>& delta,
OverscanCalibrationCallback callback) override {}
void TouchCalibration(const std::string& display_id,
ash::mojom::DisplayConfigOperation op,
ash::mojom::TouchCalibrationPtr calibration,
TouchCalibrationCallback callback) override {}
private:
mojo::Binding<ash::mojom::CrosDisplayConfigController> binding_;
DISALLOW_COPY_AND_ASSIGN(TestCrosDisplayConfig);
};
class DefaultScaleFactorRetrieverTest : public testing::Test {
public:
DefaultScaleFactorRetrieverTest() = default;
~DefaultScaleFactorRetrieverTest() override = default;
private:
base::MessageLoop message_loop_;
DISALLOW_COPY_AND_ASSIGN(DefaultScaleFactorRetrieverTest);
};
} // namespace
TEST_F(DefaultScaleFactorRetrieverTest, Basic) {
display::Display::SetInternalDisplayId(TestCrosDisplayConfig::kFakeDisplayId);
auto display_config = std::make_unique<TestCrosDisplayConfig>();
auto retriever = std::make_unique<ash::DefaultScaleFactorRetriever>();
auto callback = [](float* result, float default_scale_factor) {
result[0] = default_scale_factor;
};
float result1[1] = {0};
retriever->Start(display_config->CreateInterfacePtrAndBind());
retriever->GetDefaultScaleFactor(base::BindOnce(callback, result1));
float result2[1] = {0};
// This will cancel the 1st callback.
retriever->GetDefaultScaleFactor(base::BindOnce(callback, result2));
EXPECT_EQ(0.f, result1[0]);
EXPECT_EQ(0.f, result2[0]);
base::RunLoop().RunUntilIdle();
EXPECT_EQ(0.f, result1[0]);
EXPECT_EQ(2.f, result2[0]);
float result3[1] = {0};
// This time, it should use the cached value.
retriever->GetDefaultScaleFactor(base::BindOnce(callback, result3));
EXPECT_EQ(2.f, result3[0]);
// For test.
retriever->SetDefaultScaleFactorForTest(3.0f);
retriever->GetDefaultScaleFactor(base::BindOnce(callback, result3));
EXPECT_EQ(3.f, result3[0]);
display::Display::SetInternalDisplayId(display::kInvalidDisplayId);
}
TEST_F(DefaultScaleFactorRetrieverTest, Cancel) {
display::Display::SetInternalDisplayId(TestCrosDisplayConfig::kFakeDisplayId);
auto display_config = std::make_unique<TestCrosDisplayConfig>();
auto retriever = std::make_unique<ash::DefaultScaleFactorRetriever>();
auto callback = [](float* result, float default_scale_factor) {
result[0] = default_scale_factor;
};
float result[1] = {0};
retriever->Start(display_config->CreateInterfacePtrAndBind());
retriever->GetDefaultScaleFactor(base::BindOnce(callback, result));
retriever->CancelCallback();
EXPECT_EQ(0.f, result[0]);
base::RunLoop().RunUntilIdle();
EXPECT_EQ(0.f, result[0]);
float result2[1] = {0};
// This time, it should use the cached value.
retriever->GetDefaultScaleFactor(base::BindOnce(callback, result2));
EXPECT_EQ(2.f, result2[0]);
display::Display::SetInternalDisplayId(display::kInvalidDisplayId);
}
} // namespace ash
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