From 941e4787b2a867543276a2632624649ae1b55863 Mon Sep 17 00:00:00 2001 From: Thomas Wisniewski Date: Fri, 7 Jul 2017 20:17:23 -0400 Subject: [PATCH] Bug 1348911 - Add lastAccessed to tabs.Tab; r=mixedpuppy,zombie MozReview-Commit-ID: 4ulhseGDQ4P --HG-- extra : rebase_source : 12037d094ffe72b347436759b7011516b145fa92 --- browser/components/extensions/ext-utils.js | 5 ++ .../components/extensions/schemas/tabs.json | 1 + .../test/browser/browser-common.ini | 1 + ...ser_ext_sessions_getRecentlyClosed_tabs.js | 7 +++ .../browser/browser_ext_tabs_lastAccessed.js | 42 ++++++++++++++ .../components/extensions/ext-utils.js | 4 ++ .../components/extensions/schemas/tabs.json | 1 + .../extensions/test/mochitest/mochitest.ini | 1 + .../mochitest/test_ext_tabs_lastAccessed.html | 58 +++++++++++++++++++ .../components/extensions/ExtensionTabs.jsm | 12 ++++ .../test/mochitest/mochitest-common.ini | 2 +- 11 files changed, 133 insertions(+), 1 deletion(-) create mode 100644 browser/components/extensions/test/browser/browser_ext_tabs_lastAccessed.js create mode 100644 mobile/android/components/extensions/test/mochitest/test_ext_tabs_lastAccessed.html diff --git a/browser/components/extensions/ext-utils.js b/browser/components/extensions/ext-utils.js index 7926ce3a516b..da6a768d089e 100644 --- a/browser/components/extensions/ext-utils.js +++ b/browser/components/extensions/ext-utils.js @@ -522,6 +522,10 @@ class Tab extends TabBase { return mutedInfo; } + get lastAccessed() { + return this.nativeTab.lastAccessed; + } + get pinned() { return this.nativeTab.pinned; } @@ -578,6 +582,7 @@ class Tab extends TabBase { active: false, pinned: false, incognito: Boolean(tabData.state && tabData.state.isPrivate), + lastAccessed: tabData.state ? tabData.state.lastAccessed : tabData.lastAccessed, }; if (extension.tabManager.hasTabPermission(tabData)) { diff --git a/browser/components/extensions/schemas/tabs.json b/browser/components/extensions/schemas/tabs.json index c833fcc860db..77518ffed231 100644 --- a/browser/components/extensions/schemas/tabs.json +++ b/browser/components/extensions/schemas/tabs.json @@ -64,6 +64,7 @@ "highlighted": {"type": "boolean", "description": "Whether the tab is highlighted. Works as an alias of active"}, "active": {"type": "boolean", "description": "Whether the tab is active in its window. (Does not necessarily mean the window is focused.)"}, "pinned": {"type": "boolean", "description": "Whether the tab is pinned."}, + "lastAccessed": {"type": "integer", "optional": true, "description": "The last time the tab was accessed as the number of milliseconds since epoch."}, "audible": {"type": "boolean", "optional": true, "description": "Whether the tab has produced sound over the past couple of seconds (but it might not be heard if also muted). Equivalent to whether the speaker audio indicator is showing."}, "mutedInfo": {"$ref": "MutedInfo", "optional": true, "description": "Current tab muted state and the reason for the last state change."}, "url": {"type": "string", "optional": true, "permissions": ["tabs"], "description": "The URL the tab is displaying. This property is only present if the extension's manifest includes the \"tabs\" permission."}, diff --git a/browser/components/extensions/test/browser/browser-common.ini b/browser/components/extensions/test/browser/browser-common.ini index f41b36b1d7e3..f0361bf2630b 100644 --- a/browser/components/extensions/test/browser/browser-common.ini +++ b/browser/components/extensions/test/browser/browser-common.ini @@ -123,6 +123,7 @@ skip-if = debug || asan # Bug 1354681 [browser_ext_tabs_executeScript_runAt.js] [browser_ext_tabs_getCurrent.js] [browser_ext_tabs_insertCSS.js] +[browser_ext_tabs_lastAccessed.js] [browser_ext_tabs_removeCSS.js] [browser_ext_tabs_move_array.js] [browser_ext_tabs_move_window.js] diff --git a/browser/components/extensions/test/browser/browser_ext_sessions_getRecentlyClosed_tabs.js b/browser/components/extensions/test/browser/browser_ext_sessions_getRecentlyClosed_tabs.js index b823dda6e20f..71025e120a5c 100644 --- a/browser/components/extensions/test/browser/browser_ext_sessions_getRecentlyClosed_tabs.js +++ b/browser/components/extensions/test/browser/browser_ext_sessions_getRecentlyClosed_tabs.js @@ -43,10 +43,13 @@ add_task(async function test_sessions_get_recently_closed_tabs() { let expectedTabs = []; let tab = win.gBrowser.selectedTab; expectedTabs.push(expectedTabInfo(tab, win)); + let lastAccessedTimes = new Map(); + lastAccessedTimes.set("about:mozilla", tab.lastAccessed); for (let url of ["about:robots", "about:buildconfig"]) { tab = await BrowserTestUtils.openNewForegroundTab(win.gBrowser, url); expectedTabs.push(expectedTabInfo(tab, win)); + lastAccessedTimes.set(url, tab.lastAccessed); } await extension.startup(); @@ -59,6 +62,8 @@ add_task(async function test_sessions_get_recently_closed_tabs() { let tabInfo = recentlyClosed[0].tab; let expectedTab = expectedTabs.pop(); checkTabInfo(expectedTab, tabInfo); + ok(tabInfo.lastAccessed > lastAccessedTimes.get(tabInfo.url), + "lastAccessed has been updated"); // Test with a closed window containing tabs. await BrowserTestUtils.closeWindow(win); @@ -69,6 +74,8 @@ add_task(async function test_sessions_get_recently_closed_tabs() { is(tabInfos.length, 2, "Expected number of tabs in closed window."); for (let x = 0; x < tabInfos.length; x++) { checkTabInfo(expectedTabs[x], tabInfos[x]); + ok(tabInfos[x].lastAccessed > lastAccessedTimes.get(tabInfos[x].url), + "lastAccessed has been updated"); } await extension.unload(); diff --git a/browser/components/extensions/test/browser/browser_ext_tabs_lastAccessed.js b/browser/components/extensions/test/browser/browser_ext_tabs_lastAccessed.js new file mode 100644 index 000000000000..56a4c365c0b3 --- /dev/null +++ b/browser/components/extensions/test/browser/browser_ext_tabs_lastAccessed.js @@ -0,0 +1,42 @@ +"use strict"; + +add_task(async function testLastAccessed() { + let past = Date.now(); + + await BrowserTestUtils.openNewForegroundTab(gBrowser, "https://example.com/?1"); + await BrowserTestUtils.openNewForegroundTab(gBrowser, "https://example.com/?2"); + + let extension = ExtensionTestUtils.loadExtension({ + manifest: { + permissions: ["tabs"], + }, + async background() { + browser.test.onMessage.addListener(async function(msg, past) { + if (msg !== "past") { + return; + } + + let [tab1] = await browser.tabs.query({url: "https://example.com/?1"}); + let [tab2] = await browser.tabs.query({url: "https://example.com/?2"}); + + browser.test.assertTrue(tab1 && tab2, "Expected tabs were found"); + + let now = Date.now(); + + browser.test.assertTrue(past < tab1.lastAccessed && + tab1.lastAccessed < tab2.lastAccessed && + tab2.lastAccessed <= now, + "lastAccessed timestamps are recent and in the right order"); + + await browser.tabs.remove([tab1.id, tab2.id]); + + browser.test.notifyPass("tabs.lastAccessed"); + }); + }, + }); + + await extension.startup(); + await extension.sendMessage("past", past); + await extension.awaitFinish("tabs.lastAccessed"); + await extension.unload(); +}); diff --git a/mobile/android/components/extensions/ext-utils.js b/mobile/android/components/extensions/ext-utils.js index 4946e6363401..71da5d145d78 100644 --- a/mobile/android/components/extensions/ext-utils.js +++ b/mobile/android/components/extensions/ext-utils.js @@ -398,6 +398,10 @@ class Tab extends TabBase { return {muted: false}; } + get lastAccessed() { + return this.nativeTab.lastTouchedAt; + } + get pinned() { return false; } diff --git a/mobile/android/components/extensions/schemas/tabs.json b/mobile/android/components/extensions/schemas/tabs.json index 70a6d22a335e..2adbb0b05773 100644 --- a/mobile/android/components/extensions/schemas/tabs.json +++ b/mobile/android/components/extensions/schemas/tabs.json @@ -64,6 +64,7 @@ "highlighted": {"type": "boolean", "description": "Whether the tab is highlighted. Works as an alias of active."}, "active": {"type": "boolean", "description": "Whether the tab is active in its window. (Does not necessarily mean the window is focused.)"}, "pinned": {"type": "boolean", "description": "Whether the tab is pinned."}, + "lastAccessed": {"type": "integer", "optional": true, "description": "The last time the tab was accessed as the number of milliseconds since epoch."}, "audible": {"type": "boolean", "optional": true, "description": "Whether the tab has produced sound over the past couple of seconds (but it might not be heard if also muted). Equivalent to whether the speaker audio indicator is showing."}, "mutedInfo": {"$ref": "MutedInfo", "optional": true, "description": "Current tab muted state and the reason for the last state change."}, "url": {"type": "string", "optional": true, "permissions": ["tabs"], "description": "The URL the tab is displaying. This property is only present if the extension's manifest includes the \"tabs\" permission."}, diff --git a/mobile/android/components/extensions/test/mochitest/mochitest.ini b/mobile/android/components/extensions/test/mochitest/mochitest.ini index 7cc03c5bb0e4..c785dfc45e8c 100644 --- a/mobile/android/components/extensions/test/mochitest/mochitest.ini +++ b/mobile/android/components/extensions/test/mochitest/mochitest.ini @@ -26,6 +26,7 @@ skip-if = true # Currently fails in emulator runs [test_ext_tabs_executeScript_runAt.html] [test_ext_tabs_getCurrent.html] [test_ext_tabs_insertCSS.html] +[test_ext_tabs_lastAccessed.html] [test_ext_tabs_reload.html] [test_ext_tabs_reload_bypass_cache.html] [test_ext_tabs_onUpdated.html] diff --git a/mobile/android/components/extensions/test/mochitest/test_ext_tabs_lastAccessed.html b/mobile/android/components/extensions/test/mochitest/test_ext_tabs_lastAccessed.html new file mode 100644 index 000000000000..3706723237a6 --- /dev/null +++ b/mobile/android/components/extensions/test/mochitest/test_ext_tabs_lastAccessed.html @@ -0,0 +1,58 @@ + + + + Tabs lastAccessed Test + + + + + + + + + + + diff --git a/toolkit/components/extensions/ExtensionTabs.jsm b/toolkit/components/extensions/ExtensionTabs.jsm index 5f6c8abbd61d..08a5b3bea7a7 100644 --- a/toolkit/components/extensions/ExtensionTabs.jsm +++ b/toolkit/components/extensions/ExtensionTabs.jsm @@ -265,6 +265,17 @@ class TabBase { } } + /** + * @property {integer} lastAccessed + * Returns the last time the tab was accessed as the number of + * milliseconds since epoch. + * @readonly + * @abstract + */ + get lastAccessed() { + throw new Error("Not implemented"); + } + /** * @property {boolean} audible * Returns true if the tab is currently playing audio, false otherwise. @@ -481,6 +492,7 @@ class TabBase { incognito: this.incognito, width: this.width, height: this.height, + lastAccessed: this.lastAccessed, audible: this.audible, mutedInfo: this.mutedInfo, }; diff --git a/toolkit/components/extensions/test/mochitest/mochitest-common.ini b/toolkit/components/extensions/test/mochitest/mochitest-common.ini index 25e4dc39fc0b..6f08d3997594 100644 --- a/toolkit/components/extensions/test/mochitest/mochitest-common.ini +++ b/toolkit/components/extensions/test/mochitest/mochitest-common.ini @@ -127,4 +127,4 @@ skip-if = os == 'android' # Currently fails in emulator tests [test_ext_webnavigation_filters.html] [test_ext_window_postMessage.html] [test_ext_subframes_privileges.html] -[test_ext_xhr_capabilities.html] \ No newline at end of file +[test_ext_xhr_capabilities.html]