aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorVitaly Buka <vitalybuka@google.com>2016-02-03 16:37:28 -0800
committerVitaly Buka <vitalybuka@google.com>2016-02-03 16:49:26 -0800
commitff46c9361512be430b2aea0e8e11b51c2b9671b5 (patch)
tree3836a79d53e7ab607d6c0b89ccd6cc8eefe30cb7 /src
parent08be74de678930e6823f9fe7e460c35bb58040f9 (diff)
parent51c4d0d3184dfb5f2601367f06a46459126f377d (diff)
downloadlibweave-ff46c9361512be430b2aea0e8e11b51c2b9671b5.tar.gz
Merge remote-tracking branch 'weave/master' into dev_review
* weave/master: Revert "Make internal googletest optional." Fix incorrect weave setting file path Make internal googletest optional. Make internal libevhtp optional. Periodicly clean up command queue and remove old processed commands Changed meaning of some SSID flags Rename CommandQueue::DelayedRemove into RemoveLater() Fix memory leak when removing CommandInstance from CommandQueue Add a unit tests for deleting CloudCommandProxy along with CommandInstance Add libevent-dev to README. Make default Makefile target "all". Replace bleeding-edge libevent with libevhtp. Remove crypto type "None" Merge: Add write callback into SaveSettings function Merge: Add |name| into LoadSettings/SaveSettings Change-Id: Ia20fbfd59ee3b6287380b6e674b03f038d1b88b3
Diffstat (limited to 'src')
-rw-r--r--src/access_api_handler_unittest.cc4
-rw-r--r--src/base_api_handler_unittest.cc4
-rw-r--r--src/commands/cloud_command_proxy.h2
-rw-r--r--src/commands/cloud_command_proxy_unittest.cc41
-rw-r--r--src/commands/command_instance.cc2
-rw-r--r--src/commands/command_instance.h5
-rw-r--r--src/commands/command_queue.cc40
-rw-r--r--src/commands/command_queue.h35
-rw-r--r--src/commands/command_queue_unittest.cc60
-rw-r--r--src/component_manager_impl.cc6
-rw-r--r--src/component_manager_impl.h3
-rw-r--r--src/component_manager_unittest.cc4
-rw-r--r--src/device_manager.cc2
-rw-r--r--src/device_registration_info_unittest.cc2
-rw-r--r--src/privet/wifi_bootstrap_manager.cc16
-rw-r--r--src/privet/wifi_ssid_generator.cc17
-rw-r--r--src/privet/wifi_ssid_generator.h2
-rw-r--r--src/privet/wifi_ssid_generator_unittest.cc28
-rw-r--r--src/test/fake_task_runner.cc4
-rw-r--r--src/weave_unittest.cc5
20 files changed, 213 insertions, 69 deletions
diff --git a/src/access_api_handler_unittest.cc b/src/access_api_handler_unittest.cc
index a142735..3e7f5d7 100644
--- a/src/access_api_handler_unittest.cc
+++ b/src/access_api_handler_unittest.cc
@@ -5,6 +5,7 @@
#include "src/access_api_handler.h"
#include <gtest/gtest.h>
+#include <weave/provider/test/fake_task_runner.h>
#include <weave/test/mock_device.h>
#include <weave/test/unittest_utils.h>
@@ -99,7 +100,8 @@ class AccessApiHandlerTest : public ::testing::Test {
return std::unique_ptr<base::DictionaryValue>{state->DeepCopy()};
}
- ComponentManagerImpl component_manager_;
+ StrictMock<provider::test::FakeTaskRunner> task_runner_;
+ ComponentManagerImpl component_manager_{&task_runner_};
StrictMock<test::MockDevice> device_;
StrictMock<MockAccessBlackListManager> access_manager_;
std::unique_ptr<AccessApiHandler> handler_;
diff --git a/src/base_api_handler_unittest.cc b/src/base_api_handler_unittest.cc
index 8b0f0b2..2a202d1 100644
--- a/src/base_api_handler_unittest.cc
+++ b/src/base_api_handler_unittest.cc
@@ -8,6 +8,7 @@
#include <base/time/default_clock.h>
#include <base/values.h>
#include <gtest/gtest.h>
+#include <weave/provider/test/fake_task_runner.h>
#include <weave/provider/test/mock_config_store.h>
#include <weave/provider/test/mock_http_client.h>
#include <weave/test/mock_device.h>
@@ -93,7 +94,8 @@ class BaseApiHandlerTest : public ::testing::Test {
Config config_{&config_store_};
StrictMock<provider::test::MockHttpClient> http_client_;
std::unique_ptr<DeviceRegistrationInfo> dev_reg_;
- ComponentManagerImpl component_manager_;
+ StrictMock<provider::test::FakeTaskRunner> task_runner_;
+ ComponentManagerImpl component_manager_{&task_runner_};
std::unique_ptr<BaseApiHandler> handler_;
StrictMock<test::MockDevice> device_;
};
diff --git a/src/commands/cloud_command_proxy.h b/src/commands/cloud_command_proxy.h
index 13f4654..80efd70 100644
--- a/src/commands/cloud_command_proxy.h
+++ b/src/commands/cloud_command_proxy.h
@@ -29,7 +29,7 @@ class TaskRunner;
}
// Command proxy which publishes command updates to the cloud.
-class CloudCommandProxy final : public CommandInstance::Observer {
+class CloudCommandProxy : public CommandInstance::Observer {
public:
CloudCommandProxy(CommandInstance* command_instance,
CloudCommandUpdateInterface* cloud_command_updater,
diff --git a/src/commands/cloud_command_proxy_unittest.cc b/src/commands/cloud_command_proxy_unittest.cc
index 013769d..0de67fe 100644
--- a/src/commands/cloud_command_proxy_unittest.cc
+++ b/src/commands/cloud_command_proxy_unittest.cc
@@ -7,6 +7,7 @@
#include <memory>
#include <queue>
+#include <base/bind.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <weave/provider/test/fake_task_runner.h>
@@ -16,6 +17,7 @@
#include "src/mock_component_manager.h"
using testing::_;
+using testing::AnyNumber;
using testing::DoAll;
using testing::Invoke;
using testing::Return;
@@ -62,6 +64,27 @@ class TestBackoffEntry : public BackoffEntry {
base::Time creation_time_;
};
+class CloudCommandProxyWrapper : public CloudCommandProxy {
+ public:
+ CloudCommandProxyWrapper(CommandInstance* command_instance,
+ CloudCommandUpdateInterface* cloud_command_updater,
+ ComponentManager* component_manager,
+ std::unique_ptr<BackoffEntry> backoff_entry,
+ provider::TaskRunner* task_runner,
+ const base::Closure& destruct_callback)
+ : CloudCommandProxy{command_instance, cloud_command_updater,
+ component_manager, std::move(backoff_entry),
+ task_runner},
+ destruct_callback_{destruct_callback} {}
+
+ ~CloudCommandProxyWrapper() {
+ destruct_callback_.Run();
+ }
+
+ private:
+ base::Closure destruct_callback_;
+};
+
class CloudCommandProxyTest : public ::testing::Test {
protected:
void SetUp() override {
@@ -100,15 +123,21 @@ class CloudCommandProxyTest : public ::testing::Test {
new TestBackoffEntry{&policy, task_runner_.GetClock()}};
// Finally construct the CloudCommandProxy we are going to test here.
- std::unique_ptr<CloudCommandProxy> proxy{new CloudCommandProxy{
+ std::unique_ptr<CloudCommandProxy> proxy{new CloudCommandProxyWrapper{
command_instance_.get(), &cloud_updater_, &component_manager_,
- std::move(backoff), &task_runner_}};
+ std::move(backoff), &task_runner_,
+ base::Bind(&CloudCommandProxyTest::OnProxyDestroyed,
+ base::Unretained(this))}};
// CloudCommandProxy::CloudCommandProxy() subscribe itself to weave::Command
// notifications. When weave::Command is being destroyed it sends
// ::OnCommandDestroyed() and CloudCommandProxy deletes itself.
proxy.release();
+
+ EXPECT_CALL(*this, OnProxyDestroyed()).Times(AnyNumber());
}
+ MOCK_METHOD0(OnProxyDestroyed, void());
+
ComponentManager::UpdateID current_state_update_id_{0};
base::CallbackList<void(ComponentManager::UpdateID)> callbacks_;
testing::StrictMock<MockCloudCommandUpdateInterface> cloud_updater_;
@@ -120,6 +149,14 @@ class CloudCommandProxyTest : public ::testing::Test {
} // anonymous namespace
+TEST_F(CloudCommandProxyTest, EnsureDestroyed) {
+ EXPECT_CALL(*this, OnProxyDestroyed()).Times(1);
+ command_instance_.reset();
+ // Verify that CloudCommandProxy has been destroyed already and not at some
+ // point during the destruction of CloudCommandProxyTest class.
+ testing::Mock::VerifyAndClearExpectations(this);
+}
+
TEST_F(CloudCommandProxyTest, ImmediateUpdate) {
const char expected[] = "{'state':'done'}";
EXPECT_CALL(cloud_updater_, UpdateCommand(kCmdID, MatchJson(expected), _));
diff --git a/src/commands/command_instance.cc b/src/commands/command_instance.cc
index fc9b0e7..590bbb1 100644
--- a/src/commands/command_instance.cc
+++ b/src/commands/command_instance.cc
@@ -284,7 +284,7 @@ bool CommandInstance::SetStatus(Command::State status, ErrorPtr* error) {
void CommandInstance::RemoveFromQueue() {
if (queue_)
- queue_->DelayedRemove(GetID());
+ queue_->RemoveLater(GetID());
}
} // namespace weave
diff --git a/src/commands/command_instance.h b/src/commands/command_instance.h
index b1028d0..febe5c5 100644
--- a/src/commands/command_instance.h
+++ b/src/commands/command_instance.h
@@ -89,10 +89,7 @@ class CommandInstance final : public Command {
// Sets the pointer to queue this command is part of.
void AttachToQueue(CommandQueue* queue) { queue_ = queue; }
- void DetachFromQueue() {
- observers_.Clear();
- queue_ = nullptr;
- }
+ void DetachFromQueue() { queue_ = nullptr; }
private:
// Helper function to update the command status.
diff --git a/src/commands/command_queue.cc b/src/commands/command_queue.cc
index 134dc1c..f0d2228 100644
--- a/src/commands/command_queue.cc
+++ b/src/commands/command_queue.cc
@@ -18,6 +18,10 @@ std::string GetCommandHandlerKey(const std::string& component_path,
}
}
+CommandQueue::CommandQueue(provider::TaskRunner* task_runner,
+ base::Clock* clock)
+ : task_runner_{task_runner}, clock_{clock} {}
+
void CommandQueue::AddCommandAddedCallback(const CommandCallback& callback) {
on_command_added_.push_back(callback);
// Send all pre-existed commands.
@@ -84,18 +88,19 @@ void CommandQueue::Add(std::unique_ptr<CommandInstance> instance) {
it_handler->second.Run(pair.first->second);
else if (!default_command_callback_.is_null())
default_command_callback_.Run(pair.first->second);
-
- Cleanup();
}
-void CommandQueue::DelayedRemove(const std::string& id) {
+void CommandQueue::RemoveLater(const std::string& id) {
auto p = map_.find(id);
if (p == map_.end())
return;
- remove_queue_.push(std::make_pair(
- base::Time::Now() + base::TimeDelta::FromMinutes(kRemoveCommandDelayMin),
- id));
- Cleanup();
+ auto remove_delay = base::TimeDelta::FromMinutes(kRemoveCommandDelayMin);
+ remove_queue_.push(std::make_pair(clock_->Now() + remove_delay, id));
+ if (remove_queue_.size() == 1) {
+ // The queue was empty, this is the first command to be removed, schedule
+ // a clean-up task.
+ ScheduleCleanup(remove_delay);
+ }
}
bool CommandQueue::Remove(const std::string& id) {
@@ -110,19 +115,26 @@ bool CommandQueue::Remove(const std::string& id) {
return true;
}
-void CommandQueue::Cleanup() {
- while (!remove_queue_.empty() && remove_queue_.front().first < Now()) {
- Remove(remove_queue_.front().second);
+void CommandQueue::Cleanup(const base::Time& cutoff_time) {
+ while (!remove_queue_.empty() && remove_queue_.top().first <= cutoff_time) {
+ Remove(remove_queue_.top().second);
remove_queue_.pop();
}
}
-void CommandQueue::SetNowForTest(base::Time now) {
- test_now_ = now;
+void CommandQueue::ScheduleCleanup(base::TimeDelta delay) {
+ task_runner_->PostDelayedTask(
+ FROM_HERE,
+ base::Bind(&CommandQueue::PerformScheduledCleanup,
+ weak_ptr_factory_.GetWeakPtr()),
+ delay);
}
-base::Time CommandQueue::Now() const {
- return test_now_.is_null() ? base::Time::Now() : test_now_;
+void CommandQueue::PerformScheduledCleanup() {
+ base::Time now = clock_->Now();
+ Cleanup(now);
+ if (!remove_queue_.empty())
+ ScheduleCleanup(remove_queue_.top().first - now);
}
CommandInstance* CommandQueue::Find(const std::string& id) const {
diff --git a/src/commands/command_queue.h b/src/commands/command_queue.h
index 0f0a18b..a092c12 100644
--- a/src/commands/command_queue.h
+++ b/src/commands/command_queue.h
@@ -14,8 +14,10 @@
#include <base/callback.h>
#include <base/macros.h>
+#include <base/time/default_clock.h>
#include <base/time/time.h>
#include <weave/device.h>
+#include <weave/provider/task_runner.h>
#include "src/commands/command_instance.h"
@@ -23,7 +25,7 @@ namespace weave {
class CommandQueue final {
public:
- CommandQueue() = default;
+ CommandQueue(provider::TaskRunner* task_runner, base::Clock* clock);
// TODO: Remove AddCommandAddedCallback and AddCommandRemovedCallback.
using CommandCallback = base::Callback<void(Command* command)>;
@@ -51,7 +53,7 @@ class CommandQueue final {
// Selects command identified by |id| ready for removal. Command will actually
// be removed after some time.
- void DelayedRemove(const std::string& id);
+ void RemoveLater(const std::string& id);
// Finds a command instance in the queue by the instance |id|. Returns
// nullptr if the command with the given |id| is not found. The returned
@@ -64,23 +66,29 @@ class CommandQueue final {
// Removes a command identified by |id| from the queue.
bool Remove(const std::string& id);
- // Removes old commands selected with DelayedRemove.
- void Cleanup();
+ // Removes old commands scheduled by RemoveLater() to be deleted after
+ // |cutoff_time|.
+ void Cleanup(const base::Time& cutoff_time);
- // Overrides CommandQueue::Now() for tests.
- void SetNowForTest(base::Time now);
+ // Schedule a cleanup task to be run after the specified |delay|.
+ void ScheduleCleanup(base::TimeDelta delay);
- // Returns current time.
- base::Time Now() const;
+ // Perform removal of scheduled commands (by calling Cleanup()) and scheduling
+ // another cleanup task if the removal queue is still not empty.
+ void PerformScheduledCleanup();
- // Overridden value to be returned from Now().
- base::Time test_now_;
+ provider::TaskRunner* task_runner_{nullptr};
+ base::Clock* clock_{nullptr};
// ID-to-CommandInstance map.
std::map<std::string, std::shared_ptr<CommandInstance>> map_;
- // Queue of commands to be removed.
- std::queue<std::pair<base::Time, std::string>> remove_queue_;
+ // Queue of commands to be removed, keeps them sorted by the timestamp
+ // (earliest first). This is done to tolerate system clock changes.
+ template <typename T>
+ using InversePriorityQueue =
+ std::priority_queue<T, std::vector<T>, std::greater<T>>;
+ InversePriorityQueue<std::pair<base::Time, std::string>> remove_queue_;
using CallbackList = std::vector<CommandCallback>;
CallbackList on_command_added_;
@@ -88,6 +96,9 @@ class CommandQueue final {
std::map<std::string, Device::CommandHandlerCallback> command_callbacks_;
Device::CommandHandlerCallback default_command_callback_;
+ // WeakPtr factory for controlling the lifetime of command queue cleanup
+ // tasks.
+ base::WeakPtrFactory<CommandQueue> weak_ptr_factory_{this};
DISALLOW_COPY_AND_ASSIGN(CommandQueue);
};
diff --git a/src/commands/command_queue_unittest.cc b/src/commands/command_queue_unittest.cc
index b4c5938..1e2e0ac 100644
--- a/src/commands/command_queue_unittest.cc
+++ b/src/commands/command_queue_unittest.cc
@@ -10,12 +10,18 @@
#include <base/bind.h>
#include <base/memory/weak_ptr.h>
+#include <gmock/gmock.h>
#include <gtest/gtest.h>
+#include <weave/provider/test/fake_task_runner.h>
+#include "src/bind_lambda.h"
#include "src/string_utils.h"
namespace weave {
+using testing::Return;
+using testing::StrictMock;
+
class CommandQueueTest : public testing::Test {
public:
std::unique_ptr<CommandInstance> CreateDummyCommandInstance(
@@ -30,11 +36,15 @@ class CommandQueueTest : public testing::Test {
bool Remove(const std::string& id) { return queue_.Remove(id); }
void Cleanup(const base::TimeDelta& interval) {
- queue_.SetNowForTest(base::Time::Now() + interval);
- return queue_.Cleanup();
+ return queue_.Cleanup(task_runner_.GetClock()->Now() + interval);
+ }
+
+ std::string GetFirstCommandToBeRemoved() const {
+ return queue_.remove_queue_.top().second;
}
- CommandQueue queue_;
+ StrictMock<provider::test::FakeTaskRunner> task_runner_;
+ CommandQueue queue_{&task_runner_, task_runner_.GetClock()};
};
// Keeps track of commands being added to and removed from the queue_.
@@ -105,12 +115,12 @@ TEST_F(CommandQueueTest, Remove) {
EXPECT_TRUE(queue_.IsEmpty());
}
-TEST_F(CommandQueueTest, DelayedRemove) {
+TEST_F(CommandQueueTest, RemoveLater) {
const std::string id1 = "id1";
queue_.Add(CreateDummyCommandInstance("base.reboot", id1));
EXPECT_EQ(1u, queue_.GetCount());
- queue_.DelayedRemove(id1);
+ queue_.RemoveLater(id1);
EXPECT_EQ(1u, queue_.GetCount());
Cleanup(base::TimeDelta::FromMinutes(1));
@@ -120,6 +130,46 @@ TEST_F(CommandQueueTest, DelayedRemove) {
EXPECT_EQ(0u, queue_.GetCount());
}
+TEST_F(CommandQueueTest, RemoveLaterOnCleanupTask) {
+ const std::string id1 = "id1";
+ queue_.Add(CreateDummyCommandInstance("base.reboot", id1));
+ EXPECT_EQ(1u, queue_.GetCount());
+
+ queue_.RemoveLater(id1);
+ EXPECT_EQ(1u, queue_.GetCount());
+ ASSERT_EQ(1u, task_runner_.GetTaskQueueSize());
+
+ task_runner_.RunOnce();
+
+ EXPECT_EQ(0u, queue_.GetCount());
+ EXPECT_EQ(0u, task_runner_.GetTaskQueueSize());
+}
+
+TEST_F(CommandQueueTest, CleanupMultipleCommands) {
+ const std::string id1 = "id1";
+ const std::string id2 = "id2";
+
+ queue_.Add(CreateDummyCommandInstance("base.reboot", id1));
+ queue_.Add(CreateDummyCommandInstance("base.reboot", id2));
+ auto remove_task = [this](const std::string& id) { queue_.RemoveLater(id); };
+ remove_task(id1);
+ task_runner_.PostDelayedTask(FROM_HERE, base::Bind(remove_task, id2),
+ base::TimeDelta::FromSeconds(10));
+ EXPECT_EQ(2u, queue_.GetCount());
+ ASSERT_EQ(2u, task_runner_.GetTaskQueueSize());
+ task_runner_.RunOnce(); // Executes "remove_task(id2) @ T+10s".
+ ASSERT_EQ(2u, queue_.GetCount());
+ ASSERT_EQ(1u, task_runner_.GetTaskQueueSize());
+ EXPECT_EQ(id1, GetFirstCommandToBeRemoved());
+ task_runner_.RunOnce(); // Should remove task "id1" from queue.
+ ASSERT_EQ(1u, queue_.GetCount());
+ ASSERT_EQ(1u, task_runner_.GetTaskQueueSize());
+ EXPECT_EQ(id2, GetFirstCommandToBeRemoved());
+ task_runner_.RunOnce(); // Should remove task "id2" from queue.
+ EXPECT_EQ(0u, queue_.GetCount());
+ EXPECT_EQ(0u, task_runner_.GetTaskQueueSize());
+}
+
TEST_F(CommandQueueTest, Dispatch) {
FakeDispatcher dispatch(&queue_);
const std::string id1 = "id1";
diff --git a/src/component_manager_impl.cc b/src/component_manager_impl.cc
index 550775d..dec4a48 100644
--- a/src/component_manager_impl.cc
+++ b/src/component_manager_impl.cc
@@ -31,8 +31,10 @@ template <>
LIBWEAVE_EXPORT EnumToStringMap<UserRole>::EnumToStringMap()
: EnumToStringMap(kMap) {}
-ComponentManagerImpl::ComponentManagerImpl(base::Clock* clock)
- : clock_{clock ? clock : &default_clock_} {}
+ComponentManagerImpl::ComponentManagerImpl(provider::TaskRunner* task_runner,
+ base::Clock* clock)
+ : clock_{clock ? clock : &default_clock_},
+ command_queue_{task_runner, clock_} {}
ComponentManagerImpl::~ComponentManagerImpl() {}
diff --git a/src/component_manager_impl.h b/src/component_manager_impl.h
index 8c4ad16..f3c5451 100644
--- a/src/component_manager_impl.h
+++ b/src/component_manager_impl.h
@@ -15,7 +15,8 @@ namespace weave {
class ComponentManagerImpl final : public ComponentManager {
public:
- explicit ComponentManagerImpl(base::Clock* clock = nullptr);
+ explicit ComponentManagerImpl(provider::TaskRunner* task_runner,
+ base::Clock* clock = nullptr);
~ComponentManagerImpl() override;
// Loads trait definition schema.
diff --git a/src/component_manager_unittest.cc b/src/component_manager_unittest.cc
index 63fedac..97dc00d 100644
--- a/src/component_manager_unittest.cc
+++ b/src/component_manager_unittest.cc
@@ -7,6 +7,7 @@
#include <map>
#include <gtest/gtest.h>
+#include <weave/provider/test/fake_task_runner.h>
#include <weave/test/unittest_utils.h>
#include "src/bind_lambda.h"
@@ -90,8 +91,9 @@ class ComponentManagerTest : public ::testing::Test {
{"t5", "t6"}, nullptr));
}
+ StrictMock<provider::test::FakeTaskRunner> task_runner_;
StrictMock<test::MockClock> clock_;
- ComponentManagerImpl manager_{&clock_};
+ ComponentManagerImpl manager_{&task_runner_, &clock_};
};
} // anonymous namespace
diff --git a/src/device_manager.cc b/src/device_manager.cc
index 8eed558..deb5404 100644
--- a/src/device_manager.cc
+++ b/src/device_manager.cc
@@ -31,7 +31,7 @@ DeviceManager::DeviceManager(provider::ConfigStore* config_store,
provider::Wifi* wifi,
provider::Bluetooth* bluetooth)
: config_{new Config{config_store}},
- component_manager_{new ComponentManagerImpl} {
+ component_manager_{new ComponentManagerImpl{task_runner}} {
if (http_server) {
auth_manager_.reset(new privet::AuthManager(
config_.get(), http_server->GetHttpsCertificateFingerprint()));
diff --git a/src/device_registration_info_unittest.cc b/src/device_registration_info_unittest.cc
index cd11ac9..7908c8b 100644
--- a/src/device_registration_info_unittest.cc
+++ b/src/device_registration_info_unittest.cc
@@ -208,7 +208,7 @@ class DeviceRegistrationInfoTest : public ::testing::Test {
{},
&clock_};
std::unique_ptr<DeviceRegistrationInfo> dev_reg_;
- ComponentManagerImpl component_manager_;
+ ComponentManagerImpl component_manager_{&task_runner_};
};
TEST_F(DeviceRegistrationInfoTest, GetServiceURL) {
diff --git a/src/privet/wifi_bootstrap_manager.cc b/src/privet/wifi_bootstrap_manager.cc
index 566da80..ce2016a 100644
--- a/src/privet/wifi_bootstrap_manager.cc
+++ b/src/privet/wifi_bootstrap_manager.cc
@@ -204,8 +204,12 @@ std::string WifiBootstrapManager::GetHostedSsid() const {
}
std::set<WifiType> WifiBootstrapManager::GetTypes() const {
- // TODO(wiley) This should do some system work to figure this out.
- return {WifiType::kWifi24};
+ std::set<WifiType> result;
+ if (wifi_->IsWifi24Supported())
+ result.insert(WifiType::kWifi24);
+ if (wifi_->IsWifi50Supported())
+ result.insert(WifiType::kWifi50);
+ return result;
}
void WifiBootstrapManager::OnConnectDone(const std::string& ssid,
@@ -255,9 +259,15 @@ void WifiBootstrapManager::OnMonitorTimeout() {
void WifiBootstrapManager::UpdateConnectionState() {
connection_state_ = ConnectionState{ConnectionState::kUnconfigured};
-
Network::State service_state{network_->GetConnectionState()};
VLOG(3) << "New network state: " << EnumToString(service_state);
+
+ // TODO: Make it true wifi state, currently it's rather online state.
+ if (service_state != Network::State::kOnline &&
+ config_->GetSettings().last_configured_ssid.empty()) {
+ return;
+ }
+
switch (service_state) {
case Network::State::kOffline:
connection_state_ = ConnectionState{ConnectionState::kOffline};
diff --git a/src/privet/wifi_ssid_generator.cc b/src/privet/wifi_ssid_generator.cc
index 697e5d8..4ad1602 100644
--- a/src/privet/wifi_ssid_generator.cc
+++ b/src/privet/wifi_ssid_generator.cc
@@ -52,20 +52,27 @@ WifiSsidGenerator::WifiSsidGenerator(const CloudDelegate* cloud,
}
std::string WifiSsidGenerator::GenerateFlags() const {
- return GenerateFlagsInternal(false);
+ return GenerateFlagsInternal();
}
-std::string WifiSsidGenerator::GenerateFlagsInternal(bool for_ssid) const {
+std::string WifiSsidGenerator::GenerateFlagsInternal() const {
std::bitset<6> flags1;
// Device needs WiFi configuration.
flags1[0] = wifi_ && IsSetupNeeded(wifi_->GetConnectionState());
+
// Device needs GCD registration.
flags1[1] = IsSetupNeeded(gcd_->GetConnectionState());
std::bitset<6> flags2;
- // Device is discoverable over WiFi.
- flags2[0] = for_ssid || (wifi_ && !wifi_->GetHostedSsid().empty());
+ if (wifi_) {
+ std::set<WifiType> types = wifi_->GetTypes();
+ // Device supports 2.4Ghz WiFi networks.
+ flags2[0] = types.find(WifiType::kWifi24) != types.end();
+
+ // Device supports 5.0Ghz WiFi networks.
+ flags2[1] = types.find(WifiType::kWifi50) != types.end();
+ }
std::string result{2, base64chars[0]};
result[0] = base64chars[flags1.to_ulong()];
@@ -82,7 +89,7 @@ std::string WifiSsidGenerator::GenerateSsid() const {
std::string result =
base::StringPrintf(kSsidFormat, name.c_str(), idx.c_str(),
- model_id.c_str(), GenerateFlagsInternal(true).c_str());
+ model_id.c_str(), GenerateFlagsInternal().c_str());
CHECK_EQ(result[result.size() - 11], '.');
return result;
}
diff --git a/src/privet/wifi_ssid_generator.h b/src/privet/wifi_ssid_generator.h
index 2b86f28..1197e73 100644
--- a/src/privet/wifi_ssid_generator.h
+++ b/src/privet/wifi_ssid_generator.h
@@ -30,7 +30,7 @@ class WifiSsidGenerator final {
// Sets object to use |n| instead of random number for SSID generation.
void SetRandomForTests(int n);
- std::string GenerateFlagsInternal(bool for_ssid) const;
+ std::string GenerateFlagsInternal() const;
const CloudDelegate* gcd_{nullptr};
const WifiDelegate* wifi_{nullptr};
diff --git a/src/privet/wifi_ssid_generator_unittest.cc b/src/privet/wifi_ssid_generator_unittest.cc
index 10680c8..406576d 100644
--- a/src/privet/wifi_ssid_generator_unittest.cc
+++ b/src/privet/wifi_ssid_generator_unittest.cc
@@ -22,40 +22,44 @@ class WifiSsidGeneratorTest : public testing::Test {
WifiSsidGenerator ssid_generator_{&gcd_, &wifi_};
};
-TEST_F(WifiSsidGeneratorTest, GenerateFlagsNoHostedAp) {
+TEST_F(WifiSsidGeneratorTest, GenerateFlagsWithWifi24) {
+ EXPECT_CALL(wifi_, GetTypes())
+ .WillRepeatedly(Return(std::set<WifiType>{WifiType::kWifi24}));
+
EXPECT_EQ(ssid_generator_.GenerateFlags().size(), 2u);
wifi_.connection_state_ = ConnectionState{ConnectionState::kUnconfigured};
gcd_.connection_state_ = ConnectionState{ConnectionState::kUnconfigured};
- EXPECT_EQ("DA", ssid_generator_.GenerateFlags());
+ EXPECT_EQ("DB", ssid_generator_.GenerateFlags());
wifi_.connection_state_ = ConnectionState{ConnectionState::kOnline};
- EXPECT_EQ("CA", ssid_generator_.GenerateFlags());
+ EXPECT_EQ("CB", ssid_generator_.GenerateFlags());
gcd_.connection_state_ = ConnectionState{ConnectionState::kOffline};
- EXPECT_EQ("AA", ssid_generator_.GenerateFlags());
+ EXPECT_EQ("AB", ssid_generator_.GenerateFlags());
wifi_.connection_state_ = ConnectionState{ConnectionState::kUnconfigured};
- EXPECT_EQ("BA", ssid_generator_.GenerateFlags());
+ EXPECT_EQ("BB", ssid_generator_.GenerateFlags());
}
-TEST_F(WifiSsidGeneratorTest, GenerateFlagsWithHostedAp) {
- EXPECT_CALL(wifi_, GetHostedSsid())
- .WillRepeatedly(Return(ssid_generator_.GenerateSsid()));
+TEST_F(WifiSsidGeneratorTest, GenerateFlagsWithWifi50) {
+ EXPECT_CALL(wifi_, GetTypes())
+ .WillRepeatedly(Return(std::set<WifiType>{WifiType::kWifi50}));
+
EXPECT_EQ(ssid_generator_.GenerateFlags().size(), 2u);
wifi_.connection_state_ = ConnectionState{ConnectionState::kUnconfigured};
gcd_.connection_state_ = ConnectionState{ConnectionState::kUnconfigured};
- EXPECT_EQ("DB", ssid_generator_.GenerateFlags());
+ EXPECT_EQ("DC", ssid_generator_.GenerateFlags());
wifi_.connection_state_ = ConnectionState{ConnectionState::kOnline};
- EXPECT_EQ("CB", ssid_generator_.GenerateFlags());
+ EXPECT_EQ("CC", ssid_generator_.GenerateFlags());
gcd_.connection_state_ = ConnectionState{ConnectionState::kOffline};
- EXPECT_EQ("AB", ssid_generator_.GenerateFlags());
+ EXPECT_EQ("AC", ssid_generator_.GenerateFlags());
wifi_.connection_state_ = ConnectionState{ConnectionState::kUnconfigured};
- EXPECT_EQ("BB", ssid_generator_.GenerateFlags());
+ EXPECT_EQ("BC", ssid_generator_.GenerateFlags());
}
TEST_F(WifiSsidGeneratorTest, GenerateSsid31orLess) {
diff --git a/src/test/fake_task_runner.cc b/src/test/fake_task_runner.cc
index 88e078b..68d5e32 100644
--- a/src/test/fake_task_runner.cc
+++ b/src/test/fake_task_runner.cc
@@ -52,6 +52,10 @@ void FakeTaskRunner::PostDelayedTask(const tracked_objects::Location& from_here,
queue_.emplace(std::make_pair(test_clock_->Now() + delay, ++counter_), task);
}
+size_t FakeTaskRunner::GetTaskQueueSize() const {
+ return queue_.size();
+}
+
} // namespace test
} // namespace provider
} // namespace weave
diff --git a/src/weave_unittest.cc b/src/weave_unittest.cc
index ebc66cd..b300f57 100644
--- a/src/weave_unittest.cc
+++ b/src/weave_unittest.cc
@@ -181,7 +181,10 @@ std::set<typename Map::key_type> GetKeys(const Map& map) {
class WeaveTest : public ::testing::Test {
protected:
- void SetUp() override {}
+ void SetUp() override {
+ EXPECT_CALL(wifi_, IsWifi24Supported()).WillRepeatedly(Return(true));
+ EXPECT_CALL(wifi_, IsWifi50Supported()).WillRepeatedly(Return(false));
+ }
template <class UrlMatcher>
void ExpectRequest(HttpClient::Method method,