1// Copyright 2013 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "chrome/browser/net/client_hints.h"
6
7#include <locale>
8
9#include "base/bind.h"
10#include "base/strings/stringprintf.h"
11#include "base/task_runner_util.h"
12#include "content/public/browser/browser_thread.h"
13#include "ui/gfx/screen.h"
14
15namespace {
16
17float FetchScreenInfoOnUIThread() {
18  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
19  // TODO(bengr): Consider multi-display scenarios.
20  gfx::Display display = gfx::Screen::GetNativeScreen()->GetPrimaryDisplay();
21  return display.device_scale_factor();
22}
23
24}  // namespace
25
26const char ClientHints::kDevicePixelRatioHeader[] = "CH-DPR";
27
28ClientHints::ClientHints()
29    : weak_ptr_factory_(this) {
30}
31
32ClientHints::~ClientHints() {
33}
34
35void ClientHints::Init() {
36  // TODO(bengr): Observe the device pixel ratio in case it changes during
37  // the Chrome session.
38  RetrieveScreenInfo();
39}
40
41bool ClientHints::RetrieveScreenInfo() {
42  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
43  return content::BrowserThread::PostTaskAndReplyWithResult(
44      content::BrowserThread::UI,
45      FROM_HERE,
46      base::Bind(&FetchScreenInfoOnUIThread),
47      base::Bind(
48          &ClientHints::UpdateScreenInfo, weak_ptr_factory_.GetWeakPtr()));
49}
50
51const std::string& ClientHints::GetDevicePixelRatioHeader() const {
52  return screen_hints_;
53}
54
55void ClientHints::UpdateScreenInfo(float device_pixel_ratio_value) {
56  if (device_pixel_ratio_value <= 0.0)
57    return;
58  std::string device_pixel_ratio = base::StringPrintf("%.2f",
59      device_pixel_ratio_value);
60  // Make sure the Client Hints value doesn't change
61  // according to the machine's locale
62  std::locale locale;
63  for (std::string::iterator it = device_pixel_ratio.begin();
64       it != device_pixel_ratio.end(); ++it) {
65    if (!std::isdigit(*it, locale))
66      *it = '.';
67  }
68  screen_hints_ = device_pixel_ratio;
69}
70
71