Commit 2908cdc5 authored by Alexey Baskakov's avatar Alexey Baskakov Committed by Commit Bot

dpwa: Implement GetApps() to skip apps in sync install.

This CL introduces no behavior changes.
Now WebAppRegistrar::GetAppIds() uses foreach GetApps().

In follow up CLs:
- rename AllApps() to GetAppsIncludingStubs() (urgent)
- migrate more cases to use GetApps() instead of AllApps() (not urgent)

Implementation details:

AllApps() and GetApps() use protected method FilterApps(filter).
In general, FilterApps() allows to iterate over various subsets from
AllApps().

Internally, Iter::FilterAndSkipApps() filters out unwanted entries.

Bug: 891172
Change-Id: I9a136f9b4f77e77eac28e13d9281453015145925
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1295131Reviewed-by: default avatarAlan Cutter <alancutter@chromium.org>
Reviewed-by: default avatarDaniel Murphy <dmurph@chromium.org>
Commit-Queue: Alexey Baskakov <loyso@chromium.org>
Cr-Commit-Position: refs/heads/master@{#818710}
parent fbfe44ef
...@@ -181,12 +181,8 @@ WebAppRegistrar::GetAppDownloadedShortcutsMenuIconsSizes( ...@@ -181,12 +181,8 @@ WebAppRegistrar::GetAppDownloadedShortcutsMenuIconsSizes(
std::vector<AppId> WebAppRegistrar::GetAppIds() const { std::vector<AppId> WebAppRegistrar::GetAppIds() const {
std::vector<AppId> app_ids; std::vector<AppId> app_ids;
for (const WebApp& app : AllApps()) { for (const WebApp& app : GetApps())
// Apps in sync install are being installed and should be hidden for app_ids.push_back(app.app_id());
// most subsystems. OnWebAppInstalled() notification will be send out later.
if (!app.is_in_sync_install())
app_ids.push_back(app.app_id());
}
return app_ids; return app_ids;
} }
...@@ -219,8 +215,9 @@ void WebAppRegistrar::OnProfileMarkedForPermanentDeletion( ...@@ -219,8 +215,9 @@ void WebAppRegistrar::OnProfileMarkedForPermanentDeletion(
registry_profile_being_deleted_ = true; registry_profile_being_deleted_ = true;
} }
WebAppRegistrar::AppSet::AppSet(const WebAppRegistrar* registrar) WebAppRegistrar::AppSet::AppSet(const WebAppRegistrar* registrar, Filter filter)
: registrar_(registrar) : registrar_(registrar),
filter_(filter)
#if DCHECK_IS_ON() #if DCHECK_IS_ON()
, ,
mutations_count_(registrar->mutations_count_) mutations_count_(registrar->mutations_count_)
...@@ -235,29 +232,43 @@ WebAppRegistrar::AppSet::~AppSet() { ...@@ -235,29 +232,43 @@ WebAppRegistrar::AppSet::~AppSet() {
} }
WebAppRegistrar::AppSet::iterator WebAppRegistrar::AppSet::begin() { WebAppRegistrar::AppSet::iterator WebAppRegistrar::AppSet::begin() {
return iterator(registrar_->registry_.begin()); return iterator(registrar_->registry_.begin(), registrar_->registry_.end(),
filter_);
} }
WebAppRegistrar::AppSet::iterator WebAppRegistrar::AppSet::end() { WebAppRegistrar::AppSet::iterator WebAppRegistrar::AppSet::end() {
return iterator(registrar_->registry_.end()); return iterator(registrar_->registry_.end(), registrar_->registry_.end(),
filter_);
} }
WebAppRegistrar::AppSet::const_iterator WebAppRegistrar::AppSet::begin() const { WebAppRegistrar::AppSet::const_iterator WebAppRegistrar::AppSet::begin() const {
return const_iterator(registrar_->registry_.begin()); return const_iterator(registrar_->registry_.begin(),
registrar_->registry_.end(), filter_);
} }
WebAppRegistrar::AppSet::const_iterator WebAppRegistrar::AppSet::end() const { WebAppRegistrar::AppSet::const_iterator WebAppRegistrar::AppSet::end() const {
return const_iterator(registrar_->registry_.end()); return const_iterator(registrar_->registry_.end(),
registrar_->registry_.end(), filter_);
} }
const WebAppRegistrar::AppSet WebAppRegistrar::AllApps() const { const WebAppRegistrar::AppSet WebAppRegistrar::AllApps() const {
return AppSet(this); return AppSet(this, nullptr);
}
const WebAppRegistrar::AppSet WebAppRegistrar::GetApps() const {
return AppSet(this, [](const WebApp& web_app) {
return !web_app.is_in_sync_install();
});
} }
void WebAppRegistrar::SetRegistry(Registry&& registry) { void WebAppRegistrar::SetRegistry(Registry&& registry) {
registry_ = std::move(registry); registry_ = std::move(registry);
} }
const WebAppRegistrar::AppSet WebAppRegistrar::FilterApps(Filter filter) const {
return AppSet(this, filter);
}
void WebAppRegistrar::CountMutation() { void WebAppRegistrar::CountMutation() {
#if DCHECK_IS_ON() #if DCHECK_IS_ON()
++mutations_count_; ++mutations_count_;
...@@ -278,8 +289,19 @@ WebApp* WebAppRegistrarMutable::GetAppByIdMutable(const AppId& app_id) { ...@@ -278,8 +289,19 @@ WebApp* WebAppRegistrarMutable::GetAppByIdMutable(const AppId& app_id) {
return const_cast<WebApp*>(GetAppById(app_id)); return const_cast<WebApp*>(GetAppById(app_id));
} }
WebAppRegistrar::AppSet WebAppRegistrarMutable::FilterAppsMutable(
Filter filter) {
return AppSet(this, filter);
}
WebAppRegistrar::AppSet WebAppRegistrarMutable::AllAppsMutable() { WebAppRegistrar::AppSet WebAppRegistrarMutable::AllAppsMutable() {
return AppSet(this); return AppSet(this, nullptr);
}
WebAppRegistrar::AppSet WebAppRegistrarMutable::GetAppsMutable() {
return AppSet(this, [](const WebApp& web_app) {
return !web_app.is_in_sync_install();
});
} }
bool IsRegistryEqual(const Registry& registry, const Registry& registry2) { bool IsRegistryEqual(const Registry& registry, const Registry& registry2) {
......
...@@ -77,6 +77,9 @@ class WebAppRegistrar : public AppRegistrar, public ProfileManagerObserver { ...@@ -77,6 +77,9 @@ class WebAppRegistrar : public AppRegistrar, public ProfileManagerObserver {
void OnProfileMarkedForPermanentDeletion( void OnProfileMarkedForPermanentDeletion(
Profile* profile_to_be_deleted) override; Profile* profile_to_be_deleted) override;
// A filter must return false to skip the |web_app|.
using Filter = bool (*)(const WebApp& web_app);
// Only range-based |for| loop supported. Don't use AppSet directly. // Only range-based |for| loop supported. Don't use AppSet directly.
// Doesn't support registration and unregistration of WebApp while iterating. // Doesn't support registration and unregistration of WebApp while iterating.
class AppSet { class AppSet {
...@@ -87,24 +90,43 @@ class WebAppRegistrar : public AppRegistrar, public ProfileManagerObserver { ...@@ -87,24 +90,43 @@ class WebAppRegistrar : public AppRegistrar, public ProfileManagerObserver {
public: public:
using InternalIter = Registry::const_iterator; using InternalIter = Registry::const_iterator;
explicit Iter(InternalIter&& internal_iter) Iter(InternalIter&& internal_iter,
: internal_iter_(std::move(internal_iter)) {} InternalIter&& internal_end,
Filter filter)
: internal_iter_(std::move(internal_iter)),
internal_end_(std::move(internal_end)),
filter_(filter) {
FilterAndSkipApps();
}
Iter(Iter&&) = default; Iter(Iter&&) = default;
Iter(const Iter&) = delete; Iter(const Iter&) = delete;
Iter& operator=(const Iter&) = delete; Iter& operator=(const Iter&) = delete;
~Iter() = default; ~Iter() = default;
void operator++() { ++internal_iter_; } void operator++() {
++internal_iter_;
FilterAndSkipApps();
}
WebAppType& operator*() const { return *internal_iter_->second.get(); } WebAppType& operator*() const { return *internal_iter_->second.get(); }
bool operator!=(const Iter& iter) const { bool operator!=(const Iter& iter) const {
return internal_iter_ != iter.internal_iter_; return internal_iter_ != iter.internal_iter_;
} }
private: private:
void FilterAndSkipApps() {
if (!filter_)
return;
while (internal_iter_ != internal_end_ && !filter_(**this))
++internal_iter_;
}
InternalIter internal_iter_; InternalIter internal_iter_;
InternalIter internal_end_;
Filter filter_;
}; };
explicit AppSet(const WebAppRegistrar* registrar); AppSet(const WebAppRegistrar* registrar, Filter filter);
AppSet(AppSet&&) = default; AppSet(AppSet&&) = default;
AppSet(const AppSet&) = delete; AppSet(const AppSet&) = delete;
AppSet& operator=(const AppSet&) = delete; AppSet& operator=(const AppSet&) = delete;
...@@ -120,17 +142,26 @@ class WebAppRegistrar : public AppRegistrar, public ProfileManagerObserver { ...@@ -120,17 +142,26 @@ class WebAppRegistrar : public AppRegistrar, public ProfileManagerObserver {
private: private:
const WebAppRegistrar* const registrar_; const WebAppRegistrar* const registrar_;
const Filter filter_;
#if DCHECK_IS_ON() #if DCHECK_IS_ON()
const size_t mutations_count_; const size_t mutations_count_;
#endif #endif
}; };
// Returns all apps in the registry (a superset) including stubs.
// TODO(loyso): Rename this method to GetAppsIncludingStubs().
const AppSet AllApps() const; const AppSet AllApps() const;
// Returns all apps excluding stubs for apps in sync install. Apps in sync
// install are being installed and should be hidden for most subsystems. This
// is a subset of AllApps().
const AppSet GetApps() const;
protected: protected:
Registry& registry() { return registry_; } Registry& registry() { return registry_; }
void SetRegistry(Registry&& registry); void SetRegistry(Registry&& registry);
const AppSet FilterApps(Filter filter) const;
void CountMutation(); void CountMutation();
private: private:
...@@ -151,7 +182,12 @@ class WebAppRegistrarMutable : public WebAppRegistrar { ...@@ -151,7 +182,12 @@ class WebAppRegistrarMutable : public WebAppRegistrar {
void InitRegistry(Registry&& registry); void InitRegistry(Registry&& registry);
WebApp* GetAppByIdMutable(const AppId& app_id); WebApp* GetAppByIdMutable(const AppId& app_id);
AppSet FilterAppsMutable(Filter filter);
// TODO(loyso): Rename this method to GetAppsIncludingStubsMutable().
AppSet AllAppsMutable(); AppSet AllAppsMutable();
AppSet GetAppsMutable();
using WebAppRegistrar::CountMutation; using WebAppRegistrar::CountMutation;
using WebAppRegistrar::registry; using WebAppRegistrar::registry;
......
...@@ -10,6 +10,8 @@ ...@@ -10,6 +10,8 @@
#include <utility> #include <utility>
#include "base/bind_helpers.h" #include "base/bind_helpers.h"
#include "base/logging.h"
#include "base/notreached.h"
#include "base/optional.h" #include "base/optional.h"
#include "base/run_loop.h" #include "base/run_loop.h"
#include "base/stl_util.h" #include "base/stl_util.h"
...@@ -73,6 +75,9 @@ class WebAppRegistrarTest : public WebAppTest { ...@@ -73,6 +75,9 @@ class WebAppRegistrarTest : public WebAppTest {
return controller().database_factory(); return controller().database_factory();
} }
WebAppRegistrar& registrar() { return controller().registrar(); } WebAppRegistrar& registrar() { return controller().registrar(); }
WebAppRegistrarMutable& mutable_registrar() {
return controller().mutable_registrar();
}
WebAppSyncBridge& sync_bridge() { return controller().sync_bridge(); } WebAppSyncBridge& sync_bridge() { return controller().sync_bridge(); }
std::set<AppId> RegisterAppsForTesting(Registry registry) { std::set<AppId> RegisterAppsForTesting(Registry registry) {
...@@ -273,7 +278,7 @@ TEST_F(WebAppRegistrarTest, InitRegistrarAndDoForEachApp) { ...@@ -273,7 +278,7 @@ TEST_F(WebAppRegistrarTest, InitRegistrarAndDoForEachApp) {
TEST_F(WebAppRegistrarTest, AllAppsMutable) { TEST_F(WebAppRegistrarTest, AllAppsMutable) {
std::set<AppId> ids = InitRegistrarWithApps("https://example.com/path", 10); std::set<AppId> ids = InitRegistrarWithApps("https://example.com/path", 10);
for (WebApp& web_app : controller().mutable_registrar().AllAppsMutable()) { for (WebApp& web_app : mutable_registrar().AllAppsMutable()) {
web_app.SetDisplayMode(DisplayMode::kStandalone); web_app.SetDisplayMode(DisplayMode::kStandalone);
const size_t num_removed = ids.erase(web_app.app_id()); const size_t num_removed = ids.erase(web_app.app_id());
EXPECT_EQ(1U, num_removed); EXPECT_EQ(1U, num_removed);
...@@ -300,6 +305,73 @@ TEST_F(WebAppRegistrarTest, DoForEachAndUnregisterAllApps) { ...@@ -300,6 +305,73 @@ TEST_F(WebAppRegistrarTest, DoForEachAndUnregisterAllApps) {
EXPECT_TRUE(registrar().is_empty()); EXPECT_TRUE(registrar().is_empty());
} }
TEST_F(WebAppRegistrarTest, FilterApps) {
controller().Init();
Registry registry = CreateRegistryForTesting("https://example.com/path", 100);
auto ids = RegisterAppsForTesting(std::move(registry));
for (const WebApp& web_app : mutable_registrar().FilterAppsMutable(
[](const WebApp& web_app) { return false; })) {
NOTREACHED();
ALLOW_UNUSED_LOCAL(web_app);
}
for (const WebApp& web_app : mutable_registrar().FilterAppsMutable(
[](const WebApp& web_app) { return true; })) {
const size_t num_removed = ids.erase(web_app.app_id());
EXPECT_EQ(1U, num_removed);
}
EXPECT_TRUE(ids.empty());
}
TEST_F(WebAppRegistrarTest, GetApps) {
std::set<AppId> ids = InitRegistrarWithApps("https://example.com/path", 10);
int not_in_sync_install_count = 0;
for (const WebApp& web_app : registrar().GetApps()) {
++not_in_sync_install_count;
EXPECT_TRUE(base::Contains(ids, web_app.app_id()));
}
EXPECT_EQ(10, not_in_sync_install_count);
auto web_app_in_sync1 = CreateWebApp("https://example.org/sync1");
web_app_in_sync1->SetIsInSyncInstall(true);
const AppId web_app_id_in_sync1 = web_app_in_sync1->app_id();
RegisterApp(std::move(web_app_in_sync1));
auto web_app_in_sync2 = CreateWebApp("https://example.org/sync2");
web_app_in_sync2->SetIsInSyncInstall(true);
const AppId web_app_id_in_sync2 = web_app_in_sync2->app_id();
RegisterApp(std::move(web_app_in_sync2));
int all_apps_count = 0;
for (const WebApp& web_app : registrar().AllApps()) {
ALLOW_UNUSED_LOCAL(web_app);
++all_apps_count;
}
EXPECT_EQ(12, all_apps_count);
for (const WebApp& web_app : registrar().GetApps()) {
EXPECT_NE(web_app_id_in_sync1, web_app.app_id());
EXPECT_NE(web_app_id_in_sync2, web_app.app_id());
const size_t num_removed = ids.erase(web_app.app_id());
EXPECT_EQ(1U, num_removed);
}
EXPECT_TRUE(ids.empty());
UnregisterApp(web_app_id_in_sync1);
UnregisterApp(web_app_id_in_sync2);
not_in_sync_install_count = 0;
for (const WebApp& web_app : registrar().GetApps()) {
ALLOW_UNUSED_LOCAL(web_app);
++not_in_sync_install_count;
}
EXPECT_EQ(10, not_in_sync_install_count);
}
TEST_F(WebAppRegistrarTest, WebAppSyncBridge) { TEST_F(WebAppRegistrarTest, WebAppSyncBridge) {
std::set<AppId> ids = InitRegistrarWithApps("https://example.com/path", 100); std::set<AppId> ids = InitRegistrarWithApps("https://example.com/path", 100);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment