Avi Drissman | 4e1b7bc3 | 2022-09-15 14:03:50 | [diff] [blame] | 1 | // Copyright 2020 The Chromium Authors |
Lingqi Chi | fa0dda1 | 2020-11-18 05:32:45 | [diff] [blame] | 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
| 5 | #ifndef CONTENT_BROWSER_MOJO_BINDER_POLICY_APPLIER_H_ |
| 6 | #define CONTENT_BROWSER_MOJO_BINDER_POLICY_APPLIER_H_ |
| 7 | |
| 8 | #include <string> |
| 9 | |
Avi Drissman | adac2199 | 2023-01-11 23:46:39 | [diff] [blame] | 10 | #include "base/functional/bind.h" |
| 11 | #include "base/functional/callback.h" |
Lingqi Chi | 0611a4c | 2022-12-15 01:59:17 | [diff] [blame] | 12 | #include "base/functional/callback_forward.h" |
Ali Hijazi | d87307d | 2022-11-07 20:15:03 | [diff] [blame] | 13 | #include "base/memory/raw_ref.h" |
Lingqi Chi | 775e6075 | 2020-12-14 06:31:16 | [diff] [blame] | 14 | #include "content/browser/mojo_binder_policy_map_impl.h" |
Lingqi Chi | fa0dda1 | 2020-11-18 05:32:45 | [diff] [blame] | 15 | #include "content/common/content_export.h" |
| 16 | |
| 17 | namespace content { |
| 18 | |
| 19 | // MojoBinderPolicyApplier is a helper class for `BrowserInterfaceBrokerImpl` |
| 20 | // which allows control over when to run the binder registered for a |
| 21 | // requested interface. This is useful in cases like prerendering pages, where |
| 22 | // it can be desirable to defer binding until the page is activated, or take |
| 23 | // other actions. |
| 24 | // |
| 25 | // The action to take for each interface is specified in the given |
| 26 | // `MojoBinderPolicyMap`, and kDefer is used when no policy is specified. |
| 27 | // |
Sreeja Kamishetty | 9d39966 | 2022-07-14 20:07:51 | [diff] [blame] | 28 | // See content/browser/preloading/prerender/README.md for more about capability |
| 29 | // control. |
Lingqi Chi | fa0dda1 | 2020-11-18 05:32:45 | [diff] [blame] | 30 | class CONTENT_EXPORT MojoBinderPolicyApplier { |
| 31 | public: |
Lingqi Chi | 0ca6ac5 | 2021-03-17 10:39:55 | [diff] [blame] | 32 | enum class Mode { |
| 33 | // In the kEnforce mode, MojoBinderPolicyApplier processes binding requests |
| 34 | // strictly according to the pre-set policies. |
| 35 | kEnforce, |
| 36 | // If the page is about to activate, MojoBinderPolicyApplier will switch to |
| 37 | // the kPrepareToGrantAll mode, and all non-kGrant binders will be |
| 38 | // deferred. |
| 39 | kPrepareToGrantAll, |
| 40 | // In the kGrantAll mode, MojoBinderPolicyApplier grants all binding |
| 41 | // requests regardless of their policies. |
| 42 | kGrantAll, |
| 43 | }; |
| 44 | |
Lingqi Chi | fa0dda1 | 2020-11-18 05:32:45 | [diff] [blame] | 45 | // `policy_map` must outlive `this` and must not be null. |
Lingqi Chi | fc4b7d9c | 2021-04-08 01:41:22 | [diff] [blame] | 46 | // `cancel_callback` will be executed when ApplyPolicyToBinder() processes a |
Lingqi Chi | fa0dda1 | 2020-11-18 05:32:45 | [diff] [blame] | 47 | // kCancel interface. |
Lingqi Chi | fc4b7d9c | 2021-04-08 01:41:22 | [diff] [blame] | 48 | MojoBinderPolicyApplier( |
| 49 | const MojoBinderPolicyMapImpl* policy_map, |
| 50 | base::OnceCallback<void(const std::string& interface_name)> |
| 51 | cancel_callback); |
Lingqi Chi | fa0dda1 | 2020-11-18 05:32:45 | [diff] [blame] | 52 | ~MojoBinderPolicyApplier(); |
| 53 | |
Lingqi Chi | cd5239e | 2021-03-03 09:15:33 | [diff] [blame] | 54 | // Returns the instance used by BrowserInterfaceBrokerImpl for same-origin |
| 55 | // prerendering pages. This is used when the prerendered page and the page |
| 56 | // that triggered the prerendering are same origin. |
| 57 | static std::unique_ptr<MojoBinderPolicyApplier> |
Lingqi Chi | fc4b7d9c | 2021-04-08 01:41:22 | [diff] [blame] | 58 | CreateForSameOriginPrerendering( |
| 59 | base::OnceCallback<void(const std::string& interface_name)> |
| 60 | cancel_closure); |
Lingqi Chi | ee8814f7 | 2021-01-20 07:35:07 | [diff] [blame] | 61 | |
Takashi Toyoshima | a35e5fc | 2023-10-20 04:00:34 | [diff] [blame] | 62 | // Returns the instance used by BrowserInterfaceBrokerImpl for preview mode. |
| 63 | // This is used when a page is shown in preview mode. |
| 64 | static std::unique_ptr<MojoBinderPolicyApplier> CreateForPreview( |
| 65 | base::OnceCallback<void(const std::string& interface_name)> |
| 66 | cancel_closure); |
| 67 | |
Lingqi Chi | fa0dda1 | 2020-11-18 05:32:45 | [diff] [blame] | 68 | // Disallows copy and move operations. |
| 69 | MojoBinderPolicyApplier(const MojoBinderPolicyApplier& other) = delete; |
| 70 | MojoBinderPolicyApplier& operator=(const MojoBinderPolicyApplier& other) = |
| 71 | delete; |
| 72 | MojoBinderPolicyApplier(MojoBinderPolicyApplier&&) = delete; |
| 73 | MojoBinderPolicyApplier& operator=(MojoBinderPolicyApplier&&) = delete; |
| 74 | |
Lingqi Chi | 2e03d9d6 | 2021-11-08 05:45:41 | [diff] [blame] | 75 | // Applies `MojoBinderNonAssociatedPolicy` before binding a non-associated |
| 76 | // interface. |
Lingqi Chi | 0ca6ac5 | 2021-03-17 10:39:55 | [diff] [blame] | 77 | // - In kEnforce mode: |
| 78 | // - kGrant: Runs `binder_callback` immediately. |
| 79 | // - kDefer: Saves `binder_callback` and runs it when GrantAll() is called. |
Lingqi Chi | fc4b7d9c | 2021-04-08 01:41:22 | [diff] [blame] | 80 | // - kCancel: Drops `binder_callback` and runs `cancel_callback_`. |
Lingqi Chi | 0ca6ac5 | 2021-03-17 10:39:55 | [diff] [blame] | 81 | // - kUnexpected: Unimplemented now. |
| 82 | // - In the kPrepareToGrantAll mode: |
| 83 | // - kGrant: Runs `binder_callback` immediately. |
| 84 | // - kDefer, kCancel and kUnexpected: Saves `binder_callback` and runs it |
| 85 | // when GrantAll() is called. |
| 86 | // - In the kGrantAll mode: this always runs the callback immediately. |
Lingqi Chi | 2e03d9d6 | 2021-11-08 05:45:41 | [diff] [blame] | 87 | void ApplyPolicyToNonAssociatedBinder(const std::string& interface_name, |
| 88 | base::OnceClosure binder_callback); |
| 89 | |
| 90 | // Applies `MojoBinderAssociatedPolicy` before binding an associated |
| 91 | // interface. Note that this method only applies kCancel and kGrant to |
| 92 | // associated intefaces, because messages sent over associated interfaces |
| 93 | // cannot be deferred. See |
| 94 | // https://chromium.googlesource.com/chromium/src/+/HEAD/mojo/public/cpp/bindings/README.md#Associated-Interfaces |
| 95 | // for more information. |
| 96 | // Runs the cancellation callback and returns false if kCancel is applied. |
| 97 | // Otherwise returns true. |
| 98 | bool ApplyPolicyToAssociatedBinder(const std::string& interface_name); |
| 99 | |
Lingqi Chi | 0ca6ac5 | 2021-03-17 10:39:55 | [diff] [blame] | 100 | // Switches this to the kPrepareToGrantAll mode. |
| 101 | void PrepareToGrantAll(); |
Lingqi Chi | 2e03d9d6 | 2021-11-08 05:45:41 | [diff] [blame] | 102 | |
Lingqi Chi | fa0dda1 | 2020-11-18 05:32:45 | [diff] [blame] | 103 | // Runs all deferred binders and runs binder callbacks for all subsequent |
| 104 | // requests, i.e., it stops applying the policies. |
Lingqi Chi | 2e03d9d6 | 2021-11-08 05:45:41 | [diff] [blame] | 105 | |
Lingqi Chi | fa0dda1 | 2020-11-18 05:32:45 | [diff] [blame] | 106 | void GrantAll(); |
Lingqi Chi | 242d891e | 2021-03-10 09:45:49 | [diff] [blame] | 107 | // Deletes all deferred binders without running them. |
| 108 | void DropDeferredBinders(); |
Lingqi Chi | fa0dda1 | 2020-11-18 05:32:45 | [diff] [blame] | 109 | |
| 110 | private: |
Lingqi Chi | 242d891e | 2021-03-10 09:45:49 | [diff] [blame] | 111 | friend class MojoBinderPolicyApplierTest; |
| 112 | |
Lingqi Chi | fa0dda1 | 2020-11-18 05:32:45 | [diff] [blame] | 113 | // Gets the corresponding policy of the given mojo interface name. |
Lingqi Chi | 2e03d9d6 | 2021-11-08 05:45:41 | [diff] [blame] | 114 | MojoBinderNonAssociatedPolicy GetNonAssociatedMojoBinderPolicy( |
| 115 | const std::string& interface_name) const; |
Lingqi Chi | fa0dda1 | 2020-11-18 05:32:45 | [diff] [blame] | 116 | |
Lingqi Chi | 2e03d9d6 | 2021-11-08 05:45:41 | [diff] [blame] | 117 | const MojoBinderNonAssociatedPolicy default_policy_ = |
| 118 | MojoBinderNonAssociatedPolicy::kDefer; |
Lingqi Chi | fa0dda1 | 2020-11-18 05:32:45 | [diff] [blame] | 119 | // Maps Mojo interface name to its policy. |
Ali Hijazi | d87307d | 2022-11-07 20:15:03 | [diff] [blame] | 120 | const raw_ref<const MojoBinderPolicyMapImpl> policy_map_; |
Lingqi Chi | 0611a4c | 2022-12-15 01:59:17 | [diff] [blame] | 121 | |
Lingqi Chi | fa0dda1 | 2020-11-18 05:32:45 | [diff] [blame] | 122 | // Will be executed upon a request for a kCancel interface. |
Lingqi Chi | fc4b7d9c | 2021-04-08 01:41:22 | [diff] [blame] | 123 | base::OnceCallback<void(const std::string& interface_name)> cancel_callback_; |
Lingqi Chi | 0ca6ac5 | 2021-03-17 10:39:55 | [diff] [blame] | 124 | Mode mode_ = Mode::kEnforce; |
Lingqi Chi | 0611a4c | 2022-12-15 01:59:17 | [diff] [blame] | 125 | |
Lingqi Chi | fa0dda1 | 2020-11-18 05:32:45 | [diff] [blame] | 126 | // Stores binders which are delayed running. |
| 127 | std::vector<base::OnceClosure> deferred_binders_; |
Lingqi Chi | 0611a4c | 2022-12-15 01:59:17 | [diff] [blame] | 128 | |
| 129 | // Stores binders that can be used to send synchronous messages but |
| 130 | // are delayed running. |
| 131 | std::vector<base::OnceClosure> deferred_sync_binders_; |
Lingqi Chi | fa0dda1 | 2020-11-18 05:32:45 | [diff] [blame] | 132 | }; |
| 133 | |
| 134 | } // namespace content |
| 135 | |
| 136 | #endif // CONTENT_BROWSER_MOJO_BINDER_POLICY_APPLIER_H_ |