flypig.co.uk

List items

Items from the current list are shown below.

Blog

24 Jan 2024 : Day 148 #
After much digging around in the code and gecko project structure I eventually decided that the best thing to do is implement a Sailfish-specific version of the SessionStore.jsm module.

Unfortunately this isn't just a case of copying the file over to embedlite-components, because it has some dependencies. These are listed at the top of the file. Let's go through and figure out which ones are already available, which we can remove, which we can copy over directly to embedlite-components and which we have to reimplement ourselves.

Here's the code that relates to the dependencies:
const { PrivateBrowsingUtils } = ChromeUtils.import(
  "resource://gre/modules/PrivateBrowsingUtils.jsm"
);
const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
const { TelemetryTimestamps } = ChromeUtils.import(
  "resource://gre/modules/TelemetryTimestamps.jsm"
);
const { XPCOMUtils } = ChromeUtils.import(
  "resource://gre/modules/XPCOMUtils.jsm"
);

ChromeUtils.defineModuleGetter(
  this,
  "SessionHistory",
  "resource://gre/modules/sessionstore/SessionHistory.jsm"
);

XPCOMUtils.defineLazyServiceGetters(this, {
  gScreenManager: ["@mozilla.org/gfx/screenmanager;1", "nsIScreenManager"],
});

XPCOMUtils.defineLazyModuleGetters(this, {
  AppConstants: "resource://gre/modules/AppConstants.jsm",
  AsyncShutdown: "resource://gre/modules/AsyncShutdown.jsm",
  BrowserWindowTracker: "resource:///modules/BrowserWindowTracker.jsm",
  DevToolsShim: "chrome://devtools-startup/content/DevToolsShim.jsm",
  E10SUtils: "resource://gre/modules/E10SUtils.jsm",
  GlobalState: "resource:///modules/sessionstore/GlobalState.jsm",
  HomePage: "resource:///modules/HomePage.jsm",
  PrivacyFilter: "resource://gre/modules/sessionstore/PrivacyFilter.jsm",
  PromiseUtils: "resource://gre/modules/PromiseUtils.jsm",
  RunState: "resource:///modules/sessionstore/RunState.jsm",
  SessionCookies: "resource:///modules/sessionstore/SessionCookies.jsm",
  SessionFile: "resource:///modules/sessionstore/SessionFile.jsm",
  SessionSaver: "resource:///modules/sessionstore/SessionSaver.jsm",
  SessionStartup: "resource:///modules/sessionstore/SessionStartup.jsm",
  TabAttributes: "resource:///modules/sessionstore/TabAttributes.jsm",
  TabCrashHandler: "resource:///modules/ContentCrashHandlers.jsm",
  TabState: "resource:///modules/sessionstore/TabState.jsm",
  TabStateCache: "resource:///modules/sessionstore/TabStateCache.jsm",
  TabStateFlusher: "resource:///modules/sessionstore/TabStateFlusher.jsm",
  setTimeout: "resource://gre/modules/Timer.jsm",
});
Heres's a table to summarise. I've ordered them by their current status to help highlight what needs work and what type of work it is.
 
Module Variable Status
gre/modules/PrivateBrowsingUtils.jsm" PrivateBrowsingUtils Available
gre/modules/Services.jsm Services Available
gre/modules/TelemetryTimestamps.jsm TelemetryTimestamps Available
gre/modules/XPCOMUtils.jsm XPCOMUtils Available
gre/modules/sessionstore/SessionHistory.jsm SessionHistory Available
gre/modules/AppConstants.jsm AppConstants Available
gre/modules/AsyncShutdown.jsm AsyncShutdown Available
gre/modules/E10SUtils.jsm E10SUtils Available
gre/modules/sessionstore/PrivacyFilter.jsm PrivacyFilter Available
gre/modules/PromiseUtils.jsm PromiseUtils Available
gre/modules/Timer.jsm setTimeout Available
@mozilla.org/gfx/screenmanager;1 gScreenManager Drop
modules/ContentCrashHandlers.jsm TabCrashHandler Drop
devtools-startup/content/DevToolsShim.jsm DevToolsShim Drop
modules/sessionstore/TabAttributes.jsm TabAttributes Copy
modules/sessionstore/GlobalState.jsm GlobalState Copy
modules/sessionstore/RunState.jsm RunState Copy
modules/BrowserWindowTracker.jsm BrowserWindowTracker Drop
modules/sessionstore/SessionCookies.jsm SessionCookies Drop?
modules/HomePage.jsm HomePage Drop?
modules/sessionstore/SessionFile.jsm SessionFile Copy/drop?
modules/sessionstore/SessionSaver.jsm SessionSaver Copy/drop?
modules/sessionstore/SessionStartup.jsm SessionStartup Copy/drop?
modules/sessionstore/TabState.jsm TabState Copy/drop?
modules/sessionstore/TabStateCache.jsm TabStateCache Copy/drop?
modules/sessionstore/TabStateFlusher.jsm TabStateFlusher Copy/drop?

