// 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 "chrome/browser/ui/ash/tablet_mode_client.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.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() = default;

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->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)));
}

void DisplayInfoProviderChromeOS::StartObserving() {
  DisplayInfoProvider::StartObserving();

  TabletModeClient* client = TabletModeClient::Get();
  if (client)
    client->AddObserver(this);
}

void DisplayInfoProviderChromeOS::StopObserving() {
  DisplayInfoProvider::StopObserving();

  TabletModeClient* client = TabletModeClient::Get();
  if (client)
    client->RemoveObserver(this);
}

void DisplayInfoProviderChromeOS::OnTabletModeToggled(bool enabled) {
  DispatchOnDisplayChangedEvent();
}

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

}  // namespace extensions
