| Index: ash/display/display_color_manager_chromeos.cc
 | 
| diff --git a/ash/display/display_color_manager_chromeos.cc b/ash/display/display_color_manager_chromeos.cc
 | 
| index 1241978958018acff967d30fbfd9dcb2d0c961dd..e5559198c5a08970543401947a6ba70b36ef7ced 100644
 | 
| --- a/ash/display/display_color_manager_chromeos.cc
 | 
| +++ b/ash/display/display_color_manager_chromeos.cc
 | 
| @@ -7,39 +7,27 @@
 | 
|  #include <utility>
 | 
|  
 | 
|  #include "base/bind.h"
 | 
| -#include "base/bind_helpers.h"
 | 
| -#include "base/command_line.h"
 | 
| -#include "base/files/file_path.h"
 | 
|  #include "base/files/file_util.h"
 | 
| -#include "base/format_macros.h"
 | 
|  #include "base/logging.h"
 | 
| -#include "base/message_loop/message_loop.h"
 | 
| -#include "base/path_service.h"
 | 
|  #include "base/stl_util.h"
 | 
| -#include "base/strings/stringprintf.h"
 | 
|  #include "base/task_runner_util.h"
 | 
|  #include "base/threading/sequenced_worker_pool.h"
 | 
| -#include "chromeos/chromeos_paths.h"
 | 
| +#include "components/quirks/quirks_manager.h"
 | 
|  #include "third_party/qcms/src/qcms.h"
 | 
|  #include "ui/display/types/display_snapshot.h"
 | 
|  #include "ui/display/types/gamma_ramp_rgb_entry.h"
 | 
| -#include "ui/display/types/native_display_delegate.h"
 | 
|  #include "ui/gfx/display.h"
 | 
| -#include "ui/gfx/screen.h"
 | 
|  
 | 
