зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1260243 - Convert backgrounding/foregrounding GeckoEvent to native calls; r=snorp
Convert APP_BACKGROUNDING and APP_FOREGROUNDING events in GeckoEvent to native calls onPause and onResume in GeckoThread, respectively.
This commit is contained in:
Родитель
8318ca75b7
Коммит
2bb3a5b2e1
|
@ -111,7 +111,7 @@ public class GeckoApplication extends Application
|
|||
// low memory killer subsequently kills us, the disk cache will
|
||||
// be left in a consistent state, avoiding costly cleanup and
|
||||
// re-creation.
|
||||
GeckoAppShell.sendEventToGecko(GeckoEvent.createAppBackgroundingEvent());
|
||||
GeckoThread.onPause();
|
||||
mPausedGecko = true;
|
||||
|
||||
final BrowserDB db = GeckoProfile.get(this).getDB();
|
||||
|
@ -128,7 +128,7 @@ public class GeckoApplication extends Application
|
|||
|
||||
public void onActivityResume(GeckoActivityStatus activity) {
|
||||
if (mPausedGecko) {
|
||||
GeckoAppShell.sendEventToGecko(GeckoEvent.createAppForegroundingEvent());
|
||||
GeckoThread.onResume();
|
||||
mPausedGecko = false;
|
||||
}
|
||||
|
||||
|
|
|
@ -73,8 +73,6 @@ public class GeckoEvent {
|
|||
MOTION_EVENT(2),
|
||||
SENSOR_EVENT(3),
|
||||
LOCATION_EVENT(5),
|
||||
APP_BACKGROUNDING(9),
|
||||
APP_FOREGROUNDING(10),
|
||||
LOAD_URI(12),
|
||||
NOOP(15),
|
||||
VIEWPORT(20),
|
||||
|
@ -160,14 +158,6 @@ public class GeckoEvent {
|
|||
mType = event.value;
|
||||
}
|
||||
|
||||
public static GeckoEvent createAppBackgroundingEvent() {
|
||||
return GeckoEvent.get(NativeGeckoEvent.APP_BACKGROUNDING);
|
||||
}
|
||||
|
||||
public static GeckoEvent createAppForegroundingEvent() {
|
||||
return GeckoEvent.get(NativeGeckoEvent.APP_FOREGROUNDING);
|
||||
}
|
||||
|
||||
public static GeckoEvent createNoOpEvent() {
|
||||
return GeckoEvent.get(NativeGeckoEvent.NOOP);
|
||||
}
|
||||
|
|
|
@ -615,4 +615,28 @@ public class GeckoThread extends Thread {
|
|||
|
||||
@WrapForJNI @RobocopTarget
|
||||
public static native void waitOnGecko();
|
||||
|
||||
@WrapForJNI(stubName = "OnPause")
|
||||
private static native void nativeOnPause();
|
||||
|
||||
public static void onPause() {
|
||||
if (isStateAtLeast(State.PROFILE_READY)) {
|
||||
nativeOnPause();
|
||||
} else {
|
||||
queueNativeCallUntil(State.PROFILE_READY, GeckoThread.class,
|
||||
"nativeOnPause");
|
||||
}
|
||||
}
|
||||
|
||||
@WrapForJNI(stubName = "OnResume")
|
||||
private static native void nativeOnResume();
|
||||
|
||||
public static void onResume() {
|
||||
if (isStateAtLeast(State.PROFILE_READY)) {
|
||||
nativeOnResume();
|
||||
} else {
|
||||
queueNativeCallUntil(State.PROFILE_READY, GeckoThread.class,
|
||||
"nativeOnResume");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -628,8 +628,6 @@ public:
|
|||
MOTION_EVENT = 2,
|
||||
SENSOR_EVENT = 3,
|
||||
LOCATION_EVENT = 5,
|
||||
APP_BACKGROUNDING = 9,
|
||||
APP_FOREGROUNDING = 10,
|
||||
LOAD_URI = 12,
|
||||
NOOP = 15,
|
||||
APZ_INPUT_EVENT = 17, // used internally in AndroidJNI/nsAppShell/nsWindow
|
||||
|
|
|
@ -197,6 +197,14 @@ class GeckoThread::Natives : public mozilla::jni::NativeImpl<GeckoThread, Impl>
|
|||
public:
|
||||
static constexpr JNINativeMethod methods[] = {
|
||||
|
||||
mozilla::jni::MakeNativeMethod<GeckoThread::OnPause_t>(
|
||||
mozilla::jni::NativeStub<GeckoThread::OnPause_t, Impl>
|
||||
::template Wrap<&Impl::OnPause>),
|
||||
|
||||
mozilla::jni::MakeNativeMethod<GeckoThread::OnResume_t>(
|
||||
mozilla::jni::NativeStub<GeckoThread::OnResume_t, Impl>
|
||||
::template Wrap<&Impl::OnResume>),
|
||||
|
||||
mozilla::jni::MakeNativeMethod<GeckoThread::SpeculativeConnect_t>(
|
||||
mozilla::jni::NativeStub<GeckoThread::SpeculativeConnect_t, Impl>
|
||||
::template Wrap<&Impl::SpeculativeConnect>),
|
||||
|
|
|
@ -953,6 +953,12 @@ auto GeckoThread::CheckAndSetState(mozilla::jni::Object::Param a0, mozilla::jni:
|
|||
return mozilla::jni::Method<CheckAndSetState_t>::Call(GeckoThread::Context(), nullptr, a0, a1);
|
||||
}
|
||||
|
||||
constexpr char GeckoThread::OnPause_t::name[];
|
||||
constexpr char GeckoThread::OnPause_t::signature[];
|
||||
|
||||
constexpr char GeckoThread::OnResume_t::name[];
|
||||
constexpr char GeckoThread::OnResume_t::signature[];
|
||||
|
||||
constexpr char GeckoThread::PumpMessageLoop_t::name[];
|
||||
constexpr char GeckoThread::PumpMessageLoop_t::signature[];
|
||||
|
||||
|
|
|
@ -2249,6 +2249,32 @@ public:
|
|||
|
||||
static auto CheckAndSetState(mozilla::jni::Object::Param, mozilla::jni::Object::Param) -> bool;
|
||||
|
||||
struct OnPause_t {
|
||||
typedef GeckoThread Owner;
|
||||
typedef void ReturnType;
|
||||
typedef void SetterType;
|
||||
typedef mozilla::jni::Args<> Args;
|
||||
static constexpr char name[] = "nativeOnPause";
|
||||
static constexpr char signature[] =
|
||||
"()V";
|
||||
static const bool isStatic = true;
|
||||
static const mozilla::jni::ExceptionMode exceptionMode =
|
||||
mozilla::jni::ExceptionMode::ABORT;
|
||||
};
|
||||
|
||||
struct OnResume_t {
|
||||
typedef GeckoThread Owner;
|
||||
typedef void ReturnType;
|
||||
typedef void SetterType;
|
||||
typedef mozilla::jni::Args<> Args;
|
||||
static constexpr char name[] = "nativeOnResume";
|
||||
static constexpr char signature[] =
|
||||
"()V";
|
||||
static const bool isStatic = true;
|
||||
static const mozilla::jni::ExceptionMode exceptionMode =
|
||||
mozilla::jni::ExceptionMode::ABORT;
|
||||
};
|
||||
|
||||
struct PumpMessageLoop_t {
|
||||
typedef GeckoThread Owner;
|
||||
typedef bool ReturnType;
|
||||
|
|
|
@ -156,10 +156,26 @@ ResolveURI(const nsCString& uriStr)
|
|||
|
||||
} // namespace
|
||||
|
||||
class GeckoThreadNatives final
|
||||
: public widget::GeckoThread::Natives<GeckoThreadNatives>
|
||||
|
||||
class GeckoThreadSupport final
|
||||
: public widget::GeckoThread::Natives<GeckoThreadSupport>
|
||||
, public UsesGeckoThreadProxy
|
||||
{
|
||||
static uint32_t sPauseCount;
|
||||
|
||||
public:
|
||||
template<typename Functor>
|
||||
static void OnNativeCall(Functor&& aCall)
|
||||
{
|
||||
if (aCall.IsTarget(&SpeculativeConnect) ||
|
||||
aCall.IsTarget(&WaitOnGecko)) {
|
||||
|
||||
aCall();
|
||||
return;
|
||||
}
|
||||
return UsesGeckoThreadProxy::OnNativeCall(aCall);
|
||||
}
|
||||
|
||||
static void SpeculativeConnect(jni::String::Param uriStr)
|
||||
{
|
||||
if (!NS_IsMainThread()) {
|
||||
|
@ -190,8 +206,72 @@ public:
|
|||
};
|
||||
nsAppShell::SyncRunEvent(NoOpEvent());
|
||||
}
|
||||
|
||||
static void OnPause()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
if ((++sPauseCount) > 1) {
|
||||
// Already paused.
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIObserverService> obsServ =
|
||||
mozilla::services::GetObserverService();
|
||||
obsServ->NotifyObservers(nullptr, "application-background", nullptr);
|
||||
|
||||
NS_NAMED_LITERAL_STRING(minimize, "heap-minimize");
|
||||
obsServ->NotifyObservers(nullptr, "memory-pressure", minimize.get());
|
||||
|
||||
// If we are OOM killed with the disk cache enabled, the entire
|
||||
// cache will be cleared (bug 105843), so shut down the cache here
|
||||
// and re-init on foregrounding
|
||||
if (nsCacheService::GlobalInstance()) {
|
||||
nsCacheService::GlobalInstance()->Shutdown();
|
||||
}
|
||||
|
||||
// We really want to send a notification like profile-before-change,
|
||||
// but profile-before-change ends up shutting some things down instead
|
||||
// of flushing data
|
||||
nsIPrefService* prefs = Preferences::GetService();
|
||||
if (prefs) {
|
||||
// reset the crash loop state
|
||||
nsCOMPtr<nsIPrefBranch> prefBranch;
|
||||
prefs->GetBranch("browser.sessionstore.", getter_AddRefs(prefBranch));
|
||||
if (prefBranch)
|
||||
prefBranch->SetIntPref("recent_crashes", 0);
|
||||
|
||||
prefs->SavePrefFile(nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
static void OnResume()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
if (!sPauseCount || (--sPauseCount) > 0) {
|
||||
// Still paused.
|
||||
return;
|
||||
}
|
||||
|
||||
// If we are OOM killed with the disk cache enabled, the entire
|
||||
// cache will be cleared (bug 105843), so shut down cache on backgrounding
|
||||
// and re-init here
|
||||
if (nsCacheService::GlobalInstance()) {
|
||||
nsCacheService::GlobalInstance()->Init();
|
||||
}
|
||||
|
||||
// We didn't return from one of our own activities, so restore
|
||||
// to foreground status
|
||||
nsCOMPtr<nsIObserverService> obsServ =
|
||||
mozilla::services::GetObserverService();
|
||||
obsServ->NotifyObservers(nullptr, "application-foreground", nullptr);
|
||||
}
|
||||
};
|
||||
|
||||
uint32_t GeckoThreadSupport::sPauseCount;
|
||||
|
||||
|
||||
class GeckoAppShellSupport final
|
||||
: public widget::GeckoAppShell::Natives<GeckoAppShellSupport>
|
||||
, public UsesGeckoThreadProxy
|
||||
|
@ -248,7 +328,7 @@ nsAppShell::nsAppShell()
|
|||
// Initialize JNI and Set the corresponding state in GeckoThread.
|
||||
AndroidBridge::ConstructBridge();
|
||||
GeckoAppShellSupport::Init();
|
||||
GeckoThreadNatives::Init();
|
||||
GeckoThreadSupport::Init();
|
||||
mozilla::ANRReporter::Init();
|
||||
mozilla::PrefsHelper::Init();
|
||||
nsWindow::InitNatives();
|
||||
|
@ -600,53 +680,6 @@ nsAppShell::LegacyGeckoEvent::Run()
|
|||
break;
|
||||
}
|
||||
|
||||
case AndroidGeckoEvent::APP_BACKGROUNDING: {
|
||||
nsCOMPtr<nsIObserverService> obsServ =
|
||||
mozilla::services::GetObserverService();
|
||||
obsServ->NotifyObservers(nullptr, "application-background", nullptr);
|
||||
|
||||
NS_NAMED_LITERAL_STRING(minimize, "heap-minimize");
|
||||
obsServ->NotifyObservers(nullptr, "memory-pressure", minimize.get());
|
||||
|
||||
// If we are OOM killed with the disk cache enabled, the entire
|
||||
// cache will be cleared (bug 105843), so shut down the cache here
|
||||
// and re-init on foregrounding
|
||||
if (nsCacheService::GlobalInstance()) {
|
||||
nsCacheService::GlobalInstance()->Shutdown();
|
||||
}
|
||||
|
||||
// We really want to send a notification like profile-before-change,
|
||||
// but profile-before-change ends up shutting some things down instead
|
||||
// of flushing data
|
||||
nsIPrefService* prefs = Preferences::GetService();
|
||||
if (prefs) {
|
||||
// reset the crash loop state
|
||||
nsCOMPtr<nsIPrefBranch> prefBranch;
|
||||
prefs->GetBranch("browser.sessionstore.", getter_AddRefs(prefBranch));
|
||||
if (prefBranch)
|
||||
prefBranch->SetIntPref("recent_crashes", 0);
|
||||
|
||||
prefs->SavePrefFile(nullptr);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case AndroidGeckoEvent::APP_FOREGROUNDING: {
|
||||
// If we are OOM killed with the disk cache enabled, the entire
|
||||
// cache will be cleared (bug 105843), so shut down cache on backgrounding
|
||||
// and re-init here
|
||||
if (nsCacheService::GlobalInstance()) {
|
||||
nsCacheService::GlobalInstance()->Init();
|
||||
}
|
||||
|
||||
// We didn't return from one of our own activities, so restore
|
||||
// to foreground status
|
||||
nsCOMPtr<nsIObserverService> obsServ =
|
||||
mozilla::services::GetObserverService();
|
||||
obsServ->NotifyObservers(nullptr, "application-foreground", nullptr);
|
||||
break;
|
||||
}
|
||||
|
||||
case AndroidGeckoEvent::THUMBNAIL: {
|
||||
if (!nsAppShell::Get()->mBrowserApp)
|
||||
break;
|
||||
|
|
Загрузка…
Ссылка в новой задаче