diff options
Diffstat (limited to 'components/kiosk_wm')
-rw-r--r-- | components/kiosk_wm/BUILD.gn | 37 | ||||
-rw-r--r-- | components/kiosk_wm/DEPS | 8 | ||||
-rw-r--r-- | components/kiosk_wm/README.md | 6 | ||||
-rw-r--r-- | components/kiosk_wm/kiosk_wm.cc | 148 | ||||
-rw-r--r-- | components/kiosk_wm/kiosk_wm.h | 95 | ||||
-rw-r--r-- | components/kiosk_wm/main.cc | 13 | ||||
-rw-r--r-- | components/kiosk_wm/merged_service_provider.cc | 35 | ||||
-rw-r--r-- | components/kiosk_wm/merged_service_provider.h | 41 | ||||
-rw-r--r-- | components/kiosk_wm/navigator_host_impl.cc | 54 | ||||
-rw-r--r-- | components/kiosk_wm/navigator_host_impl.h | 43 |
10 files changed, 480 insertions, 0 deletions
diff --git a/components/kiosk_wm/BUILD.gn b/components/kiosk_wm/BUILD.gn new file mode 100644 index 0000000..2e41546 --- /dev/null +++ b/components/kiosk_wm/BUILD.gn @@ -0,0 +1,37 @@ +# Copyright 2014 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. + +import("//third_party/mojo/src/mojo/public/mojo_application.gni") +import("$mojo_sdk_root/mojo/public/tools/bindings/mojom.gni") + +# Mojo shell in chromium is only used for Mandoline, and Mandoline only uses +# kiosk_wm, so we name the target window_manager to avoid having to remap on the +# command line. +mojo_native_application("window_manager") { + sources = [ + "kiosk_wm.cc", + "kiosk_wm.h", + "main.cc", + "merged_service_provider.cc", + "merged_service_provider.h", + "navigator_host_impl.cc", + "navigator_host_impl.h", + ] + + deps = [ + "//base", + "//components/window_manager:lib", + "//mojo/application", + "//mojo/common:common", + "//mojo/converters/geometry", + "//mojo/converters/input_events", + "//third_party/mojo/src/mojo/public/cpp/bindings", + "//third_party/mojo/src/mojo/public/cpp/utility", + "//third_party/mojo/src/mojo/public/interfaces/application", + "//third_party/mojo_services/src/input_events/public/interfaces", + "//third_party/mojo_services/src/navigation/public/interfaces", + "//third_party/mojo_services/src/view_manager/public/cpp", + "//ui/base", + ] +} diff --git a/components/kiosk_wm/DEPS b/components/kiosk_wm/DEPS new file mode 100644 index 0000000..f170cf7 --- /dev/null +++ b/components/kiosk_wm/DEPS @@ -0,0 +1,8 @@ +include_rules = [ + "+components/window_manager", + "+mojo/application", + "+mojo/common", + "+third_party/mojo/src/mojo/public", + "+third_party/mojo_services", + "+ui", +] diff --git a/components/kiosk_wm/README.md b/components/kiosk_wm/README.md new file mode 100644 index 0000000..4c38010 --- /dev/null +++ b/components/kiosk_wm/README.md @@ -0,0 +1,6 @@ +A very simple window kiosk-like window manager. + +This can handle a single application at a time, any further calls to +WindowManager::Embed will replace the existing application. + +Renders full-screen. On linux defaults to a Nexus-5 aspect ratio.
\ No newline at end of file diff --git a/components/kiosk_wm/kiosk_wm.cc b/components/kiosk_wm/kiosk_wm.cc new file mode 100644 index 0000000..83331b7 --- /dev/null +++ b/components/kiosk_wm/kiosk_wm.cc @@ -0,0 +1,148 @@ +// Copyright 2014 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/kiosk_wm/kiosk_wm.h" + +#include "base/command_line.h" +#include "base/strings/utf_string_conversions.h" +#include "components/kiosk_wm/merged_service_provider.h" +#include "components/window_manager/basic_focus_rules.h" + +namespace kiosk_wm { + +KioskWM::KioskWM() + : window_manager_app_(new window_manager::WindowManagerApp(this, this)), + root_(nullptr), + content_(nullptr), + navigator_host_(this), + weak_factory_(this) { + exposed_services_impl_.AddService(this); +} + +KioskWM::~KioskWM() { +} + +base::WeakPtr<KioskWM> KioskWM::GetWeakPtr() { + return weak_factory_.GetWeakPtr(); +} + +void KioskWM::Initialize(mojo::ApplicationImpl* app) { + window_manager_app_->Initialize(app); + + base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); + base::CommandLine::StringVector args = command_line->GetArgs(); + if (args.empty()) { + default_url_ = "http://www.google.com/"; + } else { +#if defined(OS_WIN) + default_url_ = base::WideToUTF8(args[0]); +#else + default_url_ = args[0]; +#endif + } +} + +bool KioskWM::ConfigureIncomingConnection( + mojo::ApplicationConnection* connection) { + window_manager_app_->ConfigureIncomingConnection(connection); + return true; +} + +bool KioskWM::ConfigureOutgoingConnection( + mojo::ApplicationConnection* connection) { + window_manager_app_->ConfigureOutgoingConnection(connection); + return true; +} + +void KioskWM::OnEmbed( + mojo::View* root, + mojo::InterfaceRequest<mojo::ServiceProvider> services, + mojo::ServiceProviderPtr exposed_services) { + // KioskWM does not support being embedded more than once. + CHECK(!root_); + + root_ = root; + root_->AddObserver(this); + +#if defined(OS_ANDROID) + // Resize to match the Nexus 5 aspect ratio: + window_manager_app_->SetViewportSize(gfx::Size(320, 640)); +#else + window_manager_app_->SetViewportSize(gfx::Size(1280, 800)); +#endif + + content_ = root->view_manager()->CreateView(); + content_->SetBounds(root_->bounds()); + root_->AddChild(content_); + content_->SetVisible(true); + + window_manager_app_->InitFocus( + make_scoped_ptr(new window_manager::BasicFocusRules(root_))); + window_manager_app_->accelerator_manager()->Register( + ui::Accelerator(ui::VKEY_BROWSER_BACK, 0), + ui::AcceleratorManager::kNormalPriority, this); + + // Now that we're ready, either load a pending url or the default url. + if (!pending_url_.empty()) + Embed(pending_url_, services.Pass(), exposed_services.Pass()); + else if (!default_url_.empty()) + Embed(default_url_, services.Pass(), exposed_services.Pass()); +} + +void KioskWM::Embed(const mojo::String& url, + mojo::InterfaceRequest<mojo::ServiceProvider> services, + mojo::ServiceProviderPtr exposed_services) { + // We can get Embed calls before we've actually been + // embedded into the root view and content_ is created. + // Just save the last url, we'll embed it when we're ready. + if (!content_) { + pending_url_ = url; + return; + } + + merged_service_provider_.reset( + new MergedServiceProvider(exposed_services.Pass(), this)); + content_->Embed(url, services.Pass(), + merged_service_provider_->GetServiceProviderPtr().Pass()); + + navigator_host_.RecordNavigation(url); +} + +void KioskWM::Create(mojo::ApplicationConnection* connection, + mojo::InterfaceRequest<mojo::NavigatorHost> request) { + navigator_host_.Bind(request.Pass()); +} + +void KioskWM::OnViewManagerDisconnected( + mojo::ViewManager* view_manager) { + root_ = nullptr; +} + +void KioskWM::OnViewDestroyed(mojo::View* view) { + view->RemoveObserver(this); +} + +void KioskWM::OnViewBoundsChanged(mojo::View* view, + const mojo::Rect& old_bounds, + const mojo::Rect& new_bounds) { + content_->SetBounds(new_bounds); +} + +// Convenience method: +void KioskWM::ReplaceContentWithURL(const mojo::String& url) { + Embed(url, nullptr, nullptr); +} + +bool KioskWM::AcceleratorPressed(const ui::Accelerator& accelerator) { + if (accelerator.key_code() != ui::VKEY_BROWSER_BACK) + return false; + navigator_host_.RequestNavigateHistory(-1); + return true; +} + +bool KioskWM::CanHandleAccelerators() const { + return true; +} + +} // namespace kiosk_wm diff --git a/components/kiosk_wm/kiosk_wm.h b/components/kiosk_wm/kiosk_wm.h new file mode 100644 index 0000000..2d3def0 --- /dev/null +++ b/components/kiosk_wm/kiosk_wm.h @@ -0,0 +1,95 @@ +// Copyright 2014 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. + +#ifndef COMPONENTS_KIOSK_WM_KIOSK_WM_H_ +#define COMPONENTS_KIOSK_WM_KIOSK_WM_H_ + +#include "base/memory/weak_ptr.h" +#include "components/kiosk_wm/navigator_host_impl.h" +#include "components/window_manager/window_manager_app.h" +#include "components/window_manager/window_manager_delegate.h" +#include "third_party/mojo/src/mojo/public/cpp/application/application_delegate.h" +#include "third_party/mojo/src/mojo/public/cpp/application/application_impl.h" +#include "third_party/mojo/src/mojo/public/cpp/application/connect.h" +#include "third_party/mojo/src/mojo/public/cpp/application/service_provider_impl.h" +#include "third_party/mojo_services/src/input_events/public/interfaces/input_events.mojom.h" +#include "third_party/mojo_services/src/navigation/public/interfaces/navigation.mojom.h" +#include "third_party/mojo_services/src/view_manager/public/cpp/view_manager.h" +#include "third_party/mojo_services/src/view_manager/public/cpp/view_manager_delegate.h" +#include "third_party/mojo_services/src/view_manager/public/cpp/view_observer.h" +#include "ui/base/accelerators/accelerator.h" + +namespace kiosk_wm { + +class MergedServiceProvider; + +class KioskWM : public mojo::ApplicationDelegate, + public mojo::ViewManagerDelegate, + public mojo::ViewObserver, + public window_manager::WindowManagerDelegate, + public mojo::InterfaceFactory<mojo::NavigatorHost>, + public ui::AcceleratorTarget { + public: + KioskWM(); + ~KioskWM() override; + + base::WeakPtr<KioskWM> GetWeakPtr(); + + void ReplaceContentWithURL(const mojo::String& url); + + private: + // Overridden from mojo::ApplicationDelegate: + void Initialize(mojo::ApplicationImpl* app) override; + bool ConfigureIncomingConnection( + mojo::ApplicationConnection* connection) override; + bool ConfigureOutgoingConnection( + mojo::ApplicationConnection* connection) override; + + // Overridden from mojo::ViewManagerDelegate: + void OnEmbed(mojo::View* root, + mojo::InterfaceRequest<mojo::ServiceProvider> services, + mojo::ServiceProviderPtr exposed_services) override; + void OnViewManagerDisconnected(mojo::ViewManager* view_manager) override; + + // Overriden from mojo::ViewObserver: + void OnViewDestroyed(mojo::View* view) override; + void OnViewBoundsChanged(mojo::View* view, + const mojo::Rect& old_bounds, + const mojo::Rect& new_bounds) override; + + // Overridden from WindowManagerDelegate: + void Embed(const mojo::String& url, + mojo::InterfaceRequest<mojo::ServiceProvider> services, + mojo::ServiceProviderPtr exposed_services) override; + + // Overridden from mojo::InterfaceFactory<mojo::NavigatorHost>: + void Create(mojo::ApplicationConnection* connection, + mojo::InterfaceRequest<mojo::NavigatorHost> request) override; + + // Overriden from ui::AcceleratorTarget: + bool AcceleratorPressed(const ui::Accelerator& accelerator) override; + bool CanHandleAccelerators() const override; + + scoped_ptr<window_manager::WindowManagerApp> window_manager_app_; + + // Only support being embedded once, so both application-level + // and embedding-level state are shared on the same object. + mojo::View* root_; + mojo::View* content_; + std::string default_url_; + std::string pending_url_; + + mojo::ServiceProviderImpl exposed_services_impl_; + scoped_ptr<MergedServiceProvider> merged_service_provider_; + + NavigatorHostImpl navigator_host_; + + base::WeakPtrFactory<KioskWM> weak_factory_; + + DISALLOW_COPY_AND_ASSIGN(KioskWM); +}; + +} // namespace kiosk_wm + +#endif // COMPONENTS_KIOSK_WM_KIOSK_WM_H_ diff --git a/components/kiosk_wm/main.cc b/components/kiosk_wm/main.cc new file mode 100644 index 0000000..07c19db --- /dev/null +++ b/components/kiosk_wm/main.cc @@ -0,0 +1,13 @@ +// Copyright 2014 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/kiosk_wm/kiosk_wm.h" + +#include "mojo/application/application_runner_chromium.h" +#include "third_party/mojo/src/mojo/public/c/system/main.h" + +MojoResult MojoMain(MojoHandle shell_handle) { + mojo::ApplicationRunnerChromium runner(new kiosk_wm::KioskWM); + return runner.Run(shell_handle); +} diff --git a/components/kiosk_wm/merged_service_provider.cc b/components/kiosk_wm/merged_service_provider.cc new file mode 100644 index 0000000..de2c21a --- /dev/null +++ b/components/kiosk_wm/merged_service_provider.cc @@ -0,0 +1,35 @@ +// Copyright 2015 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/kiosk_wm/merged_service_provider.h" + +namespace kiosk_wm { + +MergedServiceProvider::MergedServiceProvider( + mojo::ServiceProviderPtr exposed_services, + mojo::InterfaceFactory<mojo::NavigatorHost>* factory) + : exposed_services_(exposed_services.Pass()), factory_(factory) { +} + +MergedServiceProvider::~MergedServiceProvider() { +} + +mojo::ServiceProviderPtr MergedServiceProvider::GetServiceProviderPtr() { + mojo::ServiceProviderPtr sp; + binding_.reset(new mojo::Binding<mojo::ServiceProvider>(this, GetProxy(&sp))); + return sp.Pass(); +} + +void MergedServiceProvider::ConnectToService( + const mojo::String& interface_name, + mojo::ScopedMessagePipeHandle pipe) { + if (interface_name == mojo::NavigatorHost::Name_) { + factory_->Create(nullptr, + mojo::MakeRequest<mojo::NavigatorHost>(pipe.Pass())); + } else if (exposed_services_.get()) { + exposed_services_->ConnectToService(interface_name, pipe.Pass()); + } +} + +} // namespace kiosk_wm diff --git a/components/kiosk_wm/merged_service_provider.h b/components/kiosk_wm/merged_service_provider.h new file mode 100644 index 0000000..1606ea8 --- /dev/null +++ b/components/kiosk_wm/merged_service_provider.h @@ -0,0 +1,41 @@ +// Copyright 2015 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. + +#ifndef COMPONENTS_KIOSK_WM_MERGED_SERVICE_PROVIDER_H_ +#define COMPONENTS_KIOSK_WM_MERGED_SERVICE_PROVIDER_H_ + +#include "base/memory/scoped_ptr.h" +#include "third_party/mojo/src/mojo/public/cpp/application/interface_factory.h" +#include "third_party/mojo/src/mojo/public/cpp/bindings/binding.h" +#include "third_party/mojo/src/mojo/public/interfaces/application/service_provider.mojom.h" +#include "third_party/mojo_services/src/navigation/public/interfaces/navigation.mojom.h" + +namespace kiosk_wm { + +// Used to wrap the second incoming WindowManager Embed() "exposed_services" +// parameter with a new ServiceProvider that adds the KioskWM's +// NavigatorHost service. +class MergedServiceProvider : public mojo::ServiceProvider { + public: + MergedServiceProvider(mojo::ServiceProviderPtr exposed_services, + mojo::InterfaceFactory<mojo::NavigatorHost>* factory); + ~MergedServiceProvider() override; + + mojo::ServiceProviderPtr GetServiceProviderPtr(); + + private: + // mojo::ServiceProvider: + void ConnectToService(const mojo::String& interface_name, + mojo::ScopedMessagePipeHandle pipe) override; + + mojo::ServiceProviderPtr exposed_services_; + mojo::InterfaceFactory<mojo::NavigatorHost>* factory_; + scoped_ptr<mojo::Binding<ServiceProvider>> binding_; + + DISALLOW_COPY_AND_ASSIGN(MergedServiceProvider); +}; + +} // namespace kiosk_wm + +#endif // COMPONENTS_KIOSK_WM_MERGED_SERVICE_PROVIDER_H_ diff --git a/components/kiosk_wm/navigator_host_impl.cc b/components/kiosk_wm/navigator_host_impl.cc new file mode 100644 index 0000000..7c81310a --- /dev/null +++ b/components/kiosk_wm/navigator_host_impl.cc @@ -0,0 +1,54 @@ +// Copyright 2014 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/kiosk_wm/navigator_host_impl.h" + +#include "components/kiosk_wm/kiosk_wm.h" + +namespace kiosk_wm { + +NavigatorHostImpl::NavigatorHostImpl(KioskWM* window_manager) + : current_index_(-1), kiosk_wm_(window_manager) { +} + +NavigatorHostImpl::~NavigatorHostImpl() { +} + +void NavigatorHostImpl::Bind( + mojo::InterfaceRequest<mojo::NavigatorHost> request) { + bindings_.AddBinding(this, request.Pass()); +} + +void NavigatorHostImpl::DidNavigateLocally(const mojo::String& url) { + RecordNavigation(url); + // TODO(abarth): Do something interesting. +} + +void NavigatorHostImpl::RequestNavigate(mojo::Target target, + mojo::URLRequestPtr request) { + // kiosk_wm sets up default services including navigation. + kiosk_wm_->ReplaceContentWithURL(request->url); +} + +void NavigatorHostImpl::RequestNavigateHistory(int32_t delta) { + if (history_.empty()) + return; + current_index_ = + std::max(0, std::min(current_index_ + delta, + static_cast<int32_t>(history_.size()) - 1)); + kiosk_wm_->ReplaceContentWithURL(history_[current_index_]); +} + +void NavigatorHostImpl::RecordNavigation(const std::string& url) { + if (current_index_ >= 0 && history_[current_index_] == url) { + // This is a navigation to the current entry, ignore. + return; + } + + history_.erase(history_.begin() + (current_index_ + 1), history_.end()); + history_.push_back(url); + ++current_index_; +} + +} // namespace kiosk_wm diff --git a/components/kiosk_wm/navigator_host_impl.h b/components/kiosk_wm/navigator_host_impl.h new file mode 100644 index 0000000..283d4ab --- /dev/null +++ b/components/kiosk_wm/navigator_host_impl.h @@ -0,0 +1,43 @@ +// Copyright 2014 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. + +#ifndef COMPONENTS_KIOSK_WM_NAVIGATOR_HOST_IMPL_H_ +#define COMPONENTS_KIOSK_WM_NAVIGATOR_HOST_IMPL_H_ + +#include "base/memory/weak_ptr.h" +#include "mojo/common/weak_binding_set.h" +#include "third_party/mojo/src/mojo/public/cpp/bindings/interface_request.h" +#include "third_party/mojo_services/src/navigation/public/interfaces/navigation.mojom.h" + +namespace kiosk_wm { +class KioskWM; + +class NavigatorHostImpl : public mojo::NavigatorHost { + public: + NavigatorHostImpl(KioskWM* kiosk_wm); + ~NavigatorHostImpl() override; + + void Bind(mojo::InterfaceRequest<mojo::NavigatorHost> request); + + void RecordNavigation(const std::string& url); + + // mojo::NavigatorHost implementation: + void DidNavigateLocally(const mojo::String& url) override; + void RequestNavigate(mojo::Target target, + mojo::URLRequestPtr request) override; + void RequestNavigateHistory(int32_t delta) override; + + private: + std::vector<std::string> history_; + int32_t current_index_; + + KioskWM* kiosk_wm_; + mojo::WeakBindingSet<NavigatorHost> bindings_; + + DISALLOW_COPY_AND_ASSIGN(NavigatorHostImpl); +}; + +} // namespace kiosk_wm + +#endif // COMPONENTS_KIOSK_WM_NAVIGATOR_HOST_IMPL_H_ |