[B2G][Stingray] unable to focus mozbrowser iframe while calling focus()

RESOLVED FIXED in 2.2 S3 (9jan)

Status

Firefox OS
General
RESOLVED FIXED
3 years ago
3 years ago

People

(Reporter: johnhu, Assigned: johnhu)

Tracking

unspecified
2.2 S3 (9jan)
Other
Android
Dependency tree / graph

Firefox Tracking Flags

(Not tracked)

Details

(Whiteboard: [ft:conndevices])

Attachments

(3 attachments)

The focus and activeElement didn't change while focus() called.

Environment: b2g desktop and mulet

STR:
1. Open TV build with b2g desktop.
2. Press home key with real keyboard to get smart-home app.
3. Press right and down to select app deck and open it.
4. Press home key to get home app back.
5. The focus is still in app deck, we should focus back to smart-home app.

I can confirm the focus of smart-home's iframe is called in this case. But the focus does not transfer to smart-home.

Please use the following to build TV Gaia build:
GAIA_DEVICE_TYPE=tv make

To run the TV build in b2g desktop:
/…/b2g-bin -profile /…/gaia/profile -screen 1920x1080

Updated

3 years ago
Whiteboard: [ft:conndevices]
While writing the patch for bug 1114397, I found another worse case that the focus cannot be set back when we apply any known workaround.
An workaround for comment 0 can be found at:

diff --git a/tv_apps/smart-system/js/app_transition_controller.js b/tv_apps/smart-system/js/app_transition_controller.js
index 9d5fd25..e82aca5 100644
--- a/tv_apps/smart-system/js/app_transition_controller.js
+++ b/tv_apps/smart-system/js/app_transition_controller.js
@@ -351,6 +351,9 @@
           this.handle_opened();
           break;
         case '_closed':
+          if (this.app.isHomescreen) {
+            this.app.blur();
+          }
           this.handle_closed();
           break;
         case '_closing':
Created attachment 8539977 [details] [diff] [review]
possible.patch

This is possible WORKAROUND of comment 0. I think this is better than the previous one.
After brief investigation, the real problem happens in step 3 (open app deck). The focus stays at the button in smart-home since it fails to set focus on app deck, even after app deck is shown. Thus during step 4, smart-home moves back to foreground without actually changing focus, so the user would get confused when realizing the button is still focused.

More details about the cause why app deck couldn't get focused in step 3:
1. nsFocusManager checks if the content is focusable before actually setting focus on it. [1]
2. "Frames are never directly focused; instead focusing a frame means focus what is inside the frame. To do this, the descendant content within the frame is retrieved and that will be focused instead." [2]
3. There appears a sub-document and app-deck frame is visible, so the content node is used to determine focusability. [3]
4. Somehow |ui->mUserFocus| is |NS_STYLE_USER_FOCUS_IGNORE|. Then it makes |tabIndex| be -1 and prevent app deck being focused. [4][5]

[1] http://dxr.mozilla.org/mozilla-central/source/dom/base/nsFocusManager.cpp#1164
[2] http://dxr.mozilla.org/mozilla-central/source/dom/base/nsFocusManager.cpp#1168-1171
[3] http://dxr.mozilla.org/mozilla-central/source/dom/base/nsFocusManager.cpp#1562-1572
[4] http://dxr.mozilla.org/mozilla-central/source/dom/base/nsFocusManager.cpp#1569
[5] http://dxr.mozilla.org/mozilla-central/source/dom/base/nsFocusManager.cpp#1166
Created attachment 8540059 [details] [diff] [review]
app-deck-test-case.patch

Sean,

This is the test case at app deck. I had create a button which is focusable element.

After the app deck opened, the button has the focus but the app-deck window doesn't have the focus. Once we use cmd/ctrl + tab to switch window focus back and forth, the app-deck window gets the focus. And it is the same for home app.