|  namespace ash {
 | 
|  
 | 
|  namespace {
 | 
|  
 | 
| -bool ParseFile(const base::FilePath& path,
 | 
| -               DisplayColorManager::ColorCalibrationData* data) {
 | 
| -  if (!base::PathExists(path))  // No icc file for this display; not an error.
 | 
| -    return false;
 | 
| +scoped_ptr<DisplayColorManager::ColorCalibrationData> ParseDisplayProfile(
 | 
| +    const base::FilePath& path) {
 | 
|    qcms_profile* display_profile = qcms_profile_from_path(path.value().c_str());
 | 
| -
 | 
|    if (!display_profile) {
 | 
|      LOG(WARNING) << "Unable to load ICC file: " << path.value();
 | 
| -    return false;
 | 
| +    return nullptr;
 | 
|    }
 | 
|  
 | 
|    size_t vcgt_channel_length =
 | 
| @@ -47,7 +35,7 @@ bool ParseFile(const base::FilePath& path,
 | 
|    if (!vcgt_channel_length) {
 | 
|      LOG(WARNING) << "No vcgt table in ICC file: " << path.value();
 | 
|      qcms_profile_release(display_profile);
 | 
| -    return false;
 | 
| +    return nullptr;
 | 
|    }
 | 
|  
 | 
|    std::vector<uint16_t> vcgt_data;
 | 
| @@ -55,9 +43,11 @@ bool ParseFile(const base::FilePath& path,
 | 
|    if (!qcms_profile_get_vcgt_rgb_channels(display_profile, &vcgt_data[0])) {
 | 
|      LOG(WARNING) << "Unable to get vcgt data";
 | 
|      qcms_profile_release(display_profile);
 | 
| -    return false;
 | 
| +    return nullptr;
 | 
|    }
 | 
|  
 | 
| +  scoped_ptr<DisplayColorManager::ColorCalibrationData> data(
 | 
| +      new DisplayColorManager::ColorCalibrationData());
 | 
|    data->lut.resize(vcgt_channel_length);
 | 
|    for (size_t i = 0; i < vcgt_channel_length; ++i) {
 | 
|      data->lut[i].r = vcgt_data[i];
 | 
| @@ -65,16 +55,8 @@ bool ParseFile(const base::FilePath& path,
 | 
|      data->lut[i].b = vcgt_data[(vcgt_channel_length * 2) + i];
 | 
|    }
 | 
|    qcms_profile_release(display_profile);
 | 
| -  return true;
 | 
| -}
 | 
| -
 | 
| -base::FilePath PathForDisplaySnapshot(const ui::DisplaySnapshot* snapshot) {
 | 
| -  base::FilePath path;
 | 
| -  CHECK(
 | 
| -      PathService::Get(chromeos::DIR_DEVICE_COLOR_CALIBRATION_PROFILES, &path));
 | 
| -  path = path.Append(
 | 
| -      base::StringPrintf("%08" PRIx64 ".icc", snapshot->product_id()));
 | 
| -  return path;
 | 
| +  VLOG(1) << "Gamma data successfully read from icc file";
 | 
| +  return data;
 | 
|  }
 | 
|  
 | 
|  }  // namespace
 | 
| @@ -82,7 +64,9 @@ base::FilePath PathForDisplaySnapshot(const ui::DisplaySnapshot* snapshot) {
 | 
|  DisplayColorManager::DisplayColorManager(
 | 
|      ui::DisplayConfigurator* configurator,
 | 
|      base::SequencedWorkerPool* blocking_pool)
 | 
| -    : configurator_(configurator), blocking_pool_(blocking_pool) {
 | 
| +    : configurator_(configurator),
 | 
| +      blocking_pool_(blocking_pool),
 | 
| +      weak_ptr_factory_(this) {
 | 
|    configurator_->AddObserver(this);
 | 
|  }
 | 
|  
 | 
| @@ -114,33 +98,56 @@ void DisplayColorManager::ApplyDisplayColorCalibration(int64_t display_id,
 | 
|  
 | 
|  void DisplayColorManager::LoadCalibrationForDisplay(
 | 
|      const ui::DisplaySnapshot* display) {
 | 
| +  DCHECK(thread_checker_.CalledOnValidThread());
 | 
|    if (display->display_id() == gfx::Display::kInvalidDisplayID) {
 | 
|      LOG(WARNING) << "Trying to load calibration data for invalid display id";
 | 
|      return;
 | 
|    }
 | 
|  
 | 
| -  base::FilePath path = PathForDisplaySnapshot(display);
 | 
| +  quirks::QuirksManager::Get()->RequestIccProfilePath(
 | 
| +      display->product_id(),
 | 
| +      base::Bind(&DisplayColorManager::FinishLoadCalibrationForDisplay,
 | 
| +                 weak_ptr_factory_.GetWeakPtr(), display->display_id(),
 | 
| +                 display->product_id(), display->type()));
 | 
| +}
 | 
| +
 | 
| +void DisplayColorManager::FinishLoadCalibrationForDisplay(
 | 
| +    int64_t display_id,
 | 
| +    int64_t product_id,
 | 
| +    ui::DisplayConnectionType type,
 | 
| +    const base::FilePath& path,
 | 
| +    bool file_downloaded) {
 | 
| +  DCHECK(thread_checker_.CalledOnValidThread());
 | 
| +  std::string product_string = quirks::IdToHexString(product_id);
 | 
| +  if (path.empty()) {
 | 
| +    VLOG(1) << "No ICC file found with product id: " << product_string
 | 
| +            << " for display id: " << display_id;
 | 
| +    return;
 | 
| +  }
 | 
| +
 | 
| +  if (file_downloaded && type == ui::DISPLAY_CONNECTION_TYPE_INTERNAL) {
 | 
| +    VLOG(1) << "Downloaded ICC file with product id: " << product_string
 | 
| +            << " for internal display id: " << display_id
 | 
| +            << ". Profile will be applied on next startup.";
 | 
| +    return;
 | 
| +  }
 | 
| +
 | 
|    VLOG(1) << "Loading ICC file " << path.value()
 | 
| -          << " for display id: " << display->display_id()
 | 
| -          << " with product id: " << display->product_id();
 | 
| +          << " for display id: " << display_id
 | 
| +          << " with product id: " << product_string;
 | 
|  
 | 
| -  scoped_ptr<ColorCalibrationData> data(new ColorCalibrationData());
 | 
| -  base::Callback<bool(void)> request(
 | 
| -      base::Bind(&ParseFile, path, base::Unretained(data.get())));
 | 
|    base::PostTaskAndReplyWithResult(
 | 
| -      blocking_pool_, FROM_HERE, request,
 | 
| -      base::Bind(&DisplayColorManager::UpdateCalibrationData, AsWeakPtr(),
 | 
| -                 display->display_id(), display->product_id(),
 | 
| -                 base::Passed(std::move(data))));
 | 
| +      blocking_pool_, FROM_HERE, base::Bind(&ParseDisplayProfile, path),
 | 
| +      base::Bind(&DisplayColorManager::UpdateCalibrationData,
 | 
| +                 weak_ptr_factory_.GetWeakPtr(), display_id, product_id));
 | 
|  }
 | 
|  
 | 
|  void DisplayColorManager::UpdateCalibrationData(
 | 
|      int64_t display_id,
 | 
|      int64_t product_id,
 | 
| -    scoped_ptr<ColorCalibrationData> data,
 | 
| -    bool success) {
 | 
| -  DCHECK_EQ(base::MessageLoop::current()->type(), base::MessageLoop::TYPE_UI);
 | 
| -  if (success) {
 | 
| +    scoped_ptr<ColorCalibrationData> data) {
 | 
| +  DCHECK(thread_checker_.CalledOnValidThread());
 | 
| +  if (data) {
 | 
|      // The map takes over ownership of the underlying memory.
 | 
|      calibration_map_[product_id] = data.release();
 | 
|      ApplyDisplayColorCalibration(display_id, product_id);
 | 
| 
 |