blob: ce9941b8dbd96e81013e40160b96fa80eb9daff0 [file] [log] [blame]
// Copyright 2016 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/media/desktop_media_list_base.h"
#include <set>
#include "chrome/browser/media/desktop_media_list_observer.h"
#include "content/public/browser/browser_thread.h"
using content::BrowserThread;
DesktopMediaListBase::DesktopMediaListBase(base::TimeDelta update_period)
: weak_factory_(this) {
update_period_ = update_period;
}
DesktopMediaListBase::~DesktopMediaListBase() {}
void DesktopMediaListBase::SetUpdatePeriod(base::TimeDelta period) {
DCHECK(!observer_);
update_period_ = period;
}
void DesktopMediaListBase::SetThumbnailSize(const gfx::Size& thumbnail_size) {
thumbnail_size_ = thumbnail_size;
}
void DesktopMediaListBase::SetViewDialogWindowId(
content::DesktopMediaID dialog_id) {
view_dialog_id_ = dialog_id;
}
void DesktopMediaListBase::StartUpdating(DesktopMediaListObserver* observer) {
DCHECK(!observer_);
observer_ = observer;
Refresh();
}
int DesktopMediaListBase::GetSourceCount() const {
return sources_.size();
}
const DesktopMediaList::Source& DesktopMediaListBase::GetSource(
int index) const {
DCHECK_GE(index, 0);
DCHECK_LT(index, static_cast<int>(sources_.size()));
return sources_[index];
}
DesktopMediaListBase::SourceDescription::SourceDescription(
content::DesktopMediaID id,
const base::string16& name)
: id(id), name(name) {}
void DesktopMediaListBase::UpdateSourcesList(
const std::vector<SourceDescription>& new_sources) {
typedef std::set<content::DesktopMediaID> SourceSet;
SourceSet new_source_set;
for (size_t i = 0; i < new_sources.size(); ++i) {
new_source_set.insert(new_sources[i].id);
}
// Iterate through the old sources to find the removed sources.
for (size_t i = 0; i < sources_.size(); ++i) {
if (new_source_set.find(sources_[i].id) == new_source_set.end()) {
sources_.erase(sources_.begin() + i);
observer_->OnSourceRemoved(i);
--i;
}
}
// Iterate through the new sources to find the added sources.
if (new_sources.size() > sources_.size()) {
SourceSet old_source_set;
for (size_t i = 0; i < sources_.size(); ++i) {
old_source_set.insert(sources_[i].id);
}
for (size_t i = 0; i < new_sources.size(); ++i) {
if (old_source_set.find(new_sources[i].id) == old_source_set.end()) {
sources_.insert(sources_.begin() + i, Source());
sources_[i].id = new_sources[i].id;
sources_[i].name = new_sources[i].name;
observer_->OnSourceAdded(i);
}
}
}
DCHECK_EQ(new_sources.size(), sources_.size());
// Find the moved/changed sources.
size_t pos = 0;
while (pos < sources_.size()) {
if (!(sources_[pos].id == new_sources[pos].id)) {
// Find the source that should be moved to |pos|, starting from |pos + 1|
// of |sources_|, because entries before |pos| should have been sorted.
size_t old_pos = pos + 1;
for (; old_pos < sources_.size(); ++old_pos) {
if (sources_[old_pos].id == new_sources[pos].id)
break;
}
DCHECK(sources_[old_pos].id == new_sources[pos].id);
// Move the source from |old_pos| to |pos|.
Source temp = sources_[old_pos];
sources_.erase(sources_.begin() + old_pos);
sources_.insert(sources_.begin() + pos, temp);
observer_->OnSourceMoved(old_pos, pos);
}
if (sources_[pos].name != new_sources[pos].name) {
sources_[pos].name = new_sources[pos].name;
observer_->OnSourceNameChanged(pos);
}
++pos;
}
}
void DesktopMediaListBase::UpdateSourceThumbnail(content::DesktopMediaID id,
const gfx::ImageSkia& image) {
for (size_t i = 0; i < sources_.size(); ++i) {
if (sources_[i].id == id) {
sources_[i].thumbnail = image;
observer_->OnSourceThumbnailChanged(i);
break;
}
}
}
void DesktopMediaListBase::ScheduleNextRefresh() {
BrowserThread::PostDelayedTask(
BrowserThread::UI, FROM_HERE,
base::Bind(&DesktopMediaListBase::Refresh, weak_factory_.GetWeakPtr()),
update_period_);
}