summaryrefslogtreecommitdiff
path: root/chromium/components/arc/intent_helper
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/components/arc/intent_helper')
-rw-r--r--chromium/components/arc/intent_helper/DEPS2
-rw-r--r--chromium/components/arc/intent_helper/activity_icon_loader.cc3
-rw-r--r--chromium/components/arc/intent_helper/arc_intent_helper_bridge.cc1
-rw-r--r--chromium/components/arc/intent_helper/arc_intent_helper_bridge_unittest.cc6
-rw-r--r--chromium/components/arc/intent_helper/custom_tab.cc160
-rw-r--r--chromium/components/arc/intent_helper/custom_tab.h76
-rw-r--r--chromium/components/arc/intent_helper/intent_filter.cc19
-rw-r--r--chromium/components/arc/intent_helper/intent_filter.h8
-rw-r--r--chromium/components/arc/intent_helper/intent_filter_mojom_traits.cc13
-rw-r--r--chromium/components/arc/intent_helper/intent_filter_mojom_traits.h10
-rw-r--r--chromium/components/arc/intent_helper/intent_filter_unittest.cc7
11 files changed, 291 insertions, 14 deletions
diff --git a/chromium/components/arc/intent_helper/DEPS b/chromium/components/arc/intent_helper/DEPS
index 8f0dc0b632f..7f66c60dc3b 100644
--- a/chromium/components/arc/intent_helper/DEPS
+++ b/chromium/components/arc/intent_helper/DEPS
@@ -8,6 +8,8 @@ include_rules = [
"+components/services/app_service/public/cpp",
"+components/url_formatter",
"+services/service_manager/public/cpp/connector.h",
+ "+ui/aura",
"+ui/base",
"+ui/gfx",
+ "+ui/views",
]
diff --git a/chromium/components/arc/intent_helper/activity_icon_loader.cc b/chromium/components/arc/intent_helper/activity_icon_loader.cc
index 5bcebf5a201..bbc02cc8245 100644
--- a/chromium/components/arc/intent_helper/activity_icon_loader.cc
+++ b/chromium/components/arc/intent_helper/activity_icon_loader.cc
@@ -13,6 +13,7 @@
#include "base/bind.h"
#include "base/memory/ref_counted.h"
#include "base/task/post_task.h"
+#include "base/task/thread_pool.h"
#include "components/arc/arc_service_manager.h"
#include "components/arc/arc_util.h"
#include "components/arc/session/arc_bridge_service.h"
@@ -252,7 +253,7 @@ void ActivityIconLoader::OnIconsReady(
OnIconsReadyCallback cb,
std::vector<mojom::ActivityIconPtr> icons) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- base::PostTaskAndReplyWithResult(
+ base::ThreadPool::PostTaskAndReplyWithResult(
FROM_HERE,
base::BindOnce(&ResizeAndEncodeIcons, std::move(icons), scale_factor_),
base::BindOnce(&ActivityIconLoader::OnIconsResized,
diff --git a/chromium/components/arc/intent_helper/arc_intent_helper_bridge.cc b/chromium/components/arc/intent_helper/arc_intent_helper_bridge.cc
index 8878c8f8d6b..ba948dc3077 100644
--- a/chromium/components/arc/intent_helper/arc_intent_helper_bridge.cc
+++ b/chromium/components/arc/intent_helper/arc_intent_helper_bridge.cc
@@ -144,7 +144,6 @@ void ArcIntentHelperBridge::OnOpenDownloads() {
// downloads by default, which is what we want. However if it is open it will
// simply be brought to the forgeground without forcibly being navigated to
// downloads, which is probably not ideal.
- // TODO(mash): Support this functionality without ash::Shell access in Chrome.
ash::NewWindowDelegate::GetInstance()->OpenFileManager();
}
diff --git a/chromium/components/arc/intent_helper/arc_intent_helper_bridge_unittest.cc b/chromium/components/arc/intent_helper/arc_intent_helper_bridge_unittest.cc
index c48c1ff04bf..d1b8a7aa6e1 100644
--- a/chromium/components/arc/intent_helper/arc_intent_helper_bridge_unittest.cc
+++ b/chromium/components/arc/intent_helper/arc_intent_helper_bridge_unittest.cc
@@ -24,9 +24,11 @@ IntentFilter GetIntentFilter(const std::string& host,
const std::string& pkg_name) {
std::vector<IntentFilter::AuthorityEntry> authorities;
authorities.emplace_back(host, /*port=*/-1);
- return IntentFilter(pkg_name, std::move(authorities),
+ return IntentFilter(pkg_name, /*actions=*/std::vector<std::string>(),
+ std::move(authorities),
std::vector<IntentFilter::PatternMatcher>(),
- std::vector<std::string>());
+ /*schemes=*/std::vector<std::string>(),
+ /*mime_types=*/std::vector<std::string>());
}
} // namespace
diff --git a/chromium/components/arc/intent_helper/custom_tab.cc b/chromium/components/arc/intent_helper/custom_tab.cc
new file mode 100644
index 00000000000..5af4709668a
--- /dev/null
+++ b/chromium/components/arc/intent_helper/custom_tab.cc
@@ -0,0 +1,160 @@
+// Copyright 2019 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/arc/intent_helper/custom_tab.h"
+
+#include <memory>
+#include <string>
+#include <utility>
+
+#include "base/threading/sequenced_task_runner_handle.h"
+#include "components/exo/surface.h"
+#include "ui/aura/window.h"
+#include "ui/aura/window_targeter.h"
+#include "ui/views/widget/widget.h"
+#include "ui/views/widget/widget_delegate.h"
+
+namespace arc {
+
+namespace {
+
+// Enumerates surfaces under the window.
+void EnumerateSurfaces(aura::Window* window, std::vector<exo::Surface*>* out) {
+ auto* surface = exo::Surface::AsSurface(window);
+ if (surface)
+ out->push_back(surface);
+ for (aura::Window* child : window->children())
+ EnumerateSurfaces(child, out);
+}
+
+} // namespace
+
+CustomTab::CustomTab(aura::Window* arc_app_window,
+ int32_t surface_id,
+ int32_t top_margin)
+ : arc_app_window_(arc_app_window),
+ surface_id_(surface_id),
+ top_margin_(top_margin) {
+ other_windows_observer_.Add(arc_app_window_);
+
+ host_->set_owned_by_client();
+ auto* const widget = views::Widget::GetWidgetForNativeWindow(arc_app_window_);
+ DCHECK(widget);
+ widget->GetContentsView()->AddChildView(host_.get());
+}
+
+CustomTab::~CustomTab() = default;
+
+void CustomTab::Attach(gfx::NativeView view) {
+ DCHECK(view);
+ DCHECK(!GetHostView());
+ host_->Attach(view);
+ aura::Window* const container = host_->GetNativeViewContainer();
+ container->SetEventTargeter(std::make_unique<aura::WindowTargeter>());
+ other_windows_observer_.Add(container);
+ EnsureWindowOrders();
+ UpdateSurfaceIfNecessary();
+}
+
+gfx::NativeView CustomTab::GetHostView() {
+ return host_->native_view();
+}
+
+void CustomTab::OnWindowHierarchyChanged(const HierarchyChangeParams& params) {
+ if ((params.receiver == arc_app_window_) &&
+ exo::Surface::AsSurface(params.target) && params.new_parent)
+ UpdateSurfaceIfNecessary();
+}
+
+void CustomTab::OnWindowBoundsChanged(aura::Window* window,
+ const gfx::Rect& old_bounds,
+ const gfx::Rect& new_bounds,
+ ui::PropertyChangeReason reason) {
+ if (surface_window_observer_.IsObserving(window) &&
+ old_bounds.size() != new_bounds.size())
+ OnSurfaceBoundsMaybeChanged(window);
+}
+
+void CustomTab::OnWindowPropertyChanged(aura::Window* window,
+ const void* key,
+ intptr_t old) {
+ if (surfaces_observer_.IsObserving(window) && key == exo::kClientSurfaceIdKey)
+ UpdateSurfaceIfNecessary();
+}
+
+void CustomTab::OnWindowStackingChanged(aura::Window* window) {
+ if (window == host_->GetNativeViewContainer() &&
+ !weak_ptr_factory_.HasWeakPtrs()) {
+ // Reordering should happen asynchronously -- some entity (like
+ // views::WindowReorderer) changes the window orders, and then ensures layer
+ // orders later. Changing order here synchronously leads to inconsistent
+ // window/layer ordering and causes weird graphical effects.
+ // TODO(hashimoto): fix the views ordering and remove this handling.
+ base::SequencedTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE, base::BindOnce(&CustomTab::EnsureWindowOrders,
+ weak_ptr_factory_.GetWeakPtr()));
+ }
+}
+
+void CustomTab::OnWindowDestroying(aura::Window* window) {
+ if (surfaces_observer_.IsObserving(window))
+ surfaces_observer_.Remove(window);
+ if (surface_window_observer_.IsObserving(window))
+ surface_window_observer_.Remove(window);
+ if (other_windows_observer_.IsObserving(window))
+ other_windows_observer_.Remove(window);
+}
+
+void CustomTab::OnSurfaceBoundsMaybeChanged(aura::Window* surface_window) {
+ DCHECK(surface_window);
+ gfx::Point origin(0, top_margin_);
+ gfx::Point bottom_right(surface_window->bounds().width(),
+ surface_window->bounds().height());
+ ConvertPointFromWindow(surface_window, &origin);
+ ConvertPointFromWindow(surface_window, &bottom_right);
+ host_->SetBounds(origin.x(), origin.y(), bottom_right.x() - origin.x(),
+ bottom_right.y() - origin.y());
+}
+
+void CustomTab::EnsureWindowOrders() {
+ aura::Window* const container = host_->GetNativeViewContainer();
+ if (container)
+ container->parent()->StackChildAtTop(container);
+}
+
+void CustomTab::ConvertPointFromWindow(aura::Window* window,
+ gfx::Point* point) {
+ views::Widget* const widget = host_->GetWidget();
+ aura::Window::ConvertPointToTarget(window, widget->GetNativeWindow(), point);
+ views::View::ConvertPointFromWidget(widget->GetContentsView(), point);
+}
+
+void CustomTab::UpdateSurfaceIfNecessary() {
+ std::vector<exo::Surface*> surfaces;
+ EnumerateSurfaces(arc_app_window_, &surfaces);
+
+ // Try to find the surface.
+ const auto it = std::find_if(surfaces.cbegin(), surfaces.cend(),
+ [id = surface_id_](const auto* surface) {
+ return surface->GetClientSurfaceId() == id;
+ });
+ if (it == surfaces.cend()) {
+ for (auto* surface : surfaces) {
+ if (!surface->GetClientSurfaceId() &&
+ !surfaces_observer_.IsObserving(surface->window()))
+ surfaces_observer_.Add(surface->window());
+ }
+ } else {
+ surfaces_observer_.RemoveAll();
+
+ auto* const window = (*it)->window();
+ if (!surface_window_observer_.IsObserving(window)) {
+ surface_window_observer_.RemoveAll();
+ surface_window_observer_.Add(window);
+ OnSurfaceBoundsMaybeChanged(window);
+ }
+ }
+}
+
+} // namespace arc
diff --git a/chromium/components/arc/intent_helper/custom_tab.h b/chromium/components/arc/intent_helper/custom_tab.h
new file mode 100644
index 00000000000..01815f2c56c
--- /dev/null
+++ b/chromium/components/arc/intent_helper/custom_tab.h
@@ -0,0 +1,76 @@
+// Copyright 2019 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_ARC_INTENT_HELPER_CUSTOM_TAB_H_
+#define COMPONENTS_ARC_INTENT_HELPER_CUSTOM_TAB_H_
+
+#include <memory>
+
+#include "base/macros.h"
+#include "base/scoped_observer.h"
+#include "components/arc/arc_export.h"
+#include "ui/aura/window.h"
+#include "ui/aura/window_observer.h"
+#include "ui/gfx/native_widget_types.h"
+#include "ui/views/controls/native/native_view_host.h"
+
+namespace arc {
+
+// CustomTab is responsible to embed an ARC++ custom tab.
+class ARC_EXPORT CustomTab : public aura::WindowObserver {
+ public:
+ CustomTab(aura::Window* arc_app_window,
+ int32_t surface_id,
+ int32_t top_margin);
+ CustomTab(const CustomTab&) = delete;
+ CustomTab& operator=(const CustomTab&) = delete;
+ ~CustomTab() override;
+
+ void Attach(gfx::NativeView view);
+
+ // Returns the view against which a view or dialog is positioned and parented
+ // in an CustomTab.
+ gfx::NativeView GetHostView();
+
+ // aura::WindowObserver:
+ void OnWindowHierarchyChanged(const HierarchyChangeParams& params) override;
+ void OnWindowBoundsChanged(aura::Window* window,
+ const gfx::Rect& old_bounds,
+ const gfx::Rect& new_bounds,
+ ui::PropertyChangeReason reason) override;
+ void OnWindowPropertyChanged(aura::Window* window,
+ const void* key,
+ intptr_t old) override;
+ void OnWindowStackingChanged(aura::Window* window) override;
+ void OnWindowDestroying(aura::Window* window) override;
+
+ private:
+ // Updates |host_|'s bounds to deal with changes in the bounds of the
+ // associated |surface_window|.
+ void OnSurfaceBoundsMaybeChanged(aura::Window* surface_window);
+
+ // Ensures the window/layer orders for the NativeViewHost.
+ void EnsureWindowOrders();
+
+ // Converts the point from the given window to this view.
+ void ConvertPointFromWindow(aura::Window* window, gfx::Point* point);
+
+ // Looks for the surface with |surface_id_|, and handles resultant changes.
+ void UpdateSurfaceIfNecessary();
+
+ std::unique_ptr<views::NativeViewHost> host_ =
+ std::make_unique<views::NativeViewHost>();
+ aura::Window* const arc_app_window_;
+ const int32_t surface_id_, top_margin_;
+ ScopedObserver<aura::Window, aura::WindowObserver> surfaces_observer_{this};
+ ScopedObserver<aura::Window, aura::WindowObserver> surface_window_observer_{
+ this};
+ ScopedObserver<aura::Window, aura::WindowObserver> other_windows_observer_{
+ this};
+ base::WeakPtrFactory<CustomTab> weak_ptr_factory_{this};
+};
+
+} // namespace arc
+
+#endif // COMPONENTS_ARC_INTENT_HELPER_CUSTOM_TAB_H_
diff --git a/chromium/components/arc/intent_helper/intent_filter.cc b/chromium/components/arc/intent_helper/intent_filter.cc
index 51d713dbba1..2cb365a24ec 100644
--- a/chromium/components/arc/intent_helper/intent_filter.cc
+++ b/chromium/components/arc/intent_helper/intent_filter.cc
@@ -4,10 +4,12 @@
#include "components/arc/intent_helper/intent_filter.h"
+#include <algorithm>
#include <utility>
#include "base/compiler_specific.h"
#include "base/strings/string_util.h"
+#include "components/arc/intent_helper/intent_constants.h"
#include "components/arc/mojom/intent_helper.mojom.h"
#include "components/services/app_service/public/cpp/intent_util.h"
#include "url/gurl.h"
@@ -19,12 +21,16 @@ IntentFilter::IntentFilter(IntentFilter&& other) = default;
IntentFilter::IntentFilter(
const std::string& package_name,
+ std::vector<std::string> actions,
std::vector<IntentFilter::AuthorityEntry> authorities,
std::vector<IntentFilter::PatternMatcher> paths,
- std::vector<std::string> schemes)
+ std::vector<std::string> schemes,
+ std::vector<std::string> mime_types)
: package_name_(package_name),
+ actions_(std::move(actions)),
authorities_(std::move(authorities)),
- schemes_(std::move(schemes)) {
+ schemes_(std::move(schemes)),
+ mime_types_(std::move(mime_types)) {
// In order to register a path we need to have at least one authority.
if (!authorities_.empty())
paths_ = std::move(paths);
@@ -45,6 +51,15 @@ bool IntentFilter::Match(const GURL& url) const {
return false;
}
+ // Don't return match for filters for sharing.
+ if (std::any_of(actions_.begin(), actions_.end(),
+ [](const std::string action) {
+ return action == kIntentActionSend ||
+ action == kIntentActionSendMultiple;
+ })) {
+ return false;
+ }
+
// Match the authority and the path. If there are no authorities for this
// filter, we can treat this as a match, since we already know this filter
// has a http(s) scheme and it doesn't corresponds to a MIME type.
diff --git a/chromium/components/arc/intent_helper/intent_filter.h b/chromium/components/arc/intent_helper/intent_filter.h
index db457d03827..de205499e0c 100644
--- a/chromium/components/arc/intent_helper/intent_filter.h
+++ b/chromium/components/arc/intent_helper/intent_filter.h
@@ -70,9 +70,11 @@ class IntentFilter {
IntentFilter();
IntentFilter(IntentFilter&& other);
IntentFilter(const std::string& package_name,
+ std::vector<std::string> actions,
std::vector<AuthorityEntry> authorities,
std::vector<PatternMatcher> paths,
- std::vector<std::string> schemes);
+ std::vector<std::string> schemes,
+ std::vector<std::string> mime_types);
~IntentFilter();
IntentFilter& operator=(IntentFilter&& other);
@@ -80,20 +82,24 @@ class IntentFilter {
bool Match(const GURL& url) const;
const std::string& package_name() const { return package_name_; }
+ const std::vector<std::string>& actions() const { return actions_; }
const std::vector<AuthorityEntry>& authorities() const {
return authorities_;
}
const std::vector<PatternMatcher>& paths() const { return paths_; }
const std::vector<std::string>& schemes() const { return schemes_; }
+ const std::vector<std::string>& mime_types() const { return mime_types_; }
private:
bool MatchDataAuthority(const GURL& url) const;
bool HasDataPath(const GURL& url) const;
std::string package_name_;
+ std::vector<std::string> actions_;
std::vector<AuthorityEntry> authorities_;
std::vector<PatternMatcher> paths_;
std::vector<std::string> schemes_;
+ std::vector<std::string> mime_types_;
DISALLOW_COPY_AND_ASSIGN(IntentFilter);
};
diff --git a/chromium/components/arc/intent_helper/intent_filter_mojom_traits.cc b/chromium/components/arc/intent_helper/intent_filter_mojom_traits.cc
index 16b2b9f0b33..87725074586 100644
--- a/chromium/components/arc/intent_helper/intent_filter_mojom_traits.cc
+++ b/chromium/components/arc/intent_helper/intent_filter_mojom_traits.cc
@@ -31,8 +31,17 @@ bool StructTraits<arc::mojom::IntentFilterDataView, arc::IntentFilter>::Read(
if (!data.ReadDataSchemes(&schemes))
return false;
- *out = arc::IntentFilter(package_name, std::move(authorities),
- std::move(paths), std::move(schemes));
+ std::vector<std::string> actions;
+ if (!data.ReadActions(&actions))
+ return false;
+
+ std::vector<std::string> mime_types;
+ if (!data.ReadMimeTypes(&mime_types))
+ return false;
+
+ *out = arc::IntentFilter(package_name, std::move(actions),
+ std::move(authorities), std::move(paths),
+ std::move(schemes), std::move(mime_types));
return true;
}
diff --git a/chromium/components/arc/intent_helper/intent_filter_mojom_traits.h b/chromium/components/arc/intent_helper/intent_filter_mojom_traits.h
index 636efd1d9f1..772f9299db9 100644
--- a/chromium/components/arc/intent_helper/intent_filter_mojom_traits.h
+++ b/chromium/components/arc/intent_helper/intent_filter_mojom_traits.h
@@ -16,9 +16,8 @@ namespace mojo {
template <>
struct StructTraits<arc::mojom::IntentFilterDataView, arc::IntentFilter> {
- static const base::span<std::string> actions(const arc::IntentFilter& r) {
- // Returns an empty array.
- return base::span<std::string>();
+ static const std::vector<std::string>& actions(const arc::IntentFilter& r) {
+ return r.actions();
}
static const base::span<std::string> categories(const arc::IntentFilter& r) {
// Returns an empty array.
@@ -46,6 +45,11 @@ struct StructTraits<arc::mojom::IntentFilterDataView, arc::IntentFilter> {
return r.package_name();
}
+ static const std::vector<std::string>& mime_types(
+ const arc::IntentFilter& r) {
+ return r.mime_types();
+ }
+
static bool Read(arc::mojom::IntentFilterDataView data,
arc::IntentFilter* out);
};
diff --git a/chromium/components/arc/intent_helper/intent_filter_unittest.cc b/chromium/components/arc/intent_helper/intent_filter_unittest.cc
index a2158cd26f8..4d65eeee9c3 100644
--- a/chromium/components/arc/intent_helper/intent_filter_unittest.cc
+++ b/chromium/components/arc/intent_helper/intent_filter_unittest.cc
@@ -40,8 +40,11 @@ class IntentFilterBuilder {
}
operator IntentFilter() {
- return IntentFilter(kPackageName, std::move(authorities_),
- std::move(paths_), std::vector<std::string>());
+ return IntentFilter(kPackageName,
+ /*actions=*/std::vector<std::string>(),
+ std::move(authorities_), std::move(paths_),
+ /*schemes=*/std::vector<std::string>(),
+ /*mime_types=*/std::vector<std::string>());
}
private: