Skip to content

Commit

Permalink
Make ActivityLog observe ScriptExecutor via a base::RepeatingCallback
Browse files Browse the repository at this point in the history
There once was a ScriptExecutionObserver::Delegate, but it disappeared
in some past refactoring. The lifetime around ScriptExecutionObserver
is quite complex, and relies on base::ObserverList being a
SupportsWeakPtr, which we want to stop doing for https://crbug.com/888973.

There is now exactly one ScriptExecutionObserver implementation
(ActivityLog), and the observer list only ever has exactly 1 or zero
observers in it; added and removed in concert with a TabHelper.
WebViewGuest also has an ObserverList<ScriptExecutionObserver>, but
it never added any observers to it.

We can instead make ActivityLog responsible for the lifetime of its
callbacks from ScriptExecutor. It already dispenses WeakPtrs to itself.

Bug: 888973
Change-Id: Ic773bbcbabea70627b48ef8e0e29ff4e16d1e1f5
Reviewed-on: https://chromium-review.googlesource.com/c/1256398
Commit-Queue: Trent Apted <tapted@chromium.org>
Reviewed-by: Devlin <rdevlin.cronin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#596454}
  • Loading branch information
tapted authored and Commit Bot committed Oct 4, 2018
1 parent 2df4ab3 commit 8f733b9
Show file tree
Hide file tree
Showing 11 changed files with 70 additions and 140 deletions.
5 changes: 5 additions & 0 deletions chrome/browser/extensions/activity_log/activity_log.cc
Original file line number Diff line number Diff line change
Expand Up @@ -783,6 +783,11 @@ void ActivityLog::OnScriptsExecuted(
}
}

void ActivityLog::ObserveScripts(ScriptExecutor* executor) {
executor->set_observer(base::BindRepeating(&ActivityLog::OnScriptsExecuted,
weak_factory_.GetWeakPtr()));
}

// LOOKUP ACTIONS. -------------------------------------------------------------

