Merge lp:~unity-api-team/unity-scope-click/blacklist-apps into lp:unity-scope-click

Proposed by Antti Kaijanmäki
Status: Rejected
Rejected by: dobey
Proposed branch: lp:~unity-api-team/unity-scope-click/blacklist-apps
Merge into: lp:unity-scope-click
Diff against target: 377 lines (+143/-32)
10 files modified
data/com.canonical.unity.clickscope.gschema.xml (+6/-1)
libclickscope/click/application.h (+22/-0)
libclickscope/click/configuration.cpp (+15/-1)
libclickscope/click/configuration.h (+2/-0)
libclickscope/click/interface.cpp (+8/-2)
libclickscope/click/interface.h (+2/-1)
libclickscope/tests/test_configuration.cpp (+54/-0)
libclickscope/tests/test_interface.cpp (+32/-2)
scope/clickapps/apps-query.cpp (+2/-24)
scope/clickapps/apps-query.h (+0/-1)
To merge this branch: bzr merge lp:~unity-api-team/unity-scope-click/blacklist-apps
Reviewer Review Type Date Requested Status
dobey (community) Needs Fixing
PS Jenkins bot continuous-integration Needs Fixing
Review via email: mp+286518@code.launchpad.net

Commit message

* Add "apps-blacklist" key to com.canonical.unity.clickscope.gschema.xml
  - also change the description of "core-apps" keys
* Move click::apps::ResultPusher::get_app_identifier() to
  click::Application::get_app_name()
* Add application blacklisting support to click::Configuration
  - add get_apps_blacklist()
  - filter get_core_apps() through the blacklist
* Add blacklisting support for the click::Interface::get_installed_apps()

Description of the change

.

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
dobey (dobey) wrote :

First thing I see is that the bug is not linked with commit --fixes on the commit.
Beyond that, the more I've looked at this MP, the less I like it. The code itself isn't terribly incorrect or anything, but the term "blacklist" just disturbs me, and the implementation here has some inconsistency with the existing implementation of the core-apps gsettings key. I'm also not fond of moving the one function into the struct in application.h. I also noticed that you modified the find_installed_apps() API call, but did not actually adjust the call to it within apps-query.cpp's run() method. You seem to have only implemented a call to it within Configuration::get_core_apps() by removing items from that list only. This would not completely resolve the bug, as it would only remove the items from the top set in the scope. The way the tests work here also seems a bit complicated.

I've made an MP at https://code.launchpad.net/~dobey/unity-scope-click/ignored-setting/+merge/286597 which I think is more consistent and complete. Please feel free to review it and comment, and we can discuss further tomorrow.

review: Needs Fixing

Unmerged revisions

419. By Antti Kaijanmäki

