mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-17 06:09:19 +00:00
Backed out changeset 56a33c1c3210 (bug 1734394) for causing build bustages in GeckoBundleUtils.cpp CLOSED TREE
This commit is contained in:
parent
9295c48eba
commit
d6440ec5b2
@ -1098,10 +1098,6 @@ pref("browser.sessionstore.upgradeBackup.maxUpgradeBackups", 3);
|
||||
pref("browser.sessionstore.debug", false);
|
||||
// Forget closed windows/tabs after two weeks
|
||||
pref("browser.sessionstore.cleanup.forget_closed_after", 1209600000);
|
||||
// Platform collects data for session store
|
||||
pref("browser.sessionstore.platform_collection", true);
|
||||
// Platform collects session storage data for session store
|
||||
pref("browser.sessionstore.collect_session_storage", true);
|
||||
|
||||
// Don't quit the browser when Ctrl + Q is pressed.
|
||||
pref("browser.quitShortcut.disabled", false);
|
||||
|
@ -2441,7 +2441,7 @@ nsresult CanonicalBrowsingContext::WriteSessionStorageToSessionStore(
|
||||
|
||||
void CanonicalBrowsingContext::UpdateSessionStoreSessionStorage(
|
||||
const std::function<void()>& aDone) {
|
||||
if (!StaticPrefs::browser_sessionstore_collect_session_storage_AtStartup()) {
|
||||
if constexpr (!SessionStoreUtils::NATIVE_LISTENER) {
|
||||
aDone();
|
||||
return;
|
||||
}
|
||||
@ -2474,7 +2474,7 @@ void CanonicalBrowsingContext::UpdateSessionStoreForStorage(
|
||||
}
|
||||
|
||||
void CanonicalBrowsingContext::MaybeScheduleSessionStoreUpdate() {
|
||||
if (!StaticPrefs::browser_sessionstore_platform_collection_AtStartup()) {
|
||||
if constexpr (!SessionStoreUtils::NATIVE_LISTENER) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -5791,7 +5791,7 @@ nsDocShell::OnStateChange(nsIWebProgress* aProgress, nsIRequest* aRequest,
|
||||
}
|
||||
}
|
||||
|
||||
if (StaticPrefs::browser_sessionstore_platform_collection_AtStartup()) {
|
||||
if constexpr (SessionStoreUtils::NATIVE_LISTENER) {
|
||||
if (IsForceReloadType(mLoadType)) {
|
||||
if (WindowContext* windowContext =
|
||||
mBrowsingContext->GetCurrentWindowContext()) {
|
||||
@ -6535,7 +6535,7 @@ nsresult nsDocShell::EndPageLoad(nsIWebProgress* aProgress,
|
||||
// incorrectly overrides session store data from the following load.
|
||||
return NS_OK;
|
||||
}
|
||||
if (StaticPrefs::browser_sessionstore_platform_collection_AtStartup()) {
|
||||
if constexpr (SessionStoreUtils::NATIVE_LISTENER) {
|
||||
if (WindowContext* windowContext =
|
||||
mBrowsingContext->GetCurrentWindowContext()) {
|
||||
using Change = SessionStoreChangeListener::Change;
|
||||
|
@ -3089,7 +3089,7 @@ nsresult nsFrameLoader::EnsureMessageManager() {
|
||||
NS_ENSURE_TRUE(mChildMessageManager, NS_ERROR_UNEXPECTED);
|
||||
|
||||
// Set up session store
|
||||
if (StaticPrefs::browser_sessionstore_platform_collection_AtStartup()) {
|
||||
if constexpr (SessionStoreUtils::NATIVE_LISTENER) {
|
||||
if (XRE_IsParentProcess() && mIsTopLevelContent) {
|
||||
mSessionStoreChild = SessionStoreChild::GetOrCreate(
|
||||
GetExtantBrowsingContext(), mOwnerContent);
|
||||
|
@ -26,18 +26,6 @@ interface SessionStoreFormData {
|
||||
object toJSON();
|
||||
};
|
||||
|
||||
[GenerateConversionToJS]
|
||||
dictionary SessionStoreDisplaySize {
|
||||
unsigned long width;
|
||||
unsigned long height;
|
||||
};
|
||||
|
||||
[GenerateConversionToJS]
|
||||
dictionary SessionStoreZoomData {
|
||||
double resolution;
|
||||
SessionStoreDisplaySize displaySize;
|
||||
};
|
||||
|
||||
[ChromeOnly, Exposed=Window]
|
||||
interface SessionStoreScrollData {
|
||||
[Cached, Pure]
|
||||
|
@ -519,7 +519,7 @@ nsresult BrowserChild::Init(mozIDOMWindowProxy* aParent,
|
||||
|
||||
mIPCOpen = true;
|
||||
|
||||
if (StaticPrefs::browser_sessionstore_platform_collection_AtStartup()) {
|
||||
if constexpr (SessionStoreUtils::NATIVE_LISTENER) {
|
||||
mSessionStoreChild = SessionStoreChild::GetOrCreate(mBrowsingContext);
|
||||
}
|
||||
|
||||
|
@ -918,7 +918,7 @@ void BackgroundSessionStorageManager::SetCurrentBrowsingContextId(
|
||||
}
|
||||
|
||||
void BackgroundSessionStorageManager::MaybeScheduleSessionStoreUpdate() {
|
||||
if (!StaticPrefs::browser_sessionstore_platform_collection_AtStartup()) {
|
||||
if constexpr (!SessionStoreUtils::NATIVE_LISTENER) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -28,7 +28,6 @@ const DEFAULT_INTERVAL_MS = 1500;
|
||||
const TIMEOUT_DISABLED_PREF = "browser.sessionstore.debug.no_auto_updates";
|
||||
|
||||
const PREF_INTERVAL = "browser.sessionstore.interval";
|
||||
const PREF_SESSION_COLLECTION = "browser.sessionstore.platform_collection";
|
||||
|
||||
class Handler {
|
||||
constructor(store) {
|
||||
@ -425,10 +424,6 @@ class MessageQueue extends Handler {
|
||||
TIMEOUT_DISABLED_PREF,
|
||||
false
|
||||
);
|
||||
this.sessionCollection = Services.prefs.getBoolPref(
|
||||
PREF_SESSION_COLLECTION,
|
||||
false
|
||||
);
|
||||
this._timeoutWaitIdlePeriodMs = Services.prefs.getIntPref(
|
||||
PREF_INTERVAL,
|
||||
DEFAULT_INTERVAL_MS
|
||||
@ -604,16 +599,12 @@ class SessionStateAggregator extends GeckoViewChildModule {
|
||||
this.stateChangeNotifier = new StateChangeNotifier(this);
|
||||
|
||||
this.handlers = [
|
||||
new FormDataListener(this),
|
||||
new SessionHistoryListener(this),
|
||||
new ScrollPositionListener(this),
|
||||
this.stateChangeNotifier,
|
||||
this.messageQueue,
|
||||
];
|
||||
if (!this.sessionCollection) {
|
||||
this.handlers.push(
|
||||
new FormDataListener(this),
|
||||
new ScrollPositionListener(this)
|
||||
);
|
||||
}
|
||||
|
||||
this.messageManager.addMessageListener("GeckoView:FlushSessionState", this);
|
||||
}
|
||||
|
@ -1311,36 +1311,6 @@ public class GeckoSession {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@WrapForJNI(calledFrom = "gecko")
|
||||
private void onUpdateSessionStore(final GeckoBundle aBundle) {
|
||||
ThreadUtils.runOnUiThread(
|
||||
() -> {
|
||||
final GeckoSession session = mOwner.get();
|
||||
if (session == null) {
|
||||
return;
|
||||
}
|
||||
GeckoBundle scroll = aBundle.getBundle("scroll");
|
||||
if (scroll == null) {
|
||||
scroll = new GeckoBundle();
|
||||
aBundle.putBundle("scroll", scroll);
|
||||
}
|
||||
|
||||
// Here we unfortunately need to do some re-mapping since `zoom` is passed in a separate
|
||||
// bunds and we wish to keep the bundle format.
|
||||
scroll.putBundle("zoom", aBundle.getBundle("zoom"));
|
||||
final SessionState stateCache = session.mStateCache;
|
||||
stateCache.updateSessionState(aBundle);
|
||||
final SessionState state = new SessionState(stateCache);
|
||||
if (!state.isEmpty()) {
|
||||
final ProgressDelegate progressDelegate = session.getProgressDelegate();
|
||||
if (progressDelegate != null) {
|
||||
progressDelegate.onSessionStateChange(session, state);
|
||||
} else {
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private class Listener implements BundleEventListener {
|
||||
|
@ -1454,24 +1454,6 @@
|
||||
value: 15000
|
||||
mirror: always
|
||||
|
||||
# Platform collection of data for session store
|
||||
- name: browser.sessionstore.platform_collection
|
||||
type: bool
|
||||
value: false
|
||||
mirror: once
|
||||
|
||||
# Platform collection of session storage data for session store
|
||||
- name: browser.sessionstore.collect_session_storage
|
||||
type: bool
|
||||
value: false
|
||||
mirror: once
|
||||
|
||||
# Platform collection of zoom data for session store
|
||||
- name: browser.sessionstore.collect_zoom
|
||||
type: bool
|
||||
value: false
|
||||
mirror: once
|
||||
|
||||
# Causes SessionStore to ignore non-final update messages from
|
||||
# browser tabs that were not caused by a flush from the parent.
|
||||
# This is a testing flag and should not be used by end-users.
|
||||
|
@ -9,7 +9,6 @@ include protocol PInProcess;
|
||||
include SessionStoreTypes;
|
||||
|
||||
using mozilla::dom::MaybeDiscardedBrowsingContext from "mozilla/dom/BrowsingContext.h";
|
||||
using mozilla::dom::MaybeSessionStoreZoom from "mozilla/dom/SessionStoreScrollData.h";
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
@ -32,8 +31,8 @@ parent:
|
||||
* collected incrementally.
|
||||
*/
|
||||
async SessionStoreUpdate(
|
||||
nsCString? aDocShellCaps, bool? aPrivateMode, MaybeSessionStoreZoom aZoom,
|
||||
bool aNeedCollectSHistory, uint32_t aEpoch);
|
||||
nsCString? aDocShellCaps, bool? aPrivateMode, bool aNeedCollectSHistory,
|
||||
uint32_t aEpoch);
|
||||
|
||||
/**
|
||||
* Sends data to be stored to the session store. The collected data
|
||||
|
@ -24,7 +24,6 @@
|
||||
#include "nsPIDOMWindow.h"
|
||||
#include "nsTHashMap.h"
|
||||
#include "nsTHashtable.h"
|
||||
#include "nsLayoutUtils.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
@ -32,7 +31,6 @@ using namespace mozilla::dom;
|
||||
namespace {
|
||||
constexpr auto kInput = u"input"_ns;
|
||||
constexpr auto kScroll = u"mozvisualscroll"_ns;
|
||||
constexpr auto kResize = u"mozvisualresize"_ns;
|
||||
|
||||
static constexpr char kNoAutoUpdates[] =
|
||||
"browser.sessionstore.debug.no_auto_updates";
|
||||
@ -122,16 +120,14 @@ SessionStoreChangeListener::HandleEvent(dom::Event* aEvent) {
|
||||
RecordChange(windowContext, Change::Input);
|
||||
} else if (eventType == kScroll) {
|
||||
RecordChange(windowContext, Change::Scroll);
|
||||
} else if (eventType == kResize && browsingContext->IsTop()) {
|
||||
RecordChange(windowContext, Change::Resize);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* static */ already_AddRefed<SessionStoreChangeListener>
|
||||
SessionStoreChangeListener::Create(BrowsingContext* aBrowsingContext) {
|
||||
MOZ_RELEASE_ASSERT(
|
||||
StaticPrefs::browser_sessionstore_platform_collection_AtStartup());
|
||||
MOZ_RELEASE_ASSERT(SessionStoreUtils::NATIVE_LISTENER);
|
||||
if (!aBrowsingContext) {
|
||||
return nullptr;
|
||||
}
|
||||
@ -185,29 +181,6 @@ static void CollectFormData(Document* aDocument,
|
||||
}
|
||||
}
|
||||
|
||||
static void GetZoom(BrowsingContext* aBrowsingContext,
|
||||
Maybe<SessionStoreZoom>& aZoom) {
|
||||
nsIDocShell* docShell = aBrowsingContext->GetDocShell();
|
||||
if (!docShell) {
|
||||
return;
|
||||
}
|
||||
|
||||
PresShell* presShell = docShell->GetPresShell();
|
||||
if (!presShell) {
|
||||
return;
|
||||
}
|
||||
|
||||
LayoutDeviceIntSize displaySize;
|
||||
|
||||
if (!nsLayoutUtils::GetContentViewerSize(presShell->GetPresContext(),
|
||||
displaySize)) {
|
||||
return;
|
||||
}
|
||||
|
||||
aZoom.emplace(presShell->GetResolution(), displaySize.width,
|
||||
displaySize.height);
|
||||
}
|
||||
|
||||
void SessionStoreChangeListener::FlushSessionStore() {
|
||||
if (mTimer) {
|
||||
mTimer->Cancel();
|
||||
@ -216,7 +189,6 @@ void SessionStoreChangeListener::FlushSessionStore() {
|
||||
|
||||
bool collectSessionHistory = false;
|
||||
bool collectWireFrame = false;
|
||||
bool didResize = false;
|
||||
|
||||
for (auto& iter : mSessionStoreChanges) {
|
||||
WindowContext* windowContext = iter.GetKey();
|
||||
@ -258,10 +230,6 @@ void SessionStoreChangeListener::FlushSessionStore() {
|
||||
collectSessionHistory =
|
||||
collectSessionHistory || changes.contains(Change::SessionHistory);
|
||||
|
||||
if (presShell && changes.contains(Change::Resize)) {
|
||||
didResize = true;
|
||||
}
|
||||
|
||||
mSessionStoreChild->IncrementalSessionStoreUpdate(
|
||||
browsingContext, maybeFormData, maybeScroll, mEpoch);
|
||||
}
|
||||
@ -271,13 +239,7 @@ void SessionStoreChangeListener::FlushSessionStore() {
|
||||
}
|
||||
|
||||
mSessionStoreChanges.Clear();
|
||||
|
||||
Maybe<SessionStoreZoom> zoom;
|
||||
if (didResize) {
|
||||
GetZoom(mBrowsingContext->Top(), zoom);
|
||||
}
|
||||
|
||||
mSessionStoreChild->UpdateSessionStore(collectSessionHistory, zoom);
|
||||
mSessionStoreChild->UpdateSessionStore(collectSessionHistory);
|
||||
}
|
||||
|
||||
/* static */
|
||||
@ -352,9 +314,6 @@ void SessionStoreChangeListener::AddEventListeners() {
|
||||
if (EventTarget* target = GetEventTarget()) {
|
||||
target->AddSystemEventListener(kInput, this, false);
|
||||
target->AddSystemEventListener(kScroll, this, false);
|
||||
if (StaticPrefs::browser_sessionstore_collect_zoom_AtStartup()) {
|
||||
target->AddSystemEventListener(kResize, this, false);
|
||||
}
|
||||
mCurrentEventTarget = target;
|
||||
}
|
||||
}
|
||||
@ -363,9 +322,6 @@ void SessionStoreChangeListener::RemoveEventListeners() {
|
||||
if (mCurrentEventTarget) {
|
||||
mCurrentEventTarget->RemoveSystemEventListener(kInput, this, false);
|
||||
mCurrentEventTarget->RemoveSystemEventListener(kScroll, this, false);
|
||||
if (StaticPrefs::browser_sessionstore_collect_zoom_AtStartup()) {
|
||||
mCurrentEventTarget->RemoveSystemEventListener(kResize, this, false);
|
||||
}
|
||||
}
|
||||
|
||||
mCurrentEventTarget = nullptr;
|
||||
|
@ -56,7 +56,7 @@ class SessionStoreChangeListener final : public nsINamed,
|
||||
|
||||
void FlushSessionStore();
|
||||
|
||||
enum class Change { Input, Scroll, SessionHistory, WireFrame, Resize };
|
||||
enum class Change { Input, Scroll, SessionHistory, WireFrame };
|
||||
|
||||
static SessionStoreChangeListener* CollectSessionStoreData(
|
||||
WindowContext* aWindowContext, const EnumSet<Change>& aChanges);
|
||||
|
@ -167,12 +167,10 @@ void SessionStoreChild::UpdateEventTargets() {
|
||||
}
|
||||
}
|
||||
|
||||
void SessionStoreChild::UpdateSessionStore(bool aSessionHistoryUpdate,
|
||||
const MaybeSessionStoreZoom& aZoom) {
|
||||
void SessionStoreChild::UpdateSessionStore(bool aSessionHistoryUpdate) {
|
||||
if (!mSessionStoreListener) {
|
||||
// This is the case when we're shutting down, and expect a final update.
|
||||
SessionStoreUpdate(Nothing(), Nothing(), Nothing(), aSessionHistoryUpdate,
|
||||
0);
|
||||
SessionStoreUpdate(Nothing(), Nothing(), aSessionHistoryUpdate, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -189,7 +187,7 @@ void SessionStoreChild::UpdateSessionStore(bool aSessionHistoryUpdate,
|
||||
}
|
||||
|
||||
SessionStoreUpdate(
|
||||
docShellCaps, privatedMode, aZoom,
|
||||
docShellCaps, privatedMode,
|
||||
store->GetAndClearSHistoryChanged() || aSessionHistoryUpdate,
|
||||
mSessionStoreListener->GetEpoch());
|
||||
}
|
||||
@ -218,15 +216,14 @@ mozilla::ipc::IPCResult SessionStoreChild::RecvFlushTabState(
|
||||
|
||||
void SessionStoreChild::SessionStoreUpdate(
|
||||
const Maybe<nsCString>& aDocShellCaps, const Maybe<bool>& aPrivatedMode,
|
||||
const MaybeSessionStoreZoom& aZoom, const bool aNeedCollectSHistory,
|
||||
const uint32_t& aEpoch) {
|
||||
const bool aNeedCollectSHistory, const uint32_t& aEpoch) {
|
||||
if (XRE_IsContentProcess()) {
|
||||
Unused << SendSessionStoreUpdate(aDocShellCaps, aPrivatedMode, aZoom,
|
||||
Unused << SendSessionStoreUpdate(aDocShellCaps, aPrivatedMode,
|
||||
aNeedCollectSHistory, aEpoch);
|
||||
} else if (SessionStoreParent* sessionStoreParent =
|
||||
static_cast<SessionStoreParent*>(
|
||||
InProcessChild::ParentActorFor(this))) {
|
||||
sessionStoreParent->SessionStoreUpdate(aDocShellCaps, aPrivatedMode, aZoom,
|
||||
sessionStoreParent->SessionStoreUpdate(aDocShellCaps, aPrivatedMode,
|
||||
aNeedCollectSHistory, aEpoch);
|
||||
}
|
||||
}
|
||||
|
@ -9,7 +9,6 @@
|
||||
|
||||
#include "mozilla/AlreadyAddRefed.h"
|
||||
#include "mozilla/dom/PSessionStoreChild.h"
|
||||
#include "mozilla/dom/SessionStoreScrollData.h"
|
||||
#include "mozilla/dom/SessionStoreChangeListener.h"
|
||||
#include "mozilla/dom/SessionStoreListener.h"
|
||||
#include "mozilla/RefPtr.h"
|
||||
@ -32,14 +31,12 @@ class SessionStoreChild final : public PSessionStoreChild {
|
||||
void SetOwnerContent(Element* aElement);
|
||||
void Stop();
|
||||
void UpdateEventTargets();
|
||||
void UpdateSessionStore(bool aSessionHistoryUpdate = false,
|
||||
const MaybeSessionStoreZoom& aZoom = Nothing());
|
||||
void UpdateSessionStore(bool aSessionHistoryUpdate = false);
|
||||
void FlushSessionStore();
|
||||
void UpdateSHistoryChanges();
|
||||
|
||||
void SessionStoreUpdate(const Maybe<nsCString>& aDocShellCaps,
|
||||
const Maybe<bool>& aPrivatedMode,
|
||||
const MaybeSessionStoreZoom& aZoom,
|
||||
const bool aNeedCollectSHistory,
|
||||
const uint32_t& aEpoch);
|
||||
|
||||
|
@ -25,12 +25,6 @@
|
||||
#include "nsImportModule.h"
|
||||
#include "nsIXPConnect.h"
|
||||
|
||||
#ifdef ANDROID
|
||||
# include "mozilla/widget/nsWindow.h"
|
||||
# include "mozilla/jni/GeckoBundleUtils.h"
|
||||
# include "JavaBuiltins.h"
|
||||
#endif /* ANDROID */
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
|
||||
@ -39,81 +33,9 @@ SessionStoreParent::SessionStoreParent(
|
||||
BrowserSessionStore* aSessionStore)
|
||||
: mBrowsingContext(aBrowsingContext), mSessionStore(aSessionStore) {}
|
||||
|
||||
#ifdef ANDROID
|
||||
static void DoSessionStoreUpdate(CanonicalBrowsingContext* aBrowsingContext,
|
||||
const Maybe<nsCString>& aDocShellCaps,
|
||||
const Maybe<bool>& aPrivatedMode,
|
||||
SessionStoreFormData* aFormData,
|
||||
SessionStoreScrollData* aScroll,
|
||||
const MaybeSessionStoreZoom& aZoom,
|
||||
bool aNeedCollectSHistory, uint32_t aEpoch) {
|
||||
RefPtr<BrowserSessionStore> sessionStore =
|
||||
BrowserSessionStore::GetOrCreate(aBrowsingContext->Top());
|
||||
|
||||
nsCOMPtr<nsIWidget> widget =
|
||||
aBrowsingContext->GetParentProcessWidgetContaining();
|
||||
if (RefPtr<nsWindow> window = nsWindow::From(widget)) {
|
||||
AutoJSAPI jsapi;
|
||||
if (!jsapi.Init(xpc::PrivilegedJunkScope())) {
|
||||
return;
|
||||
}
|
||||
jni::Object::LocalRef formDataBundle(jni::GetGeckoThreadEnv());
|
||||
jni::Object::LocalRef scrollBundle(jni::GetGeckoThreadEnv());
|
||||
|
||||
if (aFormData) {
|
||||
JS::RootedObject object(jsapi.cx());
|
||||
ErrorResult rv;
|
||||
aFormData->ToJSON(jsapi.cx(), &object);
|
||||
|
||||
JS::RootedValue value(jsapi.cx(), JS::ObjectValue(*object));
|
||||
|
||||
if (NS_FAILED(jni::BoxData(jsapi.cx(), value, formDataBundle, true))) {
|
||||
JS_ClearPendingException(jsapi.cx());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (aScroll) {
|
||||
JS::RootedObject object(jsapi.cx());
|
||||
ErrorResult rv;
|
||||
aScroll->ToJSON(jsapi.cx(), &object);
|
||||
JS::RootedValue value(jsapi.cx(), JS::ObjectValue(*object));
|
||||
|
||||
if (NS_FAILED(jni::BoxData(jsapi.cx(), value, scrollBundle, true))) {
|
||||
JS_ClearPendingException(jsapi.cx());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
GECKOBUNDLE_START(update);
|
||||
GECKOBUNDLE_PUT(update, "formdata", formDataBundle);
|
||||
GECKOBUNDLE_PUT(update, "scroll", scrollBundle);
|
||||
if (aZoom) {
|
||||
GECKOBUNDLE_START(zoomBundle);
|
||||
GECKOBUNDLE_PUT(zoomBundle, "resolution",
|
||||
java::sdk::Double::New(Get<0>(*aZoom)));
|
||||
GECKOBUNDLE_START(displaySizeBundle);
|
||||
GECKOBUNDLE_PUT(displaySizeBundle, "width",
|
||||
java::sdk::Integer::ValueOf(Get<1>(*aZoom)));
|
||||
GECKOBUNDLE_PUT(displaySizeBundle, "height",
|
||||
java::sdk::Integer::ValueOf(Get<2>(*aZoom)));
|
||||
GECKOBUNDLE_FINISH(displaySizeBundle);
|
||||
GECKOBUNDLE_PUT(zoomBundle, "displaySize", displaySizeBundle);
|
||||
GECKOBUNDLE_FINISH(zoomBundle);
|
||||
GECKOBUNDLE_PUT(update, "zoom", zoomBundle);
|
||||
}
|
||||
GECKOBUNDLE_FINISH(update);
|
||||
|
||||
window->OnUpdateSessionStore(update);
|
||||
}
|
||||
}
|
||||
#else
|
||||
static void DoSessionStoreUpdate(CanonicalBrowsingContext* aBrowsingContext,
|
||||
const Maybe<nsCString>& aDocShellCaps,
|
||||
const Maybe<bool>& aPrivatedMode,
|
||||
SessionStoreFormData* aFormData,
|
||||
SessionStoreScrollData* aScroll,
|
||||
const MaybeSessionStoreZoom& aZoom,
|
||||
bool aNeedCollectSHistory, uint32_t aEpoch) {
|
||||
UpdateSessionStoreData data;
|
||||
if (aDocShellCaps.isSome()) {
|
||||
@ -132,19 +54,11 @@ static void DoSessionStoreUpdate(CanonicalBrowsingContext* aBrowsingContext,
|
||||
RefPtr<BrowserSessionStore> sessionStore =
|
||||
BrowserSessionStore::GetOrCreate(aBrowsingContext->Top());
|
||||
|
||||
if (!aFormData) {
|
||||
SessionStoreFormData* formData = sessionStore->GetFormdata();
|
||||
data.mFormdata.Construct(formData);
|
||||
} else {
|
||||
data.mFormdata.Construct(aFormData);
|
||||
}
|
||||
SessionStoreFormData* formData = sessionStore->GetFormdata();
|
||||
data.mFormdata.Construct(formData);
|
||||
|
||||
if (!aScroll) {
|
||||
SessionStoreScrollData* scroll = sessionStore->GetScroll();
|
||||
data.mScroll.Construct(scroll);
|
||||
} else {
|
||||
data.mScroll.Construct(aScroll);
|
||||
}
|
||||
SessionStoreScrollData* scroll = sessionStore->GetScroll();
|
||||
data.mScroll.Construct(scroll);
|
||||
|
||||
nsCOMPtr<nsISessionStoreFunctions> funcs = do_ImportModule(
|
||||
"resource://gre/modules/SessionStoreFunctions.jsm", fallible);
|
||||
@ -168,7 +82,6 @@ static void DoSessionStoreUpdate(CanonicalBrowsingContext* aBrowsingContext,
|
||||
Unused << funcs->UpdateSessionStore(nullptr, aBrowsingContext, key, aEpoch,
|
||||
aNeedCollectSHistory, update);
|
||||
}
|
||||
#endif
|
||||
|
||||
void SessionStoreParent::FlushAllSessionStoreChildren(
|
||||
const std::function<void()>& aDone) {
|
||||
@ -244,23 +157,13 @@ void SessionStoreParent::FinalFlushAllSessionStoreChildren(
|
||||
|
||||
mozilla::ipc::IPCResult SessionStoreParent::RecvSessionStoreUpdate(
|
||||
const Maybe<nsCString>& aDocShellCaps, const Maybe<bool>& aPrivatedMode,
|
||||
const MaybeSessionStoreZoom& aZoom, const bool aNeedCollectSHistory,
|
||||
const uint32_t& aEpoch) {
|
||||
const bool aNeedCollectSHistory, const uint32_t& aEpoch) {
|
||||
if (!mBrowsingContext) {
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
RefPtr<SessionStoreFormData> formData =
|
||||
mHasNewFormData ? mSessionStore->GetFormdata() : nullptr;
|
||||
RefPtr<SessionStoreScrollData> scroll =
|
||||
mHasNewScrollPosition ? mSessionStore->GetScroll() : nullptr;
|
||||
|
||||
DoSessionStoreUpdate(mBrowsingContext, aDocShellCaps, aPrivatedMode, formData,
|
||||
scroll, aZoom, aNeedCollectSHistory, aEpoch);
|
||||
|
||||
mHasNewFormData = false;
|
||||
mHasNewScrollPosition = false;
|
||||
|
||||
DoSessionStoreUpdate(mBrowsingContext, aDocShellCaps, aPrivatedMode,
|
||||
aNeedCollectSHistory, aEpoch);
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
@ -269,13 +172,6 @@ mozilla::ipc::IPCResult SessionStoreParent::RecvIncrementalSessionStoreUpdate(
|
||||
const Maybe<FormData>& aFormData, const Maybe<nsPoint>& aScrollPosition,
|
||||
uint32_t aEpoch) {
|
||||
if (!aBrowsingContext.IsNull()) {
|
||||
if (aFormData.isSome()) {
|
||||
mHasNewFormData = true;
|
||||
}
|
||||
if (aScrollPosition.isSome()) {
|
||||
mHasNewScrollPosition = true;
|
||||
}
|
||||
|
||||
mSessionStore->UpdateSessionStore(
|
||||
aBrowsingContext.GetMaybeDiscarded()->Canonical(), aFormData,
|
||||
aScrollPosition, aEpoch);
|
||||
@ -295,9 +191,8 @@ mozilla::ipc::IPCResult SessionStoreParent::RecvResetSessionStore(
|
||||
|
||||
void SessionStoreParent::SessionStoreUpdate(
|
||||
const Maybe<nsCString>& aDocShellCaps, const Maybe<bool>& aPrivatedMode,
|
||||
const MaybeSessionStoreZoom& aZoom, const bool aNeedCollectSHistory,
|
||||
const uint32_t& aEpoch) {
|
||||
Unused << RecvSessionStoreUpdate(aDocShellCaps, aPrivatedMode, aZoom,
|
||||
const bool aNeedCollectSHistory, const uint32_t& aEpoch) {
|
||||
Unused << RecvSessionStoreUpdate(aDocShellCaps, aPrivatedMode,
|
||||
aNeedCollectSHistory, aEpoch);
|
||||
}
|
||||
|
||||
|
@ -12,7 +12,6 @@
|
||||
#include "mozilla/dom/Element.h"
|
||||
#include "mozilla/dom/PSessionStoreParent.h"
|
||||
#include "mozilla/dom/WindowGlobalParent.h"
|
||||
#include "mozilla/dom/SessionStoreScrollData.h"
|
||||
|
||||
namespace mozilla::dom {
|
||||
class BrowserParent;
|
||||
@ -32,8 +31,7 @@ class SessionStoreParent final : public PSessionStoreParent {
|
||||
*/
|
||||
mozilla::ipc::IPCResult RecvSessionStoreUpdate(
|
||||
const Maybe<nsCString>& aDocShellCaps, const Maybe<bool>& aPrivatedMode,
|
||||
const MaybeSessionStoreZoom& aZoom, const bool aNeedCollectSHistory,
|
||||
const uint32_t& aEpoch);
|
||||
const bool aNeedCollectSHistory, const uint32_t& aEpoch);
|
||||
|
||||
mozilla::ipc::IPCResult RecvIncrementalSessionStoreUpdate(
|
||||
const MaybeDiscarded<BrowsingContext>& aBrowsingContext,
|
||||
@ -50,7 +48,6 @@ class SessionStoreParent final : public PSessionStoreParent {
|
||||
friend class SessionStoreChild;
|
||||
void SessionStoreUpdate(const Maybe<nsCString>& aDocShellCaps,
|
||||
const Maybe<bool>& aPrivatedMode,
|
||||
const MaybeSessionStoreZoom& aZoom,
|
||||
const bool aNeedCollectSHistory,
|
||||
const uint32_t& aEpoch);
|
||||
|
||||
@ -68,9 +65,6 @@ class SessionStoreParent final : public PSessionStoreParent {
|
||||
already_AddRefed<SessionStoreParent::FlushTabStatePromise>
|
||||
FlushSessionStore();
|
||||
|
||||
bool mHasNewFormData = false;
|
||||
bool mHasNewScrollPosition = false;
|
||||
|
||||
RefPtr<CanonicalBrowsingContext> mBrowsingContext;
|
||||
RefPtr<BrowserSessionStore> mSessionStore;
|
||||
};
|
||||
|
@ -7,24 +7,17 @@
|
||||
#ifndef mozilla_dom_SessionStoreScrollData_h
|
||||
#define mozilla_dom_SessionStoreScrollData_h
|
||||
|
||||
#include "js/TypeDecls.h"
|
||||
#include "mozilla/WeakPtr.h"
|
||||
#include "nsPoint.h"
|
||||
#include "nsTArray.h"
|
||||
#include "nsWrapperCache.h"
|
||||
#include "mozilla/dom/WindowGlobalParent.h"
|
||||
#include "mozilla/dom/SessionStoreChangeListener.h"
|
||||
|
||||
namespace mozilla::dom {
|
||||
|
||||
class BrowsingContext;
|
||||
class WindowGlobalParent;
|
||||
class OwningByteStringOrObjectOrNull;
|
||||
struct SessionStoreZoomData;
|
||||
|
||||
using SessionStoreZoom = mozilla::Tuple<float, uint32_t, uint32_t>;
|
||||
using MaybeSessionStoreZoom =
|
||||
mozilla::Maybe<mozilla::Tuple<float, uint32_t, uint32_t>>;
|
||||
|
||||
class SessionStoreScrollData final : public nsISupports,
|
||||
public nsWrapperCache,
|
||||
@ -60,7 +53,6 @@ class SessionStoreScrollData final : public nsISupports,
|
||||
~SessionStoreScrollData() = default;
|
||||
|
||||
nsPoint mScroll;
|
||||
MaybeSessionStoreZoom mZoom;
|
||||
nsTArray<RefPtr<SessionStoreScrollData>> mChildren;
|
||||
};
|
||||
|
||||
|
@ -139,6 +139,13 @@ class SessionStoreUtils {
|
||||
const nsTArray<SSCacheCopy>& aValues,
|
||||
Record<nsCString, Record<nsString, nsString>>& aStorage);
|
||||
|
||||
#if defined(MOZ_WIDGET_ANDROID) || defined(MOZ_THUNDERBIRD) || \
|
||||
defined(MOZ_SUITE)
|
||||
static constexpr bool NATIVE_LISTENER = false;
|
||||
#else
|
||||
static constexpr bool NATIVE_LISTENER = true;
|
||||
#endif
|
||||
|
||||
static bool CopyProperty(JSContext* aCx, JS::HandleObject aDst,
|
||||
JS::HandleObject aSrc, const nsAString& aName);
|
||||
|
||||
|
@ -19,7 +19,6 @@
|
||||
#include "mozilla/ScopeExit.h"
|
||||
#include "mozilla/dom/ScriptSettings.h"
|
||||
#include "mozilla/java/EventCallbackWrappers.h"
|
||||
#include "mozilla/jni/GeckoBundleUtils.h"
|
||||
|
||||
// Disable the C++ 2a warning. See bug #1509926
|
||||
#if defined(__clang__)
|
||||
@ -39,9 +38,266 @@ bool CheckJS(JSContext* aCx, bool aResult) {
|
||||
return aResult;
|
||||
}
|
||||
|
||||
nsresult BoxString(JSContext* aCx, JS::HandleValue aData,
|
||||
jni::Object::LocalRef& aOut) {
|
||||
if (aData.isNullOrUndefined()) {
|
||||
aOut = nullptr;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(aData.isString());
|
||||
|
||||
JS::RootedString str(aCx, aData.toString());
|
||||
|
||||
if (JS::StringHasLatin1Chars(str)) {
|
||||
nsAutoJSString autoStr;
|
||||
NS_ENSURE_TRUE(CheckJS(aCx, autoStr.init(aCx, str)), NS_ERROR_FAILURE);
|
||||
|
||||
// StringParam can automatically convert a nsString to jstring.
|
||||
aOut = jni::StringParam(autoStr, aOut.Env(), fallible);
|
||||
if (!aOut) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Two-byte string
|
||||
JNIEnv* const env = aOut.Env();
|
||||
const char16_t* chars;
|
||||
{
|
||||
JS::AutoCheckCannotGC nogc;
|
||||
size_t len = 0;
|
||||
chars = JS_GetTwoByteStringCharsAndLength(aCx, nogc, str, &len);
|
||||
if (chars) {
|
||||
aOut = jni::String::LocalRef::Adopt(
|
||||
env, env->NewString(reinterpret_cast<const jchar*>(chars), len));
|
||||
}
|
||||
}
|
||||
if (NS_WARN_IF(!CheckJS(aCx, !!chars) || !aOut)) {
|
||||
env->ExceptionClear();
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult BoxObject(JSContext* aCx, JS::HandleValue aData,
|
||||
jni::Object::LocalRef& aOut);
|
||||
|
||||
template <typename Type, bool (JS::Value::*IsType)() const,
|
||||
Type (JS::Value::*ToType)() const, class ArrayType,
|
||||
typename ArrayType::LocalRef (*NewArray)(const Type*, size_t)>
|
||||
nsresult BoxArrayPrimitive(JSContext* aCx, JS::HandleObject aData,
|
||||
jni::Object::LocalRef& aOut, size_t aLength,
|
||||
JS::HandleValue aElement) {
|
||||
JS::RootedValue element(aCx);
|
||||
auto data = MakeUnique<Type[]>(aLength);
|
||||
data[0] = (aElement.get().*ToType)();
|
||||
|
||||
for (size_t i = 1; i < aLength; i++) {
|
||||
NS_ENSURE_TRUE(CheckJS(aCx, JS_GetElement(aCx, aData, i, &element)),
|
||||
NS_ERROR_FAILURE);
|
||||
NS_ENSURE_TRUE((element.get().*IsType)(), NS_ERROR_INVALID_ARG);
|
||||
|
||||
data[i] = (element.get().*ToType)();
|
||||
}
|
||||
aOut = (*NewArray)(data.get(), aLength);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
template <class Type,
|
||||
nsresult (*Box)(JSContext*, JS::HandleValue, jni::Object::LocalRef&),
|
||||
typename IsType>
|
||||
nsresult BoxArrayObject(JSContext* aCx, JS::HandleObject aData,
|
||||
jni::Object::LocalRef& aOut, size_t aLength,
|
||||
JS::HandleValue aElement, IsType&& aIsType) {
|
||||
auto out = jni::ObjectArray::New<Type>(aLength);
|
||||
JS::RootedValue element(aCx);
|
||||
jni::Object::LocalRef jniElement(aOut.Env());
|
||||
|
||||
nsresult rv = (*Box)(aCx, aElement, jniElement);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
out->SetElement(0, jniElement);
|
||||
|
||||
for (size_t i = 1; i < aLength; i++) {
|
||||
NS_ENSURE_TRUE(CheckJS(aCx, JS_GetElement(aCx, aData, i, &element)),
|
||||
NS_ERROR_FAILURE);
|
||||
NS_ENSURE_TRUE(element.isNullOrUndefined() || aIsType(element),
|
||||
NS_ERROR_INVALID_ARG);
|
||||
|
||||
rv = (*Box)(aCx, element, jniElement);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
out->SetElement(i, jniElement);
|
||||
}
|
||||
aOut = out;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult BoxArray(JSContext* aCx, JS::HandleObject aData,
|
||||
jni::Object::LocalRef& aOut) {
|
||||
uint32_t length = 0;
|
||||
NS_ENSURE_TRUE(CheckJS(aCx, JS::GetArrayLength(aCx, aData, &length)),
|
||||
NS_ERROR_FAILURE);
|
||||
|
||||
if (!length) {
|
||||
// Always represent empty arrays as an empty boolean array.
|
||||
aOut = java::GeckoBundle::EMPTY_BOOLEAN_ARRAY();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// We only check the first element's type. If the array has mixed types,
|
||||
// we'll throw an error during actual conversion.
|
||||
JS::RootedValue element(aCx);
|
||||
NS_ENSURE_TRUE(CheckJS(aCx, JS_GetElement(aCx, aData, 0, &element)),
|
||||
NS_ERROR_FAILURE);
|
||||
|
||||
if (element.isBoolean()) {
|
||||
return BoxArrayPrimitive<bool, &JS::Value::isBoolean, &JS::Value::toBoolean,
|
||||
jni::BooleanArray, &jni::BooleanArray::New>(
|
||||
aCx, aData, aOut, length, element);
|
||||
}
|
||||
|
||||
if (element.isInt32()) {
|
||||
nsresult rv =
|
||||
BoxArrayPrimitive<int32_t, &JS::Value::isInt32, &JS::Value::toInt32,
|
||||
jni::IntArray, &jni::IntArray::New>(aCx, aData, aOut,
|
||||
length, element);
|
||||
if (rv != NS_ERROR_INVALID_ARG) {
|
||||
return rv;
|
||||
}
|
||||
// Not int32, but we can still try a double array.
|
||||
}
|
||||
|
||||
if (element.isNumber()) {
|
||||
return BoxArrayPrimitive<double, &JS::Value::isNumber, &JS::Value::toNumber,
|
||||
jni::DoubleArray, &jni::DoubleArray::New>(
|
||||
aCx, aData, aOut, length, element);
|
||||
}
|
||||
|
||||
if (element.isNullOrUndefined() || element.isString()) {
|
||||
const auto isString = [](JS::HandleValue val) -> bool {
|
||||
return val.isString();
|
||||
};
|
||||
nsresult rv = BoxArrayObject<jni::String, &BoxString>(
|
||||
aCx, aData, aOut, length, element, isString);
|
||||
if (element.isString() || rv != NS_ERROR_INVALID_ARG) {
|
||||
return rv;
|
||||
}
|
||||
// First element was null/undefined, so it may still be an object array.
|
||||
}
|
||||
|
||||
const auto isObject = [aCx](JS::HandleValue val) -> bool {
|
||||
if (!val.isObject()) {
|
||||
return false;
|
||||
}
|
||||
bool array = false;
|
||||
JS::RootedObject obj(aCx, &val.toObject());
|
||||
// We don't support array of arrays.
|
||||
return CheckJS(aCx, JS::IsArrayObject(aCx, obj, &array)) && !array;
|
||||
};
|
||||
|
||||
if (element.isNullOrUndefined() || isObject(element)) {
|
||||
return BoxArrayObject<java::GeckoBundle, &BoxObject>(
|
||||
aCx, aData, aOut, length, element, isObject);
|
||||
}
|
||||
|
||||
NS_WARNING("Unknown type");
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
nsresult BoxValue(JSContext* aCx, JS::HandleValue aData,
|
||||
jni::Object::LocalRef& aOut);
|
||||
|
||||
nsresult BoxObject(JSContext* aCx, JS::HandleValue aData,
|
||||
jni::Object::LocalRef& aOut) {
|
||||
if (aData.isNullOrUndefined()) {
|
||||
aOut = nullptr;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(aData.isObject());
|
||||
|
||||
JS::Rooted<JS::IdVector> ids(aCx, JS::IdVector(aCx));
|
||||
JS::RootedObject obj(aCx, &aData.toObject());
|
||||
|
||||
bool isArray = false;
|
||||
if (CheckJS(aCx, JS::IsArrayObject(aCx, obj, &isArray)) && isArray) {
|
||||
return BoxArray(aCx, obj, aOut);
|
||||
}
|
||||
|
||||
NS_ENSURE_TRUE(CheckJS(aCx, JS_Enumerate(aCx, obj, &ids)), NS_ERROR_FAILURE);
|
||||
|
||||
const size_t length = ids.length();
|
||||
auto keys = jni::ObjectArray::New<jni::String>(length);
|
||||
auto values = jni::ObjectArray::New<jni::Object>(length);
|
||||
|
||||
// Iterate through each property of the JS object.
|
||||
for (size_t i = 0; i < ids.length(); i++) {
|
||||
const JS::RootedId id(aCx, ids[i]);
|
||||
JS::RootedValue idVal(aCx);
|
||||
JS::RootedValue val(aCx);
|
||||
jni::Object::LocalRef key(aOut.Env());
|
||||
jni::Object::LocalRef value(aOut.Env());
|
||||
|
||||
NS_ENSURE_TRUE(CheckJS(aCx, JS_IdToValue(aCx, id, &idVal)),
|
||||
NS_ERROR_FAILURE);
|
||||
|
||||
JS::RootedString idStr(aCx, JS::ToString(aCx, idVal));
|
||||
NS_ENSURE_TRUE(CheckJS(aCx, !!idStr), NS_ERROR_FAILURE);
|
||||
|
||||
idVal.setString(idStr);
|
||||
NS_ENSURE_SUCCESS(BoxString(aCx, idVal, key), NS_ERROR_FAILURE);
|
||||
NS_ENSURE_TRUE(CheckJS(aCx, JS_GetPropertyById(aCx, obj, id, &val)),
|
||||
NS_ERROR_FAILURE);
|
||||
|
||||
nsresult rv = BoxValue(aCx, val, value);
|
||||
if (rv == NS_ERROR_INVALID_ARG && !JS_IsExceptionPending(aCx)) {
|
||||
nsAutoJSString autoStr;
|
||||
if (CheckJS(aCx, autoStr.init(aCx, idVal.toString()))) {
|
||||
JS_ReportErrorUTF8(aCx, u8"Invalid event data property %s",
|
||||
NS_ConvertUTF16toUTF8(autoStr).get());
|
||||
}
|
||||
}
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
keys->SetElement(i, key);
|
||||
values->SetElement(i, value);
|
||||
}
|
||||
|
||||
aOut = java::GeckoBundle::New(keys, values);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult BoxValue(JSContext* aCx, JS::HandleValue aData,
|
||||
jni::Object::LocalRef& aOut) {
|
||||
if (aData.isNullOrUndefined()) {
|
||||
aOut = nullptr;
|
||||
} else if (aData.isBoolean()) {
|
||||
aOut = aData.toBoolean() ? java::sdk::Boolean::TRUE()
|
||||
: java::sdk::Boolean::FALSE();
|
||||
} else if (aData.isInt32()) {
|
||||
aOut = java::sdk::Integer::ValueOf(aData.toInt32());
|
||||
} else if (aData.isNumber()) {
|
||||
aOut = java::sdk::Double::New(aData.toNumber());
|
||||
} else if (aData.isString()) {
|
||||
return BoxString(aCx, aData, aOut);
|
||||
} else if (aData.isObject()) {
|
||||
return BoxObject(aCx, aData, aOut);
|
||||
} else {
|
||||
NS_WARNING("Unknown type");
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult BoxData(const nsAString& aEvent, JSContext* aCx, JS::HandleValue aData,
|
||||
jni::Object::LocalRef& aOut, bool aObjectOnly) {
|
||||
nsresult rv = jni::BoxData(aCx, aData, aOut, aObjectOnly);
|
||||
nsresult rv = NS_ERROR_INVALID_ARG;
|
||||
|
||||
if (!aObjectOnly) {
|
||||
rv = BoxValue(aCx, aData, aOut);
|
||||
} else if (aData.isObject() || aData.isNullOrUndefined()) {
|
||||
rv = BoxObject(aCx, aData, aOut);
|
||||
}
|
||||
if (rv != NS_ERROR_INVALID_ARG) {
|
||||
return rv;
|
||||
}
|
||||
|
@ -91,8 +91,6 @@ class GeckoViewSupport final
|
||||
|
||||
void OnShowDynamicToolbar() const;
|
||||
|
||||
void OnUpdateSessionStore(mozilla::jni::Object::Param aBundle);
|
||||
|
||||
void PassExternalResponse(java::WebResponse::Param aResponse);
|
||||
|
||||
void AttachMediaSessionController(
|
||||
|
@ -1,289 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "mozilla/jni/GeckoBundleUtils.h"
|
||||
|
||||
#include "JavaBuiltins.h"
|
||||
#include "js/Warnings.h"
|
||||
#include "nsJSUtils.h"
|
||||
|
||||
#include "js/Array.h"
|
||||
|
||||
namespace mozilla::jni {
|
||||
namespace detail {
|
||||
bool CheckJS(JSContext* aCx, bool aResult) {
|
||||
if (!aResult) {
|
||||
JS_ClearPendingException(aCx);
|
||||
}
|
||||
return aResult;
|
||||
}
|
||||
|
||||
nsresult BoxString(JSContext* aCx, JS::HandleValue aData,
|
||||
jni::Object::LocalRef& aOut) {
|
||||
if (aData.isNullOrUndefined()) {
|
||||
aOut = nullptr;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(aData.isString());
|
||||
|
||||
JS::RootedString str(aCx, aData.toString());
|
||||
|
||||
if (JS::StringHasLatin1Chars(str)) {
|
||||
nsAutoJSString autoStr;
|
||||
NS_ENSURE_TRUE(CheckJS(aCx, autoStr.init(aCx, str)), NS_ERROR_FAILURE);
|
||||
|
||||
// StringParam can automatically convert a nsString to jstring.
|
||||
aOut = jni::StringParam(autoStr, aOut.Env(), fallible);
|
||||
if (!aOut) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Two-byte string
|
||||
JNIEnv* const env = aOut.Env();
|
||||
const char16_t* chars;
|
||||
{
|
||||
JS::AutoCheckCannotGC nogc;
|
||||
size_t len = 0;
|
||||
chars = JS_GetTwoByteStringCharsAndLength(aCx, nogc, str, &len);
|
||||
if (chars) {
|
||||
aOut = jni::String::LocalRef::Adopt(
|
||||
env, env->NewString(reinterpret_cast<const jchar*>(chars), len));
|
||||
}
|
||||
}
|
||||
if (NS_WARN_IF(!CheckJS(aCx, !!chars) || !aOut)) {
|
||||
env->ExceptionClear();
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult BoxObject(JSContext* aCx, JS::HandleValue aData,
|
||||
jni::Object::LocalRef& aOut);
|
||||
|
||||
template <typename Type, bool (JS::Value::*IsType)() const,
|
||||
Type (JS::Value::*ToType)() const, class ArrayType,
|
||||
typename ArrayType::LocalRef (*NewArray)(const Type*, size_t)>
|
||||
nsresult BoxArrayPrimitive(JSContext* aCx, JS::HandleObject aData,
|
||||
jni::Object::LocalRef& aOut, size_t aLength,
|
||||
JS::HandleValue aElement) {
|
||||
JS::RootedValue element(aCx);
|
||||
auto data = MakeUnique<Type[]>(aLength);
|
||||
data[0] = (aElement.get().*ToType)();
|
||||
|
||||
for (size_t i = 1; i < aLength; i++) {
|
||||
NS_ENSURE_TRUE(CheckJS(aCx, JS_GetElement(aCx, aData, i, &element)),
|
||||
NS_ERROR_FAILURE);
|
||||
NS_ENSURE_TRUE((element.get().*IsType)(), NS_ERROR_INVALID_ARG);
|
||||
|
||||
data[i] = (element.get().*ToType)();
|
||||
}
|
||||
aOut = (*NewArray)(data.get(), aLength);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
template <class Type,
|
||||
nsresult (*Box)(JSContext*, JS::HandleValue, jni::Object::LocalRef&),
|
||||
typename IsType>
|
||||
nsresult BoxArrayObject(JSContext* aCx, JS::HandleObject aData,
|
||||
jni::Object::LocalRef& aOut, size_t aLength,
|
||||
JS::HandleValue aElement, IsType&& aIsType) {
|
||||
auto out = jni::ObjectArray::New<Type>(aLength);
|
||||
JS::RootedValue element(aCx);
|
||||
jni::Object::LocalRef jniElement(aOut.Env());
|
||||
|
||||
nsresult rv = (*Box)(aCx, aElement, jniElement);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
out->SetElement(0, jniElement);
|
||||
|
||||
for (size_t i = 1; i < aLength; i++) {
|
||||
NS_ENSURE_TRUE(CheckJS(aCx, JS_GetElement(aCx, aData, i, &element)),
|
||||
NS_ERROR_FAILURE);
|
||||
NS_ENSURE_TRUE(element.isNullOrUndefined() || aIsType(element),
|
||||
NS_ERROR_INVALID_ARG);
|
||||
|
||||
rv = (*Box)(aCx, element, jniElement);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
out->SetElement(i, jniElement);
|
||||
}
|
||||
aOut = out;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult BoxArray(JSContext* aCx, JS::HandleObject aData,
|
||||
jni::Object::LocalRef& aOut) {
|
||||
uint32_t length = 0;
|
||||
NS_ENSURE_TRUE(CheckJS(aCx, JS::GetArrayLength(aCx, aData, &length)),
|
||||
NS_ERROR_FAILURE);
|
||||
|
||||
if (!length) {
|
||||
// Always represent empty arrays as an empty boolean array.
|
||||
aOut = java::GeckoBundle::EMPTY_BOOLEAN_ARRAY();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// We only check the first element's type. If the array has mixed types,
|
||||
// we'll throw an error during actual conversion.
|
||||
JS::RootedValue element(aCx);
|
||||
NS_ENSURE_TRUE(CheckJS(aCx, JS_GetElement(aCx, aData, 0, &element)),
|
||||
NS_ERROR_FAILURE);
|
||||
|
||||
if (element.isBoolean()) {
|
||||
return BoxArrayPrimitive<bool, &JS::Value::isBoolean, &JS::Value::toBoolean,
|
||||
jni::BooleanArray, &jni::BooleanArray::New>(
|
||||
aCx, aData, aOut, length, element);
|
||||
}
|
||||
|
||||
if (element.isInt32()) {
|
||||
nsresult rv =
|
||||
BoxArrayPrimitive<int32_t, &JS::Value::isInt32, &JS::Value::toInt32,
|
||||
jni::IntArray, &jni::IntArray::New>(aCx, aData, aOut,
|
||||
length, element);
|
||||
if (rv != NS_ERROR_INVALID_ARG) {
|
||||
return rv;
|
||||
}
|
||||
// Not int32, but we can still try a double array.
|
||||
}
|
||||
|
||||
if (element.isNumber()) {
|
||||
return BoxArrayPrimitive<double, &JS::Value::isNumber, &JS::Value::toNumber,
|
||||
jni::DoubleArray, &jni::DoubleArray::New>(
|
||||
aCx, aData, aOut, length, element);
|
||||
}
|
||||
|
||||
if (element.isNullOrUndefined() || element.isString()) {
|
||||
const auto isString = [](JS::HandleValue val) -> bool {
|
||||
return val.isString();
|
||||
};
|
||||
nsresult rv = BoxArrayObject<jni::String, &BoxString>(
|
||||
aCx, aData, aOut, length, element, isString);
|
||||
if (element.isString() || rv != NS_ERROR_INVALID_ARG) {
|
||||
return rv;
|
||||
}
|
||||
// First element was null/undefined, so it may still be an object array.
|
||||
}
|
||||
|
||||
const auto isObject = [aCx](JS::HandleValue val) -> bool {
|
||||
if (!val.isObject()) {
|
||||
return false;
|
||||
}
|
||||
bool array = false;
|
||||
JS::RootedObject obj(aCx, &val.toObject());
|
||||
// We don't support array of arrays.
|
||||
return CheckJS(aCx, JS::IsArrayObject(aCx, obj, &array)) && !array;
|
||||
};
|
||||
|
||||
if (element.isNullOrUndefined() || isObject(element)) {
|
||||
return BoxArrayObject<java::GeckoBundle, &BoxObject>(
|
||||
aCx, aData, aOut, length, element, isObject);
|
||||
}
|
||||
|
||||
NS_WARNING("Unknown type");
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
nsresult BoxValue(JSContext* aCx, JS::HandleValue aData,
|
||||
jni::Object::LocalRef& aOut);
|
||||
|
||||
nsresult BoxObject(JSContext* aCx, JS::HandleValue aData,
|
||||
jni::Object::LocalRef& aOut) {
|
||||
if (aData.isNullOrUndefined()) {
|
||||
aOut = nullptr;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(aData.isObject());
|
||||
|
||||
JS::Rooted<JS::IdVector> ids(aCx, JS::IdVector(aCx));
|
||||
JS::RootedObject obj(aCx, &aData.toObject());
|
||||
|
||||
bool isArray = false;
|
||||
if (CheckJS(aCx, JS::IsArrayObject(aCx, obj, &isArray)) && isArray) {
|
||||
return BoxArray(aCx, obj, aOut);
|
||||
}
|
||||
|
||||
NS_ENSURE_TRUE(CheckJS(aCx, JS_Enumerate(aCx, obj, &ids)), NS_ERROR_FAILURE);
|
||||
|
||||
const size_t length = ids.length();
|
||||
auto keys = jni::ObjectArray::New<jni::String>(length);
|
||||
auto values = jni::ObjectArray::New<jni::Object>(length);
|
||||
|
||||
// Iterate through each property of the JS object.
|
||||
for (size_t i = 0; i < ids.length(); i++) {
|
||||
const JS::RootedId id(aCx, ids[i]);
|
||||
JS::RootedValue idVal(aCx);
|
||||
JS::RootedValue val(aCx);
|
||||
jni::Object::LocalRef key(aOut.Env());
|
||||
jni::Object::LocalRef value(aOut.Env());
|
||||
|
||||
NS_ENSURE_TRUE(CheckJS(aCx, JS_IdToValue(aCx, id, &idVal)),
|
||||
NS_ERROR_FAILURE);
|
||||
|
||||
JS::RootedString idStr(aCx, JS::ToString(aCx, idVal));
|
||||
NS_ENSURE_TRUE(CheckJS(aCx, !!idStr), NS_ERROR_FAILURE);
|
||||
|
||||
idVal.setString(idStr);
|
||||
NS_ENSURE_SUCCESS(BoxString(aCx, idVal, key), NS_ERROR_FAILURE);
|
||||
NS_ENSURE_TRUE(CheckJS(aCx, JS_GetPropertyById(aCx, obj, id, &val)),
|
||||
NS_ERROR_FAILURE);
|
||||
|
||||
nsresult rv = BoxValue(aCx, val, value);
|
||||
if (rv == NS_ERROR_INVALID_ARG && !JS_IsExceptionPending(aCx)) {
|
||||
nsAutoJSString autoStr;
|
||||
if (CheckJS(aCx, autoStr.init(aCx, idVal.toString()))) {
|
||||
JS_ReportErrorUTF8(aCx, u8"Invalid event data property %s",
|
||||
NS_ConvertUTF16toUTF8(autoStr).get());
|
||||
}
|
||||
}
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
keys->SetElement(i, key);
|
||||
values->SetElement(i, value);
|
||||
}
|
||||
|
||||
aOut = java::GeckoBundle::New(keys, values);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult BoxValue(JSContext* aCx, JS::HandleValue aData,
|
||||
jni::Object::LocalRef& aOut) {
|
||||
if (aData.isNullOrUndefined()) {
|
||||
aOut = nullptr;
|
||||
} else if (aData.isBoolean()) {
|
||||
aOut = aData.toBoolean() ? java::sdk::Boolean::TRUE()
|
||||
: java::sdk::Boolean::FALSE();
|
||||
} else if (aData.isInt32()) {
|
||||
aOut = java::sdk::Integer::ValueOf(aData.toInt32());
|
||||
} else if (aData.isNumber()) {
|
||||
aOut = java::sdk::Double::New(aData.toNumber());
|
||||
} else if (aData.isString()) {
|
||||
return BoxString(aCx, aData, aOut);
|
||||
} else if (aData.isObject()) {
|
||||
return BoxObject(aCx, aData, aOut);
|
||||
} else {
|
||||
NS_WARNING("Unknown type");
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
nsresult BoxData(JSContext* aCx, JS::HandleValue aData,
|
||||
jni::Object::LocalRef& aOut, bool aObjectOnly) {
|
||||
nsresult rv = NS_ERROR_INVALID_ARG;
|
||||
|
||||
if (!aObjectOnly) {
|
||||
rv = detail::BoxValue(aCx, aData, aOut);
|
||||
} else if (aData.isObject() || aData.isNullOrUndefined()) {
|
||||
rv = detail::BoxObject(aCx, aData, aOut);
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
} // namespace mozilla::jni
|
@ -9,8 +9,6 @@
|
||||
|
||||
#include "mozilla/java/GeckoBundleWrappers.h"
|
||||
|
||||
#include "jsapi.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace jni {
|
||||
|
||||
@ -37,9 +35,6 @@ namespace jni {
|
||||
auto name = \
|
||||
mozilla::java::GeckoBundle::New(_##name##_jkeys, _##name##_jvalues);
|
||||
|
||||
nsresult BoxData(JSContext* aCx, JS::HandleValue aData,
|
||||
jni::Object::LocalRef& aOut, bool aObjectOnly);
|
||||
|
||||
} // namespace jni
|
||||
} // namespace mozilla
|
||||
|
||||
|
@ -21,7 +21,6 @@ EXPORTS.mozilla.jni += [
|
||||
|
||||
UNIFIED_SOURCES += [
|
||||
"Conversions.cpp",
|
||||
"GeckoBundleUtils.cpp",
|
||||
"Utils.cpp",
|
||||
]
|
||||
|
||||
|
@ -2093,15 +2093,6 @@ RefPtr<MozPromise<bool, bool, false>> nsWindow::OnLoadRequest(
|
||||
: nullptr;
|
||||
}
|
||||
|
||||
void nsWindow::OnUpdateSessionStore(mozilla::jni::Object::Param aBundle) {
|
||||
auto geckoViewSupport(mGeckoViewSupport.Access());
|
||||
if (!geckoViewSupport) {
|
||||
return;
|
||||
}
|
||||
|
||||
geckoViewSupport->OnUpdateSessionStore(aBundle);
|
||||
}
|
||||
|
||||
float nsWindow::GetDPI() {
|
||||
float dpi = 160.0f;
|
||||
|
||||
@ -2439,16 +2430,6 @@ void nsWindow::ShowDynamicToolbar() {
|
||||
acc->OnShowDynamicToolbar();
|
||||
}
|
||||
|
||||
void GeckoViewSupport::OnUpdateSessionStore(
|
||||
mozilla::jni::Object::Param aBundle) {
|
||||
GeckoSession::Window::LocalRef window(mGeckoViewWindow);
|
||||
if (!window) {
|
||||
return;
|
||||
}
|
||||
|
||||
window->OnUpdateSessionStore(aBundle);
|
||||
}
|
||||
|
||||
void nsWindow::OnSizeChanged(const gfx::IntSize& aSize) {
|
||||
ALOG("nsWindow: %p OnSizeChanged [%d %d]", (void*)this, aSize.width,
|
||||
aSize.height);
|
||||
|
@ -69,8 +69,6 @@ class nsWindow final : public nsBaseWidget {
|
||||
nsIPrincipal* aTriggeringPrincipal, bool aHasUserGesture,
|
||||
bool aIsTopLevel);
|
||||
|
||||
void OnUpdateSessionStore(mozilla::jni::Object::Param aBundle);
|
||||
|
||||
private:
|
||||
// Unique ID given to each widget, used to map Surfaces to widgets
|
||||
// in the CompositorSurfaceManager.
|
||||
|
Loading…
x
Reference in New Issue
Block a user