void ActivityLog::GetFilteredActions(
Expand Down
17 changes: 9 additions & 8 deletions chrome/browser/extensions/activity_log/activity_log.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
#include "content/public/browser/notification_registrar.h"
#include "extensions/browser/browser_context_keyed_api_factory.h"
#include "extensions/browser/extension_registry_observer.h"
#include "extensions/browser/script_execution_observer.h"
#include "extensions/browser/script_executor.h"
#include "extensions/common/dom_action_types.h"

class Profile;
Expand All @@ -47,7 +47,6 @@ class ExtensionSystem;
// each profile.
//
class ActivityLog : public BrowserContextKeyedAPI,
public ScriptExecutionObserver,
public ExtensionRegistryObserver,
public content::NotificationObserver {
public:
Expand All @@ -64,6 +63,14 @@ class ActivityLog : public BrowserContextKeyedAPI,
// the constructor; use GetInstance instead.
static ActivityLog* GetInstance(content::BrowserContext* context);

// Invoked when a ContentScript is executed.
void OnScriptsExecuted(const content::WebContents* web_contents,
const ExecutingScriptsMap& extension_ids,
const GURL& on_url);

// Observe tabs.executeScript on the given |executor|.
void ObserveScripts(ScriptExecutor* executor);

// Add/remove observer: the activityLogPrivate API only listens when the
// ActivityLog extension is registered for an event.
void AddObserver(Observer* observer);
Expand Down Expand Up @@ -145,12 +152,6 @@ class ActivityLog : public BrowserContextKeyedAPI,
// in prefs.
void UpdateCachedConsumerCount();

// ScriptExecutionObserver implementation.
// Fires when a ContentScript is executed.
void OnScriptsExecuted(const content::WebContents* web_contents,
const ExecutingScriptsMap& extension_ids,
const GURL& on_url) override;

// At the moment, ActivityLog will use only one policy for summarization.
// These methods are used to choose and set the most appropriate policy.
// Changing policies at runtime is not recommended, and likely only should be
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -255,11 +255,8 @@ TEST_F(ActivityLogTest, LogPrerender) {
content::WebContents *contents = contentses[0];
ASSERT_TRUE(prerender_manager->IsWebContentsPrerendering(contents, NULL));

ScriptExecutionObserver::ExecutingScriptsMap executing_scripts;
executing_scripts[extension->id()].insert("script");

static_cast<ScriptExecutionObserver*>(activity_log)
->OnScriptsExecuted(contents, executing_scripts, url);
activity_log->OnScriptsExecuted(contents, {{extension->id(), {"script"}}},
url);

activity_log->GetFilteredActions(
extension->id(), Action::ACTION_ANY, "", "", "", 0,
Expand Down
24 changes: 6 additions & 18 deletions chrome/browser/extensions/tab_helper.cc
Original file line number Diff line number Diff line change
Expand Up @@ -68,18 +68,15 @@ using content::WebContents;

namespace extensions {

TabHelper::~TabHelper() {
RemoveScriptExecutionObserver(ActivityLog::GetInstance(profile_));
}
TabHelper::~TabHelper() = default;

TabHelper::TabHelper(content::WebContents* web_contents)
: content::WebContentsObserver(web_contents),
profile_(Profile::FromBrowserContext(web_contents->GetBrowserContext())),
extension_app_(NULL),
pending_web_app_action_(NONE),
last_committed_nav_entry_unique_id_(0),
script_executor_(
new ScriptExecutor(web_contents, &script_execution_observers_)),
script_executor_(new ScriptExecutor(web_contents)),
extension_action_runner_(new ExtensionActionRunner(web_contents)),
registry_observer_(this),
image_loader_ptr_factory_(this),
Expand All @@ -93,7 +90,7 @@ TabHelper::TabHelper(content::WebContents* web_contents)
active_tab_permission_granter_.reset(new ActiveTabPermissionGranter(
web_contents, SessionTabHelper::IdForTab(web_contents).id(), profile_));

AddScriptExecutionObserver(ActivityLog::GetInstance(profile_));
ActivityLog::GetInstance(profile_)->ObserveScripts(script_executor_.get());

InvokeForContentRulesRegistries([this](ContentRulesRegistry* registry) {
registry->MonitorWebContentsForRuleEvaluation(this->web_contents());
Expand Down Expand Up @@ -124,15 +121,6 @@ bool TabHelper::CanCreateBookmarkApp() const {
IsValidBookmarkAppUrl(web_contents()->GetURL());
}

void TabHelper::AddScriptExecutionObserver(ScriptExecutionObserver* observer) {
script_execution_observers_.AddObserver(observer);
}

void TabHelper::RemoveScriptExecutionObserver(
ScriptExecutionObserver* observer) {
script_execution_observers_.RemoveObserver(observer);
}

void TabHelper::SetExtensionApp(const Extension* extension) {
DCHECK(!extension || AppLaunchInfo::GetFullLaunchURL(extension).is_valid());
if (extension_app_ == extension)
Expand Down Expand Up @@ -332,10 +320,10 @@ void TabHelper::OnGetAppInstallState(content::RenderFrameHost* host,

void TabHelper::OnContentScriptsExecuting(
content::RenderFrameHost* host,
const ScriptExecutionObserver::ExecutingScriptsMap& executing_scripts_map,
const ExecutingScriptsMap& executing_scripts_map,
const GURL& on_url) {
for (auto& observer : script_execution_observers_)
observer.OnScriptsExecuted(web_contents(), executing_scripts_map, on_url);
ActivityLog::GetInstance(profile_)->OnScriptsExecuted(
web_contents(), executing_scripts_map, on_url);
}

const Extension* TabHelper::GetExtension(const ExtensionId& extension_app_id) {
Expand Down
17 changes: 3 additions & 14 deletions chrome/browser/extensions/tab_helper.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
#include "content/public/browser/web_contents_user_data.h"
#include "extensions/browser/extension_function_dispatcher.h"
#include "extensions/browser/extension_registry_observer.h"
#include "extensions/browser/script_execution_observer.h"
#include "extensions/browser/script_executor.h"
#include "extensions/common/extension_id.h"
#include "extensions/common/stack_frame.h"
Expand Down Expand Up @@ -53,10 +52,6 @@ class TabHelper : public content::WebContentsObserver,
void CreateHostedAppFromWebContents(bool shortcut_app_requested);
bool CanCreateBookmarkApp() const;

// ScriptExecutionObserver::Delegate
virtual void AddScriptExecutionObserver(ScriptExecutionObserver* observer);
virtual void RemoveScriptExecutionObserver(ScriptExecutionObserver* observer);

// Sets the extension denoting this as an app. If |extension| is non-null this
// tab becomes an app-tab. WebContents does not listen for unload events for
// the extension. It's up to consumers of WebContents to do that.
Expand Down Expand Up @@ -146,10 +141,9 @@ class TabHelper : public content::WebContentsObserver,
const GURL& requestor_url,
int return_route_id,
int callback_id);
void OnContentScriptsExecuting(
content::RenderFrameHost* host,
const ScriptExecutionObserver::ExecutingScriptsMap& extension_ids,
const GURL& on_url);
void OnContentScriptsExecuting(content::RenderFrameHost* host,
const ExecutingScriptsMap& extension_ids,
const GURL& on_url);

// App extensions related methods:

Expand All @@ -171,11 +165,6 @@ class TabHelper : public content::WebContentsObserver,

Profile* profile_;

// Our content script observers. Declare at top so that it will outlive all
// other members, since they might add themselves as observers.
base::ObserverList<ScriptExecutionObserver>::Unchecked
script_execution_observers_;

// If non-null this tab is an app tab and this is the extension the tab was
// created for.
const Extension* extension_app_;
Expand Down
1 change: 0 additions & 1 deletion extensions/browser/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -316,7 +316,6 @@ jumbo_source_set("browser_sources") {
"runtime_data.h",
"sandboxed_unpacker.cc",
"sandboxed_unpacker.h",
"script_execution_observer.h",
"script_executor.cc",
"script_executor.h",
"serial_extension_host_queue.cc",
Expand Down
3 changes: 1 addition & 2 deletions extensions/browser/guest_view/web_view/web_view_guest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -399,8 +399,7 @@ void WebViewGuest::DidDropLink(const GURL& url) {
}

void WebViewGuest::DidInitialize(const base::DictionaryValue& create_params) {
script_executor_ =
std::make_unique<ScriptExecutor>(web_contents(), &script_observers_);
script_executor_ = std::make_unique<ScriptExecutor>(web_contents());

ExtensionsAPIClient::Get()->AttachWebContentsHelpers(web_contents());
web_view_permission_helper_ = std::make_unique<WebViewPermissionHelper>(this);
Expand Down
3 changes: 0 additions & 3 deletions extensions/browser/guest_view/web_view/web_view_guest.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
#include <vector>

#include "base/macros.h"
#include "base/observer_list.h"
#include "components/guest_view/browser/guest_view.h"
#include "content/public/browser/javascript_dialog_manager.h"
#include "extensions/browser/guest_view/web_view/javascript_dialog_helper.h"
Expand Down Expand Up @@ -321,8 +320,6 @@ class WebViewGuest : public guest_view::GuestView<WebViewGuest> {

// Handles find requests and replies for the webview find API.
WebViewFindHelper find_helper_;

base::ObserverList<ScriptExecutionObserver>::Unchecked script_observers_;
std::unique_ptr<ScriptExecutor> script_executor_;

// True if the user agent is overridden.
Expand Down
44 changes: 0 additions & 44 deletions extensions/browser/script_execution_observer.h

This file was deleted.

48 changes: 16 additions & 32 deletions extensions/browser/script_executor.cc
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,15 @@
#include <string>

#include "base/bind.h"
#include "base/callback.h"
#include "base/hash.h"
#include "base/logging.h"
#include "base/macros.h"
#include "base/pickle.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_observer.h"
#include "extensions/browser/extension_api_frame_id_map.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/browser/script_execution_observer.h"
#include "extensions/browser/url_loader_factory_manager.h"
#include "extensions/common/extension_messages.h"
#include "ipc/ipc_message.h"
Expand Down Expand Up @@ -54,15 +51,14 @@ const std::string GenerateInjectionKey(const HostID& host_id,
// corresponding response comes from the renderer, or the renderer is destroyed.
class Handler : public content::WebContentsObserver {
public:
Handler(
base::ObserverList<ScriptExecutionObserver>::Unchecked* script_observers,
content::WebContents* web_contents,
const ExtensionMsg_ExecuteCode_Params& params,
ScriptExecutor::FrameScope scope,
int frame_id,
const ScriptExecutor::ExecuteScriptCallback& callback)
Handler(ScriptsExecutedNotification observer,
content::WebContents* web_contents,
const ExtensionMsg_ExecuteCode_Params& params,
ScriptExecutor::FrameScope scope,
int frame_id,
const ScriptExecutor::ScriptFinishedCallback& callback)
: content::WebContentsObserver(web_contents),
script_observers_(AsWeakPtr(script_observers)),
observer_(std::move(observer)),
host_id_(params.host_id),
request_id_(params.request_id),
include_sub_frames_(scope == ScriptExecutor::INCLUDE_SUB_FRAMES),
Expand Down Expand Up @@ -184,21 +180,17 @@ class Handler : public content::WebContentsObserver {
results_.Clear();
}

if (script_observers_.get() && root_frame_error_.empty() &&
if (!observer_.is_null() && root_frame_error_.empty() &&
host_id_.type() == HostID::EXTENSIONS) {
ScriptExecutionObserver::ExecutingScriptsMap id_map;
id_map[host_id_.id()] = std::set<std::string>();
for (auto& observer : *script_observers_)
observer.OnScriptsExecuted(web_contents(), id_map, root_frame_url_);
observer_.Run(web_contents(), {{host_id_.id(), {}}}, root_frame_url_);
}

if (!callback_.is_null())
callback_.Run(root_frame_error_, root_frame_url_, results_);
delete this;
}

base::WeakPtr<base::ObserverList<ScriptExecutionObserver>::Unchecked>
script_observers_;
ScriptsExecutedNotification observer_;

// The id of the host (the extension or the webui) doing the injection.
HostID host_id_;
Expand Down Expand Up @@ -229,27 +221,19 @@ class Handler : public content::WebContentsObserver {
GURL root_frame_url_;

// The callback to run after all injections complete.
ScriptExecutor::ExecuteScriptCallback callback_;
ScriptExecutor::ScriptFinishedCallback callback_;

DISALLOW_COPY_AND_ASSIGN(Handler);
};

} // namespace

ScriptExecutionObserver::~ScriptExecutionObserver() {
}

ScriptExecutor::ScriptExecutor(
content::WebContents* web_contents,
base::ObserverList<ScriptExecutionObserver>::Unchecked* script_observers)
: next_request_id_(0),
web_contents_(web_contents),
script_observers_(script_observers) {
ScriptExecutor::ScriptExecutor(content::WebContents* web_contents)
: web_contents_(web_contents) {
CHECK(web_contents_);
}

ScriptExecutor::~ScriptExecutor() {
}
ScriptExecutor::~ScriptExecutor() {}

void ScriptExecutor::ExecuteScript(const HostID& host_id,
ScriptExecutor::ScriptType script_type,
Expand All @@ -265,7 +249,7 @@ void ScriptExecutor::ExecuteScript(const HostID& host_id,
bool user_gesture,
base::Optional<CSSOrigin> css_origin,
ScriptExecutor::ResultType result_type,
const ExecuteScriptCallback& callback) {
const ScriptFinishedCallback& callback) {
if (host_id.type() == HostID::EXTENSIONS) {
// Don't execute if the extension has been unloaded.
const Extension* extension =
Expand Down Expand Up @@ -298,7 +282,7 @@ void ScriptExecutor::ExecuteScript(const HostID& host_id,
params.injection_key = GenerateInjectionKey(host_id, file_url, code);

// Handler handles IPCs and deletes itself on completion.
new Handler(script_observers_, web_contents_, params, frame_scope, frame_id,
new Handler(observer_, web_contents_, params, frame_scope, frame_id,
callback);
}

Expand Down
Loading

0 comments on commit 8f733b9

Please sign in to comment.