Merge fx-team to m-c. a=merge

CLOSED TREE
This commit is contained in:
Ryan VanderMeulen 2014-12-09 14:16:03 -05:00
commit 98457578ce
24 changed files with 193 additions and 90 deletions

View File

@ -665,6 +665,19 @@ function assertWebRTCIndicatorStatus(expected) {
}
if (!("nsISystemStatusBar" in Ci)) {
if (!expected) {
let win = Services.wm.getMostRecentWindow("Browser:WebRTCGlobalIndicator");
if (win) {
yield new Promise((resolve, reject) => {
win.addEventListener("unload", (e) => {
if (e.target == win.document) {
win.removeEventListener("unload", arguments.callee);
resolve();
}
}, false);
});
}
}
let indicator = Services.wm.getEnumerator("Browser:WebRTCGlobalIndicator");
let hasWindow = indicator.hasMoreElements();
is(hasWindow, !!expected, "popup " + msg);

View File

@ -39,18 +39,14 @@ loop.webapp = (function($, _, OT, mozL10n) {
*/
var UnsupportedBrowserView = React.createClass({displayName: 'UnsupportedBrowserView',
render: function() {
var useLatestFF = mozL10n.get("use_latest_firefox", {
"firefoxBrandNameLink": React.renderComponentToStaticMarkup(
React.DOM.a({target: "_blank", href: loop.config.brandWebsiteUrl},
mozL10n.get("brandShortname")
)
)
});
return (
React.DOM.div(null,
React.DOM.h2(null, mozL10n.get("incompatible_browser")),
React.DOM.p(null, mozL10n.get("powered_by_webrtc", {clientShortname: mozL10n.get("clientShortname2")})),
React.DOM.p({dangerouslySetInnerHTML: {__html: useLatestFF}})
React.DOM.div({className: "expired-url-info"},
React.DOM.div({className: "info-panel"},
React.DOM.div({className: "firefox-logo"}),
React.DOM.h1(null, mozL10n.get("incompatible_browser_heading")),
React.DOM.h4(null, mozL10n.get("incompatible_browser_message"))
),
PromoteFirefoxView({helper: this.props.helper})
)
);
}
@ -993,7 +989,7 @@ loop.webapp = (function($, _, OT, mozL10n) {
return UnsupportedDeviceView(null);
}
case "unsupportedBrowser": {
return UnsupportedBrowserView(null);
return UnsupportedBrowserView({helper: this.props.helper});
}
case "outgoing": {
return (

View File

@ -39,18 +39,14 @@ loop.webapp = (function($, _, OT, mozL10n) {
*/
var UnsupportedBrowserView = React.createClass({
render: function() {
var useLatestFF = mozL10n.get("use_latest_firefox", {
"firefoxBrandNameLink": React.renderComponentToStaticMarkup(
<a target="_blank" href={loop.config.brandWebsiteUrl}>
{mozL10n.get("brandShortname")}
</a>
)
});
return (
<div>
<h2>{mozL10n.get("incompatible_browser")}</h2>
<p>{mozL10n.get("powered_by_webrtc", {clientShortname: mozL10n.get("clientShortname2")})}</p>
<p dangerouslySetInnerHTML={{__html: useLatestFF}}></p>
<div className="expired-url-info">
<div className="info-panel">
<div className="firefox-logo" />
<h1>{mozL10n.get("incompatible_browser_heading")}</h1>
<h4>{mozL10n.get("incompatible_browser_message")}</h4>
</div>
<PromoteFirefoxView helper={this.props.helper} />
</div>
);
}
@ -993,7 +989,7 @@ loop.webapp = (function($, _, OT, mozL10n) {
return <UnsupportedDeviceView />;
}
case "unsupportedBrowser": {
return <UnsupportedBrowserView />;
return <UnsupportedBrowserView helper={this.props.helper}/>;
}
case "outgoing": {
return (

View File

@ -20,7 +20,8 @@ unmute_local_video_button_title=Unmute your video
outgoing_call_title=Start conversation?
call_with_contact_title=Conversation with {{incomingCallIdentity}}
welcome=Welcome to the {{clientShortname}} web client.
incompatible_browser=Incompatible Browser
incompatible_browser_heading=Oops!
incompatible_browser_message=Firefox Hello only works in browsers that support WebRTC
powered_by_webrtc=The audio and video components of {{clientShortname}} are powered by WebRTC.
use_latest_firefox=Please try this link in a WebRTC-enabled browser, such as {{firefoxBrandNameLink}}.
incompatible_device=Incompatible device

View File

@ -441,14 +441,6 @@ let SnapshotsListView = Heritage.extend(WidgetMethods, {
snapshotItem.isLoadedFromDisk = true;
data.calls.forEach(e => e.isLoadedFromDisk = true);
// Create array buffers from the parsed pixel arrays.
for (let thumbnail of data.thumbnails) {
let thumbnailPixelsArray = thumbnail.pixels.split(",");
thumbnail.pixels = new Uint32Array(thumbnailPixelsArray);
}
let screenshotPixelsArray = data.screenshot.pixels.split(",");
data.screenshot.pixels = new Uint32Array(screenshotPixelsArray);
this.customizeSnapshot(snapshotItem, data.calls, data);
});
},
@ -498,24 +490,12 @@ let SnapshotsListView = Heritage.extend(WidgetMethods, {
// Prepare all the thumbnails for serialization.
yield DevToolsUtils.yieldingEach(thumbnails, (thumbnail, i) => {
let { index, width, height, flipped, pixels } = thumbnail;
data.thumbnails.push({
index: index,
width: width,
height: height,
flipped: flipped,
pixels: Array.join(pixels, ",")
});
data.thumbnails.push({ index, width, height, flipped, pixels });
});
// Prepare the screenshot for serialization.
let { index, width, height, flipped, pixels } = screenshot;
data.screenshot = {
index: index,
width: width,
height: height,
flipped: flipped,
pixels: Array.join(pixels, ",")
};
data.screenshot = { index, width, height, flipped, pixels };
let string = JSON.stringify(data);
let converter = Cc["@mozilla.org/intl/scriptableunicodeconverter"].
@ -1147,7 +1127,7 @@ getImageDataStorage.cache = null;
* The image data width.
* @param number height
* The image data height.
* @param pixels
* @param array pixels
* An array buffer view of the image data.
* @param object options
* Additional options supported by this operation:
@ -1165,9 +1145,8 @@ function drawImage(canvas, width, height, pixels, options = {}) {
return;
}
let arrayBuffer = new Uint8Array(pixels.buffer);
let imageData = getImageDataStorage(ctx, width, height);
imageData.data.set(arrayBuffer);
imageData.data.set(pixels);
if (options.centered) {
let left = (canvas.width - width) / 2;
@ -1188,7 +1167,7 @@ function drawImage(canvas, width, height, pixels, options = {}) {
* The image data width.
* @param number height
* The image data height.
* @param pixels
* @param array pixels
* An array buffer view of the image data.
*/
function drawBackground(id, width, height, pixels) {

View File

@ -39,7 +39,7 @@ function ifTestingSupported() {
"The first thumbnail's height is correct.");
is(thumbnails[0].flipped, false,
"The first thumbnail's flipped flag is correct.");
is([].find.call(thumbnails[0].pixels, e => e > 0), undefined,
is([].find.call(Uint32(thumbnails[0].pixels), e => e > 0), undefined,
"The first thumbnail's pixels seem to be completely transparent.");
is(thumbnails[1].index, 2,
@ -50,7 +50,7 @@ function ifTestingSupported() {
"The second thumbnail's height is correct.");
is(thumbnails[1].flipped, false,
"The second thumbnail's flipped flag is correct.");
is([].find.call(thumbnails[1].pixels, e => e > 0), 4290822336,
is([].find.call(Uint32(thumbnails[1].pixels), e => e > 0), 4290822336,
"The second thumbnail's pixels seem to not be completely transparent.");
is(thumbnails[2].index, 4,
@ -61,7 +61,7 @@ function ifTestingSupported() {
"The third thumbnail's height is correct.");
is(thumbnails[2].flipped, false,
"The third thumbnail's flipped flag is correct.");
is([].find.call(thumbnails[2].pixels, e => e > 0), 4290822336,
is([].find.call(Uint32(thumbnails[2].pixels), e => e > 0), 4290822336,
"The third thumbnail's pixels seem to not be completely transparent.");
is(thumbnails[3].index, 6,
@ -72,9 +72,14 @@ function ifTestingSupported() {
"The fourth thumbnail's height is correct.");
is(thumbnails[3].flipped, false,
"The fourth thumbnail's flipped flag is correct.");
is([].find.call(thumbnails[3].pixels, e => e > 0), 4290822336,
is([].find.call(Uint32(thumbnails[3].pixels), e => e > 0), 4290822336,
"The fourth thumbnail's pixels seem to not be completely transparent.");
yield removeTab(target.tab);
finish();
}
function Uint32(src) {
let charView = new Uint8Array(src);
return new Uint32Array(charView.buffer);
}

View File

@ -37,9 +37,14 @@ function ifTestingSupported() {
"The screenshot's height is correct.");
is(screenshot.flipped, false,
"The screenshot's flipped flag is correct.");
is([].find.call(screenshot.pixels, e => e > 0), 4290822336,
is([].find.call(Uint32(screenshot.pixels), e => e > 0), 4290822336,
"The screenshot's pixels seem to not be completely transparent.");
yield removeTab(target.tab);
finish();
}
function Uint32(src) {
let charView = new Uint8Array(src);
return new Uint32Array(charView.buffer);
}

View File

@ -47,7 +47,7 @@ function ifTestingSupported() {
"The first draw call has the correct screenshot width.");
is(firstDrawCallScreenshot.height, 128,
"The first draw call has the correct screenshot height.");
is([].find.call(firstDrawCallScreenshot.pixels, e => e > 0), undefined,
is([].find.call(Uint32(firstDrawCallScreenshot.pixels), e => e > 0), undefined,
"The first draw call's screenshot's pixels seems to be completely transparent.");
ok(secondDrawCallScreenshot,
@ -58,7 +58,7 @@ function ifTestingSupported() {
"The second draw call has the correct screenshot width.");
is(secondDrawCallScreenshot.height, 128,
"The second draw call has the correct screenshot height.");
is([].find.call(firstDrawCallScreenshot.pixels, e => e > 0), undefined,
is([].find.call(Uint32(firstDrawCallScreenshot.pixels), e => e > 0), undefined,
"The second draw call's screenshot's pixels seems to be completely transparent.");
ok(thirdDrawCallScreenshot,
@ -69,7 +69,7 @@ function ifTestingSupported() {
"The third draw call has the correct screenshot width.");
is(thirdDrawCallScreenshot.height, 128,
"The third draw call has the correct screenshot height.");
is([].find.call(thirdDrawCallScreenshot.pixels, e => e > 0), 2160001024,
is([].find.call(Uint32(thirdDrawCallScreenshot.pixels), e => e > 0), 2160001024,
"The third draw call's screenshot's pixels seems to not be completely transparent.");
ok(fourthDrawCallScreenshot,
@ -80,7 +80,7 @@ function ifTestingSupported() {
"The fourth draw call has the correct screenshot width.");
is(fourthDrawCallScreenshot.height, 128,
"The fourth draw call has the correct screenshot height.");
is([].find.call(fourthDrawCallScreenshot.pixels, e => e > 0), 2147483839,
is([].find.call(Uint32(fourthDrawCallScreenshot.pixels), e => e > 0), 2147483839,
"The fourth draw call's screenshot's pixels seems to not be completely transparent.");
isnot(firstDrawCallScreenshot.pixels, secondDrawCallScreenshot.pixels,
@ -93,3 +93,8 @@ function ifTestingSupported() {
yield removeTab(target.tab);
finish();
}
function Uint32(src) {
let charView = new Uint8Array(src);
return new Uint32Array(charView.buffer);
}

View File

@ -69,15 +69,15 @@ function ifTestingSupported() {
"The second screenshot has the correct scaling.");
is(secondScreenshot.flipped, true,
"The second screenshot has the correct 'flipped' flag.");
is(secondScreenshot.pixels.length, Math.pow(CanvasFront.WEBGL_SCREENSHOT_MAX_HEIGHT, 2),
is(secondScreenshot.pixels.length, Math.pow(CanvasFront.WEBGL_SCREENSHOT_MAX_HEIGHT, 2) * 4,
"The second screenshot should not be empty.");
is(new Uint8Array(secondScreenshot.pixels.buffer)[0], 0,
is(secondScreenshot.pixels[0], 0,
"The second screenshot has the correct red component.");
is(new Uint8Array(secondScreenshot.pixels.buffer)[1], 0,
is(secondScreenshot.pixels[1], 0,
"The second screenshot has the correct green component.");
is(new Uint8Array(secondScreenshot.pixels.buffer)[2], 255,
is(secondScreenshot.pixels[2], 255,
"The second screenshot has the correct blue component.");
is(new Uint8Array(secondScreenshot.pixels.buffer)[3], 255,
is(secondScreenshot.pixels[3], 255,
"The second screenshot has the correct alpha component.");
is((yield evalInDebuggee("gl.getParameter(gl.FRAMEBUFFER_BINDING) === customFramebuffer")),

View File

@ -19,6 +19,7 @@ skip-if = e10s # Bug 1070837 - devtools/framework/toolbox.js |doc| getter not e1
[browser_target_support.js]
[browser_two_tabs.js]
[browser_toolbox_dynamic_registration.js]
[browser_toolbox_getpanelwhenready.js]
[browser_toolbox_highlight.js]
[browser_toolbox_hosts.js]
[browser_toolbox_options.js]

View File

@ -0,0 +1,34 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
// Tests that getPanelWhenReady returns the correct panel in promise
// resolutions regardless of whether it has opened first.
let toolbox = null;
const URL = "data:text/html;charset=utf8,test for getPanelWhenReady";
let test = asyncTest(function*() {
let tab = yield addTab(URL);
let target = TargetFactory.forTab(tab);
toolbox = yield gDevTools.showToolbox(target);
let debuggerPanelPromise = toolbox.getPanelWhenReady("jsdebugger");
yield toolbox.selectTool("jsdebugger");
let debuggerPanel = yield debuggerPanelPromise;
is (debuggerPanel, toolbox.getPanel("jsdebugger"),
"The debugger panel from getPanelWhenReady before loading is the actual panel");
let debuggerPanel2 = yield toolbox.getPanelWhenReady("jsdebugger");
is (debuggerPanel2, toolbox.getPanel("jsdebugger"),
"The debugger panel from getPanelWhenReady after loading is the actual panel");
yield cleanup();
});
function* cleanup() {
yield toolbox.destroy();
gBrowser.removeCurrentTab();
toolbox = null;
}

View File

@ -106,12 +106,10 @@ function bindToolboxHandlers() {
// Badge the dock icon to differentiate this process from the main application process.
updateBadgeText(false);
// Check if the debugger panel is already loaded otherwise listen for it to be.
if (gToolbox.getPanel("jsdebugger")) {
setupThreadListeners(gToolbox.getPanel("jsdebugger"));
} else {
gToolbox.once("jsdebugger-ready", (e, panel) => setupThreadListeners(panel));
}
// Once the debugger panel opens listen for thread pause / resume.
gToolbox.getPanelWhenReady("jsdebugger").then(panel => {
setupThreadListeners(panel);
});
#endif
}

View File

@ -174,6 +174,33 @@ Toolbox.prototype = {
return this._toolPanels.get(id);
},
/**
* Get the panel instance for a given tool once it is ready.
* If the tool is already opened, the promise will resolve immediately,
* otherwise it will wait until the tool has been opened before resolving.
*
* Note that this does not open the tool, use selectTool if you'd
* like to select the tool right away.
*
* @param {String} id
* The id of the panel, for example "jsdebugger".
* @returns Promise
* A promise that resolves once the panel is ready.
*/
getPanelWhenReady: function(id) {
let deferred = promise.defer();
let panel = this.getPanel(id);
if (panel) {
deferred.resolve(panel);
} else {
this.on(id + "-ready", (e, panel) => {
deferred.resolve(panel);
});
}
return deferred.promise;
},
/**
* This is a shortcut for getPanel(currentToolId) because it is much more
* likely that we're going to want to get the panel that we've just made

Binary file not shown.

After

Width:  |  Height:  |  Size: 808 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 581 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1016 B

View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- 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/. -->
<ImageButton xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/nav_back"
android:layout_width="@dimen/tabs_panel_indicator_width"
android:layout_height="match_parent"
android:minWidth="@dimen/tabs_panel_indicator_width"
android:src="@drawable/new_tablet_nav_back"
android:contentDescription="@string/back"
android:background="@drawable/action_bar_button_inverse"/>

View File

@ -18,6 +18,11 @@
android:layout_height="match_parent"
android:background="@color/background_tabs">
<ViewStub android:id="@+id/nav_back_stub"
android:layout="@layout/new_tablet_tabs_panel_back_button"
android:layout_width="wrap_content"
android:layout_height="match_parent"/>
<org.mozilla.gecko.widget.IconTabWidget android:id="@+id/tab_widget"
android:layout_width="wrap_content"
android:layout_height="match_parent"

View File

@ -9,4 +9,5 @@
<item type="layout" name="new_tablet_browser_toolbar">@null</item>
<item type="layout" name="new_tablet_tab_strip">@null</item>
<item type="layout" name="new_tablet_tabs_item_cell">@null</item>
<item type="layout" name="new_tablet_tabs_panel_back_button">@null</item>
</resources>

View File

@ -30,6 +30,7 @@ import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewStub;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.ImageButton;
@ -88,6 +89,7 @@ public class TabsPanel extends LinearLayout
private IconTabWidget mTabWidget;
private static ImageButton mMenuButton;
private static ImageButton mAddTab;
private ImageButton mNavBackButton;
private Panel mCurrentPanel;
private boolean mIsSideBar;
@ -163,6 +165,17 @@ public class TabsPanel extends LinearLayout
showMenu();
}
});
if(NewTabletUI.isEnabled(getContext())) {
ViewStub backButtonStub = (ViewStub) findViewById(R.id.nav_back_stub);
mNavBackButton = (ImageButton) backButtonStub.inflate( );
mNavBackButton.setOnClickListener(new Button.OnClickListener() {
@Override
public void onClick(View view) {
mActivity.onBackPressed();
}
});
}
}
public void showMenu() {

View File

@ -289,6 +289,10 @@ public class SearchEngineManager implements SharedPreferences.OnSharedPreference
}
final File[] files = (new File(pluginsDir, "common")).listFiles();
if (files == null) {
Log.e(LOG_TAG, "Could not find search plugin files in distribution directory");
return null;
}
return createEngineFromFileList(files, name);
}
@ -353,6 +357,10 @@ public class SearchEngineManager implements SharedPreferences.OnSharedPreference
}
final File[] files = pluginsDir.listFiles();
if (files == null) {
Log.e(LOG_TAG, "Could not find search plugin files in profile directory");
return null;
}
return createEngineFromFileList(files, name);
}
@ -360,7 +368,7 @@ public class SearchEngineManager implements SharedPreferences.OnSharedPreference
* This method iterates through an array of search plugin files, creating
* SearchEngine instances until it finds one with the right name.
*
* @param files Array of search plugin files.
* @param files Array of search plugin files. Should not be null.
* @param name Search engine name.
* @return SearchEngine instance for name.
*/

View File

@ -5,11 +5,6 @@
android:label="@string/search_app_name"
android:configChanges="orientation|screenSize"
android:theme="@style/AppTheme">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.ASSIST"/>

View File

@ -52,15 +52,21 @@ const INTERESTING_CALLS = [
];
/**
* Type representing an Uint32Array buffer, serialized fast(er).
* Type representing an ArrayBufferView, serialized fast(er).
*
* Don't create a new array buffer view from the parsed array on the frontend.
* Consumers may copy the data into an existing buffer, or create a new one if
* necesasry. For example, this avoids the need for a redundant copy when
* populating ImageData objects, at the expense of transferring char views
* of a pixel buffer over the protocol instead of a packed int view.
*
* XXX: It would be nice if on local connections (only), we could just *give*
* the buffer directly to the front, instead of going through all this
* serialization redundancy.
*/
protocol.types.addType("uint32-array", {
protocol.types.addType("array-buffer-view", {
write: (v) => "[" + Array.join(v, ",") + "]",
read: (v) => new Uint32Array(JSON.parse(v))
read: (v) => JSON.parse(v)
});
/**
@ -72,7 +78,7 @@ protocol.types.addDictType("snapshot-image", {
height: "number",
scaling: "number",
flipped: "boolean",
pixels: "uint32-array"
pixels: "array-buffer-view"
});
/**
@ -363,14 +369,14 @@ let CanvasActor = exports.CanvasActor = protocol.ActorClass({
let width = this._lastContentCanvasWidth;
let height = this._lastContentCanvasHeight;
let flipped = !!this._lastThumbnailFlipped; // undefined -> false
let pixels = ContextUtils.getPixelStorage()["32bit"];
let pixels = ContextUtils.getPixelStorage()["8bit"];
let animationFrameEndScreenshot = {
index: index,
width: width,
height: height,
scaling: 1,
flipped: flipped,
pixels: pixels.subarray(0, width * height)
pixels: pixels.subarray(0, width * height * 4)
};
// Wrap the function calls and screenshot in a FrameSnapshotActor instance,
@ -461,7 +467,8 @@ let ContextUtils = {
* @param number dstHeight [optional]
* The desired generated screenshot height.
* @return object
* An objet containing the screenshot's width, height and pixel data.
* An objet containing the screenshot's width, height and pixel data,
* represented as an 8-bit array buffer of r, g, b, a values.
*/
getPixelsForWebGL: function(gl,
srcX = 0, srcY = 0,
@ -492,7 +499,8 @@ let ContextUtils = {
* @param number dstHeight [optional]
* The desired generated screenshot height.
* @return object
* An objet containing the screenshot's width, height and pixel data.
* An objet containing the screenshot's width, height and pixel data,
* represented as an 8-bit array buffer of r, g, b, a values.
*/
getPixelsFor2D: function(ctx,
srcX = 0, srcY = 0,
@ -518,14 +526,13 @@ let ContextUtils = {
* @param number dstHeight [optional]
* The desired resized pixel data height.
* @return object
* An objet containing the resized pixels width, height and data.
* An objet containing the resized pixels width, height and data,
* represented as an 8-bit array buffer of r, g, b, a values.
*/
resizePixels: function(srcPixels, srcWidth, srcHeight, dstHeight) {
let screenshotRatio = dstHeight / srcHeight;
let dstWidth = (srcWidth * screenshotRatio) | 0;
// Use a plain array instead of a Uint32Array to make serializing faster.
let dstPixels = new Array(dstWidth * dstHeight);
let dstPixels = new Uint32Array(dstWidth * dstHeight);
// If the resized image ends up being completely transparent, returning
// an empty array will skip some redundant serialization cycles.
@ -547,7 +554,7 @@ let ContextUtils = {
return {
width: dstWidth,
height: dstHeight,
pixels: isTransparent ? [] : dstPixels
pixels: isTransparent ? [] : new Uint8Array(dstPixels.buffer)
};
},