[bfcache] Update IPC hash setting functionality in mojo and add unit tests + browser test for IPC tracking to frames in cache
Currently, IPC hash isn't set for tasks posted on the IO thread; adding IPC to SimpleWatcher when tasks are posted allows for the task posted on the IO thread to be annotated with an IPC hash, so that it can then be tracked in the histograms. ScopedSetIpcHash changes are to allow for tracking of IPCs posted from remote mojo objects. However, calculating the MD5 hash of a char* on every posted task is expensive, so we have also introduced storage of the IPC interface name. The IPC interface name can be used to calculate IPC hash on an as-needed basis (i.e. only in cases where IPC is posted to cached frames/documents). Also includes histogram testing to ensure metrics are recorded. and how ScopedSetIpcHash is set. Bug: 1110344 Change-Id: I26da160b65145f06639c33679ff03872f686e4af Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2345673 Commit-Queue: Harkiran Bolaria <hbolaria@google.com> Reviewed-by: François Doray <fdoray@chromium.org> Reviewed-by: Ken Rockot <rockot@google.com> Reviewed-by: Kentaro Hara <haraken@chromium.org> Reviewed-by: Alexander Timin <altimin@chromium.org> Cr-Commit-Position: refs/heads/master@{#807106}
This commit is contained in:

committed by
Commit Bot

