browser/modules/NetworkPrioritizer.jsm

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

     1 /* This Source Code Form is subject to the terms of the Mozilla Public
     2  * License, v. 2.0. If a copy of the MPL was not distributed with this
     3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     5 /*
     6  * This module adjusts network priority for tabs in a way that gives 'important'
     7  * tabs a higher priority. There are 3 levels of priority. Each is listed below
     8  * with the priority adjustment used.
     9  *
    10  * Highest (-10): Selected tab in the focused window.
    11  * Medium (0):    Background tabs in the focused window.
    12  *                Selected tab in background windows.
    13  * Lowest (+10):  Background tabs in background windows.
    14  */
    16 this.EXPORTED_SYMBOLS = ["trackBrowserWindow"];
    18 const Ci = Components.interfaces;
    20 Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
    23 // Lazy getters
    24 XPCOMUtils.defineLazyServiceGetter(this, "_focusManager",
    25                                    "@mozilla.org/focus-manager;1",
    26                                    "nsIFocusManager");
    29 // Constants
    30 const TAB_EVENTS = ["TabOpen", "TabSelect"];
    31 const WINDOW_EVENTS = ["activate", "unload"];
    32 // PRIORITY DELTA is -10 because lower priority value is actually a higher priority
    33 const PRIORITY_DELTA = -10;
    36 // Variables
    37 let _lastFocusedWindow = null;
    38 let _windows = [];
    41 // Exported symbol
    42 this.trackBrowserWindow = function trackBrowserWindow(aWindow) {
    43   WindowHelper.addWindow(aWindow);
    44 }
    47 // Global methods
    48 function _handleEvent(aEvent) {
    49   switch (aEvent.type) {
    50     case "TabOpen":
    51       BrowserHelper.onOpen(aEvent.target.linkedBrowser);
    52       break;
    53     case "TabSelect":
    54       BrowserHelper.onSelect(aEvent.target.linkedBrowser);
    55       break;
    56     case "activate":
    57       WindowHelper.onActivate(aEvent.target);
    58       break;
    59     case "unload":
    60       WindowHelper.removeWindow(aEvent.currentTarget);
    61       break;
    62   }
    63 }
    66 // Methods that impact a browser. Put into single object for organization.
    67 let BrowserHelper = {
    68   onOpen: function NP_BH_onOpen(aBrowser) {
    69     // If the tab is in the focused window, leave priority as it is
    70     if (aBrowser.ownerDocument.defaultView != _lastFocusedWindow)
    71       this.decreasePriority(aBrowser);
    72   },
    74   onSelect: function NP_BH_onSelect(aBrowser) {
    75     let windowEntry = WindowHelper.getEntry(aBrowser.ownerDocument.defaultView);
    76     if (windowEntry.lastSelectedBrowser)
    77       this.decreasePriority(windowEntry.lastSelectedBrowser);
    78     this.increasePriority(aBrowser);
    80     windowEntry.lastSelectedBrowser = aBrowser;
    81   },
    83   increasePriority: function NP_BH_increasePriority(aBrowser) {
    84     aBrowser.adjustPriority(PRIORITY_DELTA);
    85   },
    87   decreasePriority: function NP_BH_decreasePriority(aBrowser) {
    88     aBrowser.adjustPriority(PRIORITY_DELTA * -1);
    89   }
    90 };
    93 // Methods that impact a window. Put into single object for organization.
    94 let WindowHelper = {
    95   addWindow: function NP_WH_addWindow(aWindow) {
    96     // Build internal data object
    97     _windows.push({ window: aWindow, lastSelectedBrowser: null });
    99     // Add event listeners
   100     TAB_EVENTS.forEach(function(event) {
   101       aWindow.gBrowser.tabContainer.addEventListener(event, _handleEvent, false);
   102     });
   103     WINDOW_EVENTS.forEach(function(event) {
   104       aWindow.addEventListener(event, _handleEvent, false);
   105     });
   107     // This gets called AFTER activate event, so if this is the focused window
   108     // we want to activate it. Otherwise, deprioritize it.
   109     if (aWindow == _focusManager.activeWindow)
   110       this.handleFocusedWindow(aWindow);
   111     else
   112       this.decreasePriority(aWindow);
   114     // Select the selected tab
   115     BrowserHelper.onSelect(aWindow.gBrowser.selectedBrowser);
   116   },
   118   removeWindow: function NP_WH_removeWindow(aWindow) {
   119     if (aWindow == _lastFocusedWindow)
   120       _lastFocusedWindow = null;
   122     // Delete this window from our tracking
   123     _windows.splice(this.getEntryIndex(aWindow), 1);
   125     // Remove the event listeners
   126     TAB_EVENTS.forEach(function(event) {
   127       aWindow.gBrowser.tabContainer.removeEventListener(event, _handleEvent, false);
   128     });
   129     WINDOW_EVENTS.forEach(function(event) {
   130       aWindow.removeEventListener(event, _handleEvent, false);
   131     });
   132   },
   134   onActivate: function NP_WH_onActivate(aWindow, aHasFocus) {
   135     // If this window was the last focused window, we don't need to do anything
   136     if (aWindow == _lastFocusedWindow)
   137       return;
   139     // handleFocusedWindow will deprioritize the current window
   140     this.handleFocusedWindow(aWindow);
   142     // Lastly we should increase priority for this window
   143     this.increasePriority(aWindow);
   144   },
   146   handleFocusedWindow: function NP_WH_handleFocusedWindow(aWindow) {
   147     // If we have a last focused window, we need to deprioritize it first
   148     if (_lastFocusedWindow)
   149       this.decreasePriority(_lastFocusedWindow);
   151     // aWindow is now focused
   152     _lastFocusedWindow = aWindow;
   153   },
   155   // Auxiliary methods
   156   increasePriority: function NP_WH_increasePriority(aWindow) {
   157     aWindow.gBrowser.browsers.forEach(function(aBrowser) {
   158       BrowserHelper.increasePriority(aBrowser);
   159     });
   160   },
   162   decreasePriority: function NP_WH_decreasePriority(aWindow) {
   163     aWindow.gBrowser.browsers.forEach(function(aBrowser) {
   164       BrowserHelper.decreasePriority(aBrowser);
   165     });
   166   },
   168   getEntry: function NP_WH_getEntry(aWindow) {
   169     return _windows[this.getEntryIndex(aWindow)];
   170   },
   172   getEntryIndex: function NP_WH_getEntryAtIndex(aWindow) {
   173     // Assumes that every object has a unique window & it's in the array
   174     for (let i = 0; i < _windows.length; i++)
   175       if (_windows[i].window == aWindow)
   176         return i;
   177   }
   178 };

mercurial