Bug 975084 - Part 1: Access browser frames. r=vingtetun,ochameau
authorJ. Ryan Stinnett <jryans@gmail.com>
Mon, 13 Oct 2014 08:43:00 +0200
changeset 234617 7d7d64553c684fb913c0d53d7e49813da15d0c0b
parent 234541 54b2b11d1895353b49061cd27cddc86e37304a79
child 234618 4b9af1d6b1a8317c82ac7e1e0ef20d9817dcd6b2
push id4311
push userraliiev@mozilla.com
push dateMon, 12 Jan 2015 19:37:41 +0000
treeherdermozilla-beta@150c9fed433b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersvingtetun, ochameau
bugs975084
milestone36.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 975084 - Part 1: Access browser frames. r=vingtetun,ochameau
b2g/chrome/content/devtools/hud.js
b2g/components/AppFrames.jsm
b2g/components/Frames.jsm
b2g/components/SystemAppProxy.jsm
b2g/components/moz.build
toolkit/devtools/apps/tests/debugger-protocol-helper.js
toolkit/devtools/server/actors/webapps.js
--- a/b2g/chrome/content/devtools/hud.js
+++ b/b2g/chrome/content/devtools/hud.js
@@ -24,17 +24,17 @@ XPCOMUtils.defineLazyGetter(this, 'WebCo
 XPCOMUtils.defineLazyGetter(this, 'EventLoopLagFront', function() {
   return devtools.require('devtools/server/actors/eventlooplag').EventLoopLagFront;
 });
 
 XPCOMUtils.defineLazyGetter(this, 'MemoryFront', function() {
   return devtools.require('devtools/server/actors/memory').MemoryFront;
 });
 
-Cu.import('resource://gre/modules/AppFrames.jsm');
+Cu.import('resource://gre/modules/Frames.jsm');
 
 /**
  * The Developer HUD is an on-device developer tool that displays widgets,
  * showing visual debug information about apps. Each widget corresponds to a
  * metric as tracked by a metric watcher (e.g. consoleWatcher).
  */
 let developerHUD = {
 
@@ -75,19 +75,20 @@ let developerHUD = {
     this._client = new DebuggerClient(transport);
 
     for (let w of this._watchers) {
       if (w.init) {
         w.init(this._client);
       }
     }
 
-    AppFrames.addObserver(this);
+    Frames.addObserver(this);
 
-    for (let frame of AppFrames.list()) {
+    let appFrames = Frames.list().filter(frame => frame.getAttribute('mozapp'));
+    for (let frame of appFrames) {
       this.trackFrame(frame);
     }
 
     SettingsListener.observe('hud.logging', this._logging, enabled => {
       this._logging = enabled;
     });
   },
 
@@ -95,17 +96,17 @@ let developerHUD = {
     if (!this._client) {
       return;
     }
 
     for (let frame of this._targets.keys()) {
       this.untrackFrame(frame);
     }
 
-    AppFrames.removeObserver(this);
+    Frames.removeObserver(this);
 
     this._client.close();
     delete this._client;
   },
 
   /**
    * This method will ask all registered watchers to track and update metrics
    * on an app frame.
@@ -132,21 +133,29 @@ let developerHUD = {
         w.untrackTarget(target);
       }
 
       target.destroy();
       this._targets.delete(frame);
     }
   },
 
-  onAppFrameCreated: function (frame, isFirstAppFrame) {
+  onFrameCreated: function (frame, isFirstAppFrame) {
+    let mozapp = frame.getAttribute('mozapp');
+    if (!mozapp) {
+      return;
+    }
     this.trackFrame(frame);
   },
 
-  onAppFrameDestroyed: function (frame, isLastAppFrame) {
+  onFrameDestroyed: function (frame, isLastAppFrame) {
+    let mozapp = frame.getAttribute('mozapp');
+    if (!mozapp) {
+      return;
+    }
     this.untrackFrame(frame);
   },
 
   log: function dwp_log(message) {
     if (this._logging) {
       dump(DEVELOPER_HUD_LOG_PREFIX + ': ' + message + '\n');
     }
   }
rename from b2g/components/AppFrames.jsm
rename to b2g/components/Frames.jsm
--- a/b2g/components/AppFrames.jsm
+++ b/b2g/components/Frames.jsm
@@ -1,15 +1,15 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 'use strict';
 
-this.EXPORTED_SYMBOLS = ['AppFrames'];
+this.EXPORTED_SYMBOLS = ['Frames'];
 
 const Cu = Components.utils;
 const Ci = Components.interfaces;
 
 Cu.import('resource://gre/modules/Services.jsm');
 Cu.import('resource://gre/modules/SystemAppProxy.jsm');
 
 const listeners = [];
@@ -22,21 +22,23 @@ const Observer = {
   // Also save current number of iframes opened by app
   _apps: new Map(),
 
   start: function () {
     Services.obs.addObserver(this, 'remote-browser-shown', false);
     Services.obs.addObserver(this, 'inprocess-browser-shown', false);
     Services.obs.addObserver(this, 'message-manager-disconnect', false);
 
-    SystemAppProxy.getAppFrames().forEach((frame) => {
+    SystemAppProxy.getFrames().forEach(frame => {
       let mm = frame.QueryInterface(Ci.nsIFrameLoaderOwner).frameLoader.messageManager;
       this._frames.set(mm, frame);
       let mozapp = frame.getAttribute('mozapp');
-      this._apps.set(mozapp, (this._apps.get(mozapp) || 0) + 1);
+      if (mozapp) {
+        this._apps.set(mozapp, (this._apps.get(mozapp) || 0) + 1);
+      }
     });
   },
 
   stop: function () {
     Services.obs.removeObserver(this, 'remote-browser-shown');
     Services.obs.removeObserver(this, 'inprocess-browser-shown');
     Services.obs.removeObserver(this, 'message-manager-disconnect');
     this._frames.clear();
@@ -63,58 +65,66 @@ const Observer = {
         this.onMessageManagerDestroyed(subject);
         break;
     }
   },
 
   onMessageManagerCreated: function (mm, frame) {
     this._frames.set(mm, frame);
 
+    let isFirstAppFrame = null;
     let mozapp = frame.getAttribute('mozapp');
-    let count = (this._apps.get(mozapp) || 0) + 1;
-    this._apps.set(mozapp, count);
+    if (mozapp) {
+      let count = (this._apps.get(mozapp) || 0) + 1;
+      this._apps.set(mozapp, count);
+      isFirstAppFrame = (count === 1);
+    }
 
-    let isFirstAppFrame = (count === 1);
     listeners.forEach(function (listener) {
       try {
-        listener.onAppFrameCreated(frame, isFirstAppFrame);
+        listener.onFrameCreated(frame, isFirstAppFrame);
       } catch(e) {
-        dump('Exception while calling Frames.jsm listener:' + e + '\n' + e.stack + '\n');
+        dump('Exception while calling Frames.jsm listener:' + e + '\n' +
+             e.stack + '\n');
       }
     });
   },
 
   onMessageManagerDestroyed: function (mm) {
     let frame = this._frames.get(mm);
     if (!frame) {
-      // We receive an event for a non mozapp message manager
+      // We received an event for an unknown message manager
       return;
     }
 
     this._frames.delete(mm);
 
+    let isLastAppFrame = null;
     let mozapp = frame.getAttribute('mozapp');
-    let count = (this._apps.get(mozapp) || 0) - 1;
-    this._apps.set(mozapp, count);
+    if (mozapp) {
+      let count = (this._apps.get(mozapp) || 0) - 1;
+      this._apps.set(mozapp, count);
+      isLastAppFrame = (count === 0);
+    }
 
-    let isLastAppFrame = (count === 0);
     listeners.forEach(function (listener) {
       try {
-        listener.onAppFrameDestroyed(frame, isLastAppFrame);
+        listener.onFrameDestroyed(frame, isLastAppFrame);
       } catch(e) {
-        dump('Exception while calling Frames.jsm listener:' + e + '\n' + e.stack + '\n');
+        dump('Exception while calling Frames.jsm listener:' + e + '\n' +
+             e.stack + '\n');
       }
     });
   }
 
 };
 
-let AppFrames = this.AppFrames = {
+let Frames = this.Frames = {
 
-  list: () => SystemAppProxy.getAppFrames(),
+  list: () => SystemAppProxy.getFrames(),
 
   addObserver: function (listener) {
     if (listeners.indexOf(listener) !== -1) {
       return;
     }
 
     listeners.push(listener);
     if (listeners.length == 1) {
--- a/b2g/components/SystemAppProxy.jsm
+++ b/b2g/components/SystemAppProxy.jsm
@@ -112,30 +112,23 @@ let SystemAppProxy = {
     } else {
       this._pendingListeners = this._pendingListeners.filter(
         args => {
           return args[0] != name || args[1] != listener;
         });
     }
   },
 
-  getAppFrames: function systemApp_getAppFrames() {
+  getFrames: function systemApp_getFrames() {
     let systemAppFrame = this._frame;
     if (!systemAppFrame) {
       return [];
     }
-
     let list = [systemAppFrame];
-
-    // List all app frames hosted in the system app: the homescreen,
-    // all regular apps, activities, rocket bar, attention screen and the keyboard.
-    // Bookmark apps and other system app internal frames like captive portal
-    // are also hosted in system app, but they are not using mozapp attribute.
-    let frames = systemAppFrame.contentDocument.querySelectorAll("iframe[mozapp]");
+    let frames = systemAppFrame.contentDocument.querySelectorAll('iframe');
     for (let i = 0; i < frames.length; i++) {
       list.push(frames[i]);
     }
-
     return list;
   }
 };
 this.SystemAppProxy = SystemAppProxy;
 
--- a/b2g/components/moz.build
+++ b/b2g/components/moz.build
@@ -43,19 +43,19 @@ EXTRA_PP_COMPONENTS += [
 
 if CONFIG['MOZ_UPDATER']:
     EXTRA_PP_COMPONENTS += [
         'UpdatePrompt.js',
     ]
 
 EXTRA_JS_MODULES += [
     'AlertsHelper.jsm',
-    'AppFrames.jsm',
     'ContentRequestHelper.jsm',
     'ErrorPage.jsm',
+    'Frames.jsm',
     'FxAccountsMgmtService.jsm',
     'LogCapture.jsm',
     'LogParser.jsm',
     'LogShake.jsm',
     'SignInToWebsite.jsm',
     'SystemAppProxy.jsm',
     'TelURIParser.jsm',
     'WebappsUpdater.jsm',
--- a/toolkit/devtools/apps/tests/debugger-protocol-helper.js
+++ b/toolkit/devtools/apps/tests/debugger-protocol-helper.js
@@ -146,17 +146,17 @@ addMessageListener("addFrame", function 
 });
 
 addMessageListener("cleanup", function () {
   webappActorRequest({type: "unwatchApps"}, function () {
     gClient.close();
   });
 });
 
-let AppFramesMock = {
+let FramesMock = {
   list: function () {
     return Frames;
   },
   addObserver: function () {},
   removeObserver: function () {}
 };
 
-require("devtools/server/actors/webapps").setAppFramesMock(AppFramesMock);
+require("devtools/server/actors/webapps").setFramesMock(FramesMock);
--- a/toolkit/devtools/server/actors/webapps.js
+++ b/toolkit/devtools/server/actors/webapps.js
@@ -13,29 +13,29 @@ Cu.import("resource://gre/modules/FileUt
 
 let {Promise: promise} = Cu.import("resource://gre/modules/Promise.jsm", {});
 
 let DevToolsUtils = require("devtools/toolkit/DevToolsUtils");
 let { ActorPool } = require("devtools/server/actors/common");
 let { DebuggerServer } = require("devtools/server/main");
 let Services = require("Services");
 
-let AppFramesMock = null;
+let FramesMock = null;
 
-exports.setAppFramesMock = function (mock) {
-  AppFramesMock = mock;
-}
+exports.setFramesMock = function (mock) {
+  FramesMock = mock;
+};
 
-DevToolsUtils.defineLazyGetter(this, "AppFrames", () => {
+DevToolsUtils.defineLazyGetter(this, "Frames", () => {
   // Offer a way for unit test to provide a mock
-  if (AppFramesMock) {
-    return AppFramesMock;
+  if (FramesMock) {
+    return FramesMock;
   }
   try {
-    return Cu.import("resource://gre/modules/AppFrames.jsm", {}).AppFrames;
+    return Cu.import("resource://gre/modules/Frames.jsm", {}).Frames;
   } catch(e) {}
   return null;
 });
 
 function debug(aMsg) {
   /*
   Cc["@mozilla.org/consoleservice;1"]
     .getService(Ci.nsIConsoleService)
@@ -855,18 +855,20 @@ WebappsActor.prototype = {
 
     reg.close(app);
 
     return {};
   },
 
   _appFrames: function () {
     // Try to filter on b2g and mulet
-    if (AppFrames) {
-      return AppFrames.list();
+    if (Frames) {
+      return Frames.list().filter(frame => {
+        return frame.getAttribute('mozapp');
+      });
     } else {
       return [];
     }
   },
 
   listRunningApps: function (aRequest) {
     debug("listRunningApps\n");
 
@@ -950,37 +952,38 @@ WebappsActor.prototype = {
       }
 
       return { actor: actor };
     });
   },
 
   watchApps: function () {
     // For now, app open/close events are only implement on b2g
-    if (AppFrames) {
-      AppFrames.addObserver(this);
+    if (Frames) {
+      Frames.addObserver(this);
     }
     Services.obs.addObserver(this, "webapps-installed", false);
     Services.obs.addObserver(this, "webapps-uninstall", false);
 
     return {};
   },
 
   unwatchApps: function () {
-    if (AppFrames) {
-      AppFrames.removeObserver(this);
+    if (Frames) {
+      Frames.removeObserver(this);
     }
     Services.obs.removeObserver(this, "webapps-installed", false);
     Services.obs.removeObserver(this, "webapps-uninstall", false);
 
     return {};
   },
 
-  onAppFrameCreated: function (frame, isFirstAppFrame) {
-    if (!isFirstAppFrame) {
+  onFrameCreated: function (frame, isFirstAppFrame) {
+    let mozapp = frame.getAttribute('mozapp');
+    if (!mozapp || !isFirstAppFrame) {
       return;
     }
 
     let manifestURL = frame.appManifestURL;
     // Only track app frames
     if (!manifestURL) {
       return;
     }
@@ -990,18 +993,19 @@ WebappsActor.prototype = {
         this.conn.send({ from: this.actorID,
                          type: "appOpen",
                          manifestURL: manifestURL
                        });
       }
     });
   },
 
-  onAppFrameDestroyed: function (frame, isLastAppFrame) {
-    if (!isLastAppFrame) {
+  onFrameDestroyed: function (frame, isLastAppFrame) {
+    let mozapp = frame.getAttribute('mozapp');
+    if (!mozapp || !isLastAppFrame) {
       return;
     }
 
     let manifestURL = frame.appManifestURL;
     // Only track app frames
     if (!manifestURL) {
       return;
     }