parent
f1b030220f
commit
875dd0da93
base
content/browser
ipc
mojo/public/cpp
third_party/blink
common
public
common
renderer
platform
@@ -61,12 +61,12 @@ struct BASE_EXPORT PendingTask {
|
|||||||
// The context of the IPC message that was being handled when this task was
|
// The context of the IPC message that was being handled when this task was
|
||||||
// posted. This is a hash of the IPC message name that is set within the scope
|
// posted. This is a hash of the IPC message name that is set within the scope
|
||||||
// of an IPC handler and when symbolized uniquely identifies the message being
|
// of an IPC handler and when symbolized uniquely identifies the message being
|
||||||
// processed. This property is also propagated from one PendingTask to the
|
// processed. This property is not propagated from one PendingTask to the
|
||||||
// next. For example, if pending task A was posted while handling an IPC,
|
// next. For example, if pending task A was posted while handling an IPC,
|
||||||
// and pending task B was posted from within pending task A, then pending task
|
// and pending task B was posted from within pending task A, then pending task
|
||||||
// B will inherit the |ipc_hash| of pending task A. In some sense this can be
|
// B will not inherit the |ipc_hash| of pending task A.
|
||||||
// interpreted as a "root" task backtrace frame.
|
|
||||||
uint32_t ipc_hash = 0;
|
uint32_t ipc_hash = 0;
|
||||||
|
const char* ipc_interface_name = nullptr;
|
||||||
|
|
||||||
// Secondary sort key for run time.
|
// Secondary sort key for run time.
|
||||||
int sequence_num = 0;
|
int sequence_num = 0;
|
||||||
|
@@ -6,9 +6,12 @@
|
|||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
|
|
||||||
|
#include "base/check_op.h"
|
||||||
#include "base/debug/activity_tracker.h"
|
#include "base/debug/activity_tracker.h"
|
||||||
#include "base/debug/alias.h"
|
#include "base/debug/alias.h"
|
||||||
|
#include "base/hash/md5.h"
|
||||||
#include "base/no_destructor.h"
|
#include "base/no_destructor.h"
|
||||||
|
#include "base/sys_byteorder.h"
|
||||||
#include "base/threading/thread_local.h"
|
#include "base/threading/thread_local.h"
|
||||||
#include "base/trace_event/base_tracing.h"
|
#include "base/trace_event/base_tracing.h"
|
||||||
|
|
||||||
@@ -30,6 +33,17 @@ ThreadLocalPointer<PendingTask>* GetTLSForCurrentPendingTask() {
|
|||||||
return instance.get();
|
return instance.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Returns the TLS slot that stores scoped IPC-related data (IPC hash and/or
|
||||||
|
// IPC interface name). IPC hash or interface name can be known before the
|
||||||
|
// associated task object is created; store in the TLS so that this data can be
|
||||||
|
// affixed to the associated task.
|
||||||
|
ThreadLocalPointer<TaskAnnotator::ScopedSetIpcHash>*
|
||||||
|
GetTLSForCurrentScopedIpcHash() {
|
||||||
|
static NoDestructor<ThreadLocalPointer<TaskAnnotator::ScopedSetIpcHash>>
|
||||||
|
instance;
|
||||||
|
return instance.get();
|
||||||
|
}
|
||||||
|
|
||||||
// Determines whether or not the given |task| is a dummy pending task that has
|
// Determines whether or not the given |task| is a dummy pending task that has
|
||||||
// been injected by ScopedSetIpcHash solely for the purposes of
|
// been injected by ScopedSetIpcHash solely for the purposes of
|
||||||
// tracking IPC context.
|
// tracking IPC context.
|
||||||
@@ -49,7 +63,7 @@ const PendingTask* TaskAnnotator::CurrentTaskForThread() {
|
|||||||
|
|
||||||
// Don't return "dummy" current tasks that are only used for storing IPC
|
// Don't return "dummy" current tasks that are only used for storing IPC
|
||||||
// context.
|
// context.
|
||||||
if (current_task && IsDummyPendingTask(current_task))
|
if (!current_task || (current_task && IsDummyPendingTask(current_task)))
|
||||||
return nullptr;
|
return nullptr;
|
||||||
return current_task;
|
return current_task;
|
||||||
}
|
}
|
||||||
@@ -74,11 +88,18 @@ void TaskAnnotator::WillQueueTask(const char* trace_event_name,
|
|||||||
if (pending_task->task_backtrace[0])
|
if (pending_task->task_backtrace[0])
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
DCHECK(!pending_task->ipc_interface_name);
|
||||||
|
DCHECK(!pending_task->ipc_hash);
|
||||||
|
auto* current_ipc_hash = GetTLSForCurrentScopedIpcHash()->Get();
|
||||||
|
if (current_ipc_hash) {
|
||||||
|
pending_task->ipc_interface_name = current_ipc_hash->GetIpcInterfaceName();
|
||||||
|
pending_task->ipc_hash = current_ipc_hash->GetIpcHash();
|
||||||
|
}
|
||||||
|
|
||||||
const auto* parent_task = CurrentTaskForThread();
|
const auto* parent_task = CurrentTaskForThread();
|
||||||
if (!parent_task)
|
if (!parent_task)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
pending_task->ipc_hash = parent_task->ipc_hash;
|
|
||||||
pending_task->task_backtrace[0] = parent_task->posted_from.program_counter();
|
pending_task->task_backtrace[0] = parent_task->posted_from.program_counter();
|
||||||
std::copy(parent_task->task_backtrace.begin(),
|
std::copy(parent_task->task_backtrace.begin(),
|
||||||
parent_task->task_backtrace.end() - 1,
|
parent_task->task_backtrace.end() - 1,
|
||||||
@@ -170,31 +191,42 @@ void TaskAnnotator::ClearObserverForTesting() {
|
|||||||
g_task_annotator_observer = nullptr;
|
g_task_annotator_observer = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
TaskAnnotator::ScopedSetIpcHash::ScopedSetIpcHash(uint32_t ipc_hash) {
|
TaskAnnotator::ScopedSetIpcHash::ScopedSetIpcHash(uint32_t ipc_hash)
|
||||||
// We store the IPC context in the currently running task. If there is none
|
: ScopedSetIpcHash(ipc_hash, nullptr) {}
|
||||||
// then introduce a dummy task.
|
|
||||||
auto* tls = GetTLSForCurrentPendingTask();
|
|
||||||
auto* current_task = tls->Get();
|
|
||||||
if (!current_task) {
|
|
||||||
dummy_pending_task_ = std::make_unique<PendingTask>();
|
|
||||||
dummy_pending_task_->sequence_num = kSentinelSequenceNum;
|
|
||||||
current_task = dummy_pending_task_.get();
|
|
||||||
tls->Set(current_task);
|
|
||||||
}
|
|
||||||
|
|
||||||
old_ipc_hash_ = current_task->ipc_hash;
|
TaskAnnotator::ScopedSetIpcHash::ScopedSetIpcHash(
|
||||||
current_task->ipc_hash = ipc_hash;
|
const char* ipc_interface_name)
|
||||||
|
: ScopedSetIpcHash(0, ipc_interface_name) {}
|
||||||
|
|
||||||
|
TaskAnnotator::ScopedSetIpcHash::ScopedSetIpcHash(
|
||||||
|
uint32_t ipc_hash,
|
||||||
|
const char* ipc_interface_name) {
|
||||||
|
TRACE_EVENT_BEGIN2("base", "ScopedSetIpcHash", "ipc_hash", ipc_hash,
|
||||||
|
"ipc_interface_name", ipc_interface_name);
|
||||||
|
auto* tls_ipc_hash = GetTLSForCurrentScopedIpcHash();
|
||||||
|
auto* current_ipc_hash = tls_ipc_hash->Get();
|
||||||
|
old_scoped_ipc_hash_ = current_ipc_hash;
|
||||||
|
ipc_hash_ = ipc_hash;
|
||||||
|
ipc_interface_name_ = ipc_interface_name;
|
||||||
|
tls_ipc_hash->Set(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Static
|
||||||
|
uint32_t TaskAnnotator::ScopedSetIpcHash::MD5HashMetricName(
|
||||||
|
base::StringPiece name) {
|
||||||
|
base::MD5Digest digest;
|
||||||
|
base::MD5Sum(name.data(), name.size(), &digest);
|
||||||
|
uint32_t value;
|
||||||
|
DCHECK_GE(sizeof(digest.a), sizeof(value));
|
||||||
|
memcpy(&value, digest.a, sizeof(value));
|
||||||
|
return base::NetToHost32(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
TaskAnnotator::ScopedSetIpcHash::~ScopedSetIpcHash() {
|
TaskAnnotator::ScopedSetIpcHash::~ScopedSetIpcHash() {
|
||||||
auto* tls = GetTLSForCurrentPendingTask();
|
auto* tls_ipc_hash = GetTLSForCurrentScopedIpcHash();
|
||||||
auto* current_task = tls->Get();
|
DCHECK_EQ(this, tls_ipc_hash->Get());
|
||||||
DCHECK(current_task);
|
tls_ipc_hash->Set(old_scoped_ipc_hash_);
|
||||||
if (current_task == dummy_pending_task_.get()) {
|
TRACE_EVENT_END0("base", "ScopedSetIpcHash");
|
||||||
tls->Set(nullptr);
|
|
||||||
} else {
|
|
||||||
current_task->ipc_hash = old_ipc_hash_;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace base
|
} // namespace base
|
||||||
|
@@ -13,6 +13,7 @@
|
|||||||
#include "base/compiler_specific.h"
|
#include "base/compiler_specific.h"
|
||||||
#include "base/macros.h"
|
#include "base/macros.h"
|
||||||
#include "base/pending_task.h"
|
#include "base/pending_task.h"
|
||||||
|
#include "base/strings/string_piece.h"
|
||||||
|
|
||||||
namespace base {
|
namespace base {
|
||||||
|
|
||||||
@@ -71,11 +72,22 @@ class BASE_EXPORT TaskAnnotator {
|
|||||||
class BASE_EXPORT TaskAnnotator::ScopedSetIpcHash {
|
class BASE_EXPORT TaskAnnotator::ScopedSetIpcHash {
|
||||||
public:
|
public:
|
||||||
explicit ScopedSetIpcHash(uint32_t ipc_hash);
|
explicit ScopedSetIpcHash(uint32_t ipc_hash);
|
||||||
|
|
||||||
|
// Compile-time-const string identifying the current IPC context. Not always
|
||||||
|
// available due to binary size constraints, so IPC hash might be set instead.
|
||||||
|
explicit ScopedSetIpcHash(const char* ipc_interface_name);
|
||||||
~ScopedSetIpcHash();
|
~ScopedSetIpcHash();
|
||||||
|
|
||||||
|
uint32_t GetIpcHash() const { return ipc_hash_; }
|
||||||
|
const char* GetIpcInterfaceName() const { return ipc_interface_name_; }
|
||||||
|
|
||||||
|
static uint32_t MD5HashMetricName(base::StringPiece name);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<PendingTask> dummy_pending_task_;
|
ScopedSetIpcHash(uint32_t ipc_hash, const char* ipc_interface_name);
|
||||||
uint32_t old_ipc_hash_ = 0;
|
ScopedSetIpcHash* old_scoped_ipc_hash_ = nullptr;
|
||||||
|
uint32_t ipc_hash_ = 0;
|
||||||
|
const char* ipc_interface_name_ = nullptr;
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(ScopedSetIpcHash);
|
DISALLOW_COPY_AND_ASSIGN(ScopedSetIpcHash);
|
||||||
};
|
};
|
||||||
|
@@ -165,7 +165,8 @@ TEST_F(TaskAnnotatorBacktraceIntegrationTest, SingleThreadedSimple) {
|
|||||||
RunLoop run_loop;
|
RunLoop run_loop;
|
||||||
|
|
||||||
// Task 0 executes with no IPC context. Task 1 executes under an explicitly
|
// Task 0 executes with no IPC context. Task 1 executes under an explicitly
|
||||||
// set IPC context, and tasks 2-5 inherit that context.
|
// set IPC context. Tasks 2-5 don't necessarily inherit that context, as
|
||||||
|
// IPCs may spawn subtasks that aren't necessarily IPCs themselves.
|
||||||
|
|
||||||
// Task 5 has tasks 4/3/2/1 as parents (task 0 isn't visible as only the
|
// Task 5 has tasks 4/3/2/1 as parents (task 0 isn't visible as only the
|
||||||
// last 4 parents are kept).
|
// last 4 parents are kept).
|
||||||
@@ -174,7 +175,7 @@ TEST_F(TaskAnnotatorBacktraceIntegrationTest, SingleThreadedSimple) {
|
|||||||
Unretained(this), ThreadTaskRunnerHandle::Get(), location5, FROM_HERE,
|
Unretained(this), ThreadTaskRunnerHandle::Get(), location5, FROM_HERE,
|
||||||
ExpectedTrace({location4.program_counter(), location3.program_counter(),
|
ExpectedTrace({location4.program_counter(), location3.program_counter(),
|
||||||
location2.program_counter(), location1.program_counter()}),
|
location2.program_counter(), location1.program_counter()}),
|
||||||
dummy_ipc_hash, run_loop.QuitClosure());
|
0, run_loop.QuitClosure());
|
||||||
|
|
||||||
// Task i=4/3/2/1/0 have tasks [0,i) as parents.
|
// Task i=4/3/2/1/0 have tasks [0,i) as parents.
|
||||||
OnceClosure task4 = BindOnce(
|
OnceClosure task4 = BindOnce(
|
||||||
@@ -182,13 +183,13 @@ TEST_F(TaskAnnotatorBacktraceIntegrationTest, SingleThreadedSimple) {
|
|||||||
Unretained(this), ThreadTaskRunnerHandle::Get(), location4, location5,
|
Unretained(this), ThreadTaskRunnerHandle::Get(), location4, location5,
|
||||||
ExpectedTrace({location3.program_counter(), location2.program_counter(),
|
ExpectedTrace({location3.program_counter(), location2.program_counter(),
|
||||||
location1.program_counter(), location0.program_counter()}),
|
location1.program_counter(), location0.program_counter()}),
|
||||||
dummy_ipc_hash, std::move(task5));
|
0, std::move(task5));
|
||||||
OnceClosure task3 = BindOnce(
|
OnceClosure task3 = BindOnce(
|
||||||
&TaskAnnotatorBacktraceIntegrationTest::VerifyTraceAndPost,
|
&TaskAnnotatorBacktraceIntegrationTest::VerifyTraceAndPost,
|
||||||
Unretained(this), ThreadTaskRunnerHandle::Get(), location3, location4,
|
Unretained(this), ThreadTaskRunnerHandle::Get(), location3, location4,
|
||||||
ExpectedTrace({location2.program_counter(), location1.program_counter(),
|
ExpectedTrace({location2.program_counter(), location1.program_counter(),
|
||||||
location0.program_counter()}),
|
location0.program_counter()}),
|
||||||
dummy_ipc_hash, std::move(task4));
|
0, std::move(task4));
|
||||||
OnceClosure task2 = BindOnce(
|
OnceClosure task2 = BindOnce(
|
||||||
&TaskAnnotatorBacktraceIntegrationTest::VerifyTraceAndPost,
|
&TaskAnnotatorBacktraceIntegrationTest::VerifyTraceAndPost,
|
||||||
Unretained(this), ThreadTaskRunnerHandle::Get(), location2, location3,
|
Unretained(this), ThreadTaskRunnerHandle::Get(), location2, location3,
|
||||||
@@ -359,19 +360,19 @@ TEST_F(TaskAnnotatorBacktraceIntegrationTest, SingleThreadedNested) {
|
|||||||
Unretained(this), ThreadTaskRunnerHandle::Get(), location5, FROM_HERE,
|
Unretained(this), ThreadTaskRunnerHandle::Get(), location5, FROM_HERE,
|
||||||
ExpectedTrace({location4.program_counter(), location3.program_counter(),
|
ExpectedTrace({location4.program_counter(), location3.program_counter(),
|
||||||
location2.program_counter(), location1.program_counter()}),
|
location2.program_counter(), location1.program_counter()}),
|
||||||
dummy_ipc_hash, run_loop.QuitClosure());
|
0, run_loop.QuitClosure());
|
||||||
OnceClosure task4 = BindOnce(
|
OnceClosure task4 = BindOnce(
|
||||||
&TaskAnnotatorBacktraceIntegrationTest::VerifyTraceAndPost,
|
&TaskAnnotatorBacktraceIntegrationTest::VerifyTraceAndPost,
|
||||||
Unretained(this), ThreadTaskRunnerHandle::Get(), location4, location5,
|
Unretained(this), ThreadTaskRunnerHandle::Get(), location4, location5,
|
||||||
ExpectedTrace({location3.program_counter(), location2.program_counter(),
|
ExpectedTrace({location3.program_counter(), location2.program_counter(),
|
||||||
location1.program_counter(), location0.program_counter()}),
|
location1.program_counter(), location0.program_counter()}),
|
||||||
dummy_ipc_hash, std::move(task5));
|
0, std::move(task5));
|
||||||
OnceClosure task3 = BindOnce(
|
OnceClosure task3 = BindOnce(
|
||||||
&TaskAnnotatorBacktraceIntegrationTest::VerifyTraceAndPost,
|
&TaskAnnotatorBacktraceIntegrationTest::VerifyTraceAndPost,
|
||||||
Unretained(this), ThreadTaskRunnerHandle::Get(), location3, location4,
|
Unretained(this), ThreadTaskRunnerHandle::Get(), location3, location4,
|
||||||
ExpectedTrace({location2.program_counter(), location1.program_counter(),
|
ExpectedTrace({location2.program_counter(), location1.program_counter(),
|
||||||
location0.program_counter()}),
|
location0.program_counter()}),
|
||||||
dummy_ipc_hash, std::move(task4));
|
0, std::move(task4));
|
||||||
|
|
||||||
OnceClosure run_task_3_then_quit_nested_loop1 =
|
OnceClosure run_task_3_then_quit_nested_loop1 =
|
||||||
BindOnce(&TaskAnnotatorBacktraceIntegrationTest::RunTwo, std::move(task3),
|
BindOnce(&TaskAnnotatorBacktraceIntegrationTest::RunTwo, std::move(task3),
|
||||||
@@ -381,7 +382,7 @@ TEST_F(TaskAnnotatorBacktraceIntegrationTest, SingleThreadedNested) {
|
|||||||
&TaskAnnotatorBacktraceIntegrationTest::VerifyTraceAndPost,
|
&TaskAnnotatorBacktraceIntegrationTest::VerifyTraceAndPost,
|
||||||
Unretained(this), ThreadTaskRunnerHandle::Get(), location2, location3,
|
Unretained(this), ThreadTaskRunnerHandle::Get(), location2, location3,
|
||||||
ExpectedTrace({location1.program_counter(), location0.program_counter()}),
|
ExpectedTrace({location1.program_counter(), location0.program_counter()}),
|
||||||
dummy_ipc_hash, std::move(run_task_3_then_quit_nested_loop1));
|
0, std::move(run_task_3_then_quit_nested_loop1));
|
||||||
|
|
||||||
// Task 1 is custom. It enters another nested RunLoop, has it do work and exit
|
// Task 1 is custom. It enters another nested RunLoop, has it do work and exit
|
||||||
// before posting the next task. This confirms that |task1| is restored as the
|
// before posting the next task. This confirms that |task1| is restored as the
|
||||||
|
@@ -15,6 +15,7 @@
|
|||||||
#include "base/run_loop.h"
|
#include "base/run_loop.h"
|
||||||
#include "base/strings/string_piece_forward.h"
|
#include "base/strings/string_piece_forward.h"
|
||||||
#include "base/system/sys_info.h"
|
#include "base/system/sys_info.h"
|
||||||
|
#include "base/task/common/task_annotator.h"
|
||||||
#include "base/task/post_task.h"
|
#include "base/task/post_task.h"
|
||||||
#include "base/test/bind_test_util.h"
|
#include "base/test/bind_test_util.h"
|
||||||
#include "base/test/scoped_feature_list.h"
|
#include "base/test/scoped_feature_list.h"
|
||||||
@@ -78,6 +79,7 @@
|
|||||||
#include "services/device/public/mojom/vibration_manager.mojom.h"
|
#include "services/device/public/mojom/vibration_manager.mojom.h"
|
||||||
#include "services/service_manager/public/cpp/interface_provider.h"
|
#include "services/service_manager/public/cpp/interface_provider.h"
|
||||||
#include "testing/gmock/include/gmock/gmock.h"
|
#include "testing/gmock/include/gmock/gmock.h"
|
||||||
|
#include "third_party/blink/public/common/features.h"
|
||||||
#include "third_party/blink/public/common/scheduler/web_scheduler_tracked_feature.h"
|
#include "third_party/blink/public/common/scheduler/web_scheduler_tracked_feature.h"
|
||||||
#include "third_party/blink/public/mojom/app_banner/app_banner.mojom.h"
|
#include "third_party/blink/public/mojom/app_banner/app_banner.mojom.h"
|
||||||
|
|
||||||
@@ -152,6 +154,9 @@ class BackForwardCacheBrowserTest : public ContentBrowserTest,
|
|||||||
EnableFeatureAndSetParams(
|
EnableFeatureAndSetParams(
|
||||||
features::kBackForwardCache, "skip_same_site_if_unload_exists",
|
features::kBackForwardCache, "skip_same_site_if_unload_exists",
|
||||||
skip_same_site_if_unload_exists_ ? "true" : "false");
|
skip_same_site_if_unload_exists_ ? "true" : "false");
|
||||||
|
EnableFeatureAndSetParams(
|
||||||
|
blink::features::kLogUnexpectedIPCPostedToBackForwardCachedDocuments,
|
||||||
|
"delay_before_tracking_ms", "0");
|
||||||
#if defined(OS_ANDROID)
|
#if defined(OS_ANDROID)
|
||||||
EnableFeatureAndSetParams(features::kBackForwardCache,
|
EnableFeatureAndSetParams(features::kBackForwardCache,
|
||||||
"process_binding_strength", "NORMAL");
|
"process_binding_strength", "NORMAL");
|
||||||
@@ -2332,6 +2337,46 @@ IN_PROC_BROWSER_TEST_F(BackForwardCacheBrowserTest,
|
|||||||
blink::scheduler::WebSchedulerTrackedFeature::kKeyboardLock, FROM_HERE);
|
blink::scheduler::WebSchedulerTrackedFeature::kKeyboardLock, FROM_HERE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IN_PROC_BROWSER_TEST_F(BackForwardCacheBrowserTest, LogIpcPostedToCachedFrame) {
|
||||||
|
ASSERT_TRUE(embedded_test_server()->Start());
|
||||||
|
|
||||||
|
// 1) Navigate to a page.
|
||||||
|
GURL url(embedded_test_server()->GetURL("/title1.html"));
|
||||||
|
EXPECT_TRUE(NavigateToURL(shell(), url));
|
||||||
|
RenderFrameHostImpl* rfh_a = current_frame_host();
|
||||||
|
|
||||||
|
// 2) Navigate away. The first page should be in the cache.
|
||||||
|
EXPECT_TRUE(NavigateToURL(
|
||||||
|
shell(), embedded_test_server()->GetURL("b.com", "/title1.html")));
|
||||||
|
|
||||||
|
// 3) Post IPC tasks to the page, testing both mojo remote and associated
|
||||||
|
// remote objects.
|
||||||
|
|
||||||
|
// TODO(hbolaria) - implement non-frame-associated tracking, which will be
|
||||||
|
// used by the code below.
|
||||||
|
|
||||||
|
// Post a non-associated interface. Will be routed to a frame-specific task
|
||||||
|
// queue with IPC set in SimpleWatcher.
|
||||||
|
base::RunLoop run_loop;
|
||||||
|
rfh_a->GetHighPriorityLocalFrame()->DispatchBeforeUnload(
|
||||||
|
false,
|
||||||
|
base::BindOnce([](base::RepeatingClosure quit_closure, bool proceed,
|
||||||
|
base::TimeTicks start_time,
|
||||||
|
base::TimeTicks end_time) { quit_closure.Run(); },
|
||||||
|
run_loop.QuitClosure()));
|
||||||
|
run_loop.Run();
|
||||||
|
|
||||||
|
// 4) Check the histogram.
|
||||||
|
FetchHistogramsFromChildProcesses();
|
||||||
|
base::HistogramBase::Sample sample = base::HistogramBase::Sample(
|
||||||
|
base::TaskAnnotator::ScopedSetIpcHash::MD5HashMetricName(
|
||||||
|
"blink.mojom.HighPriorityLocalFrame"));
|
||||||
|
histogram_tester_.ExpectUniqueSample(
|
||||||
|
"BackForwardCache.Experimental."
|
||||||
|
"UnexpectedIPCMessagePostedToCachedFrame.MethodHash",
|
||||||
|
sample, 1);
|
||||||
|
}
|
||||||
|
|
||||||
class MockAppBannerService : public blink::mojom::AppBannerService {
|
class MockAppBannerService : public blink::mojom::AppBannerService {
|
||||||
public:
|
public:
|
||||||
MockAppBannerService() = default;
|
MockAppBannerService() = default;
|
||||||
|
@@ -165,15 +165,14 @@ class ChannelAssociatedGroupController
|
|||||||
DCHECK(thread_checker_.CalledOnValidThread());
|
DCHECK(thread_checker_.CalledOnValidThread());
|
||||||
DCHECK(task_runner_->BelongsToCurrentThread());
|
DCHECK(task_runner_->BelongsToCurrentThread());
|
||||||
|
|
||||||
connector_.reset(new mojo::Connector(
|
connector_ = std::make_unique<mojo::Connector>(
|
||||||
std::move(handle), mojo::Connector::SINGLE_THREADED_SEND,
|
std::move(handle), mojo::Connector::SINGLE_THREADED_SEND, task_runner_,
|
||||||
task_runner_));
|
"IPC Channel");
|
||||||
connector_->set_incoming_receiver(&dispatcher_);
|
connector_->set_incoming_receiver(&dispatcher_);
|
||||||
connector_->set_connection_error_handler(
|
connector_->set_connection_error_handler(
|
||||||
base::BindOnce(&ChannelAssociatedGroupController::OnPipeError,
|
base::BindOnce(&ChannelAssociatedGroupController::OnPipeError,
|
||||||
base::Unretained(this)));
|
base::Unretained(this)));
|
||||||
connector_->set_enforce_errors_from_incoming_receiver(false);
|
connector_->set_enforce_errors_from_incoming_receiver(false);
|
||||||
connector_->SetWatcherHeapProfilerTag("IPC Channel");
|
|
||||||
if (quota_checker_)
|
if (quota_checker_)
|
||||||
connector_->SetMessageQuotaChecker(quota_checker_);
|
connector_->SetMessageQuotaChecker(quota_checker_);
|
||||||
|
|
||||||
|
@@ -84,7 +84,8 @@ class COMPONENT_EXPORT(MOJO_CPP_BINDINGS) Connector : public MessageReceiver {
|
|||||||
// The Connector takes ownership of |message_pipe|.
|
// The Connector takes ownership of |message_pipe|.
|
||||||
Connector(ScopedMessagePipeHandle message_pipe,
|
Connector(ScopedMessagePipeHandle message_pipe,
|
||||||
ConnectorConfig config,
|
ConnectorConfig config,
|
||||||
scoped_refptr<base::SequencedTaskRunner> runner);
|
scoped_refptr<base::SequencedTaskRunner> runner,
|
||||||
|
const char* heap_profiler_tag = "unknown interface");
|
||||||
~Connector() override;
|
~Connector() override;
|
||||||
|
|
||||||
// Sets outgoing serialization mode.
|
// Sets outgoing serialization mode.
|
||||||
@@ -193,10 +194,6 @@ class COMPONENT_EXPORT(MOJO_CPP_BINDINGS) Connector : public MessageReceiver {
|
|||||||
|
|
||||||
base::SequencedTaskRunner* task_runner() const { return task_runner_.get(); }
|
base::SequencedTaskRunner* task_runner() const { return task_runner_.get(); }
|
||||||
|
|
||||||
// Sets the tag used by the heap profiler.
|
|
||||||
// |tag| must be a const string literal.
|
|
||||||
void SetWatcherHeapProfilerTag(const char* tag);
|
|
||||||
|
|
||||||
// Sets the quota checker.
|
// Sets the quota checker.
|
||||||
void SetMessageQuotaChecker(
|
void SetMessageQuotaChecker(
|
||||||
scoped_refptr<internal::MessageQuotaChecker> checker);
|
scoped_refptr<internal::MessageQuotaChecker> checker);
|
||||||
|
@@ -120,8 +120,7 @@ void BindingStateBase::BindInternal(
|
|||||||
? MultiplexRouter::SINGLE_INTERFACE_WITH_SYNC_METHODS
|
? MultiplexRouter::SINGLE_INTERFACE_WITH_SYNC_METHODS
|
||||||
: MultiplexRouter::SINGLE_INTERFACE);
|
: MultiplexRouter::SINGLE_INTERFACE);
|
||||||
router_ = new MultiplexRouter(std::move(receiver_state->pipe), config, false,
|
router_ = new MultiplexRouter(std::move(receiver_state->pipe), config, false,
|
||||||
sequenced_runner);
|
sequenced_runner, interface_name);
|
||||||
router_->SetPrimaryInterfaceName(interface_name);
|
|
||||||
router_->SetConnectionGroup(std::move(receiver_state->connection_group));
|
router_->SetConnectionGroup(std::move(receiver_state->connection_group));
|
||||||
|
|
||||||
endpoint_client_.reset(new InterfaceEndpointClient(
|
endpoint_client_.reset(new InterfaceEndpointClient(
|
||||||
|
@@ -144,13 +144,15 @@ void Connector::ActiveDispatchTracker::NotifyBeginNesting() {
|
|||||||
|
|
||||||
Connector::Connector(ScopedMessagePipeHandle message_pipe,
|
Connector::Connector(ScopedMessagePipeHandle message_pipe,
|
||||||
ConnectorConfig config,
|
ConnectorConfig config,
|
||||||
scoped_refptr<base::SequencedTaskRunner> runner)
|
scoped_refptr<base::SequencedTaskRunner> runner,
|
||||||
|
const char* heap_profiler_tag)
|
||||||
: message_pipe_(std::move(message_pipe)),
|
: message_pipe_(std::move(message_pipe)),
|
||||||
task_runner_(std::move(runner)),
|
task_runner_(std::move(runner)),
|
||||||
error_(false),
|
error_(false),
|
||||||
force_immediate_dispatch_(!EnableTaskPerMessage()),
|
force_immediate_dispatch_(!EnableTaskPerMessage()),
|
||||||
outgoing_serialization_mode_(g_default_outgoing_serialization_mode),
|
outgoing_serialization_mode_(g_default_outgoing_serialization_mode),
|
||||||
incoming_serialization_mode_(g_default_incoming_serialization_mode),
|
incoming_serialization_mode_(g_default_incoming_serialization_mode),
|
||||||
|
heap_profiler_tag_(heap_profiler_tag),
|
||||||
nesting_observer_(RunLoopNestingObserver::GetForThread()) {
|
nesting_observer_(RunLoopNestingObserver::GetForThread()) {
|
||||||
if (config == MULTI_THREADED_SEND)
|
if (config == MULTI_THREADED_SEND)
|
||||||
lock_.emplace();
|
lock_.emplace();
|
||||||
@@ -351,14 +353,6 @@ void Connector::AllowWokenUpBySyncWatchOnSameThread() {
|
|||||||
sync_watcher_->AllowWokenUpBySyncWatchOnSameThread();
|
sync_watcher_->AllowWokenUpBySyncWatchOnSameThread();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Connector::SetWatcherHeapProfilerTag(const char* tag) {
|
|
||||||
if (tag) {
|
|
||||||
heap_profiler_tag_ = tag;
|
|
||||||
if (handle_watcher_)
|
|
||||||
handle_watcher_->set_heap_profiler_tag(tag);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Connector::SetMessageQuotaChecker(
|
void Connector::SetMessageQuotaChecker(
|
||||||
scoped_refptr<internal::MessageQuotaChecker> checker) {
|
scoped_refptr<internal::MessageQuotaChecker> checker) {
|
||||||
DCHECK(checker && !quota_checker_);
|
DCHECK(checker && !quota_checker_);
|
||||||
@@ -414,9 +408,9 @@ void Connector::WaitToReadMore() {
|
|||||||
DCHECK(!handle_watcher_);
|
DCHECK(!handle_watcher_);
|
||||||
|
|
||||||
DCHECK(task_runner_->RunsTasksInCurrentSequence());
|
DCHECK(task_runner_->RunsTasksInCurrentSequence());
|
||||||
handle_watcher_.reset(new SimpleWatcher(
|
handle_watcher_ = std::make_unique<SimpleWatcher>(
|
||||||
FROM_HERE, SimpleWatcher::ArmingPolicy::MANUAL, task_runner_));
|
FROM_HERE, SimpleWatcher::ArmingPolicy::MANUAL, task_runner_,
|
||||||
handle_watcher_->set_heap_profiler_tag(heap_profiler_tag_);
|
heap_profiler_tag_);
|
||||||
MojoResult rv = handle_watcher_->Watch(
|
MojoResult rv = handle_watcher_->Watch(
|
||||||
message_pipe_.get(), MOJO_HANDLE_SIGNAL_READABLE,
|
message_pipe_.get(), MOJO_HANDLE_SIGNAL_READABLE,
|
||||||
base::BindRepeating(&Connector::OnWatcherHandleReady,
|
base::BindRepeating(&Connector::OnWatcherHandleReady,
|
||||||
|
@@ -90,13 +90,14 @@ bool InterfacePtrStateBase::InitializeEndpointClient(
|
|||||||
? MultiplexRouter::SINGLE_INTERFACE_WITH_SYNC_METHODS
|
? MultiplexRouter::SINGLE_INTERFACE_WITH_SYNC_METHODS
|
||||||
: MultiplexRouter::SINGLE_INTERFACE);
|
: MultiplexRouter::SINGLE_INTERFACE);
|
||||||
DCHECK(runner_->RunsTasksInCurrentSequence());
|
DCHECK(runner_->RunsTasksInCurrentSequence());
|
||||||
router_ = new MultiplexRouter(std::move(handle_), config, true, runner_);
|
router_ = new MultiplexRouter(std::move(handle_), config, true, runner_,
|
||||||
endpoint_client_.reset(new InterfaceEndpointClient(
|
interface_name);
|
||||||
|
endpoint_client_ = std::make_unique<InterfaceEndpointClient>(
|
||||||
router_->CreateLocalEndpointHandle(kPrimaryInterfaceId), nullptr,
|
router_->CreateLocalEndpointHandle(kPrimaryInterfaceId), nullptr,
|
||||||
std::move(payload_validator), false, std::move(runner_),
|
std::move(payload_validator), false, std::move(runner_),
|
||||||
// The version is only queried from the client so the value passed here
|
// The version is only queried from the client so the value passed here
|
||||||
// will not be used.
|
// will not be used.
|
||||||
0u, interface_name));
|
0u, interface_name);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -260,7 +260,6 @@ class InterfacePtrState : public InterfacePtrStateBase {
|
|||||||
Interface::PassesAssociatedKinds_, Interface::HasSyncMethods_,
|
Interface::PassesAssociatedKinds_, Interface::HasSyncMethods_,
|
||||||
std::make_unique<typename Interface::ResponseValidator_>(),
|
std::make_unique<typename Interface::ResponseValidator_>(),
|
||||||
Interface::Name_)) {
|
Interface::Name_)) {
|
||||||
router()->SetPrimaryInterfaceName(Interface::Name_);
|
|
||||||
proxy_ = std::make_unique<Proxy>(endpoint_client());
|
proxy_ = std::make_unique<Proxy>(endpoint_client());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -14,6 +14,7 @@
|
|||||||
#include "base/memory/ptr_util.h"
|
#include "base/memory/ptr_util.h"
|
||||||
#include "base/sequenced_task_runner.h"
|
#include "base/sequenced_task_runner.h"
|
||||||
#include "base/stl_util.h"
|
#include "base/stl_util.h"
|
||||||
|
#include "base/strings/string_util.h"
|
||||||
#include "base/synchronization/waitable_event.h"
|
#include "base/synchronization/waitable_event.h"
|
||||||
#include "mojo/public/cpp/bindings/interface_endpoint_client.h"
|
#include "mojo/public/cpp/bindings/interface_endpoint_client.h"
|
||||||
#include "mojo/public/cpp/bindings/interface_endpoint_controller.h"
|
#include "mojo/public/cpp/bindings/interface_endpoint_controller.h"
|
||||||
@@ -315,14 +316,16 @@ MultiplexRouter::MultiplexRouter(
|
|||||||
ScopedMessagePipeHandle message_pipe,
|
ScopedMessagePipeHandle message_pipe,
|
||||||
Config config,
|
Config config,
|
||||||
bool set_interface_id_namespace_bit,
|
bool set_interface_id_namespace_bit,
|
||||||
scoped_refptr<base::SequencedTaskRunner> runner)
|
scoped_refptr<base::SequencedTaskRunner> runner,
|
||||||
|
const char* primary_interface_name)
|
||||||
: set_interface_id_namespace_bit_(set_interface_id_namespace_bit),
|
: set_interface_id_namespace_bit_(set_interface_id_namespace_bit),
|
||||||
task_runner_(runner),
|
task_runner_(runner),
|
||||||
dispatcher_(this),
|
dispatcher_(this),
|
||||||
connector_(std::move(message_pipe),
|
connector_(std::move(message_pipe),
|
||||||
config == MULTI_INTERFACE ? Connector::MULTI_THREADED_SEND
|
config == MULTI_INTERFACE ? Connector::MULTI_THREADED_SEND
|
||||||
: Connector::SINGLE_THREADED_SEND,
|
: Connector::SINGLE_THREADED_SEND,
|
||||||
std::move(runner)),
|
std::move(runner),
|
||||||
|
primary_interface_name),
|
||||||
control_message_handler_(this),
|
control_message_handler_(this),
|
||||||
control_message_proxy_(&connector_) {
|
control_message_proxy_(&connector_) {
|
||||||
DCHECK(task_runner_->RunsTasksInCurrentSequence());
|
DCHECK(task_runner_->RunsTasksInCurrentSequence());
|
||||||
@@ -352,6 +355,14 @@ MultiplexRouter::MultiplexRouter(
|
|||||||
std::make_unique<MessageHeaderValidator>();
|
std::make_unique<MessageHeaderValidator>();
|
||||||
header_validator_ = header_validator.get();
|
header_validator_ = header_validator.get();
|
||||||
dispatcher_.SetValidator(std::move(header_validator));
|
dispatcher_.SetValidator(std::move(header_validator));
|
||||||
|
|
||||||
|
if (primary_interface_name) {
|
||||||
|
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
|
||||||
|
header_validator_->SetDescription(base::JoinString(
|
||||||
|
{primary_interface_name, "[primary] MessageHeaderValidator"}, " "));
|
||||||
|
control_message_handler_.SetDescription(base::JoinString(
|
||||||
|
{primary_interface_name, "[primary] PipeControlMessageHandler"}, " "));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MultiplexRouter::~MultiplexRouter() {
|
MultiplexRouter::~MultiplexRouter() {
|
||||||
@@ -369,15 +380,6 @@ void MultiplexRouter::SetIncomingMessageFilter(
|
|||||||
dispatcher_.SetFilter(std::move(filter));
|
dispatcher_.SetFilter(std::move(filter));
|
||||||
}
|
}
|
||||||
|
|
||||||
void MultiplexRouter::SetPrimaryInterfaceName(const char* name) {
|
|
||||||
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
|
|
||||||
header_validator_->SetDescription(std::string(name) +
|
|
||||||
" [primary] MessageHeaderValidator");
|
|
||||||
control_message_handler_.SetDescription(
|
|
||||||
std::string(name) + " [primary] PipeControlMessageHandler");
|
|
||||||
connector_.SetWatcherHeapProfilerTag(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MultiplexRouter::SetConnectionGroup(ConnectionGroup::Ref ref) {
|
void MultiplexRouter::SetConnectionGroup(ConnectionGroup::Ref ref) {
|
||||||
connector_.SetConnectionGroup(std::move(ref));
|
connector_.SetConnectionGroup(std::move(ref));
|
||||||
}
|
}
|
||||||
|
@@ -79,17 +79,13 @@ class COMPONENT_EXPORT(MOJO_CPP_BINDINGS) MultiplexRouter
|
|||||||
MultiplexRouter(ScopedMessagePipeHandle message_pipe,
|
MultiplexRouter(ScopedMessagePipeHandle message_pipe,
|
||||||
Config config,
|
Config config,
|
||||||
bool set_interface_id_namespace_bit,
|
bool set_interface_id_namespace_bit,
|
||||||
scoped_refptr<base::SequencedTaskRunner> runner);
|
scoped_refptr<base::SequencedTaskRunner> runner,
|
||||||
|
const char* primary_interface_name = "unknown interface");
|
||||||
|
|
||||||
// Sets a MessageReceiver which can filter a message after validation but
|
// Sets a MessageReceiver which can filter a message after validation but
|
||||||
// before dispatch.
|
// before dispatch.
|
||||||
void SetIncomingMessageFilter(std::unique_ptr<MessageFilter> filter);
|
void SetIncomingMessageFilter(std::unique_ptr<MessageFilter> filter);
|
||||||
|
|
||||||
// Sets the primary interface name for this router. Only used when reporting
|
|
||||||
// message header or control message validation errors.
|
|
||||||
// |name| must be a string literal.
|
|
||||||
void SetPrimaryInterfaceName(const char* name);
|
|
||||||
|
|
||||||
// Adds this object to a ConnectionGroup identified by |ref|. All receiving
|
// Adds this object to a ConnectionGroup identified by |ref|. All receiving
|
||||||
// pipe endpoints decoded from inbound messages on this MultiplexRouter will
|
// pipe endpoints decoded from inbound messages on this MultiplexRouter will
|
||||||
// be added to the same group.
|
// be added to the same group.
|
||||||
|
@@ -9,6 +9,7 @@
|
|||||||
#include "base/memory/ptr_util.h"
|
#include "base/memory/ptr_util.h"
|
||||||
#include "base/sequenced_task_runner.h"
|
#include "base/sequenced_task_runner.h"
|
||||||
#include "base/synchronization/lock.h"
|
#include "base/synchronization/lock.h"
|
||||||
|
#include "base/task/common/task_annotator.h"
|
||||||
#include "base/threading/thread_task_runner_handle.h"
|
#include "base/threading/thread_task_runner_handle.h"
|
||||||
#include "base/trace_event/heap_profiler.h"
|
#include "base/trace_event/heap_profiler.h"
|
||||||
#include "base/trace_event/trace_event.h"
|
#include "base/trace_event/trace_event.h"
|
||||||
@@ -30,9 +31,10 @@ class SimpleWatcher::Context : public base::RefCountedThreadSafe<Context> {
|
|||||||
MojoHandleSignals signals,
|
MojoHandleSignals signals,
|
||||||
MojoTriggerCondition condition,
|
MojoTriggerCondition condition,
|
||||||
int watch_id,
|
int watch_id,
|
||||||
MojoResult* result) {
|
MojoResult* result,
|
||||||
|
const char* heap_profiler_tag) {
|
||||||
scoped_refptr<Context> context =
|
scoped_refptr<Context> context =
|
||||||
new Context(watcher, task_runner, watch_id);
|
new Context(watcher, task_runner, watch_id, heap_profiler_tag);
|
||||||
|
|
||||||
// If MojoAddTrigger succeeds, it effectively assumes ownership of a
|
// If MojoAddTrigger succeeds, it effectively assumes ownership of a
|
||||||
// reference to |context|. In that case, this reference is balanced in
|
// reference to |context|. In that case, this reference is balanced in
|
||||||
@@ -67,10 +69,12 @@ class SimpleWatcher::Context : public base::RefCountedThreadSafe<Context> {
|
|||||||
|
|
||||||
Context(base::WeakPtr<SimpleWatcher> weak_watcher,
|
Context(base::WeakPtr<SimpleWatcher> weak_watcher,
|
||||||
scoped_refptr<base::SequencedTaskRunner> task_runner,
|
scoped_refptr<base::SequencedTaskRunner> task_runner,
|
||||||
int watch_id)
|
int watch_id,
|
||||||
|
const char* heap_profiler_tag)
|
||||||
: weak_watcher_(weak_watcher),
|
: weak_watcher_(weak_watcher),
|
||||||
task_runner_(task_runner),
|
task_runner_(task_runner),
|
||||||
watch_id_(watch_id) {}
|
watch_id_(watch_id),
|
||||||
|
heap_profiler_tag_(heap_profiler_tag) {}
|
||||||
|
|
||||||
~Context() = default;
|
~Context() = default;
|
||||||
|
|
||||||
@@ -87,28 +91,37 @@ class SimpleWatcher::Context : public base::RefCountedThreadSafe<Context> {
|
|||||||
// the default task runner for the IO thread.
|
// the default task runner for the IO thread.
|
||||||
weak_watcher_->OnHandleReady(watch_id_, result, state);
|
weak_watcher_->OnHandleReady(watch_id_, result, state);
|
||||||
} else {
|
} else {
|
||||||
task_runner_->PostTask(
|
{
|
||||||
FROM_HERE, base::BindOnce(&SimpleWatcher::OnHandleReady,
|
// Annotate the posted task with |heap_profiler_tag_| as the IPC
|
||||||
weak_watcher_, watch_id_, result, state));
|
// interface.
|
||||||
|
base::TaskAnnotator::ScopedSetIpcHash scoped_set_ipc_hash(
|
||||||
|
heap_profiler_tag_);
|
||||||
|
task_runner_->PostTask(
|
||||||
|
FROM_HERE, base::BindOnce(&SimpleWatcher::OnHandleReady,
|
||||||
|
weak_watcher_, watch_id_, result, state));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const base::WeakPtr<SimpleWatcher> weak_watcher_;
|
const base::WeakPtr<SimpleWatcher> weak_watcher_;
|
||||||
const scoped_refptr<base::SequencedTaskRunner> task_runner_;
|
const scoped_refptr<base::SequencedTaskRunner> task_runner_;
|
||||||
const int watch_id_;
|
const int watch_id_;
|
||||||
|
const char* heap_profiler_tag_ = nullptr;
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(Context);
|
DISALLOW_COPY_AND_ASSIGN(Context);
|
||||||
};
|
};
|
||||||
|
|
||||||
SimpleWatcher::SimpleWatcher(const base::Location& from_here,
|
SimpleWatcher::SimpleWatcher(const base::Location& from_here,
|
||||||
ArmingPolicy arming_policy,
|
ArmingPolicy arming_policy,
|
||||||
scoped_refptr<base::SequencedTaskRunner> runner)
|
scoped_refptr<base::SequencedTaskRunner> runner,
|
||||||
|
const char* heap_profiler_tag)
|
||||||
: arming_policy_(arming_policy),
|
: arming_policy_(arming_policy),
|
||||||
task_runner_(std::move(runner)),
|
task_runner_(std::move(runner)),
|
||||||
is_default_task_runner_(base::ThreadTaskRunnerHandle::IsSet() &&
|
is_default_task_runner_(base::ThreadTaskRunnerHandle::IsSet() &&
|
||||||
task_runner_ ==
|
task_runner_ ==
|
||||||
base::ThreadTaskRunnerHandle::Get()),
|
base::ThreadTaskRunnerHandle::Get()),
|
||||||
heap_profiler_tag_(from_here.file_name()) {
|
heap_profiler_tag_(heap_profiler_tag ? heap_profiler_tag
|
||||||
|
: from_here.file_name()) {
|
||||||
MojoResult rv = CreateTrap(&Context::CallNotify, &trap_handle_);
|
MojoResult rv = CreateTrap(&Context::CallNotify, &trap_handle_);
|
||||||
DCHECK_EQ(MOJO_RESULT_OK, rv);
|
DCHECK_EQ(MOJO_RESULT_OK, rv);
|
||||||
DCHECK(task_runner_->RunsTasksInCurrentSequence());
|
DCHECK(task_runner_->RunsTasksInCurrentSequence());
|
||||||
@@ -139,7 +152,7 @@ MojoResult SimpleWatcher::Watch(Handle handle,
|
|||||||
MojoResult result = MOJO_RESULT_UNKNOWN;
|
MojoResult result = MOJO_RESULT_UNKNOWN;
|
||||||
context_ = Context::Create(weak_factory_.GetWeakPtr(), task_runner_,
|
context_ = Context::Create(weak_factory_.GetWeakPtr(), task_runner_,
|
||||||
trap_handle_.get(), handle_, signals, condition,
|
trap_handle_.get(), handle_, signals, condition,
|
||||||
watch_id_, &result);
|
watch_id_, &result, heap_profiler_tag_);
|
||||||
if (!context_) {
|
if (!context_) {
|
||||||
handle_.set_value(kInvalidHandleValue);
|
handle_.set_value(kInvalidHandleValue);
|
||||||
callback_.Reset();
|
callback_.Reset();
|
||||||
@@ -216,10 +229,15 @@ void SimpleWatcher::ArmOrNotify() {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
DCHECK_EQ(MOJO_RESULT_FAILED_PRECONDITION, rv);
|
DCHECK_EQ(MOJO_RESULT_FAILED_PRECONDITION, rv);
|
||||||
task_runner_->PostTask(
|
{
|
||||||
FROM_HERE,
|
// Annotate the posted task with |heap_profiler_tag_| as the IPC interface.
|
||||||
base::BindOnce(&SimpleWatcher::OnHandleReady, weak_factory_.GetWeakPtr(),
|
base::TaskAnnotator::ScopedSetIpcHash scoped_set_ipc_hash(
|
||||||
watch_id_, ready_result, ready_state));
|
heap_profiler_tag_);
|
||||||
|
task_runner_->PostTask(FROM_HERE,
|
||||||
|
base::BindOnce(&SimpleWatcher::OnHandleReady,
|
||||||
|
weak_factory_.GetWeakPtr(), watch_id_,
|
||||||
|
ready_result, ready_state));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SimpleWatcher::OnHandleReady(int watch_id,
|
void SimpleWatcher::OnHandleReady(int watch_id,
|
||||||
@@ -263,5 +281,4 @@ void SimpleWatcher::OnHandleReady(int watch_id,
|
|||||||
ArmOrNotify();
|
ArmOrNotify();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace mojo
|
} // namespace mojo
|
||||||
|
@@ -89,7 +89,8 @@ class MOJO_CPP_SYSTEM_EXPORT SimpleWatcher {
|
|||||||
SimpleWatcher(const base::Location& from_here,
|
SimpleWatcher(const base::Location& from_here,
|
||||||
ArmingPolicy arming_policy,
|
ArmingPolicy arming_policy,
|
||||||
scoped_refptr<base::SequencedTaskRunner> runner =
|
scoped_refptr<base::SequencedTaskRunner> runner =
|
||||||
base::SequencedTaskRunnerHandle::Get());
|
base::SequencedTaskRunnerHandle::Get(),
|
||||||
|
const char* heap_profiler_tag = nullptr);
|
||||||
~SimpleWatcher();
|
~SimpleWatcher();
|
||||||
|
|
||||||
// Indicates if the SimpleWatcher is currently watching a handle.
|
// Indicates if the SimpleWatcher is currently watching a handle.
|
||||||
@@ -179,12 +180,6 @@ class MOJO_CPP_SYSTEM_EXPORT SimpleWatcher {
|
|||||||
Handle handle() const { return handle_; }
|
Handle handle() const { return handle_; }
|
||||||
ReadyCallbackWithState ready_callback() const { return callback_; }
|
ReadyCallbackWithState ready_callback() const { return callback_; }
|
||||||
|
|
||||||
// Sets the tag used by the heap profiler.
|
|
||||||
// |tag| must be a const string literal.
|
|
||||||
void set_heap_profiler_tag(const char* heap_profiler_tag) {
|
|
||||||
heap_profiler_tag_ = heap_profiler_tag;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
class Context;
|
class Context;
|
||||||
|
|
||||||
|
3
third_party/blink/common/features.cc
vendored
3
third_party/blink/common/features.cc
vendored
@@ -771,5 +771,8 @@ const char kBackForwardCacheABExperimentGroup[] =
|
|||||||
const base::Feature kPreferCompositingToLCDText = {
|
const base::Feature kPreferCompositingToLCDText = {
|
||||||
"PreferCompositingToLCDText", base::FEATURE_DISABLED_BY_DEFAULT};
|
"PreferCompositingToLCDText", base::FEATURE_DISABLED_BY_DEFAULT};
|
||||||
|
|
||||||
|
const base::Feature kLogUnexpectedIPCPostedToBackForwardCachedDocuments{
|
||||||
|
"LogUnexpectedIPCPostedToBackForwardCachedDocuments",
|
||||||
|
base::FEATURE_ENABLED_BY_DEFAULT};
|
||||||
} // namespace features
|
} // namespace features
|
||||||
} // namespace blink
|
} // namespace blink
|
||||||
|
2
third_party/blink/public/common/features.h
vendored
2
third_party/blink/public/common/features.h
vendored
@@ -315,6 +315,8 @@ extern const char kBackForwardCacheABExperimentGroup[];
|
|||||||
|
|
||||||
BLINK_COMMON_EXPORT extern const base::Feature kPreferCompositingToLCDText;
|
BLINK_COMMON_EXPORT extern const base::Feature kPreferCompositingToLCDText;
|
||||||
|
|
||||||
|
BLINK_COMMON_EXPORT extern const base::Feature
|
||||||
|
kLogUnexpectedIPCPostedToBackForwardCachedDocuments;
|
||||||
} // namespace features
|
} // namespace features
|
||||||
} // namespace blink
|
} // namespace blink
|
||||||
|
|
||||||
|
@@ -37,6 +37,7 @@ include_rules = [
|
|||||||
"+base/synchronization/cancellation_flag.h",
|
"+base/synchronization/cancellation_flag.h",
|
||||||
"+base/synchronization/lock.h",
|
"+base/synchronization/lock.h",
|
||||||
"+base/task/common/scoped_defer_task_posting.h",
|
"+base/task/common/scoped_defer_task_posting.h",
|
||||||
|
"+base/task/common/task_annotator.h",
|
||||||
"+base/task/sequence_manager/lazy_now.h",
|
"+base/task/sequence_manager/lazy_now.h",
|
||||||
"+base/task/sequence_manager/sequence_manager.h",
|
"+base/task/sequence_manager/sequence_manager.h",
|
||||||
"+base/task/sequence_manager/task_queue.h",
|
"+base/task/sequence_manager/task_queue.h",
|
||||||
|
@@ -10,6 +10,7 @@
|
|||||||
#include "base/metrics/histogram_functions.h"
|
#include "base/metrics/histogram_functions.h"
|
||||||
#include "base/metrics/histogram_macros.h"
|
#include "base/metrics/histogram_macros.h"
|
||||||
#include "base/task/common/scoped_defer_task_posting.h"
|
#include "base/task/common/scoped_defer_task_posting.h"
|
||||||
|
#include "base/task/common/task_annotator.h"
|
||||||
#include "base/task/sequence_manager/lazy_now.h"
|
#include "base/task/sequence_manager/lazy_now.h"
|
||||||
#include "base/time/time.h"
|
#include "base/time/time.h"
|
||||||
#include "base/trace_event/blame_context.h"
|
#include "base/trace_event/blame_context.h"
|
||||||
@@ -718,7 +719,7 @@ void FrameSchedulerImpl::ReportActiveSchedulerTrackedFeatures() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
base::WeakPtr<FrameSchedulerImpl>
|
base::WeakPtr<FrameSchedulerImpl>
|
||||||
FrameSchedulerImpl::GetInvalidingOnBFCacheRestoreWeakPtr() {
|
FrameSchedulerImpl::GetInvalidatingOnBFCacheRestoreWeakPtr() {
|
||||||
return invalidating_on_bfcache_restore_weak_factory_.GetWeakPtr();
|
return invalidating_on_bfcache_restore_weak_factory_.GetWeakPtr();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1228,18 +1229,18 @@ void FrameSchedulerImpl::SetOnIPCTaskPostedWhileInBackForwardCacheHandler() {
|
|||||||
// Only log IPC tasks. IPC tasks are only logged currently as IPC
|
// Only log IPC tasks. IPC tasks are only logged currently as IPC
|
||||||
// hash can be mapped back to a function name, and IPC tasks may
|
// hash can be mapped back to a function name, and IPC tasks may
|
||||||
// potentially post sensitive information.
|
// potentially post sensitive information.
|
||||||
if (!task.ipc_hash) {
|
if (!task.ipc_hash && !task.ipc_interface_name) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
base::ScopedDeferTaskPosting::PostOrDefer(
|
base::ScopedDeferTaskPosting::PostOrDefer(
|
||||||
task_runner, FROM_HERE,
|
task_runner, FROM_HERE,
|
||||||
base::BindOnce(
|
base::BindOnce(
|
||||||
&FrameSchedulerImpl::OnIPCTaskPostedWhileInBackForwardCache,
|
&FrameSchedulerImpl::OnIPCTaskPostedWhileInBackForwardCache,
|
||||||
frame_scheduler, task.ipc_hash, task.posted_from),
|
frame_scheduler, task.ipc_hash, task.ipc_interface_name),
|
||||||
base::TimeDelta());
|
base::TimeDelta());
|
||||||
},
|
},
|
||||||
main_thread_scheduler_->DefaultTaskRunner(),
|
main_thread_scheduler_->DefaultTaskRunner(),
|
||||||
GetInvalidingOnBFCacheRestoreWeakPtr()));
|
GetInvalidatingOnBFCacheRestoreWeakPtr()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1254,7 +1255,20 @@ void FrameSchedulerImpl::DetachOnIPCTaskPostedWhileInBackForwardCacheHandler() {
|
|||||||
|
|
||||||
void FrameSchedulerImpl::OnIPCTaskPostedWhileInBackForwardCache(
|
void FrameSchedulerImpl::OnIPCTaskPostedWhileInBackForwardCache(
|
||||||
uint32_t ipc_hash,
|
uint32_t ipc_hash,
|
||||||
const base::Location& task_from) {
|
const char* ipc_interface_name) {
|
||||||
|
// IPC tasks may have an IPC interface name in addition to, or instead of an
|
||||||
|
// IPC hash. IPC hash is known from the mojo Accept method. When IPC hash is
|
||||||
|
// 0, then the IPC hash must be calculated from the IPC interface name
|
||||||
|
// instead.
|
||||||
|
if (!ipc_hash) {
|
||||||
|
// base::HashMetricName produces a uint64; however, the MD5 hash calculation
|
||||||
|
// for an IPC interface name is always calculated as uint32; the IPC hash on
|
||||||
|
// a task is also a uint32. The calculation here is meant to mimic the
|
||||||
|
// calculation used in base::MD5Hash32Constexpr.
|
||||||
|
ipc_hash = base::TaskAnnotator::ScopedSetIpcHash::MD5HashMetricName(
|
||||||
|
ipc_interface_name);
|
||||||
|
}
|
||||||
|
|
||||||
DCHECK(parent_page_scheduler_->IsStoredInBackForwardCache());
|
DCHECK(parent_page_scheduler_->IsStoredInBackForwardCache());
|
||||||
base::UmaHistogramSparse(
|
base::UmaHistogramSparse(
|
||||||
"BackForwardCache.Experimental.UnexpectedIPCMessagePostedToCachedFrame."
|
"BackForwardCache.Experimental.UnexpectedIPCMessagePostedToCachedFrame."
|
||||||
|
@@ -142,7 +142,7 @@ class PLATFORM_EXPORT FrameSchedulerImpl : public FrameScheduler,
|
|||||||
|
|
||||||
base::WeakPtr<FrameScheduler> GetWeakPtr() override;
|
base::WeakPtr<FrameScheduler> GetWeakPtr() override;
|
||||||
base::WeakPtr<const FrameSchedulerImpl> GetWeakPtr() const;
|
base::WeakPtr<const FrameSchedulerImpl> GetWeakPtr() const;
|
||||||
base::WeakPtr<FrameSchedulerImpl> GetInvalidingOnBFCacheRestoreWeakPtr();
|
base::WeakPtr<FrameSchedulerImpl> GetInvalidatingOnBFCacheRestoreWeakPtr();
|
||||||
|
|
||||||
void ReportActiveSchedulerTrackedFeatures() override;
|
void ReportActiveSchedulerTrackedFeatures() override;
|
||||||
|
|
||||||
@@ -184,7 +184,7 @@ class PLATFORM_EXPORT FrameSchedulerImpl : public FrameScheduler,
|
|||||||
void SetOnIPCTaskPostedWhileInBackForwardCacheHandler();
|
void SetOnIPCTaskPostedWhileInBackForwardCacheHandler();
|
||||||
void DetachOnIPCTaskPostedWhileInBackForwardCacheHandler();
|
void DetachOnIPCTaskPostedWhileInBackForwardCacheHandler();
|
||||||
void OnIPCTaskPostedWhileInBackForwardCache(uint32_t ipc_hash,
|
void OnIPCTaskPostedWhileInBackForwardCache(uint32_t ipc_hash,
|
||||||
const base::Location& task_from);
|
const char* ipc_interface_name);
|
||||||
|
|
||||||
// Returns the list of active features which currently tracked by the
|
// Returns the list of active features which currently tracked by the
|
||||||
// scheduler for back-forward cache metrics.
|
// scheduler for back-forward cache metrics.
|
||||||
|
72
third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl_unittest.cc
vendored
72
third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl_unittest.cc
vendored
@@ -1263,6 +1263,58 @@ TEST_F(FrameSchedulerImplTest, SubesourceLoadingPaused) {
|
|||||||
worker_throttled_count, worker_stopped_count);
|
worker_throttled_count, worker_stopped_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(FrameSchedulerImplTest, LogIpcsPostedToFramesInBackForwardCache) {
|
||||||
|
base::HistogramTester histogram_tester;
|
||||||
|
|
||||||
|
// Create the task queue implicitly.
|
||||||
|
const scoped_refptr<base::SingleThreadTaskRunner> task_runner =
|
||||||
|
frame_scheduler_->GetTaskRunner(TaskType::kInternalTest);
|
||||||
|
|
||||||
|
StorePageInBackForwardCache();
|
||||||
|
|
||||||
|
// Run the tasks so that they are recorded in the histogram
|
||||||
|
task_environment_.FastForwardBy(base::TimeDelta::FromHours(1));
|
||||||
|
|
||||||
|
// Post IPC tasks, accounting for delay for when tracking starts.
|
||||||
|
{
|
||||||
|
base::TaskAnnotator::ScopedSetIpcHash scoped_set_ipc_hash(1);
|
||||||
|
task_runner->PostTask(FROM_HERE, base::DoNothing());
|
||||||
|
}
|
||||||
|
{
|
||||||
|
base::TaskAnnotator::ScopedSetIpcHash scoped_set_ipc_hash_2(2);
|
||||||
|
task_runner->PostTask(FROM_HERE, base::DoNothing());
|
||||||
|
}
|
||||||
|
task_environment_.RunUntilIdle();
|
||||||
|
|
||||||
|
// Once the page is restored from the cache, IPCs should no longer be
|
||||||
|
// recorded.
|
||||||
|
RestorePageFromBackForwardCache();
|
||||||
|
|
||||||
|
// Start posting tasks immediately - will not be recorded
|
||||||
|
{
|
||||||
|
base::TaskAnnotator::ScopedSetIpcHash scoped_set_ipc_hash_3(3);
|
||||||
|
task_runner->PostTask(FROM_HERE, base::DoNothing());
|
||||||
|
}
|
||||||
|
{
|
||||||
|
base::TaskAnnotator::ScopedSetIpcHash scoped_set_ipc_hash_4(4);
|
||||||
|
task_runner->PostTask(FROM_HERE, base::DoNothing());
|
||||||
|
}
|
||||||
|
|
||||||
|
EXPECT_THAT(
|
||||||
|
histogram_tester.GetAllSamples(
|
||||||
|
"BackForwardCache.Experimental."
|
||||||
|
"UnexpectedIPCMessagePostedToCachedFrame.MethodHash"),
|
||||||
|
testing::UnorderedElementsAre(base::Bucket(1, 1), base::Bucket(2, 1)));
|
||||||
|
|
||||||
|
// TimeUntilIPCReceived should have values in the 300000 bucket corresponding
|
||||||
|
// with the hour delay in task_environment_.FastForwardBy.
|
||||||
|
EXPECT_THAT(
|
||||||
|
histogram_tester.GetAllSamples(
|
||||||
|
"BackForwardCache.Experimental."
|
||||||
|
"UnexpectedIPCMessagePostedToCachedFrame.TimeUntilIPCReceived"),
|
||||||
|
testing::UnorderedElementsAre(base::Bucket(300000, 2)));
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(FrameSchedulerImplTest,
|
TEST_F(FrameSchedulerImplTest,
|
||||||
LogIpcsFromMultipleThreadsPostedToFramesInBackForwardCache) {
|
LogIpcsFromMultipleThreadsPostedToFramesInBackForwardCache) {
|
||||||
base::HistogramTester histogram_tester;
|
base::HistogramTester histogram_tester;
|
||||||
@@ -1282,7 +1334,7 @@ TEST_F(FrameSchedulerImplTest,
|
|||||||
base::BindOnce(
|
base::BindOnce(
|
||||||
[](scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
|
[](scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
|
||||||
base::TaskAnnotator::ScopedSetIpcHash scoped_set_ipc_hash(1);
|
base::TaskAnnotator::ScopedSetIpcHash scoped_set_ipc_hash(1);
|
||||||
task_runner->PostTask(FROM_HERE, base::BindOnce([]() {}));
|
task_runner->PostTask(FROM_HERE, base::DoNothing());
|
||||||
},
|
},
|
||||||
task_runner));
|
task_runner));
|
||||||
task_environment_.RunUntilIdle();
|
task_environment_.RunUntilIdle();
|
||||||
@@ -1298,7 +1350,7 @@ TEST_F(FrameSchedulerImplTest,
|
|||||||
base::RepeatingClosure restore_from_cache_callback) {
|
base::RepeatingClosure restore_from_cache_callback) {
|
||||||
{
|
{
|
||||||
base::TaskAnnotator::ScopedSetIpcHash scoped_set_ipc_hash(2);
|
base::TaskAnnotator::ScopedSetIpcHash scoped_set_ipc_hash(2);
|
||||||
task_runner->PostTask(FROM_HERE, base::BindOnce([]() {}));
|
task_runner->PostTask(FROM_HERE, base::DoNothing());
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
// Once the page is restored from the cache, ensure that the IPC
|
// Once the page is restored from the cache, ensure that the IPC
|
||||||
@@ -1308,7 +1360,7 @@ TEST_F(FrameSchedulerImplTest,
|
|||||||
}
|
}
|
||||||
{
|
{
|
||||||
base::TaskAnnotator::ScopedSetIpcHash scoped_set_ipc_hash(4);
|
base::TaskAnnotator::ScopedSetIpcHash scoped_set_ipc_hash(4);
|
||||||
task_runner->PostTask(FROM_HERE, base::BindOnce([]() {}));
|
task_runner->PostTask(FROM_HERE, base::DoNothing());
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
task_runner, restore_from_cache_callback));
|
task_runner, restore_from_cache_callback));
|
||||||
@@ -1320,7 +1372,7 @@ TEST_F(FrameSchedulerImplTest,
|
|||||||
base::BindOnce(
|
base::BindOnce(
|
||||||
[](scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
|
[](scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
|
||||||
base::TaskAnnotator::ScopedSetIpcHash scoped_set_ipc_hash(5);
|
base::TaskAnnotator::ScopedSetIpcHash scoped_set_ipc_hash(5);
|
||||||
task_runner->PostTask(FROM_HERE, base::BindOnce([]() {}));
|
task_runner->PostTask(FROM_HERE, base::DoNothing());
|
||||||
},
|
},
|
||||||
task_runner));
|
task_runner));
|
||||||
task_environment_.RunUntilIdle();
|
task_environment_.RunUntilIdle();
|
||||||
@@ -1330,16 +1382,16 @@ TEST_F(FrameSchedulerImplTest,
|
|||||||
base::BindOnce(
|
base::BindOnce(
|
||||||
[](scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
|
[](scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
|
||||||
base::TaskAnnotator::ScopedSetIpcHash scoped_set_ipc_hash(6);
|
base::TaskAnnotator::ScopedSetIpcHash scoped_set_ipc_hash(6);
|
||||||
task_runner->PostTask(FROM_HERE, base::BindOnce([]() {}));
|
task_runner->PostTask(FROM_HERE, base::DoNothing());
|
||||||
},
|
},
|
||||||
task_runner));
|
task_runner));
|
||||||
task_environment_.RunUntilIdle();
|
task_environment_.RunUntilIdle();
|
||||||
|
|
||||||
EXPECT_THAT(histogram_tester.GetAllSamples(
|
EXPECT_THAT(
|
||||||
"BackForwardCache.Experimental."
|
histogram_tester.GetAllSamples(
|
||||||
"UnexpectedIPCMessagePostedToCachedFrame.MethodHash"),
|
"BackForwardCache.Experimental."
|
||||||
testing::UnorderedElementsAreArray(
|
"UnexpectedIPCMessagePostedToCachedFrame.MethodHash"),
|
||||||
{base::Bucket(1, 1), base::Bucket(2, 1)}));
|
testing::UnorderedElementsAre(base::Bucket(1, 1), base::Bucket(2, 1)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(farahcharab) Move priority testing to MainThreadTaskQueueTest after
|
// TODO(farahcharab) Move priority testing to MainThreadTaskQueueTest after
|
||||||
|
@@ -68,6 +68,9 @@ constexpr base::TimeDelta kDefaultDelayForBackgroundAndNetworkIdleTabFreezing =
|
|||||||
constexpr base::TimeDelta kThrottledWakeUpDuration =
|
constexpr base::TimeDelta kThrottledWakeUpDuration =
|
||||||
base::TimeDelta::FromMilliseconds(3);
|
base::TimeDelta::FromMilliseconds(3);
|
||||||
|
|
||||||
|
constexpr base::TimeDelta kDefaultDelayForTrackingIPCsPostedToCachedFrames =
|
||||||
|
base::TimeDelta::FromSeconds(15);
|
||||||
|
|
||||||
// Values coming from the field trial config are interpreted as follows:
|
// Values coming from the field trial config are interpreted as follows:
|
||||||
// -1 is "not set". Scheduler should use a reasonable default.
|
// -1 is "not set". Scheduler should use a reasonable default.
|
||||||
// 0 corresponds to base::nullopt.
|
// 0 corresponds to base::nullopt.
|
||||||
@@ -145,6 +148,21 @@ base::TimeDelta GetDelayForBackgroundAndNetworkIdleTabFreezing() {
|
|||||||
kDelayForBackgroundAndNetworkIdleTabFreezingMillis.Get());
|
kDelayForBackgroundAndNetworkIdleTabFreezingMillis.Get());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
base::TimeDelta GetTimeToDelayIPCTrackingWhileStoredInBackForwardCache() {
|
||||||
|
if (base::FeatureList::IsEnabled(
|
||||||
|
features::kLogUnexpectedIPCPostedToBackForwardCachedDocuments)) {
|
||||||
|
static const base::FeatureParam<int>
|
||||||
|
kDelayForLoggingUnexpectedIPCPostedToBckForwardCacheMillis{
|
||||||
|
&features::kLogUnexpectedIPCPostedToBackForwardCachedDocuments,
|
||||||
|
"delay_before_tracking_ms",
|
||||||
|
static_cast<int>(kDefaultDelayForTrackingIPCsPostedToCachedFrames
|
||||||
|
.InMilliseconds())};
|
||||||
|
return base::TimeDelta::FromMilliseconds(
|
||||||
|
kDelayForLoggingUnexpectedIPCPostedToBckForwardCacheMillis.Get());
|
||||||
|
}
|
||||||
|
return kDefaultDelayForTrackingIPCsPostedToCachedFrames;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
constexpr base::TimeDelta PageSchedulerImpl::kDefaultThrottledWakeUpInterval;
|
constexpr base::TimeDelta PageSchedulerImpl::kDefaultThrottledWakeUpInterval;
|
||||||
@@ -340,7 +358,7 @@ void PageSchedulerImpl::SetPageBackForwardCached(
|
|||||||
*main_thread_scheduler_->ControlTaskRunner(), FROM_HERE,
|
*main_thread_scheduler_->ControlTaskRunner(), FROM_HERE,
|
||||||
base::BindRepeating(&PageSchedulerImpl::SetUpIPCTaskDetection,
|
base::BindRepeating(&PageSchedulerImpl::SetUpIPCTaskDetection,
|
||||||
GetWeakPtr()),
|
GetWeakPtr()),
|
||||||
base::TimeDelta::FromSeconds(15));
|
GetTimeToDelayIPCTrackingWhileStoredInBackForwardCache());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user