зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1353440 - Annotate background hang reports which occur while the user is interacting with the browser, r=ehsan
MozReview-Commit-ID: CSO0K5wiK5H
This commit is contained in:
Родитель
fd01a9ec9f
Коммит
bbb295c668
|
@ -219,6 +219,7 @@
|
|||
#include "mozilla/dom/TabGroup.h"
|
||||
#include "nsIWebNavigationInfo.h"
|
||||
#include "nsPluginHost.h"
|
||||
#include "mozilla/HangAnnotations.h"
|
||||
|
||||
#include "nsIBidiKeyboard.h"
|
||||
|
||||
|
@ -303,6 +304,9 @@ bool nsContentUtils::sRequestIdleCallbackEnabled = false;
|
|||
int32_t nsContentUtils::sPrivacyMaxInnerWidth = 1000;
|
||||
int32_t nsContentUtils::sPrivacyMaxInnerHeight = 1000;
|
||||
|
||||
nsContentUtils::UserInteractionObserver*
|
||||
nsContentUtils::sUserInteractionObserver = nullptr;
|
||||
|
||||
uint32_t nsContentUtils::sHandlingInputTimeout = 1000;
|
||||
|
||||
uint32_t nsContentUtils::sCookiesLifetimePolicy = nsICookieService::ACCEPT_NORMALLY;
|
||||
|
@ -494,6 +498,32 @@ private:
|
|||
|
||||
} // namespace
|
||||
|
||||
/**
|
||||
* This class is used to determine whether or not the user is currently
|
||||
* interacting with the browser. It listens to observer events to toggle the
|
||||
* value of the sUserActive static.
|
||||
*
|
||||
* This class is an internal implementation detail.
|
||||
* nsContentUtils::GetUserIsInteracting() should be used to access current
|
||||
* user interaction status.
|
||||
*/
|
||||
class nsContentUtils::UserInteractionObserver final : public nsIObserver
|
||||
, public HangMonitor::Annotator
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIOBSERVER
|
||||
|
||||
void Init();
|
||||
void Shutdown();
|
||||
virtual void AnnotateHang(HangMonitor::HangAnnotations& aAnnotations) override;
|
||||
|
||||
static Atomic<bool> sUserActive;
|
||||
|
||||
private:
|
||||
~UserInteractionObserver() {}
|
||||
};
|
||||
|
||||
/* static */
|
||||
TimeDuration
|
||||
nsContentUtils::HandlingUserInputTimeout()
|
||||
|
@ -663,6 +693,10 @@ nsContentUtils::Init()
|
|||
}
|
||||
uuidGenerator.forget(&sUUIDGenerator);
|
||||
|
||||
RefPtr<UserInteractionObserver> uio = new UserInteractionObserver();
|
||||
uio->Init();
|
||||
uio.forget(&sUserInteractionObserver);
|
||||
|
||||
sInitialized = true;
|
||||
|
||||
return NS_OK;
|
||||
|
@ -2029,6 +2063,11 @@ nsContentUtils::Shutdown()
|
|||
|
||||
NS_IF_RELEASE(sSameOriginChecker);
|
||||
|
||||
if (sUserInteractionObserver) {
|
||||
sUserInteractionObserver->Shutdown();
|
||||
NS_RELEASE(sUserInteractionObserver);
|
||||
}
|
||||
|
||||
HTMLInputElement::Shutdown();
|
||||
nsMappedAttributes::Shutdown();
|
||||
}
|
||||
|
@ -10345,5 +10384,71 @@ nsContentUtils::GenerateTabId()
|
|||
uint64_t tabBits = tabId & ((uint64_t(1) << kTabIdTabBits) - 1);
|
||||
|
||||
return (processBits << kTabIdTabBits) | tabBits;
|
||||
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
nsContentUtils::GetUserIsInteracting()
|
||||
{
|
||||
return UserInteractionObserver::sUserActive;
|
||||
}
|
||||
|
||||
static const char* kUserInteractionInactive = "user-interaction-inactive";
|
||||
static const char* kUserInteractionActive = "user-interaction-active";
|
||||
|
||||
void
|
||||
nsContentUtils::UserInteractionObserver::Init()
|
||||
{
|
||||
// Listen for the observer messages from EventStateManager which are telling
|
||||
// us whether or not the user is interacting.
|
||||
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
|
||||
obs->AddObserver(this, kUserInteractionInactive, false);
|
||||
obs->AddObserver(this, kUserInteractionActive, false);
|
||||
|
||||
// Register ourselves as an annotator for the Background Hang Reporter, so
|
||||
// that hang stacks are annotated with whether or not the user was
|
||||
// interacting with the browser when the hang occurred.
|
||||
HangMonitor::RegisterAnnotator(*this);
|
||||
}
|
||||
|
||||
void
|
||||
nsContentUtils::UserInteractionObserver::Shutdown()
|
||||
{
|
||||
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
|
||||
if (obs) {
|
||||
obs->RemoveObserver(this, kUserInteractionInactive);
|
||||
obs->RemoveObserver(this, kUserInteractionActive);
|
||||
}
|
||||
|
||||
HangMonitor::UnregisterAnnotator(*this);
|
||||
}
|
||||
|
||||
/**
|
||||
* NB: This function is always called by the HangMonitor thread.
|
||||
* Plan accordingly
|
||||
*/
|
||||
void
|
||||
nsContentUtils::UserInteractionObserver::AnnotateHang(HangMonitor::HangAnnotations& aAnnotations)
|
||||
{
|
||||
// NOTE: Only annotate the hang report if the user is known to be interacting.
|
||||
if (sUserActive) {
|
||||
aAnnotations.AddAnnotation(NS_LITERAL_STRING("UserInteracting"), true);
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsContentUtils::UserInteractionObserver::Observe(nsISupports* aSubject,
|
||||
const char* aTopic,
|
||||
const char16_t* aData)
|
||||
{
|
||||
if (!strcmp(aTopic, kUserInteractionInactive)) {
|
||||
sUserActive = false;
|
||||
} else if (!strcmp(aTopic, kUserInteractionActive)) {
|
||||
sUserActive = true;
|
||||
} else {
|
||||
NS_WARNING("Unexpected observer notification");
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
Atomic<bool> nsContentUtils::UserInteractionObserver::sUserActive(false);
|
||||
NS_IMPL_ISUPPORTS(nsContentUtils::UserInteractionObserver, nsIObserver)
|
||||
|
|
|
@ -2927,6 +2927,13 @@ public:
|
|||
static bool
|
||||
SkipCursorMoveForSameValueSet() { return sSkipCursorMoveForSameValueSet; }
|
||||
|
||||
/**
|
||||
* Determine whether or not the user is currently interacting with the web
|
||||
* browser. This method is safe to call from off of the main thread.
|
||||
*/
|
||||
static bool
|
||||
GetUserIsInteracting();
|
||||
|
||||
private:
|
||||
static bool InitializeEventTable();
|
||||
|
||||
|
@ -3059,6 +3066,9 @@ private:
|
|||
static int32_t sPrivacyMaxInnerWidth;
|
||||
static int32_t sPrivacyMaxInnerHeight;
|
||||
|
||||
class UserInteractionObserver;
|
||||
static UserInteractionObserver* sUserInteractionObserver;
|
||||
|
||||
static nsHtml5StringParser* sHTMLFragmentParser;
|
||||
static nsIParser* sXMLFragmentParser;
|
||||
static nsIFragmentContentSink* sXMLFragmentSink;
|
||||
|
|
|
@ -189,7 +189,6 @@ static bool sNeedsFullGC = false;
|
|||
static bool sNeedsGCAfterCC = false;
|
||||
static bool sIncrementalCC = false;
|
||||
static bool sDidPaintAfterPreviousICCSlice = false;
|
||||
static bool sUserActive = false;
|
||||
static int32_t sActiveIntersliceGCBudget = 0; // ms;
|
||||
static nsScriptNameSpaceManager *gNameSpaceManager;
|
||||
|
||||
|
@ -350,12 +349,10 @@ nsJSEnvironmentObserver::Observe(nsISupports* aSubject, const char* aTopic,
|
|||
}
|
||||
}
|
||||
} else if (!nsCRT::strcmp(aTopic, "user-interaction-inactive")) {
|
||||
sUserActive = false;
|
||||
if (sCompactOnUserInactive) {
|
||||
nsJSContext::PokeShrinkingGC();
|
||||
}
|
||||
} else if (!nsCRT::strcmp(aTopic, "user-interaction-active")) {
|
||||
sUserActive = true;
|
||||
nsJSContext::KillShrinkingGCTimer();
|
||||
if (sIsCompactingOnUserInactive) {
|
||||
JS::AbortIncrementalGC(sContext);
|
||||
|
@ -1744,7 +1741,7 @@ InterSliceGCTimerFired(nsITimer *aTimer, void *aClosure)
|
|||
{
|
||||
nsJSContext::KillInterSliceGCTimer();
|
||||
bool e10sParent = XRE_IsParentProcess() && BrowserTabsRemoteAutostart();
|
||||
int64_t budget = e10sParent && sUserActive && sActiveIntersliceGCBudget ?
|
||||
int64_t budget = e10sParent && nsContentUtils::GetUserIsInteracting() && sActiveIntersliceGCBudget ?
|
||||
sActiveIntersliceGCBudget : NS_INTERSLICE_GC_BUDGET;
|
||||
nsJSContext::GarbageCollectNow(JS::gcreason::INTER_SLICE_GC,
|
||||
nsJSContext::IncrementalGC,
|
||||
|
|
Загрузка…
Ссылка в новой задаче