Merge ~santoshbit2007/oxide:GetShellMode_Implementation into oxide:master

Proposed by Santosh on 2016-09-21
Status: Merged
Merge reported by: Santosh
Merged at revision: not available
Proposed branch: ~santoshbit2007/oxide:GetShellMode_Implementation
Merge into: oxide:master
Diff against target: 404 lines (+176/-9)
13 files modified
build/cmake/ChromiumBuildShim.cmake (+13/-0)
build/config/Qt5/BUILD.gn (+8/-0)
build/config/Qt5/moc.gni (+12/-3)
build/config/Qt5/moc.py (+6/-1)
build/config/build_flags.gni (+2/-0)
build/config/linux/qt/BUILD.gn (+7/-0)
qt/core/BUILD.gn (+14/-0)
qt/core/browser/qt_screen.cc (+90/-0)
qt/core/browser/qt_screen.h (+18/-0)
shared/browser/oxide_content_browser_client.cc (+1/-1)
shared/browser/screen.h (+1/-1)
shared/browser/screen_observer.h (+1/-0)
shared/browser/screen_unittest.cc (+3/-3)
Reviewer Review Type Date Requested Status
Chris Coulson 2016-09-21 Approve on 2016-10-27
Review via email: mp+306388@code.launchpad.net

Description of the change

Implement shell mode change detection based on
scanning of input devices.

To post a comment you must log in.
Santosh (santoshbit2007) wrote :

Just to note, QtSystemInfo is not yet in ubuntu image, but silo to include it in image is in testing phase, so we might get it with ubuntu Image.

For images, QtsystemInfo is not available, user need install package libqt5systeminfo5

May be we should use declare some #define to check availability for package and write code within that check. Any suggestion is welcomed.
 e.g all the code below should put within
#if defined QT5_SYSTEM_INFO
  // code
#endif

Chris Coulson (chrisccoulson) wrote :

Thanks, I've left a few comments inline.

This does also need to be optional at build time - I don't mind if this is a build option or an automatic check (there are some CMake macros that could help here, eg https://cmake.org/cmake/help/v3.0/module/CheckCXXSymbolExists.html)

review: Needs Fixing
Santosh (santoshbit2007) :
Santosh (santoshbit2007) :
Chris Coulson (chrisccoulson) wrote :

Thanks, I've left some comments inline

