| // Copyright 2020 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef CONTENT_BROWSER_MOJO_BINDER_POLICY_APPLIER_H_ |
| #define CONTENT_BROWSER_MOJO_BINDER_POLICY_APPLIER_H_ |
| |
| #include <string> |
| |
| #include "base/functional/bind.h" |
| #include "base/functional/callback.h" |
| #include "base/functional/callback_forward.h" |
| #include "base/memory/raw_ref.h" |
| #include "content/browser/mojo_binder_policy_map_impl.h" |
| #include "content/common/content_export.h" |
| |
| namespace content { |
| |
| // MojoBinderPolicyApplier is a helper class for `BrowserInterfaceBrokerImpl` |
| // which allows control over when to run the binder registered for a |
| // requested interface. This is useful in cases like prerendering pages, where |
| // it can be desirable to defer binding until the page is activated, or take |
| // other actions. |
| // |
| // The action to take for each interface is specified in the given |
| // `MojoBinderPolicyMap`, and kDefer is used when no policy is specified. |
| // |
| // See content/browser/preloading/prerender/README.md for more about capability |
| // control. |
| class CONTENT_EXPORT MojoBinderPolicyApplier { |
| public: |
| enum class Mode { |
| // In the kEnforce mode, MojoBinderPolicyApplier processes binding requests |
| // strictly according to the pre-set policies. |
| kEnforce, |
| // If the page is about to activate, MojoBinderPolicyApplier will switch to |
| // the kPrepareToGrantAll mode, and all non-kGrant binders will be |
| // deferred. |
| kPrepareToGrantAll, |
| // In the kGrantAll mode, MojoBinderPolicyApplier grants all binding |
| // requests regardless of their policies. |
| kGrantAll, |
| }; |
| |
| // `policy_map` must outlive `this` and must not be null. |
| // `cancel_callback` will be executed when ApplyPolicyToBinder() processes a |
| // kCancel interface. |
| MojoBinderPolicyApplier( |
| const MojoBinderPolicyMapImpl* policy_map, |
| base::OnceCallback<void(const std::string& interface_name)> |
| cancel_callback); |
| ~MojoBinderPolicyApplier(); |
| |
| // Returns the instance used by BrowserInterfaceBrokerImpl for same-origin |
| // prerendering pages. This is used when the prerendered page and the page |
| // that triggered the prerendering are same origin. |
| static std::unique_ptr<MojoBinderPolicyApplier> |
| CreateForSameOriginPrerendering( |
| base::OnceCallback<void(const std::string& interface_name)> |
| cancel_closure); |
| |
| // Returns the instance used by BrowserInterfaceBrokerImpl for preview mode. |
| // This is used when a page is shown in preview mode. |
| static std::unique_ptr<MojoBinderPolicyApplier> CreateForPreview( |
| base::OnceCallback<void(const std::string& interface_name)> |
| cancel_closure); |
| |
| // Disallows copy and move operations. |
| MojoBinderPolicyApplier(const MojoBinderPolicyApplier& other) = delete; |
| MojoBinderPolicyApplier& operator=(const MojoBinderPolicyApplier& other) = |
| delete; |
| MojoBinderPolicyApplier(MojoBinderPolicyApplier&&) = delete; |
| MojoBinderPolicyApplier& operator=(MojoBinderPolicyApplier&&) = delete; |
| |
| // Applies `MojoBinderNonAssociatedPolicy` before binding a non-associated |
| // interface. |
| // - In kEnforce mode: |
| // - kGrant: Runs `binder_callback` immediately. |
| // - kDefer: Saves `binder_callback` and runs it when GrantAll() is called. |
| // - kCancel: Drops `binder_callback` and runs `cancel_callback_`. |
| // - kUnexpected: Unimplemented now. |
| // - In the kPrepareToGrantAll mode: |
| // - kGrant: Runs `binder_callback` immediately. |
| // - kDefer, kCancel and kUnexpected: Saves `binder_callback` and runs it |
| // when GrantAll() is called. |
| // - In the kGrantAll mode: this always runs the callback immediately. |
| void ApplyPolicyToNonAssociatedBinder(const std::string& interface_name, |
| base::OnceClosure binder_callback); |
| |
| // Applies `MojoBinderAssociatedPolicy` before binding an associated |
| // interface. Note that this method only applies kCancel and kGrant to |
| // associated intefaces, because messages sent over associated interfaces |
| // cannot be deferred. See |
| // https://chromium.googlesource.com/chromium/src/+/HEAD/mojo/public/cpp/bindings/README.md#Associated-Interfaces |
| // for more information. |
| // Runs the cancellation callback and returns false if kCancel is applied. |
| // Otherwise returns true. |
| bool ApplyPolicyToAssociatedBinder(const std::string& interface_name); |
| |
| // Switches this to the kPrepareToGrantAll mode. |
| void PrepareToGrantAll(); |
| |
| // Runs all deferred binders and runs binder callbacks for all subsequent |
| // requests, i.e., it stops applying the policies. |
| |
| void GrantAll(); |
| // Deletes all deferred binders without running them. |
| void DropDeferredBinders(); |
| |
| private: |
| friend class MojoBinderPolicyApplierTest; |
| |
| // Gets the corresponding policy of the given mojo interface name. |
| MojoBinderNonAssociatedPolicy GetNonAssociatedMojoBinderPolicy( |
| const std::string& interface_name) const; |
| |
| const MojoBinderNonAssociatedPolicy default_policy_ = |
| MojoBinderNonAssociatedPolicy::kDefer; |
| // Maps Mojo interface name to its policy. |
| const raw_ref<const MojoBinderPolicyMapImpl> policy_map_; |
| |
| // Will be executed upon a request for a kCancel interface. |
| base::OnceCallback<void(const std::string& interface_name)> cancel_callback_; |
| Mode mode_ = Mode::kEnforce; |
| |
| // Stores binders which are delayed running. |
| std::vector<base::OnceClosure> deferred_binders_; |
| |
| // Stores binders that can be used to send synchronous messages but |
| // are delayed running. |
| std::vector<base::OnceClosure> deferred_sync_binders_; |
| }; |
| |
| } // namespace content |
| |
| #endif // CONTENT_BROWSER_MOJO_BINDER_POLICY_APPLIER_H_ |