In addition to the above there's also the SessionStore.jsm file itself.

As you can see there's still a fair bit of uncertainty in the table. But also, quite a large number of the dependencies are already available.

From the code it looks like the functionality is around saving and restoring sessions, including tab data, cookies, window positions and the like. Some of this isn't relevant on Sailfish OS (there's no point saving and restoring window sizes) or is already handled by other parts of the system (cookie storage). In fact, it's not clear that this module is providing any additional functionality that sailfish-browser actually needs.

Given this my focus will be on creating a minimal implementation that doesn't error when called but performs very little functionality in practice. That will hopefully make the task tractable.

It's early in the morning here still, but time for me to start work; so I'll pick this up again tonight.

[...]

It's now late evening and I have just a bit of time to move some files around. I've started by copying the SessionStore.jsm file into the embedlite-components project, alongside the other files I think I can copy without making changes. Apart from SessionStore.jsm, I've tried to copy over only files that don't require dependencies, or where the dependencies are all available.
$ find . -iname "SessionStore.jsm"
./gecko-dev/browser/components/sessionstore/SessionStore.jsm
$ cp ./gecko-dev/browser/components/sessionstore/SessionStore.jsm \
    ../../embedlite-components/jscomps/
$ cp ./gecko-dev/browser/components/sessionstore/TabAttributes.jsm \
    ../../embedlite-components/jscomps/
$ cp ./gecko-dev/browser/components/sessionstore/GlobalState.jsm \
     ../../embedlite-components/jscomps/
$ cp ./gecko-dev/browser/components/sessionstore/RunState.jsm \
    ../../embedlite-components/jscomps/
I've also been through and removed all of the code that used any of the dropped dependency. And in fact I've gone ahead and dropped all of the modules marked as "Drop" or "Copy/drop" in the table above. Despite the quantity of code in the original files, it really doesn't look like there's much functionality that's needed for sailfish-browser in these scripts. But having the functions available may turn out to be useful at some point in the future and in the meantime if the module just provides methods that don't do anything, then they will at least be successful in suppressing the errors.

The final step is to hook them up into the system so that they get included and can be accessed by other parts of the code. And this is where I hit a problem. The embedlite-components package contains two types of JavaScript entity. The first are in the jscomps folder. These all seem to be components that have a defined interface (they satisfy a "contract") as specified in the EmbedLiteJSComponents.manifest file. Here's an example of the entry for the AboutRedirector component:
# AboutRedirector.js
component {59f3da9a-6c88-11e2-b875-33d1bd379849} AboutRedirector.js
contract @mozilla.org/network/protocol/about;1?what= {59f3da9a-6c88-11e2-b875-33d1bd379849}
contract @mozilla.org/network/protocol/about;1?what=embedlite {59f3da9a-6c88-11e2-b875-33d1bd379849}
contract @mozilla.org/network/protocol/about;1?what=certerror {59f3da9a-6c88-11e2-b875-33d1bd379849}
contract @mozilla.org/network/protocol/about;1?what=home {59f3da9a-6c88-11e2-b875-33d1bd379849}
Our SessionStore.jsm files can't be added like this because they're not components with defined interfaces in this way. The other type are in the jsscipts folder. These aren't components and the files would fit perfectly in there. But they are all accessed using a particular path and the chrome:// scheme, like this:
const { NetErrorHelper } = ChromeUtils.import("chrome://embedlite/content/NetErrorHelper.jsm")
This won't work for SessionStore.jsm, which is expected to be accessed like this:
XPCOMUtils.defineLazyModuleGetters(this, {
  SessionStore: "resource:///modules/sessionstore/SessionStore.jsm",
});
Different location; different approach.

So I'm going to need to find some other way to do this. As it's late, it will take me a while to come up with an alternative. But my immediate thought is that maybe I can just add the missing files in to the EmbedLite build process. It looks like this is being controlled by the embedlite/moz.build file. So I've added the component folder /browser/components/sessionstore into the list of directories there:
LOCAL_INCLUDES += [
    '!/build',
    '/browser/components/sessionstore',
    '/dom/base',
    '/dom/ipc',
    '/gfx/layers',
    '/gfx/layers/apz/util',
    '/hal',
    '/js/xpconnect/src',
    '/netwerk/base/',
    '/toolkit/components/resistfingerprinting',
    '/toolkit/xre',
    '/widget',
    '/xpcom/base',
    '/xpcom/build',
    '/xpcom/threads',
    'embedhelpers',
    'embedprocess',
    'embedshared',
    'embedthread',
    'modules',
    'utils',
]
I've added the directory, cleaned out the build directory and started off a fresh build to run overnight. Let's see whether that worked in the morning.

If you'd like to read any of my other gecko diary entries, they're all available on my Gecko-dev Diary page.

Comments

Uncover Disqus comments