// Copyright 2014 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 "chrome/browser/extensions/system_display/display_info_provider_chromeos.h"

#include <stdint.h>
#include <cmath>

#include "ash/public/interfaces/constants.mojom.h"
#include "ash/public/interfaces/cros_display_config.mojom.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/stringprintf.h"
#include "base/threading/thread_task_runner_handle.h"
#include "content/public/common/service_manager_connection.h"
#include "extensions/common/api/system_display.h"
#include "services/service_manager/public/cpp/connector.h"
#include "ui/display/display.h"
#include "ui/display/screen.h"
#include "ui/gfx/geometry/point.h"
#include "ui/gfx/geometry/rect.h"

namespace extensions {

namespace system_display = api::system_display;

namespace {

int64_t GetDisplayId(const std::string& display_id_str) {
  int64_t display_id;
  if (!base::StringToInt64(display_id_str, &display_id))
    display_id = display::kInvalidDisplayId;
  return display_id;
}

display::Display GetDisplayForId(const std::string& display_id_str) {
  int64_t id = GetDisplayId(display_id_str);
  display::Display display;
  display::Screen::GetScreen()->GetDisplayWithDisplayId(id, &display);
  return display;
}

ash::mojom::DisplayLayoutPosition GetDisplayLayoutPosition(
    system_display::LayoutPosition position) {
  switch (position) {
    case system_display::LAYOUT_POSITION_TOP:
      return ash::mojom::DisplayLayoutPosition::kTop;
    case system_display::LAYOUT_POSITION_RIGHT:
      return ash::mojom::DisplayLayoutPosition::kRight;
    case system_display::LAYOUT_POSITION_BOTTOM:
      return ash::mojom::DisplayLayoutPosition::kBottom;
    case system_display::LAYOUT_POSITION_LEFT:
    case system_display::LAYOUT_POSITION_NONE:
      return ash::mojom::DisplayLayoutPosition::kLeft;
  }
  NOTREACHED();
  return ash::mojom::DisplayLayoutPosition::kLeft;
}

system_display::LayoutPosition GetLayoutPositionFromMojo(
    ash::mojom::DisplayLayoutPosition position) {
  switch (position) {
    case ash::mojom::DisplayLayoutPosition::kTop:
      return system_display::LayoutPosition::LAYOUT_POSITION_TOP;
    case ash::mojom::DisplayLayoutPosition::kRight:
      return system_display::LayoutPosition::LAYOUT_POSITION_RIGHT;
    case ash::mojom::DisplayLayoutPosition::kBottom:
      return system_display::LayoutPosition::LAYOUT_POSITION_BOTTOM;
    case ash::mojom::DisplayLayoutPosition::kLeft:
      return system_display::LayoutPosition::LAYOUT_POSITION_LEFT;
  }
  NOTREACHED();
  return system_display::LayoutPosition::LAYOUT_POSITION_LEFT;
}

gfx::Insets GetInsets(const system_display::Insets& insets) {
  return gfx::Insets(insets.top, insets.left, insets.bottom, insets.right);
}

// Validates the DisplayProperties input. Does not perform any tests with
// DisplayManager dependencies. Returns an error string on failure or nullopt
// on success.
base::Optional<std::string> ValidateDisplayPropertiesInput(
    const std::string& display_id_str,
    const system_display::DisplayProperties& info) {
  int64_t id = GetDisplayId(display_id_str);
  if (id == display::kInvalidDisplayId)
    return "Invalid display id";

  const display::Display& primary =
      display::Screen::GetScreen()->GetPrimaryDisplay();
  bool is_primary = id == primary.id() || (info.is_primary && *info.is_primary);

  if (info.is_unified) {
    if (!is_primary)
      return "Unified desktop mode can only be set for the primary display.";
    // Setting isUnfied may change the display layout so no other properties
    // should be set.
    if (info.mirroring_source_id)
      return "Unified desktop mode can not be set with mirroringSourceId.";
    if (info.bounds_origin_x || info.bounds_origin_y || info.rotation ||
        info.overscan || info.display_mode || info.display_zoom_factor) {
      LOG(WARNING)
          << "Unified mode set with other properties which will be ignored.";
    }
    return base::nullopt;
  }

  // If mirroring source parameter is specified, no other properties should be
  // set the display list may change when mirroring is applied.
  if (info.mirroring_source_id &&
      (info.is_primary || info.bounds_origin_x || info.bounds_origin_y ||
       info.rotation || info.overscan || info.display_mode ||
       info.display_zoom_factor)) {
    return "No other parameter should be set with mirroringSourceId.";
  }

  // Verify the rotation value is valid.
  if (info.rotation && !display::Display::IsValidRotation(*info.rotation))
    return "Invalid rotation.";

  return base::nullopt;
}

system_display::DisplayMode GetDisplayModeFromMojo(
    const ash::mojom::DisplayMode mode) {
  system_display::DisplayMode result;
  result.width = mode.size.width();
  result.height = mode.size.height();
  result.width_in_native_pixels = mode.size_in_native_pixels.width();
  result.height_in_native_pixels = mode.size_in_native_pixels.height();
  result.ui_scale = mode.ui_scale;
  result.device_scale_factor = mode.device_scale_factor;
  result.refresh_rate = mode.refresh_rate;
  result.is_native = mode.is_native;
  return result;
}

system_display::DisplayUnitInfo GetDisplayUnitInfoFromMojo(
    const ash::mojom::DisplayUnitInfo& mojo_info) {
  system_display::DisplayUnitInfo info;
  info.id = mojo_info.id;
  info.name = mojo_info.name;
  if (mojo_info.edid) {
    info.edid = std::make_unique<system_display::Edid>();
    info.edid->manufacturer_id = mojo_info.edid->manufacturer_id;
    info.edid->product_id = mojo_info.edid->product_id;
    info.edid->year_of_manufacture = mojo_info.edid->year_of_manufacture;
  }
  info.is_primary = mojo_info.is_primary;
  info.is_internal = mojo_info.is_internal;
  info.is_enabled = mojo_info.is_enabled;
  info.is_tablet_mode = std::make_unique<bool>(mojo_info.is_tablet_mode);
  info.dpi_x = mojo_info.dpi_x;
  info.dpi_y = mojo_info.dpi_y;
  info.rotation = display::Display::RotationToDegrees(mojo_info.rotation);
  const gfx::Rect& bounds = mojo_info.bounds;
  info.bounds.left = bounds.x();
  info.bounds.top = bounds.y();
  info.bounds.width = bounds.width();
  info.bounds.height = bounds.height();
  const gfx::Insets& overscan = mojo_info.overscan;
  info.overscan.left = overscan.left();
  info.overscan.top = overscan.top();
  info.overscan.right = overscan.right();
  info.overscan.bottom = overscan.bottom();
  const gfx::Rect& work_area = mojo_info.work_area;
  info.work_area.left = work_area.x();
  info.work_area.top = work_area.y();
  info.work_area.width = work_area.width();
  info.work_area.height = work_area.height();
  for (const ash::mojom::DisplayModePtr& mode :
       mojo_info.available_display_modes) {
    info.modes.emplace_back(GetDisplayModeFromMojo(*mode));
  }
  if (!info.modes.empty()) {
    int index = mojo_info.selected_display_mode_index;
    if (index < 0 || index >= static_cast<int>(info.modes.size()))
      index = 0;
    info.modes[index].is_selected = true;
  }
  info.has_touch_support = mojo_info.has_touch_support;
  info.has_accelerometer_support = mojo_info.has_accelerometer_support;
  info.available_display_zoom_factors =
      mojo_info.available_display_zoom_factors;
  info.display_zoom_factor = mojo_info.display_zoom_factor;
  return info;
}

ash::mojom::TouchCalibrationPairPtr GetTouchCalibrationPair(
    const system_display::TouchCalibrationPair& pair) {
  auto result = ash::mojom::TouchCalibrationPair::New();
  result->display_point =
      gfx::Point(pair.display_point.x, pair.display_point.y);
  result->touch_point = gfx::Point(pair.touch_point.x, pair.touch_point.y);
  return result;
}

void SetDisplayUnitInfoLayoutProperties(
    const ash::mojom::DisplayLayoutInfo& layout,
    system_display::DisplayUnitInfo* display) {
  display->is_unified =
      layout.layout_mode == ash::mojom::DisplayLayoutMode::kUnified;
  if (layout.mirror_source_id) {
    display->mirroring_source_id = *layout.mirror_source_id;
    if (layout.mirror_destination_ids) {
      for (const std::string& id : *layout.mirror_destination_ids)
        display->mirroring_destination_ids.push_back(id);
    }
  }
}

void RunResultCallback(DisplayInfoProvider::ErrorCallback callback,
                       base::Optional<std::string> error) {
  if (error)
    LOG(ERROR) << "API call failed: " << *error;
  base::ThreadTaskRunnerHandle::Get()->PostTask(
      FROM_HERE, base::BindOnce(std::move(callback), std::move(error)));
}

base::Optional<std::string> GetStringResult(
    ash::mojom::DisplayConfigResult result) {
  switch (result) {
    case ash::mojom::DisplayConfigResult::kSuccess:
      return base::nullopt;
    case ash::mojom::DisplayConfigResult::kInvalidOperationError:
      return "Invalid operation";
    case ash::mojom::DisplayConfigResult::kInvalidDisplayIdError:
      return "Invalid display id";
    case ash::mojom::DisplayConfigResult::kUnifiedNotEnabledError:
      return "enableUnifiedDesktop must be called before setting is_unified";
    case ash::mojom::DisplayConfigResult::kPropertyValueOutOfRangeError:
      return "Property value out of range";
    case ash::mojom::DisplayConfigResult::kNotSupportedOnInternalDisplayError:
      return "Not supported for internal displays";
    case ash::mojom::DisplayConfigResult::kNegativeValueError:
      return "Negative values not supported";
    case ash::mojom::DisplayConfigResult::kSetDisplayModeError:
      return "Setting the display mode failed";
    case ash::mojom::DisplayConfigResult::kInvalidDisplayLayoutError:
      return "Invalid display layout";
    case ash::mojom::DisplayConfigResult::kMirrorModeSingleDisplayError:
      return "Mirror mode requires multiple displays";
    case ash::mojom::DisplayConfigResult::kMirrorModeSourceIdError:
      return "Mirror mode source id invalid";
    case ash::mojom::DisplayConfigResult::kMirrorModeDestIdError:
      return "Mirror mode destination id invalid";
    case ash::mojom::DisplayConfigResult::kCalibrationNotAvailableError:
      return "Calibration not available";
    case ash::mojom::DisplayConfigResult::kCalibrationNotStartedError:
      return "Calibration not started";
    case ash::mojom::DisplayConfigResult::kCalibrationInProgressError:
      return "Calibration in progress";
    case ash::mojom::DisplayConfigResult::kCalibrationInvalidDataError:
      return "Calibration data invalid";
    case ash::mojom::DisplayConfigResult::kCalibrationFailedError:
      return "Calibration failed";
  }
  return "Unknown error";
}

void LogErrorResult(ash::mojom::DisplayConfigResult result) {
  base::Optional<std::string> str_result = GetStringResult(result);
  if (!str_result)
    return;
  LOG(ERROR) << *str_result;
}

}  // namespace

DisplayInfoProviderChromeOS::DisplayInfoProviderChromeOS(
    service_manager::Connector* connector)
    : weak_ptr_factory_(this) {
  CHECK(connector);
  connector->BindInterface(ash::mojom::kServiceName, &cros_display_config_);
}

DisplayInfoProviderChromeOS::~DisplayInfoProviderChromeOS() {}

void DisplayInfoProviderChromeOS::SetDisplayProperties(
    const std::string& display_id_str,
    const api::system_display::DisplayProperties& properties,
    ErrorCallback callback) {
  base::Optional<std::string> error =
      ValidateDisplayPropertiesInput(display_id_str, properties);
  if (error) {
    RunResultCallback(std::move(callback), std::move(*error));
    return;
  }

  // Process the 'isUnified' property.
  if (properties.is_unified) {
    auto layout_info = ash::mojom::DisplayLayoutInfo::New();
    layout_info->layout_mode = *properties.is_unified
                                   ? ash::mojom::DisplayLayoutMode::kUnified
                                   : ash::mojom::DisplayLayoutMode::kNormal;
    cros_display_config_->SetDisplayLayoutInfo(
        std::move(layout_info),
        base::BindOnce(
            [](ErrorCallback callback, ash::mojom::DisplayConfigResult result) {
              std::move(callback).Run(GetStringResult(result));
            },
            std::move(callback)));
    // Note: If other properties are set they will be ignored.
    return;
  }

  // Process the deprecated 'mirroringSourceId' property. Validation ensures
  // that no other properties are set.
  if (properties.mirroring_source_id) {
    bool mirror = !properties.mirroring_source_id->empty();
    if (mirror) {
      // A display with the given id should exist and if should not be the same
      // as the target display's id.

      int64_t mirroring_id =
          GetDisplayForId(*properties.mirroring_source_id).id();
      if (mirroring_id == display::kInvalidDisplayId)
        RunResultCallback(std::move(callback), "Invalid mirroring source id");
      if (mirroring_id == GetDisplayId(display_id_str))
        RunResultCallback(std::move(callback), "Not allowed to mirror self");
    }
    api::system_display::MirrorModeInfo info;
    info.mode = system_display::MIRROR_MODE_NORMAL;
    SetMirrorMode(info, std::move(callback));
    return;
  }

  // Global config properties.
  auto config_properties = ash::mojom::DisplayConfigProperties::New();
  config_properties->set_primary =
      properties.is_primary ? *properties.is_primary : false;
  if (properties.overscan)
    config_properties->overscan = GetInsets(*properties.overscan);
  if (properties.rotation) {
    config_properties->rotation = ash::mojom::DisplayRotation::New(
        display::Display::DegreesToRotation(*properties.rotation));
  }
  if (properties.bounds_origin_x || properties.bounds_origin_y) {
    gfx::Point bounds_origin;
    display::Display display = GetDisplayForId(display_id_str);
    if (display.id() != display::kInvalidDisplayId)
      bounds_origin = display.bounds().origin();
    else
      DLOG(ERROR) << "Unable to get origin for display: " << display_id_str;
    if (properties.bounds_origin_x)
      bounds_origin.set_x(*properties.bounds_origin_x);
    if (properties.bounds_origin_y)
      bounds_origin.set_y(*properties.bounds_origin_y);
    LOG(ERROR) << "Bounds origin: " << bounds_origin.ToString();
    config_properties->bounds_origin = std::move(bounds_origin);
  }
  config_properties->display_zoom_factor =
      properties.display_zoom_factor ? *properties.display_zoom_factor : 0;

  // Display mode.
  if (properties.display_mode) {
    auto mojo_display_mode = ash::mojom::DisplayMode::New();
    const api::system_display::DisplayMode& api_display_mode =
        *properties.display_mode;
    mojo_display_mode->size =
        gfx::Size(api_display_mode.width, api_display_mode.height);
    mojo_display_mode->size_in_native_pixels =
        gfx::Size(api_display_mode.width_in_native_pixels,
                  api_display_mode.height_in_native_pixels);
    mojo_display_mode->ui_scale = api_display_mode.ui_scale;
    mojo_display_mode->device_scale_factor =
        api_display_mode.device_scale_factor;
    mojo_display_mode->refresh_rate = api_display_mode.refresh_rate;
    mojo_display_mode->is_native = api_display_mode.is_native;
    config_properties->display_mode = std::move(mojo_display_mode);
  }

  cros_display_config_->SetDisplayProperties(
      display_id_str, std::move(config_properties),
      base::BindOnce(
          [](ErrorCallback callback, ash::mojom::DisplayConfigResult result) {
            std::move(callback).Run(GetStringResult(result));
          },
          std::move(callback)));
}

void DisplayInfoProviderChromeOS::SetDisplayLayout(
    const DisplayLayoutList& layout_list,
    ErrorCallback callback) {
  auto layout_info = ash::mojom::DisplayLayoutInfo::New();
  // Generate the new list of layouts.
  std::vector<ash::mojom::DisplayLayoutPtr> display_layouts;
  for (const system_display::DisplayLayout& layout : layout_list) {
    auto display_layout = ash::mojom::DisplayLayout::New();
    display_layout->id = layout.id;
    display_layout->parent_id = layout.parent_id;
    display_layout->position = GetDisplayLayoutPosition(layout.position);
    display_layout->offset = layout.offset;
    display_layouts.emplace_back(std::move(display_layout));
  }
  layout_info->layouts = std::move(display_layouts);
  // We need to get the current layout info to provide the layout mode.
  cros_display_config_->GetDisplayLayoutInfo(
      base::BindOnce(&DisplayInfoProviderChromeOS::CallSetDisplayLayoutInfo,
                     weak_ptr_factory_.GetWeakPtr(), std::move(layout_info),
                     std::move(callback)));
}

void DisplayInfoProviderChromeOS::CallSetDisplayLayoutInfo(
    ash::mojom::DisplayLayoutInfoPtr layout_info,
    ErrorCallback callback,
    ash::mojom::DisplayLayoutInfoPtr cur_info) {
  // Copy the existing layout_mode.
  layout_info->layout_mode = cur_info->layout_mode;
  cros_display_config_->SetDisplayLayoutInfo(
      std::move(layout_info),
      base::BindOnce(
          [](ErrorCallback callback, ash::mojom::DisplayConfigResult result) {
            std::move(callback).Run(GetStringResult(result));
          },
          std::move(callback)));
}

void DisplayInfoProviderChromeOS::EnableUnifiedDesktop(bool enable) {
  cros_display_config_->SetUnifiedDesktopEnabled(enable);
}

void DisplayInfoProviderChromeOS::GetAllDisplaysInfo(
    bool single_unified,
    base::OnceCallback<void(DisplayUnitInfoList result)> callback) {
  cros_display_config_->GetDisplayLayoutInfo(base::BindOnce(
      &DisplayInfoProviderChromeOS::CallGetDisplayUnitInfoList,
      weak_ptr_factory_.GetWeakPtr(), single_unified, std::move(callback)));
}

void DisplayInfoProviderChromeOS::CallGetDisplayUnitInfoList(
    bool single_unified,
    base::OnceCallback<void(DisplayUnitInfoList result)> callback,
    ash::mojom::DisplayLayoutInfoPtr layout) {
  cros_display_config_->GetDisplayUnitInfoList(
      single_unified,
      base::BindOnce(
          [](ash::mojom::DisplayLayoutInfoPtr layout,
             base::OnceCallback<void(DisplayUnitInfoList)> callback,
             std::vector<ash::mojom::DisplayUnitInfoPtr> info_list) {
            DisplayUnitInfoList all_displays;
            for (const ash::mojom::DisplayUnitInfoPtr& info : info_list) {
              system_display::DisplayUnitInfo display =
                  GetDisplayUnitInfoFromMojo(*info);
              SetDisplayUnitInfoLayoutProperties(*layout, &display);
              all_displays.emplace_back(std::move(display));
            }
            base::ThreadTaskRunnerHandle::Get()->PostTask(
                FROM_HERE,
                base::BindOnce(std::move(callback), std::move(all_displays)));
          },
          std::move(layout), std::move(callback)));
}

void DisplayInfoProviderChromeOS::GetDisplayLayout(
    base::OnceCallback<void(DisplayLayoutList result)> callback) {
  cros_display_config_->GetDisplayLayoutInfo(base::BindOnce(
      [](base::OnceCallback<void(DisplayInfoProvider::DisplayLayoutList)>
             callback,
         ash::mojom::DisplayLayoutInfoPtr info) {
        DisplayInfoProvider::DisplayLayoutList result;
        if (info->layouts) {
          for (ash::mojom::DisplayLayoutPtr& layout : *info->layouts) {
            system_display::DisplayLayout display_layout;
            display_layout.id = layout->id;
            display_layout.parent_id = layout->parent_id;
            display_layout.position =
                GetLayoutPositionFromMojo(layout->position);
            display_layout.offset = layout->offset;
            result.emplace_back(std::move(display_layout));
          }
        }
        std::move(callback).Run(std::move(result));
      },
      std::move(callback)));
}

bool DisplayInfoProviderChromeOS::OverscanCalibrationStart(
    const std::string& id) {
  cros_display_config_->OverscanCalibration(
      id, ash::mojom::DisplayConfigOperation::kStart, base::nullopt,
      base::BindOnce(&LogErrorResult));
  return true;
}

bool DisplayInfoProviderChromeOS::OverscanCalibrationAdjust(
    const std::string& id,
    const system_display::Insets& delta) {
  cros_display_config_->OverscanCalibration(
      id, ash::mojom::DisplayConfigOperation::kAdjust, GetInsets(delta),
      base::BindOnce(&LogErrorResult));
  return true;
}

bool DisplayInfoProviderChromeOS::OverscanCalibrationReset(
    const std::string& id) {
  cros_display_config_->OverscanCalibration(
      id, ash::mojom::DisplayConfigOperation::kReset, base::nullopt,
      base::BindOnce(&LogErrorResult));
  return true;
}

bool DisplayInfoProviderChromeOS::OverscanCalibrationComplete(
    const std::string& id) {
  cros_display_config_->OverscanCalibration(
      id, ash::mojom::DisplayConfigOperation::kComplete, base::nullopt,
      base::BindOnce(&LogErrorResult));
  return true;
}

void DisplayInfoProviderChromeOS::ShowNativeTouchCalibration(
    const std::string& id,
    ErrorCallback callback) {
  CallTouchCalibration(id, ash::mojom::DisplayConfigOperation::kShowNative,
                       nullptr, std::move(callback));
}

bool DisplayInfoProviderChromeOS::StartCustomTouchCalibration(
    const std::string& id) {
  touch_calibration_target_id_ = id;
  CallTouchCalibration(id, ash::mojom::DisplayConfigOperation::kStart, nullptr,
                       ErrorCallback());
  return true;
}

bool DisplayInfoProviderChromeOS::CompleteCustomTouchCalibration(
    const api::system_display::TouchCalibrationPairQuad& pairs,
    const api::system_display::Bounds& bounds) {
  auto calibration = ash::mojom::TouchCalibration::New();
  calibration->pairs.emplace_back(GetTouchCalibrationPair(pairs.pair1));
  calibration->pairs.emplace_back(GetTouchCalibrationPair(pairs.pair2));
  calibration->pairs.emplace_back(GetTouchCalibrationPair(pairs.pair3));
  calibration->pairs.emplace_back(GetTouchCalibrationPair(pairs.pair4));
  calibration->bounds = gfx::Size(bounds.width, bounds.height);
  CallTouchCalibration(touch_calibration_target_id_,
                       ash::mojom::DisplayConfigOperation::kComplete,
                       std::move(calibration), ErrorCallback());
  return true;
}

bool DisplayInfoProviderChromeOS::ClearTouchCalibration(const std::string& id) {
  CallTouchCalibration(id, ash::mojom::DisplayConfigOperation::kReset, nullptr,
                       ErrorCallback());
  return true;
}

void DisplayInfoProviderChromeOS::CallTouchCalibration(
    const std::string& id,
    ash::mojom::DisplayConfigOperation op,
    ash::mojom::TouchCalibrationPtr calibration,
    ErrorCallback callback) {
  cros_display_config_->TouchCalibration(
      id, op, std::move(calibration),
      base::BindOnce(
          [](ErrorCallback callback, ash::mojom::DisplayConfigResult result) {
            if (!callback)
              return;
            std::move(callback).Run(
                result == ash::mojom::DisplayConfigResult::kSuccess
                    ? base::nullopt
                    : GetStringResult(result));
          },
          std::move(callback)));
}

void DisplayInfoProviderChromeOS::SetMirrorMode(
    const api::system_display::MirrorModeInfo& info,
    ErrorCallback callback) {
  auto display_layout_info = ash::mojom::DisplayLayoutInfo::New();
  if (info.mode == api::system_display::MIRROR_MODE_OFF) {
    display_layout_info->layout_mode = ash::mojom::DisplayLayoutMode::kNormal;
  } else {
    display_layout_info->layout_mode = ash::mojom::DisplayLayoutMode::kMirrored;
    if (info.mode == api::system_display::MIRROR_MODE_MIXED) {
      if (!info.mirroring_source_id) {
        RunResultCallback(std::move(callback), "Mirror mode source id invalid");
        return;
      }
      if (!info.mirroring_destination_ids) {
        RunResultCallback(std::move(callback),
                          "Mixed mirror mode requires destination ids");
        return;
      }
      display_layout_info->mirror_source_id = *info.mirroring_source_id;
      display_layout_info->mirror_destination_ids =
          base::make_optional<std::vector<std::string>>(
              *info.mirroring_destination_ids);
    }
  }
  cros_display_config_->SetDisplayLayoutInfo(
      std::move(display_layout_info),
      base::BindOnce(
          [](ErrorCallback callback, ash::mojom::DisplayConfigResult result) {
            std::move(callback).Run(GetStringResult(result));
          },
          std::move(callback)));
}

// static
DisplayInfoProvider* DisplayInfoProvider::Create() {
  std::unique_ptr<service_manager::Connector> connector =
      content::ServiceManagerConnection::GetForProcess()
          ->GetConnector()
          ->Clone();
  return new DisplayInfoProviderChromeOS(connector.get());
}

}  // namespace extensions
