1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
|
// 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_
|