review: Needs Fixing
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/build/cmake/ChromiumBuildShim.cmake b/build/cmake/ChromiumBuildShim.cmake
2index b6fe9ba..30a2288 100644
3--- a/build/cmake/ChromiumBuildShim.cmake
4+++ b/build/cmake/ChromiumBuildShim.cmake
5@@ -267,6 +267,19 @@ function(run_generate_ninja)
6 list(APPEND MAKE_GN_ARGS_CMD -Dqt_moc_executable=${QT_MOC_EXECUTABLE})
7 endif()
8
9+
10+ find_package(Qt5SystemInfo QUIET)
11+ if(Qt5SystemInfo_FOUND)
12+ set(CMAKE_REQUIRED_FLAGS "-fPIC")
13+ set(CMAKE_REQUIRED_INCLUDES ${Qt5SystemInfo_INCLUDE_DIRS})
14+ CHECK_INCLUDE_FILE_CXX("QInputDevice" HAVE_QINPUTDEVICE)
15+ if (HAVE_QINPUTDEVICE EQUAL 1)
16+ list(APPEND MAKE_GN_ARGS_CMD -Duse_qinputdevice=true)
17+ endif()
18+ else()
19+ list(APPEND MAKE_GN_ARGS_CMD -Duse_qinputdevice=false)
20+ endif()
21+
22 if(BOOTSTRAP_GN)
23 list(APPEND MAKE_GN_ARGS_CMD -Denable_gn_build=true)
24 else()
25diff --git a/build/config/Qt5/BUILD.gn b/build/config/Qt5/BUILD.gn
26index 677df5d..e38c131 100644
27--- a/build/config/Qt5/BUILD.gn
28+++ b/build/config/Qt5/BUILD.gn
29@@ -16,6 +16,8 @@
30 # License along with this library; if not, write to the Free Software
31 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
32
33+import("//oxide/build/config/build_flags.gni")
34+
35 assert(is_linux)
36
37 group("Core") {
38@@ -45,3 +47,9 @@ group("Network") {
39 group("Positioning") {
40 public_configs = [ "//oxide/build/config/linux/qt:Qt5Positioning" ]
41 }
42+
43+group("SystemInfo") {
44+ if (use_qinputdevice) {
45+ public_configs = [ "//oxide/build/config/linux/qt:Qt5SystemInfo" ]
46+ }
47+}
48diff --git a/build/config/Qt5/moc.gni b/build/config/Qt5/moc.gni
49index e981bf5..2bf2fa2 100644
50--- a/build/config/Qt5/moc.gni
51+++ b/build/config/Qt5/moc.gni
52@@ -34,9 +34,15 @@ template("moc_action_foreach") {
53 output = "${root_gen_dir}/{{source_root_relative_dir}}/${invoker.output_prefix}{{source_name_part}}.${invoker.output_extension}"
54 outputs = [ output ]
55
56- args = [
57- "-m", "$qt_moc_executable", "{{source}}", rebase_path("$output", "", ".")
58- ]
59+ args = [ "-m", "$qt_moc_executable" ]
60+ if (defined(invoker.defines)) {
61+ define_flags = ""
62+ foreach(define, invoker.defines) {
63+ define_flags += "-D" + define + " "
64+ }
65+ args += [ "-f", "$define_flags" ]
66+ }
67+ args += [ "{{source}}", rebase_path("$output", "", ".") ]
68 }
69 }
70
71@@ -60,6 +66,9 @@ template("qtmoc") {
72 }
73
74 targets = []
75+ if (defined(invoker.defines)) {
76+ defines = invoker.defines
77+ }
78
79 if (defined(sources_cc)) {
80 name = "${target_name}_cc"
81diff --git a/build/config/Qt5/moc.py b/build/config/Qt5/moc.py
82index af0ed8d..abbb113 100644
83--- a/build/config/Qt5/moc.py
84+++ b/build/config/Qt5/moc.py
85@@ -27,6 +27,7 @@ import sys
86 def main(argv):
87 parser = OptionParser(usage="usage: %prog [options] input output")
88 parser.add_option("-m", dest="moc")
89+ parser.add_option("-f", dest="defs")
90
91 (options, args) = parser.parse_args(argv)
92
93@@ -44,7 +45,11 @@ def main(argv):
94 print("moc is not executable", file=sys.stderr)
95 return 1
96
97- subprocess.check_call([moc, "-o", args[1], args[0]])
98+ cmd_line = [moc, "-o", args[1], args[0]]
99+ if options.defs != None:
100+ cmd_line += options.defs.strip().split();
101+
102+ subprocess.check_call(cmd_line)
103
104 if __name__ == "__main__":
105 sys.exit(main(sys.argv[1:]))
106diff --git a/build/config/build_flags.gni b/build/config/build_flags.gni
107index 0474b7d..487e4b0 100644
108--- a/build/config/build_flags.gni
109+++ b/build/config/build_flags.gni
110@@ -23,6 +23,8 @@ declare_args() {
111
112 enable_mediahub = false
113
114+ use_qinputdevice = false
115+
116 oxide_gettext_domain = false
117
118 oxide_libexec_subdir = ""
119diff --git a/build/config/linux/qt/BUILD.gn b/build/config/linux/qt/BUILD.gn
120index a413d69..c96ce0e 100644
121--- a/build/config/linux/qt/BUILD.gn
122+++ b/build/config/linux/qt/BUILD.gn
123@@ -17,6 +17,7 @@
124 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
125
126 import("//build/config/linux/pkg_config.gni")
127+import("//oxide/build/config/build_flags.gni")
128
129 template("qt_private_includes") {
130 module = invoker.module
131@@ -88,3 +89,9 @@ pkg_config("Qt5Positioning") {
132 visibility = [ "//oxide/build/config/Qt5:Positioning" ]
133 packages = [ "Qt5Positioning" ]
134 }
135+
136+if (use_qinputdevice) {
137+ pkg_config("Qt5SystemInfo") {
138+ packages = [ "Qt5SystemInfo" ]
139+ }
140+}
141diff --git a/qt/core/BUILD.gn b/qt/core/BUILD.gn
142index 06d58d2..08eac79 100644
143--- a/qt/core/BUILD.gn
144+++ b/qt/core/BUILD.gn
145@@ -38,6 +38,10 @@ config("core_api_include_dir") {
146 }
147
148 qtmoc("core_moc_gen") {
149+ if (use_qinputdevice) {
150+ defines = [ "USE_QINPUTDEVICE" ]
151+ }
152+
153 sources = [
154 "api/oxideqcertificateerror.h",
155 "api/oxideqdownloadrequest.h",
156@@ -118,6 +122,11 @@ source_set("core_sources") {
157 "//url"
158 ]
159
160+ if (use_qinputdevice) {
161+ deps += [ "//oxide/build/config/Qt5:SystemInfo" ]
162+ defines += [ "USE_QINPUTDEVICE" ]
163+ }
164+
165 sources = [
166 "$target_gen_dir/api/moc_oxideqcertificateerror.cc",
167 "$target_gen_dir/api/moc_oxideqdownloadrequest.cc",
168@@ -386,6 +395,11 @@ test_executable("core_screen_unittests") {
169 "//ui/display",
170 ]
171
172+ if (use_qinputdevice) {
173+ deps += [ "//oxide/build/config/Qt5:SystemInfo" ]
174+ defines += [ "USE_QINPUTDEVICE" ]
175+ }
176+
177 sources = [
178 "browser/qt_screen_unittest.cc",
179 "test/run_all_unittests.cc",
180diff --git a/qt/core/browser/qt_screen.cc b/qt/core/browser/qt_screen.cc
181index 8273885..fa9f3ba 100644
182--- a/qt/core/browser/qt_screen.cc
183+++ b/qt/core/browser/qt_screen.cc
184@@ -31,6 +31,7 @@
185
186 #include "shared/browser/display_form_factor.h"
187 #include "shared/browser/hybris_utils.h"
188+#include "shared/browser/shell_mode.h"
189
190 #include "oxide_qt_dpi_utils.h"
191 #include "oxide_qt_screen_utils.h"
192@@ -192,6 +193,83 @@ void Screen::OnPrimaryScreenChanged(QScreen* screen) {
193 NotifyPrimaryDisplayChanged();
194 }
195
196+#if defined(USE_QINPUTDEVICE)
197+void Screen::OnInputDeviceAdded(QInputDevice* device) {
198+ DCHECK(input_device_manager_.count() > 0);
199+ VLOG(1) << "Input Device ADDED : " << device->name().toStdString();
200+ ShellMode mode = GetShellMode();
201+ if (mode != current_shell_mode_) {
202+ current_shell_mode_ = mode;
203+ NotifyShellModeChanged();
204+ }
205+}
206+
207+void Screen::OnInputDeviceRemoved(const QString& deviceid) {
208+ VLOG(1) << "Input Device REMOVED : " << deviceid.toStdString();
209+ ShellMode mode = GetShellMode();
210+ if (mode != current_shell_mode_) {
211+ current_shell_mode_ = mode;
212+ NotifyShellModeChanged();
213+ }
214+}
215+
216+void Screen::OnInputDevicesReady() {
217+ VLOG(2) << "Input Devices READY";
218+ current_shell_mode_ = GetShellMode();
219+ NotifyShellModeChanged();
220+}
221+
222+bool Screen::GetShellModeFromInputDevices(ShellMode* mode) {
223+ QMap<QString, QInputDevice*> device_map;
224+ device_map = input_device_manager_.deviceMap();
225+ bool mouse = false, keyboard = false, touchpad = false, touchscreen = false;
226+ for (auto i = device_map.begin(); i != device_map.end(); ++i) {
227+ const QInputDevice::InputTypeFlags type = i.value()->types();
228+ if (type & QInputDevice::InputType::Mouse) {
229+ mouse = true;
230+ }
231+ if (type & QInputDevice::InputType::Keyboard) {
232+ keyboard = true;
233+ }
234+ if (type & QInputDevice::InputType::TouchPad) {
235+ touchpad = true;
236+ }
237+ if (type & QInputDevice::InputType::TouchScreen) {
238+ touchscreen = true;
239+ }
240+ }
241+ if (mouse || keyboard || touchpad) {
242+ *mode = ShellMode::Windowed;
243+ return true;
244+ }
245+ if (touchscreen) {
246+ *mode = ShellMode::NonWindowed;
247+ return true;
248+ }
249+
250+ return false;
251+}
252+#endif
253+
254+ShellMode Screen::GetShellMode() {
255+ ShellMode mode;
256+ // Qt input devices state heuristics to detect mode.
257+ bool ret = false;
258+#if defined(USE_QINPUTDEVICE)
259+ ret = GetShellModeFromInputDevices(&mode);
260+#endif
261+
262+ if (!ret) {
263+ // oxide heuristics to detect mode form factor, hybris.
264+ mode = oxide::Screen::GetShellMode();
265+ }
266+
267+ // other heuristics to determine like connecting
268+ // device to Monitor.
269+ // mode = .....
270+ return mode;
271+}
272+
273 void Screen::OnPlatformScreenPropertyChanged(QPlatformScreen* screen,
274 const QString& property_name) {
275 if (property_name == QStringLiteral("scale") ||
276@@ -261,6 +339,18 @@ Screen::Screen() {
277 SLOT(OnPrimaryScreenChanged(QScreen*)));
278 }
279 #endif
280+#if defined(USE_QINPUTDEVICE)
281+ input_device_manager_.setFilter(QInputDevice::InputType::Mouse |
282+ QInputDevice::InputType::Keyboard |
283+ QInputDevice::InputType::TouchPad |
284+ QInputDevice::InputType::TouchScreen);
285+ connect(&input_device_manager_, SIGNAL(ready()),
286+ SLOT(OnInputDevicesReady()));
287+ connect(&input_device_manager_, SIGNAL(deviceAdded(QInputDevice*)),
288+ SLOT(OnInputDeviceAdded(QInputDevice*)));
289+ connect(&input_device_manager_, SIGNAL(deviceRemoved(const QString&)),
290+ SLOT(OnInputDeviceRemoved(const QString&)));
291+#endif
292
293 QString platform = QGuiApplication::platformName();
294 if ((platform.startsWith("ubuntu") || platform == "mirserver" ||
295diff --git a/qt/core/browser/qt_screen.h b/qt/core/browser/qt_screen.h
296index 2e68d30..a67c798 100644
297--- a/qt/core/browser/qt_screen.h
298+++ b/qt/core/browser/qt_screen.h
299@@ -22,6 +22,9 @@
300
301 #include <QObject>
302 #include <QtGlobal>
303+#if defined(USE_QINPUTDEVICE)
304+#include <QInputDevice>
305+#endif
306
307 #include "base/macros.h"
308
309@@ -57,20 +60,35 @@ class OXIDE_QT_EXPORT Screen : public QObject,
310
311 static void SetEnableQtUbuntuIntegrationForTesting(bool enable);
312
313+ protected :
314+ ShellMode GetShellMode() override;
315+
316 private Q_SLOTS:
317 void OnScreenAdded(QScreen* screen);
318 void OnScreenRemoved(QScreen* screen);
319 void OnPrimaryScreenChanged(QScreen* screen);
320+#if defined(USE_QINPUTDEVICE)
321+ void OnInputDeviceAdded(QInputDevice* device);
322+ void OnInputDeviceRemoved(const QString& deviceId);
323+ void OnInputDevicesReady();
324+#endif
325 void OnPlatformScreenPropertyChanged(QPlatformScreen* screen,
326 const QString& property_name);
327
328 private:
329 QScreen* QScreenFromDisplay(const display::Display& display) const;
330 void UpdateDisplayForScreen(QScreen* screen);
331+#if defined(USE_QINPUTDEVICE)
332+ bool GetShellModeFromInputDevices(ShellMode* mode);
333+#endif
334
335 #if QT_VERSION >= QT_VERSION_CHECK(5, 4, 0)
336 std::map<QScreen*, display::Display> displays_;
337 #endif
338+#if defined(USE_QINPUTDEVICE)
339+ QInputInfoManager input_device_manager_;
340+#endif
341+ oxide::ShellMode current_shell_mode_;
342 };
343
344 } // namespace qt
345diff --git a/shared/browser/oxide_content_browser_client.cc b/shared/browser/oxide_content_browser_client.cc
346index f588268..eeef6ab 100644
347--- a/shared/browser/oxide_content_browser_client.cc
348+++ b/shared/browser/oxide_content_browser_client.cc
349@@ -299,7 +299,7 @@ void ContentBrowserClient::OverrideWebkitPrefs(
350 break;
351 };
352
353- if (Screen::GetShellMode() == ShellMode::NonWindowed) {
354+ if (Screen::GetInstance()->GetShellMode() == ShellMode::NonWindowed) {
355 prefs->shrinks_viewport_contents_to_fit = true;
356 prefs->viewport_enabled = true;
357 prefs->main_frame_resizes_are_orientation_changes = true;
358diff --git a/shared/browser/screen.h b/shared/browser/screen.h
359index 61307fb..514f65b 100644
360--- a/shared/browser/screen.h
361+++ b/shared/browser/screen.h
362@@ -51,7 +51,7 @@ class OXIDE_SHARED_EXPORT Screen {
363 virtual DisplayFormFactor GetDisplayFormFactor(
364 const display::Display& display);
365
366- static ShellMode GetShellMode();
367+ virtual ShellMode GetShellMode();
368
369 protected:
370 Screen();
371diff --git a/shared/browser/screen_observer.h b/shared/browser/screen_observer.h
372index c887942..f730eda 100644
373--- a/shared/browser/screen_observer.h
374+++ b/shared/browser/screen_observer.h
375@@ -27,6 +27,7 @@ class Display;
376 namespace oxide {
377
378 class Screen;
379+enum class ShellMode;
380
381 class OXIDE_SHARED_EXPORT ScreenObserver {
382 public:
383diff --git a/shared/browser/screen_unittest.cc b/shared/browser/screen_unittest.cc
384index 552c1ba..9782c17 100644
385--- a/shared/browser/screen_unittest.cc
386+++ b/shared/browser/screen_unittest.cc
387@@ -195,15 +195,15 @@ TEST_F(ScreenTest, GetShellMode) {
388 #if defined(ENABLE_HYBRIS)
389 {
390 FakeHybrisUtils hybris_utils(false);
391- EXPECT_EQ(ShellMode::Windowed, Screen::GetShellMode());
392+ EXPECT_EQ(ShellMode::Windowed, Screen::GetInstance()->GetShellMode());
393 }
394
395 {
396 FakeHybrisUtils hybris_utils(true);
397- EXPECT_EQ(ShellMode::NonWindowed, Screen::GetShellMode());
398+ EXPECT_EQ(ShellMode::NonWindowed, Screen::GetInstance()->GetShellMode());
399 }
400 #else
401- EXPECT_EQ(ShellMode::Windowed, Screen::GetShellMode());
402+ EXPECT_EQ(ShellMode::Windowed, Screen::GetInstance()->GetShellMode());
403 #endif
404 }
405

Subscribers

People subscribed via source and target branches

to all changes: