// Copyright 2018 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 "components/cryptauth/remote_device_cache.h" #include "base/memory/ptr_util.h" #include "base/no_destructor.h" #include "base/stl_util.h" namespace cryptauth { // static RemoteDeviceCache::Factory* RemoteDeviceCache::Factory::test_factory_ = nullptr; // static RemoteDeviceCache::Factory* RemoteDeviceCache::Factory::Get() { if (test_factory_) return test_factory_; static base::NoDestructor factory; return factory.get(); } // static void RemoteDeviceCache::Factory::SetFactoryForTesting(Factory* test_factory) { test_factory_ = test_factory; } RemoteDeviceCache::Factory::~Factory() = default; std::unique_ptr RemoteDeviceCache::Factory::BuildInstance() { return base::WrapUnique(new RemoteDeviceCache()); } RemoteDeviceCache::RemoteDeviceCache() = default; RemoteDeviceCache::~RemoteDeviceCache() = default; void RemoteDeviceCache::SetRemoteDevices( const RemoteDeviceList& remote_devices) { for (const auto& remote_device : remote_devices) { if (base::ContainsKey(remote_device_map_, remote_device.GetDeviceId())) { // TODO(khorimoto): Do not overwrite device metadata if the new device // contains a stale timestamp; see https://crbug.com/856746. // Keep the same shared_ptr object, and simply // update the RemoteDevice it references. This transparently updates // the RemoteDeviceRefs used by clients. *remote_device_map_[remote_device.GetDeviceId()] = remote_device; } else { remote_device_map_[remote_device.GetDeviceId()] = std::make_shared(remote_device); } } // Intentionally leave behind devices in the map which weren't in // |remote_devices|, to prevent clients from segfaulting by accessing "stale" // devices. } RemoteDeviceRefList RemoteDeviceCache::GetRemoteDevices() const { RemoteDeviceRefList remote_devices; for (const auto& it : remote_device_map_) remote_devices.push_back(RemoteDeviceRef(it.second)); return remote_devices; } base::Optional RemoteDeviceCache::GetRemoteDevice( const std::string& device_id) const { if (!base::ContainsKey(remote_device_map_, device_id)) return base::nullopt; return RemoteDeviceRef(remote_device_map_.at(device_id)); } } // namespace cryptauth