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:
Jim Chen 2016-04-05 21:43:41 -04:00
Родитель 8318ca75b7
Коммит 2bb3a5b2e1
8 изменённых файлов: 149 добавлений и 64 удалений

Просмотреть файл

@ -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;