blacklist applications

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'data/com.canonical.unity.clickscope.gschema.xml'
--- data/com.canonical.unity.clickscope.gschema.xml 2014-07-04 13:10:05 +0000
+++ data/com.canonical.unity.clickscope.gschema.xml 2016-02-18 14:56:35 +0000
@@ -4,7 +4,12 @@
4 <key type="as" name="core-apps">4 <key type="as" name="core-apps">
5 <default>[]</default>5 <default>[]</default>
6 <summary>Applications to display in the top category of the Apps scope</summary>6 <summary>Applications to display in the top category of the Apps scope</summary>
7 <description>List of application IDs that will be displayed in the upper area of the Applications scope for quick access.</description>7 <description>List of application names that will be displayed in the upper area of the Applications scope for quick access.</description>
8 </key>
9 <key type="as" name="apps-blacklist">
10 <default>[]</default>
11 <summary>Applications to be blacklisted from the Apps scope</summary>
12 <description>List of application names that will not be displayed in the Apps scope. Blacklisting is applied to search results as well as core-apps.</description>
8 </key>13 </key>
9 </schema>14 </schema>
10</schemalist>15</schemalist>
1116
=== modified file 'libclickscope/click/application.h'
--- libclickscope/click/application.h 2014-08-08 08:20:38 +0000
+++ libclickscope/click/application.h 2016-02-18 14:56:35 +0000
@@ -62,6 +62,28 @@
62 std::string default_department;62 std::string default_department;
63 std::string real_department;63 std::string real_department;
64 time_t installed_time;64 time_t installed_time;
65
66 //
67 // Return an application name used to match applications against core-apps dconf key;
68 // For click apps, it just returns application name (e.g. com.canonical.calculator).
69 // For non-click apps, it return the desktop file name (without extension), taken from app uri.
70 std::string get_app_name() const
71 {
72 static const std::string app_prefix("application:///");
73 if (!name.empty())
74 {
75 return name;
76 }
77 if (url.size() > app_prefix.size())
78 {
79 auto i = url.rfind('.');
80 if (i != std::string::npos)
81 {
82 return url.substr(app_prefix.size(), i - app_prefix.size());
83 }
84 }
85 throw std::runtime_error("Cannot determine application identifier for" + url);
86 }
65};87};
6688
67std::ostream& operator<<(std::ostream& out, const Application& app);89std::ostream& operator<<(std::ostream& out, const Application& app);
6890
=== modified file 'libclickscope/click/configuration.cpp'
--- libclickscope/click/configuration.cpp 2015-11-24 19:14:11 +0000
+++ libclickscope/click/configuration.cpp 2016-02-18 14:56:35 +0000
@@ -27,6 +27,7 @@
27 * files in the program, then also delete it here.27 * files in the program, then also delete it here.
28 */28 */
2929
30#include <algorithm>
30#include <string>31#include <string>
31#include <vector>32#include <vector>
3233
@@ -232,7 +233,20 @@
232 if (apps.empty()) {233 if (apps.empty()) {
233 apps = get_default_core_apps();234 apps = get_default_core_apps();
234 }235 }
235 return apps;236
237 auto blacklist = get_apps_blacklist();
238 auto end = std::remove_if(apps.begin(),
239 apps.end(),
240 [blacklist](std::string i) {
241 return std::count(blacklist.begin(), blacklist.end(), i) != 0;
242 });
243 return std::vector<std::string>(apps.begin(), end);
244}
245
246 const std::vector<std::string> Configuration::get_apps_blacklist() const
247{
248 auto blacklist = get_dconf_strings(Configuration::COREAPPS_SCHEMA, Configuration::BLACKLIST_KEY);
249 return blacklist;
236}250}
237251
238} // namespace click252} // namespace click
239253
=== modified file 'libclickscope/click/configuration.h'
--- libclickscope/click/configuration.h 2015-11-24 19:14:11 +0000
+++ libclickscope/click/configuration.h 2016-02-18 14:56:35 +0000
@@ -66,8 +66,10 @@
6666
67 constexpr static const char* COREAPPS_SCHEMA {"com.canonical.Unity.ClickScope"};67 constexpr static const char* COREAPPS_SCHEMA {"com.canonical.Unity.ClickScope"};
68 constexpr static const char* COREAPPS_KEY {"coreApps"};68 constexpr static const char* COREAPPS_KEY {"coreApps"};
69 constexpr static const char* BLACKLIST_KEY {"appsBlacklist"};
6970
70 virtual const std::vector<std::string> get_core_apps() const;71 virtual const std::vector<std::string> get_core_apps() const;
72 virtual const std::vector<std::string> get_apps_blacklist() const;
71 virtual ~Configuration() {}73 virtual ~Configuration() {}
72protected:74protected:
73 virtual std::vector<std::string> list_folder(const std::string &folder, const std::string &pattern);75 virtual std::vector<std::string> list_folder(const std::string &folder, const std::string &pattern);
7476
=== modified file 'libclickscope/click/interface.cpp'
--- libclickscope/click/interface.cpp 2016-01-04 20:56:17 +0000
+++ libclickscope/click/interface.cpp 2016-02-18 14:56:35 +0000
@@ -33,6 +33,7 @@
33#include <QStandardPaths>33#include <QStandardPaths>
34#include <QTimer>34#include <QTimer>
3535
36#include <algorithm>
36#include <cstdio>37#include <cstdio>
37#include <list>38#include <list>
38#include <sys/stat.h>39#include <sys/stat.h>
@@ -240,7 +241,8 @@
240 */241 */
241std::vector<click::Application> Interface::find_installed_apps(const std::string& search_query,242std::vector<click::Application> Interface::find_installed_apps(const std::string& search_query,
242 const std::string& current_department,243 const std::string& current_department,
243 const std::shared_ptr<click::DepartmentsDb>& depts_db)244 const std::shared_ptr<click::DepartmentsDb>& depts_db,
245 const std::vector<std::string>& blacklist)
244{246{
245 //247 //
246 // only apply department filtering if not in root of all departments.248 // only apply department filtering if not in root of all departments.
@@ -265,7 +267,7 @@
265267
266 bool include_desktop_results = show_desktop_apps();268 bool include_desktop_results = show_desktop_apps();
267269
268 auto enumerator = [&result, this, search_query, current_department, packages_in_department, apply_department_filter, include_desktop_results, depts_db]270 auto enumerator = [&result, this, search_query, current_department, packages_in_department, apply_department_filter, include_desktop_results, depts_db, blacklist]
269 (const unity::util::IniParser& keyFile, const std::string& filename)271 (const unity::util::IniParser& keyFile, const std::string& filename)
270 {272 {
271 if (keyFile.has_group(DESKTOP_FILE_GROUP) == false) {273 if (keyFile.has_group(DESKTOP_FILE_GROUP) == false) {
@@ -340,6 +342,10 @@
340 }342 }
341 }343 }
342344
345 if (std::count(blacklist.begin(), blacklist.end(), app.get_app_name()) != 0) {
346 return;
347 }
348
343 if (search_query.empty()) {349 if (search_query.empty()) {
344 result.push_back(app);350 result.push_back(app);
345 } else {351 } else {
346352
=== modified file 'libclickscope/click/interface.h'
--- libclickscope/click/interface.h 2014-07-18 11:18:27 +0000
+++ libclickscope/click/interface.h 2016-02-18 14:56:35 +0000
@@ -94,7 +94,8 @@
94 static std::vector<Application> sort_apps(const std::vector<Application>& apps);94 static std::vector<Application> sort_apps(const std::vector<Application>& apps);
95 virtual std::vector<Application> find_installed_apps(const std::string& search_query,95 virtual std::vector<Application> find_installed_apps(const std::string& search_query,
96 const std::string& current_department = "",96 const std::string& current_department = "",
97 const std::shared_ptr<click::DepartmentsDb>& depts_db = nullptr);97 const std::shared_ptr<click::DepartmentsDb>& depts_db = nullptr,
98 const std::vector<std::string>& blacklist = {});
9899
99 static bool is_non_click_app(const QString& filename);100 static bool is_non_click_app(const QString& filename);
100101
101102
=== modified file 'libclickscope/tests/test_configuration.cpp'
--- libclickscope/tests/test_configuration.cpp 2015-11-24 19:14:11 +0000
+++ libclickscope/tests/test_configuration.cpp 2016-02-18 14:56:35 +0000
@@ -27,6 +27,7 @@
27 * files in the program, then also delete it here.27 * files in the program, then also delete it here.
28 */28 */
2929
30#include <algorithm>
30#include <QStringList>31#include <QStringList>
3132
32#include <gmock/gmock.h>33#include <gmock/gmock.h>
@@ -47,6 +48,7 @@
47 const std::string& folder, const std::string& pattern));48 const std::string& folder, const std::string& pattern));
48 MOCK_CONST_METHOD2(get_dconf_strings, const std::vector<std::string>(const std::string& schema, const std::string& key));49 MOCK_CONST_METHOD2(get_dconf_strings, const std::vector<std::string>(const std::string& schema, const std::string& key));
49 using Configuration::get_default_core_apps;50 using Configuration::get_default_core_apps;
51 using Configuration::get_apps_blacklist;
50};52};
5153
52}54}
@@ -56,6 +58,9 @@
56 using namespace ::testing;58 using namespace ::testing;
57 FakeConfiguration c;59 FakeConfiguration c;
58 EXPECT_CALL(c, get_dconf_strings(Configuration::COREAPPS_SCHEMA,60 EXPECT_CALL(c, get_dconf_strings(Configuration::COREAPPS_SCHEMA,
61 Configuration::BLACKLIST_KEY))
62 .WillOnce(Return(std::vector<std::string>{}));
63 EXPECT_CALL(c, get_dconf_strings(Configuration::COREAPPS_SCHEMA,
59 Configuration::COREAPPS_KEY))64 Configuration::COREAPPS_KEY))
60 .WillOnce(Return(std::vector<std::string>{"package1", "package2"}));65 .WillOnce(Return(std::vector<std::string>{"package1", "package2"}));
61 auto found_apps = c.get_core_apps();66 auto found_apps = c.get_core_apps();
@@ -68,6 +73,9 @@
68 using namespace ::testing;73 using namespace ::testing;
69 FakeConfiguration c;74 FakeConfiguration c;
70 EXPECT_CALL(c, get_dconf_strings(Configuration::COREAPPS_SCHEMA,75 EXPECT_CALL(c, get_dconf_strings(Configuration::COREAPPS_SCHEMA,
76 Configuration::BLACKLIST_KEY))
77 .WillOnce(Return(std::vector<std::string>{}));
78 EXPECT_CALL(c, get_dconf_strings(Configuration::COREAPPS_SCHEMA,
71 Configuration::COREAPPS_KEY))79 Configuration::COREAPPS_KEY))
72 .WillOnce(Return(std::vector<std::string>{}));80 .WillOnce(Return(std::vector<std::string>{}));
73 auto found_apps = c.get_core_apps();81 auto found_apps = c.get_core_apps();
@@ -75,6 +83,52 @@
75 ASSERT_EQ(found_apps, expected_apps);83 ASSERT_EQ(found_apps, expected_apps);
76}84}
7785
86TEST(Configuration, getAppsBlacklist)
87{
88 using namespace ::testing;
89 FakeConfiguration c;
90 EXPECT_CALL(c, get_dconf_strings(Configuration::COREAPPS_SCHEMA,
91 Configuration::BLACKLIST_KEY))
92 .WillOnce(Return(std::vector<std::string>{"package1", "package2"}));
93 auto blacklist = c.get_apps_blacklist();
94 auto expected = std::vector<std::string>{"package1", "package2"};
95 ASSERT_EQ(blacklist, expected);
96}
97
98TEST(Configuration, getCoreAppsFoundBlacklisted)
99{
100 using namespace ::testing;
101 FakeConfiguration c;
102 EXPECT_CALL(c, get_dconf_strings(Configuration::COREAPPS_SCHEMA,
103 Configuration::BLACKLIST_KEY))
104 .WillOnce(Return(std::vector<std::string>{"package1"}));
105 EXPECT_CALL(c, get_dconf_strings(Configuration::COREAPPS_SCHEMA,
106 Configuration::COREAPPS_KEY))
107 .WillOnce(Return(std::vector<std::string>{"package1", "package2"}));
108 auto found_apps = c.get_core_apps();
109 auto expected_apps = std::vector<std::string>{"package2"};
110 ASSERT_EQ(found_apps, expected_apps);
111}
112
113TEST(Configuration, getCoreAppsEmptyBlacklisted)
114{
115 using namespace ::testing;
116 FakeConfiguration c;
117 EXPECT_CALL(c, get_dconf_strings(Configuration::COREAPPS_SCHEMA,
118 Configuration::BLACKLIST_KEY))
119 .WillOnce(Return(std::vector<std::string>{"dialer-app", "messaging-app"}));
120 EXPECT_CALL(c, get_dconf_strings(Configuration::COREAPPS_SCHEMA,
121 Configuration::COREAPPS_KEY))
122 .WillOnce(Return(std::vector<std::string>{}));
123 auto found_apps = c.get_core_apps();
124
125 auto tmp = c.get_default_core_apps();
126 auto end = std::remove_if(tmp.begin(), tmp.end(), [&c](std::string i){ return i == "dialer-app" || i == "messaging-app"; });
127 std::vector<std::string> expected_apps(tmp.begin(), end);
128
129 ASSERT_EQ(found_apps, expected_apps);
130}
131
78TEST(Configuration, getAvailableFrameworksUsesRightFolder)132TEST(Configuration, getAvailableFrameworksUsesRightFolder)
79{133{
80 using namespace ::testing;134 using namespace ::testing;
81135
=== modified file 'libclickscope/tests/test_interface.cpp'
--- libclickscope/tests/test_interface.cpp 2016-01-04 20:56:17 +0000
+++ libclickscope/tests/test_interface.cpp 2016-02-18 14:56:35 +0000
@@ -35,6 +35,7 @@
35#include <QDir>35#include <QDir>
36#include <QTimer>36#include <QTimer>
3737
38#include <algorithm>
38#include <cstdlib>39#include <cstdlib>
3940
40#include <gmock/gmock.h>41#include <gmock/gmock.h>
@@ -379,7 +380,7 @@
379 Interface::add_theme_scheme("/usr/share/unity8/graphics/applicationIcons/contacts-app@18.png"));380 Interface::add_theme_scheme("/usr/share/unity8/graphics/applicationIcons/contacts-app@18.png"));
380}381}
381382
382std::vector<click::Application> find_installed_apps(const std::string& query, bool include_desktop_results)383std::vector<click::Application> find_installed_apps(const std::string& query, bool include_desktop_results, const std::vector<std::string>& blacklist={})
383{384{
384 using namespace ::testing;385 using namespace ::testing;
385 QSharedPointer<click::KeyFileLocator> keyFileLocator(386 QSharedPointer<click::KeyFileLocator> keyFileLocator(
@@ -392,7 +393,7 @@
392 .Times(1)393 .Times(1)
393 .WillOnce(Return(include_desktop_results));394 .WillOnce(Return(include_desktop_results));
394395
395 return iface.find_installed_apps(query);396 return iface.find_installed_apps(query, "", nullptr, blacklist);
396}397}
397398
398TEST(ClickInterface, testFindInstalledAppsOnPhone)399TEST(ClickInterface, testFindInstalledAppsOnPhone)
@@ -410,6 +411,35 @@
410 EXPECT_EQ(result.end(), std::find(result.begin(), result.end(), desktop_application));411 EXPECT_EQ(result.end(), std::find(result.begin(), result.end(), desktop_application));
411}412}
412413
414TEST(ClickInterface, testFindInstalledAppsOnPhoneBlacklist)
415{
416 auto result = find_installed_apps(emptyQuery, false, {"com.ubuntu.terminal", "messaging-app"});
417
418 EXPECT_TRUE(result.size() > 0);
419
420 std::vector<Application> tmp;
421 std::copy_if(non_desktop_applications.begin(),
422 non_desktop_applications.end(),
423 std::back_inserter(tmp),
424 [](const Application &app) {
425 if (app.get_app_name() == "com.ubuntu.terminal") {
426 return false;
427 }
428 if (app.get_app_name() == "messaging-app") {
429 return false;
430 }
431 return true;
432 });
433
434 for (const auto& app : tmp)
435 {
436 qDebug() << "comparing" << QString::fromStdString(app.title);
437 EXPECT_NE(result.end(), std::find(result.begin(), result.end(), app));
438 }
439
440 EXPECT_EQ(result.end(), std::find(result.begin(), result.end(), desktop_application));
441}
442
413TEST(ClickInterface, testFindInstalledAppsOnDesktop)443TEST(ClickInterface, testFindInstalledAppsOnDesktop)
414{444{
415 auto result = find_installed_apps(emptyQuery, true);445 auto result = find_installed_apps(emptyQuery, true);
416446
=== modified file 'scope/clickapps/apps-query.cpp'
--- scope/clickapps/apps-query.cpp 2016-01-06 18:08:33 +0000
+++ scope/clickapps/apps-query.cpp 2016-02-18 14:56:35 +0000
@@ -130,28 +130,6 @@
130 replyProxy->push(res);130 replyProxy->push(res);
131}131}
132132
133//
134// Return an application identifier used to match applications against core-apps dconf key;
135// For click apps, it just returns application name (e.g. com.canonical.calculator).
136// For non-click apps, it return the desktop file name (without extension), taken from app uri.
137std::string click::apps::ResultPusher::get_app_identifier(const click::Application& app)
138{
139 static const std::string app_prefix("application:///");
140 if (!app.name.empty())
141 {
142 return app.name;
143 }
144 if (app.url.size() > app_prefix.size())
145 {
146 auto i = app.url.rfind('.');
147 if (i != std::string::npos)
148 {
149 return app.url.substr(app_prefix.size(), i - app_prefix.size());
150 }
151 }
152 throw std::runtime_error("Cannot determine application identifier for" + app.url);
153}
154
155void click::apps::ResultPusher::push_local_results(133void click::apps::ResultPusher::push_local_results(
156 const std::vector<click::Application> &apps,134 const std::vector<click::Application> &apps,
157 const std::string &categoryTemplate,135 const std::string &categoryTemplate,
@@ -164,7 +142,7 @@
164 {142 {
165 try143 try
166 {144 {
167 if (top_apps_lookup.size() == 0 || top_apps_lookup.find(get_app_identifier(a)) == top_apps_lookup.end())145 if (top_apps_lookup.size() == 0 || top_apps_lookup.find(a.get_app_name()) == top_apps_lookup.end())
168 {146 {
169 push_result(cat, a);147 push_result(cat, a);
170 }148 }
@@ -190,7 +168,7 @@
190 {168 {
191 try169 try
192 {170 {
193 const auto id = get_app_identifier(a);171 const auto id = a.get_app_name();
194 if (top_apps_lookup.find(id) != top_apps_lookup.end())172 if (top_apps_lookup.find(id) != top_apps_lookup.end())
195 {173 {
196 top_apps_to_push[id] = a;174 top_apps_to_push[id] = a;
197175
=== modified file 'scope/clickapps/apps-query.h'
--- scope/clickapps/apps-query.h 2014-08-19 18:21:14 +0000
+++ scope/clickapps/apps-query.h 2016-02-18 14:56:35 +0000
@@ -102,7 +102,6 @@
102 const std::string& categoryTemplate);102 const std::string& categoryTemplate);
103protected:103protected:
104 virtual void push_result(scopes::Category::SCPtr& cat, const click::Application& a);104 virtual void push_result(scopes::Category::SCPtr& cat, const click::Application& a);
105 static std::string get_app_identifier(const click::Application& app);
106};105};
107} // namespace apps106} // namespace apps
108} // namespace query107} // namespace query

Subscribers

People subscribed via source and target branches

to all changes: