Add light browser.windows API to Android

ASSIGNED
Assigned to

Status

enhancement
P5
normal
ASSIGNED
2 years ago
2 months ago

People

(Reporter: robwu, Assigned: Oriol)

Tracking

(Blocks 3 bugs)

58 Branch
Dependency tree / graph

Firefox Tracking Flags

(firefox58 affected)

Details

Attachments

(1 attachment)

(Reporter)

Description

2 years ago
Android does currently not have a browser.windows API.
However, it does have two tab stacks, private and public.

The lack of windows API makes it difficult/impossible for extensions to support private browsing tabs on Android (e.g. bug 1372178). And when one opens a pageAction popup, it opens in the main tab stack instead of the private one.

A way to solve this issue is to implement a light windows API:

browser.windows.Window:
- id
- focused
- tabs (optional)
- incognito
- type (which is always "normal")

browser.windows.WINDOW_ID_NONE
browser.windows.WINDOW_ID_CURRENT
browser.windows.get - fully supported
browser.windows.getCurrent - fully supported
browser.windows.getLastFocused - fully supported
browser.windows.getAll - fully supported
browser.windows.update - only supports property "focused"
browser.windows.onFocusChanged - when the user changes tab stacks.

NOT SUPPORTED (because the number of tab stacks is fixed and immutable):
browser.windows.create
browser.windows.remove
browser.windows.onCreated
browser.windows.onRemoved
(Reporter)

Updated

2 years ago
Blocks: 1372178

Updated

2 years ago
Priority: -- → P5

Updated

11 months ago

Updated

10 months ago
Product: Toolkit → WebExtensions
(Assignee)

Comment 1

7 months ago
Internally, Android uses a single window for both private and normal tabs. Simulating two windows would require some work to monkey-patch all APIs which either accept or return a windowId or a tab index.

Also, this would have a performance impact, e.g. querying the tab at a specific index is a fast operation now: https://searchfox.org/mozilla-central/rev/21588b2a9824e0758fe11d10065e2c01ea9f32be/mobile/android/components/extensions/ext-utils.js#701
> let nativeTab = this.window.BrowserApp.tabs[index];
Simulating two windows would require looping all tabs and checking their privateness. And performance is specially important on mobile.

So I don't agree with this 2-window simulation that doesn't reflect internal reality. I would just do this:

browser.windows.Window:
- id
- tabs (optional)
- type (which is always "normal")

browser.windows.WINDOW_ID_NONE
browser.windows.WINDOW_ID_CURRENT
browser.windows.get
browser.windows.getCurrent
browser.windows.getLastFocused
browser.windows.getAll

onCreated and onRemoved could be implemented as no-op.

The only advantage of simulating two windows is that it would address bug 1372178, but that can also be fixed by allowing an "incognito" property in tabs.create, which could also make things simpler on desktop.

Comment 2

7 months ago
(In reply to Oriol Brufau [:Oriol] from comment #1)
> onCreated and onRemoved could be implemented as no-op.

I agree with that.


> The only advantage of simulating two windows is that it would address bug
> 1372178, but that can also be fixed by allowing an "incognito" property in
> tabs.create, which could also make things simpler on desktop.

The issue with adding an `incognito`/`inPrivate` property to `browser.tabs.create(…)` is that desktop Firefox doesn’t currently support private tabs in non‑private windows (there used to be the Private Tab extension¹, but that is no longer supported since Firefox 57)

¹ https://addons.mozilla.org/firefox/addon/private-tab (https://github.com/Infocatcher/Private_Tab)
(Assignee)

Comment 3

7 months ago
(In reply to ExE Boss from comment #2)
> The issue with adding an `incognito`/`inPrivate` property to
> `browser.tabs.create(…)` is that desktop Firefox doesn’t currently support
> private tabs in non‑private windows (there used to be the Private Tab
> extension¹, but that is no longer supported since Firefox 57)

Sure, if both `incognito` and `windowId` are specified, then Firefox desktop could check if the specified window can have a tab with that privateness, and abort if not.

Comment 4

4 months ago
I think that there could be value in supporting:

- browser.windows.onCreated
- browser.windows.onRemoved

They could fire whenever the user minimizes or maximizes/opens the Firefox App.

A concrete use case for this is the LeechBlock NG add-on, that, among other things, times how much time the user spends on any given website. this is currently not fully functional, as the add-on doesn't get notified when the user minimizes the app, thus the timer keeps counting after the Firefox app has been minimized.

https://addons.mozilla.org/en-US/firefox/addon/leechblock-ng/
https://github.com/proginosko/LeechBlockNG
https://github.com/proginosko/LeechBlockNG/issues/81
(Reporter)

Comment 5

4 months ago
onCreated / onRemoved are definitely not the right event for the behavior described in comment 4.
The closest event would be windows.onFocusChanged [1] (and to match your use case, one would need to call it with ID WINDOW_ID_NONE, i.e. -1).

[1] https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/windows/onFocusChanged

Comment 6

4 months ago
Rob Wu is correct in comment 5.

LeechBlock NG uses windows.onFocusChanged to detect when the user switches focus to another window/app, so the add-on is not fully functional on Android. A number of users have contacted me about this. As the developer of LeechBlock, I strongly support Rob's proposal for a minimal implementation of the windows API for Android. I'm putting this on my Santa list. :)
(Reporter)

Comment 7

4 months ago
Patches are welcome ;)

If anyone is familiar with Java and JavaScript and willing to implement this feature, see the following guide to get started: https://wiki.mozilla.org/WebExtensions/Contribution_Onramp
(Assignee)

Updated

2 months ago
Assignee: nobody → oriol-bugzilla
Status: NEW → ASSIGNED
(Assignee)

Comment 9

2 months ago

This patch implements

  • get() method
  • getAll() method
  • getCurrent() method
  • getLastFocused() method
  • WINDOW_ID_CURRENT property
  • WINDOW_ID_NONE property
  • Window type
  • WindowState type
  • WindowType type
  • onCreated event (no-op)
  • onRemoved event (no-op)

It doesn't implement

  • create() method
  • remove() method
  • update() method
  • CreateType type
  • onFocusChanged event

The API reflects internal reality, i.e. showing a single window instead of faking a normal window and a private one. This reality is already exposed by the tabs API.

onFocusChanged event when the app is minimized makes sense but is less trivial. Better do it in a follow-up bug.

You need to log in before you can comment on or make changes to this bug.