It looks like that the keyboard focus had set to app-deck app but the window focus doesn't.
(In reply to Sean Lin [:seanlin] from comment #4)
> More details about the cause why app deck couldn't get focused in step 3:
> 1. nsFocusManager checks if the content is focusable before actually setting
> focus on it. [1]
> 2. "Frames are never directly focused; instead focusing a frame means focus
> what is inside the frame. To do this, the descendant content within the
> frame is retrieved and that will be focused instead." [2]
> 3. There appears a sub-document and app-deck frame is visible, so the
> content node is used to determine focusability. [3]
> 4. Somehow |ui->mUserFocus| is |NS_STYLE_USER_FOCUS_IGNORE|. Then it makes
> |tabIndex| be -1 and prevent app deck being focused. [4][5]

It's strange about why app deck receives the keyboard event while I put a button in app-deck. BTW, it is confirmed that the setVisible of app-deck's frame is called at smart-system app. Is the setVisible(true) failed to execute in some special case??
We may have similar issue, like the one we met in bug 1114397, once we enable the keyboard navigation on context menu.
Blocks: 1115288
Depends on: 1115455
Assignee: nobody → im
Created attachment 8541438 [details] [review]
blur activeElement before focus

Luke,

Please review this patch. It blurs the activeElement before we focus window.
Attachment #8541438 - Flags: review?(lchang)
Actually the issue appears to be composed of two different ones.

The first one is partially described in comment 4, which is due to the attempt to set focus to app deck iframe before its document gets fully loaded. (Please see bug 1115455 for more details and the correspondent solution.)

The second is due to the following security constraint:
1. When the user opens app-deck with 'Enter' key press, the current focused window is smart-home window with an inner focused element (smart button). And it tries to change the focused window to the visible active app-deck window.
2. |nsFocusManager| has a nullable member variable |mFocusedContent| to keep track of the current focused element. (In this case, it points to the smart button in smart-home window.) When it comes to move the focus to another document's element (app-deck window), |nsFocusManager| needs to make sure the document which we're trying to move the focus to has the permission to access the document which the original focused element belongs to. [1]
3. Since app-deck window cannot access smart-home window (probably due to same-origin policy), no focus change is allowed. [2] Thus it won't trigger the original focused element to be blurred or new element to be focused. [3]
4. The only exception of the constraint stated in 2 is when the transition is triggered by a mouse button event handled by the document which we try to move the focus to. [4] So this issue won't happen if the user clicks app-deck window.
5. This constraint won't apply if there's no focused element (e.g. the smart button gets blurred before the attempt of focus transition).

Based on the logic stated above, the patch provided in comment 3 looks the right way to bypass this security constraint.

[1] http://dxr.mozilla.org/mozilla-central/source/dom/base/nsFocusManager.cpp#1278-1284
[2] http://dxr.mozilla.org/mozilla-central/source/dom/base/nsFocusManager.cpp#1289
[3] http://dxr.mozilla.org/mozilla-central/source/dom/base/nsFocusManager.cpp#1304-1336
[4] http://dxr.mozilla.org/mozilla-central/source/dom/base/nsFocusManager.cpp#1285-1295
Comment on attachment 8541438 [details] [review]
blur activeElement before focus

Looks good! Thanks.
Attachment #8541438 - Flags: review?(lchang) → review+
Recap the STR at comment 1:

1. add `dev_apps/uitest` to `build/config/tv/app-engineering.list`
2. open uitest -> new notification
3. click notification
4. press ESC to cancel the notification <== the focus is still at system instead of uitest
merged to master:
https://github.com/mozilla-b2g/gaia/commit/1ba46e98674362209e021f8704cb6f086003fbba

gaia-try is all green
https://treeherder.mozilla.org/ui/#/jobs?repo=gaia-try&revision=91c1980c9cd4
Status: NEW → RESOLVED
Last Resolved: 3 years ago
Resolution: --- → FIXED
Another STR for the issue mentioned in comment 11 is listed below:

1. Open app-deck, and then right click to get the context menu.
2. Press ESC to close the context menu. But the focus won't get back to app-deck.

The root cause is due to another security constraint applied by |nsFocusManager| only for keyboard events. More details are as follows:

The original focus is on the context menu, which is part of smart-system app using its own principal; whereas the element trying to get the focus is app-deck, whose principal doesn't subsume the principal smart-system uses. Thus |nsFocusManager| forbids this kind of focus moves due to some security concerns stated in bug 552255, especially while a keyboard event is on-going. [1]

John's workaround is to postpone the focus move after the keyboard event has been completely handled.

[1] http://dxr.mozilla.org/mozilla-central/source/dom/base/nsFocusManager.cpp#1215-1232
Blocks: 1115648
No longer blocks: 1115648
Target Milestone: --- → 2.2 S3 (9jan)
You need to log in before you can comment on or make changes to this bug.