mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Merge m-c to inbound.
This commit is contained in:
commit
e8180505f0
@ -1,5 +1,5 @@
|
||||
<?xml version="1.0"?>
|
||||
<blocklist xmlns="http://www.mozilla.org/2006/addons-blocklist" lastupdate="1378508419000">
|
||||
<blocklist xmlns="http://www.mozilla.org/2006/addons-blocklist" lastupdate="1379114379000">
|
||||
<emItems>
|
||||
<emItem blockID="i350" id="sqlmoz@facebook.com">
|
||||
<versionRange minVersion="0" maxVersion="*" severity="3">
|
||||
@ -19,6 +19,10 @@
|
||||
<versionRange minVersion="0" maxVersion="*">
|
||||
</versionRange>
|
||||
</emItem>
|
||||
<emItem blockID="i404" id="{a9bb9fa0-4122-4c75-bd9a-bc27db3f9155}">
|
||||
<versionRange minVersion="0" maxVersion="*" severity="1">
|
||||
</versionRange>
|
||||
</emItem>
|
||||
<emItem blockID="i8" id="{B13721C7-F507-4982-B2E5-502A71474FED}">
|
||||
<versionRange minVersion=" " severity="1">
|
||||
</versionRange>
|
||||
@ -216,8 +220,8 @@
|
||||
<versionRange minVersion="0.1" maxVersion="14.4.0" severity="1">
|
||||
</versionRange>
|
||||
</emItem>
|
||||
<emItem blockID="i93" id="{68b8676b-99a5-46d1-b390-22411d8bcd61}">
|
||||
<versionRange minVersion="0" maxVersion="*">
|
||||
<emItem blockID="i449" id="gystqfr@ylgga.com">
|
||||
<versionRange minVersion="0" maxVersion="*" severity="1">
|
||||
</versionRange>
|
||||
</emItem>
|
||||
<emItem blockID="i142" id="{a3a5c777-f583-4fef-9380-ab4add1bc2a8}">
|
||||
@ -425,7 +429,7 @@
|
||||
<versionRange minVersion="0" maxVersion="*" severity="1">
|
||||
</versionRange>
|
||||
</emItem>
|
||||
<emItem blockID="i404" id="{a9bb9fa0-4122-4c75-bd9a-bc27db3f9155}">
|
||||
<emItem blockID="i448" id="{0134af61-7a0c-4649-aeca-90d776060cb3}">
|
||||
<versionRange minVersion="0" maxVersion="*" severity="1">
|
||||
</versionRange>
|
||||
</emItem>
|
||||
@ -602,6 +606,10 @@
|
||||
<versionRange minVersion="0" maxVersion="*">
|
||||
</versionRange>
|
||||
</emItem>
|
||||
<emItem blockID="i93" id="{68b8676b-99a5-46d1-b390-22411d8bcd61}">
|
||||
<versionRange minVersion="0" maxVersion="*">
|
||||
</versionRange>
|
||||
</emItem>
|
||||
<emItem blockID="i439" id="{d2cf9842-af95-48cd-b873-bfbb48cd7f5e}">
|
||||
<versionRange minVersion="0" maxVersion="*" severity="1">
|
||||
</versionRange>
|
||||
|
@ -1072,7 +1072,7 @@ pref("devtools.commands.dir", "");
|
||||
|
||||
// Disable the app manager
|
||||
pref("devtools.appmanager.enabled", true);
|
||||
pref("devtools.appmanager.simulatorInstallPage", "https://addons.mozilla.org/firefox/addon/firefox-os-simulator/");
|
||||
pref("devtools.appmanager.firstrun", true);
|
||||
|
||||
// Toolbox preferences
|
||||
pref("devtools.toolbox.footer.height", 250);
|
||||
|
@ -159,10 +159,11 @@ SocialUI = {
|
||||
}
|
||||
break;
|
||||
case "social:profile-changed":
|
||||
// make sure anything that happens here only affects the provider for
|
||||
// which the profile is changing, and that anything we call actually
|
||||
// needs to change based on profile data.
|
||||
if (this._matchesCurrentProvider(data)) {
|
||||
SocialToolbar.updateProvider();
|
||||
SocialMarks.update();
|
||||
SocialChatBar.update();
|
||||
}
|
||||
break;
|
||||
case "social:frameworker-error":
|
||||
@ -215,13 +216,20 @@ SocialUI = {
|
||||
// enabled == true means we at least have a defaultProvider
|
||||
let provider = Social.provider || Social.defaultProvider;
|
||||
// We only need to update the command itself - all our menu items use it.
|
||||
let label = gNavigatorBundle.getFormattedString(Social.provider ?
|
||||
"social.turnOff.label" :
|
||||
"social.turnOn.label",
|
||||
[provider.name]);
|
||||
let accesskey = gNavigatorBundle.getString(Social.provider ?
|
||||
"social.turnOff.accesskey" :
|
||||
"social.turnOn.accesskey");
|
||||
let label;
|
||||
if (Social.providers.length == 1) {
|
||||
label = gNavigatorBundle.getFormattedString(Social.provider
|
||||
? "social.turnOff.label"
|
||||
: "social.turnOn.label",
|
||||
[provider.name]);
|
||||
} else {
|
||||
label = gNavigatorBundle.getString(Social.provider
|
||||
? "social.turnOffAll.label"
|
||||
: "social.turnOnAll.label");
|
||||
}
|
||||
let accesskey = gNavigatorBundle.getString(Social.provider
|
||||
? "social.turnOff.accesskey"
|
||||
: "social.turnOn.accesskey");
|
||||
toggleCommand.setAttribute("label", label);
|
||||
toggleCommand.setAttribute("accesskey", accesskey);
|
||||
}
|
||||
@ -868,17 +876,19 @@ SocialToolbar = {
|
||||
toggleNotificationsCommand.setAttribute("hidden", !socialEnabled);
|
||||
|
||||
let parent = document.getElementById("social-notification-panel");
|
||||
while (parent.hasChildNodes()) {
|
||||
let frame = parent.firstChild;
|
||||
SharedFrame.forgetGroup(frame.id);
|
||||
parent.removeChild(frame);
|
||||
}
|
||||
|
||||
let tbi = document.getElementById("social-provider-button");
|
||||
if (tbi) {
|
||||
// buttons after social-provider-button are ambient icons
|
||||
// buttons after social-provider-button are ambient icons, remove the
|
||||
// button and the attached shared frame.
|
||||
while (tbi.nextSibling) {
|
||||
tbi.parentNode.removeChild(tbi.nextSibling);
|
||||
let tb = tbi.nextSibling;
|
||||
let nid = tb.getAttribute("notificationFrameId");
|
||||
let frame = document.getElementById(nid);
|
||||
if (frame) {
|
||||
SharedFrame.forgetGroup(frame.id);
|
||||
parent.removeChild(frame);
|
||||
}
|
||||
tbi.parentNode.removeChild(tb);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -1119,18 +1119,25 @@ var gBrowserInit = {
|
||||
// If the user manually opens the download manager before the timeout, the
|
||||
// downloads will start right away, and getting the service again won't hurt.
|
||||
setTimeout(function() {
|
||||
let DownloadsCommon =
|
||||
Cu.import("resource:///modules/DownloadsCommon.jsm", {}).DownloadsCommon;
|
||||
if (DownloadsCommon.useJSTransfer) {
|
||||
// Open the data link without initalizing nsIDownloadManager.
|
||||
DownloadsCommon.initializeAllDataLinks();
|
||||
} else {
|
||||
// Initalizing nsIDownloadManager will trigger the data link.
|
||||
Services.downloads;
|
||||
try {
|
||||
let DownloadsCommon =
|
||||
Cu.import("resource:///modules/DownloadsCommon.jsm", {}).DownloadsCommon;
|
||||
if (DownloadsCommon.useJSTransfer) {
|
||||
// Open the data link without initalizing nsIDownloadManager.
|
||||
DownloadsCommon.initializeAllDataLinks();
|
||||
let DownloadsTaskbar =
|
||||
Cu.import("resource:///modules/DownloadsTaskbar.jsm", {}).DownloadsTaskbar;
|
||||
DownloadsTaskbar.registerIndicator(window);
|
||||
} else {
|
||||
// Initalizing nsIDownloadManager will trigger the data link.
|
||||
Services.downloads;
|
||||
let DownloadTaskbarProgress =
|
||||
Cu.import("resource://gre/modules/DownloadTaskbarProgress.jsm", {}).DownloadTaskbarProgress;
|
||||
DownloadTaskbarProgress.onBrowserWindowLoad(window);
|
||||
}
|
||||
} catch (ex) {
|
||||
Cu.reportError(ex);
|
||||
}
|
||||
let DownloadTaskbarProgress =
|
||||
Cu.import("resource://gre/modules/DownloadTaskbarProgress.jsm", {}).DownloadTaskbarProgress;
|
||||
DownloadTaskbarProgress.onBrowserWindowLoad(window);
|
||||
}, 10000);
|
||||
|
||||
// The object handling the downloads indicator is also initialized here in the
|
||||
|
@ -7,6 +7,7 @@ function test() {
|
||||
|
||||
Services.prefs.setBoolPref("social.allowMultipleWorkers", true);
|
||||
runSocialTestWithProvider(gProviders, function (finishcb) {
|
||||
Social.enabled = true;
|
||||
runSocialTests(tests, undefined, undefined, function() {
|
||||
Services.prefs.clearUserPref("social.allowMultipleWorkers");
|
||||
finishcb();
|
||||
|
@ -2,18 +2,36 @@
|
||||
* 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/. */
|
||||
|
||||
let manifest = { // normal provider
|
||||
name: "provider 1",
|
||||
let manifests = [{ // normal provider
|
||||
name: "provider example.com",
|
||||
origin: "https://example.com",
|
||||
workerURL: "https://example.com/browser/browser/base/content/test/social/social_worker.js",
|
||||
iconURL: "https://example.com/browser/browser/base/content/test/moz.png"
|
||||
};
|
||||
}, { // used for testing install
|
||||
name: "provider test1",
|
||||
origin: "https://test1.example.com",
|
||||
statusURL: "https://test1.example.com/browser/browser/base/content/test/social/social_panel.html",
|
||||
iconURL: "https://test1.example.com/browser/browser/base/content/test/moz.png",
|
||||
}];
|
||||
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
|
||||
runSocialTestWithProvider(manifest, function (finishcb) {
|
||||
runSocialTests(tests, undefined, undefined, finishcb);
|
||||
// required to test status button in combination with the toolbaritem
|
||||
Services.prefs.setBoolPref("social.allowMultipleWorkers", true);
|
||||
|
||||
// Preset the currentSet so the statusbutton is in the toolbar on addition. We
|
||||
// bypass the SocialStatus class here since it requires the manifest already
|
||||
// be installed.
|
||||
let tbh = SocialStatus._toolbarHelper;
|
||||
tbh.setPersistentPosition(tbh.idFromOrgin(manifests[1].origin));
|
||||
|
||||
runSocialTestWithProvider(manifests, function (finishcb) {
|
||||
runSocialTests(tests, undefined, undefined, function() {
|
||||
Services.prefs.clearUserPref("social.allowMultipleWorkers");
|
||||
SocialStatus.removePosition(manifests[1].origin);
|
||||
finishcb();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@ -37,7 +55,7 @@ var tests = {
|
||||
},
|
||||
testProfileSet: function(next) {
|
||||
let statusIcon = document.getElementById("social-provider-button").style.listStyleImage;
|
||||
is(statusIcon, "url(\"" + manifest.iconURL + "\")", "manifest iconURL is showing");
|
||||
is(statusIcon, "url(\"" + manifests[0].iconURL + "\")", "manifest iconURL is showing");
|
||||
let profile = {
|
||||
portrait: "https://example.com/portrait.jpg",
|
||||
userName: "trickster",
|
||||
@ -167,14 +185,32 @@ var tests = {
|
||||
}, "statusIcon was never found");
|
||||
},
|
||||
testProfileUnset: function(next) {
|
||||
Social.provider.updateUserProfile({});
|
||||
// check dom values
|
||||
let ambientIcons = document.querySelectorAll("#social-toolbar-item > box");
|
||||
for (let ambientIcon of ambientIcons) {
|
||||
ok(ambientIcon.collapsed, "ambient icon (" + ambientIcon.id + ") is collapsed");
|
||||
}
|
||||
let panel = document.getElementById("social-notification-panel");
|
||||
// load the status button for provider 2
|
||||
let provider = Social._getProviderFromOrigin(manifests[1].origin);
|
||||
let id = SocialStatus._toolbarHelper.idFromOrgin(provider.origin);
|
||||
let btn = document.getElementById(id)
|
||||
ok(btn, "got a status button");
|
||||
// cheat a little, we want the iframe for the status button to be created,
|
||||
// not testing the statusbutton itself here.
|
||||
SocialStatus._attachNotificatonPanel(btn, provider);
|
||||
|
||||
let numIcons = Object.keys(Social.provider.ambientNotificationIcons).length;
|
||||
let ambientIcons = document.querySelectorAll("#social-toolbar-item > toolbarbutton[type='badged']");
|
||||
is(numIcons, ambientIcons.length, "all ambient icons exist");
|
||||
is(panel.childNodes.length, ambientIcons.length + 1, "frames all exist");
|
||||
|
||||
next();
|
||||
// we need to wait until after social:profile-changed has completed
|
||||
waitForNotification("social:profile-changed", function() {
|
||||
// let the notifications finish first
|
||||
executeSoon(function() {
|
||||
let icons = document.querySelectorAll("#social-toolbar-item > toolbarbutton[type='badged']");
|
||||
is(icons.length, 0, "ambient icons have been removed");
|
||||
is(panel.childNodes.length, 1, "frame still exists");
|
||||
next();
|
||||
});
|
||||
});
|
||||
Social.provider.updateUserProfile({});
|
||||
},
|
||||
testMenuitemsExist: function(next) {
|
||||
let toggleSidebarMenuitems = document.getElementsByClassName("social-toggle-sidebar-menuitem");
|
||||
@ -194,5 +230,5 @@ var tests = {
|
||||
is(cmd.getAttribute("checked"), enabled ? "true" : "false");
|
||||
Services.prefs.clearUserPref("social.toast-notifications.enabled");
|
||||
next();
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@ -298,6 +298,14 @@ function checkSocialUI(win) {
|
||||
is(numGoodTests, numTests, "The Social UI tests succeeded.")
|
||||
}
|
||||
|
||||
function waitForNotification(topic, cb) {
|
||||
function observer(subject, topic, data) {
|
||||
Services.obs.removeObserver(observer, topic);
|
||||
cb();
|
||||
}
|
||||
Services.obs.addObserver(observer, topic, false);
|
||||
}
|
||||
|
||||
// blocklist testing
|
||||
function updateBlocklist(aCallback) {
|
||||
var blocklistNotifier = Cc["@mozilla.org/extensions/blocklist;1"]
|
||||
|
180
browser/components/downloads/src/DownloadsTaskbar.jsm
Normal file
180
browser/components/downloads/src/DownloadsTaskbar.jsm
Normal file
@ -0,0 +1,180 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=2 et sw=2 tw=80 filetype=javascript: */
|
||||
/* 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/. */
|
||||
|
||||
/**
|
||||
* Handles the download progress indicator in the taskbar.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
this.EXPORTED_SYMBOLS = [
|
||||
"DownloadsTaskbar",
|
||||
];
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//// Globals
|
||||
|
||||
const Cc = Components.classes;
|
||||
const Ci = Components.interfaces;
|
||||
const Cu = Components.utils;
|
||||
const Cr = Components.results;
|
||||
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "Downloads",
|
||||
"resource://gre/modules/Downloads.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "RecentWindow",
|
||||
"resource:///modules/RecentWindow.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "Services",
|
||||
"resource://gre/modules/Services.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyGetter(this, "gWinTaskbar", function () {
|
||||
if (!("@mozilla.org/windows-taskbar;1" in Cc)) {
|
||||
return null;
|
||||
}
|
||||
let winTaskbar = Cc["@mozilla.org/windows-taskbar;1"]
|
||||
.getService(Ci.nsIWinTaskbar);
|
||||
return winTaskbar.available && winTaskbar;
|
||||
});
|
||||
|
||||
XPCOMUtils.defineLazyGetter(this, "gMacTaskbarProgress", function () {
|
||||
return ("@mozilla.org/widget/macdocksupport;1" in Cc) &&
|
||||
Cc["@mozilla.org/widget/macdocksupport;1"]
|
||||
.getService(Ci.nsITaskbarProgress);
|
||||
});
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//// DownloadsTaskbar
|
||||
|
||||
/**
|
||||
* Handles the download progress indicator in the taskbar.
|
||||
*/
|
||||
this.DownloadsTaskbar = {
|
||||
/**
|
||||
* Underlying DownloadSummary providing the aggregate download information, or
|
||||
* null if the indicator has never been initialized.
|
||||
*/
|
||||
_summary: null,
|
||||
|
||||
/**
|
||||
* nsITaskbarProgress object to which download information is dispatched.
|
||||
* This can be null if the indicator has never been initialized or if the
|
||||
* indicator is currently hidden on Windows.
|
||||
*/
|
||||
_taskbarProgress: null,
|
||||
|
||||
/**
|
||||
* This method is called after a new browser window is opened, and ensures
|
||||
* that the download progress indicator is displayed in the taskbar.
|
||||
*
|
||||
* On Windows, the indicator is attached to the first browser window that
|
||||
* calls this method. When the window is closed, the indicator is moved to
|
||||
* another browser window, if available, in no particular order. When there
|
||||
* are no browser windows visible, the indicator is hidden.
|
||||
*
|
||||
* On Mac OS X, the indicator is initialized globally when this method is
|
||||
* called for the first time. Subsequent calls have no effect.
|
||||
*
|
||||
* @param aBrowserWindow
|
||||
* nsIDOMWindow object of the newly opened browser window to which the
|
||||
* indicator may be attached.
|
||||
*/
|
||||
registerIndicator: function (aBrowserWindow)
|
||||
{
|
||||
if (!this._taskbarProgress) {
|
||||
if (gMacTaskbarProgress) {
|
||||
// On Mac OS X, we have to register the global indicator only once.
|
||||
this._taskbarProgress = gMacTaskbarProgress;
|
||||
// Free the XPCOM reference on shutdown, to prevent detecting a leak.
|
||||
Services.obs.addObserver(() => {
|
||||
this._taskbarProgress = null;
|
||||
gMacTaskbarProgress = null;
|
||||
}, "quit-application-granted", false);
|
||||
} else if (gWinTaskbar) {
|
||||
// On Windows, the indicator is currently hidden because we have no
|
||||
// previous browser window, thus we should attach the indicator now.
|
||||
this._attachIndicator(aBrowserWindow);
|
||||
} else {
|
||||
// The taskbar indicator is not available on this platform.
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure that the DownloadSummary object will be created asynchronously.
|
||||
if (!this._summary) {
|
||||
Downloads.getSummary(Downloads.ALL).then(summary => {
|
||||
// In case the method is re-entered, we simply ignore redundant
|
||||
// invocations of the callback, instead of keeping separate state.
|
||||
if (this._summary) {
|
||||
return;
|
||||
}
|
||||
this._summary = summary;
|
||||
this._summary.addView(this);
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* On Windows, attaches the taskbar indicator to the specified browser window.
|
||||
*/
|
||||
_attachIndicator: function (aWindow)
|
||||
{
|
||||
// Activate the indicator on the specified window.
|
||||
let docShell = aWindow.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIWebNavigation)
|
||||
.QueryInterface(Ci.nsIDocShellTreeItem).treeOwner
|
||||
.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIXULWindow).docShell;
|
||||
this._taskbarProgress = gWinTaskbar.getTaskbarProgress(docShell);
|
||||
|
||||
// If the DownloadSummary object has already been created, we should update
|
||||
// the state of the new indicator, otherwise it will be updated as soon as
|
||||
// the DownloadSummary view is registered.
|
||||
if (this._summary) {
|
||||
this.onSummaryChanged();
|
||||
}
|
||||
|
||||
aWindow.addEventListener("unload", () => {
|
||||
// Locate another browser window, excluding the one being closed.
|
||||
let browserWindow = RecentWindow.getMostRecentBrowserWindow();
|
||||
if (browserWindow) {
|
||||
// Move the progress indicator to the other browser window.
|
||||
this._attachIndicator(browserWindow);
|
||||
} else {
|
||||
// The last browser window has been closed. We remove the reference to
|
||||
// the taskbar progress object so that the indicator will be registered
|
||||
// again on the next browser window that is opened.
|
||||
this._taskbarProgress = null;
|
||||
}
|
||||
}, false);
|
||||
},
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//// DownloadSummary view
|
||||
|
||||
onSummaryChanged: function ()
|
||||
{
|
||||
// If the last browser window has been closed, we have no indicator anymore.
|
||||
if (!this._taskbarProgress) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this._summary.allHaveStopped || this._summary.progressTotalBytes == 0) {
|
||||
this._taskbarProgress.setProgressState(
|
||||
Ci.nsITaskbarProgress.STATE_NO_PROGRESS, 0, 0);
|
||||
} else {
|
||||
// For a brief moment before completion, some download components may
|
||||
// report more transferred bytes than the total number of bytes. Thus,
|
||||
// ensure that we never break the expectations of the progress indicator.
|
||||
let progressCurrentBytes = Math.min(this._summary.progressTotalBytes,
|
||||
this._summary.progressCurrentBytes);
|
||||
this._taskbarProgress.setProgressState(
|
||||
Ci.nsITaskbarProgress.STATE_NORMAL,
|
||||
progressCurrentBytes,
|
||||
this._summary.progressTotalBytes);
|
||||
}
|
||||
},
|
||||
};
|
@ -13,5 +13,6 @@ EXTRA_COMPONENTS += [
|
||||
EXTRA_JS_MODULES += [
|
||||
'DownloadsCommon.jsm',
|
||||
'DownloadsLogger.jsm',
|
||||
'DownloadsTaskbar.jsm',
|
||||
]
|
||||
|
||||
|
24
browser/devtools/app-manager/builtin-adb-store.js
Normal file
24
browser/devtools/app-manager/builtin-adb-store.js
Normal file
@ -0,0 +1,24 @@
|
||||
/* 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/. */
|
||||
|
||||
const {Cu} = require("chrome");
|
||||
const ObservableObject = require("devtools/shared/observable-object");
|
||||
const {Devices} = Cu.import("resource://gre/modules/devtools/Devices.jsm");
|
||||
|
||||
let store = new ObservableObject({versions:[]});
|
||||
|
||||
function feedStore() {
|
||||
store.object.available = Devices.helperAddonInstalled;
|
||||
store.object.devices = Devices.available().map(n => {
|
||||
return {name:n}
|
||||
});
|
||||
}
|
||||
|
||||
Devices.on("register", feedStore);
|
||||
Devices.on("unregister", feedStore);
|
||||
Devices.on("addon-status-updated", feedStore);
|
||||
|
||||
feedStore();
|
||||
|
||||
module.exports = store;
|
@ -8,6 +8,7 @@ Cu.import("resource://gre/modules/Services.jsm");
|
||||
Cu.import("resource:///modules/devtools/gDevTools.jsm");
|
||||
|
||||
const {Simulator} = Cu.import("resource://gre/modules/devtools/Simulator.jsm")
|
||||
const {Devices} = Cu.import("resource://gre/modules/devtools/Devices.jsm");
|
||||
const {devtools} = Cu.import("resource://gre/modules/devtools/Loader.jsm", {});
|
||||
const {require} = devtools;
|
||||
|
||||
@ -15,6 +16,7 @@ const {ConnectionManager, Connection} = require("devtools/client/connection-mana
|
||||
const ConnectionStore = require("devtools/app-manager/connection-store");
|
||||
const DeviceStore = require("devtools/app-manager/device-store");
|
||||
const simulatorsStore = require("devtools/app-manager/simulators-store");
|
||||
const adbStore = require("devtools/app-manager/builtin-adb-store");
|
||||
|
||||
let UI = {
|
||||
init: function() {
|
||||
@ -46,6 +48,7 @@ let UI = {
|
||||
"device": new DeviceStore(this.connection),
|
||||
"connection": new ConnectionStore(this.connection),
|
||||
"simulators": simulatorsStore,
|
||||
"adb": adbStore
|
||||
});
|
||||
|
||||
let pre = document.querySelector("#logs > pre");
|
||||
@ -109,7 +112,7 @@ let UI = {
|
||||
},
|
||||
|
||||
installSimulator: function() {
|
||||
let url = Services.prefs.getCharPref("devtools.appmanager.simulatorInstallPage");
|
||||
let url = "https://developer.mozilla.org/docs/Mozilla/Firefox_OS/Using_the_App_Manager#Simulator";
|
||||
window.open(url);
|
||||
},
|
||||
|
||||
@ -142,4 +145,13 @@ let UI = {
|
||||
});
|
||||
document.body.classList.remove("show-simulators");
|
||||
},
|
||||
|
||||
connectToAdbDevice: function(name) {
|
||||
let device = Devices.getByName(name);
|
||||
device.connect().then((port) => {
|
||||
this.connection.host = "localhost";
|
||||
this.connection.port = port;
|
||||
this.connect();
|
||||
});
|
||||
},
|
||||
}
|
||||
|
@ -34,10 +34,23 @@
|
||||
<div id="banner-disconnected" class="banner">
|
||||
<div class="connected-indicator"></div>
|
||||
<div class="banner-box">
|
||||
<div class="banner-content">
|
||||
<span>&connection.notConnected;</span>
|
||||
<button class="action-primary left" onclick="UI.connect()" id="connect-button" template='{"type":"localizedContent","property":"connection.connectTo","paths":["connection.host","connection.port"]}' title="&connection.connectTooltip;"></button>
|
||||
<button class="right" onclick="UI.editConnectionParameters()" title="&connection.changeHostAndPortTooltip;">&connection.changeHostAndPort;</button>
|
||||
<div class="banner-content" template='{"type":"attribute","path":"adb.available","name":"adb-available"}'>
|
||||
<span>&connection.notConnected2;</span>
|
||||
<div id="connection-manual">
|
||||
<button class="action-primary left" onclick="UI.connect()" id="connect-button" template='{"type":"localizedContent","property":"connection.connectTo","paths":["connection.host","connection.port"]}'></button>
|
||||
<button class="right" onclick="UI.editConnectionParameters()">&connection.changeHostAndPort;</button>
|
||||
<button class="action-primary left" onclick="UI.connect()" id="connect-button" template='{"type":"localizedContent","property":"connection.connectTo","paths":["connection.host","connection.port"]}' title="&connection.connectTooltip;"></button>
|
||||
<button class="right" onclick="UI.editConnectionParameters()" title="&connection.changeHostAndPortTooltip;">&connection.changeHostAndPort;</button>
|
||||
</div>
|
||||
<div id="connection-assisted" template='{"type":"attribute","path":"adb.devices.length","name":"device-count"}'>
|
||||
<div id="connection-found-device">
|
||||
<span>&connection.connectTo;</span>
|
||||
<span template-loop='{"arrayPath":"adb.devices","childSelector":"#adb-devices-template"}'></span>
|
||||
</div>
|
||||
<div id="connection-no-device">
|
||||
<span>&connection.noDeviceFound;</span>
|
||||
</div>
|
||||
</div>
|
||||
<div id="start-simulator-box">
|
||||
<span>&connection.or;</span>
|
||||
<button id="start-simulator-button" class="action-primary" onclick="UI.showSimulatorList()" title="&connection.startSimulatorTooltip;">&connection.startSimulator;</button>
|
||||
@ -119,6 +132,14 @@
|
||||
</span>
|
||||
</template>
|
||||
|
||||
<template id="adb-devices-template">
|
||||
<span>
|
||||
<button class="adb-device action-primary" onclick="UI.connectToAdbDevice(this.dataset.name)" template='{"type":"attribute","path":"name","name":"data-name"}'>
|
||||
<span template='{"type":"textContent", "path":"name"}'></span>
|
||||
</button>
|
||||
</span>
|
||||
</template>
|
||||
|
||||
<script type="application/javascript;version=1.8" src="utils.js"></script>
|
||||
<script type="application/javascript;version=1.8" src="template.js"></script>
|
||||
<script type="application/javascript;version=1.8" src="connection-footer.js"></script>
|
||||
|
73
browser/devtools/app-manager/content/help.xhtml
Normal file
73
browser/devtools/app-manager/content/help.xhtml
Normal file
@ -0,0 +1,73 @@
|
||||
<?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/. -->
|
||||
<!DOCTYPE html [
|
||||
<!ENTITY % appMgrDTD SYSTEM "chrome://browser/locale/devtools/app-manager.dtd" >
|
||||
%appMgrDTD;
|
||||
]>
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
|
||||
<head>
|
||||
<meta charset="utf8"/>
|
||||
<base href="chrome://browser/content/devtools/app-manager/"></base>
|
||||
<title>&help.title;</title>
|
||||
<link rel="stylesheet" href="chrome://browser/skin/devtools/app-manager/help.css" type="text/css"/>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<h1>&help.title;</h1>
|
||||
|
||||
<p>&help.intro;</p>
|
||||
|
||||
<p>&help.usefullLinks;</p>
|
||||
<ul>
|
||||
<li id="linkToAppMgrDoc">&help.linkToAppMgrDoc;</li>
|
||||
<li id="linkToConfiguringDevice">&help.linkToConfiguringDevice;</li>
|
||||
<li id="linkToTroubleShooting">&help.linkToTroubleShooting;</li>
|
||||
<li id="linkToSimulatorAddon">&help.linkToSimulatorAddon;</li>
|
||||
<li id="linkToAdbHelperAddon">&help.linkToAdbHelperAddon;</li>
|
||||
</ul>
|
||||
|
||||
<button id="close-button" onclick="closeHelp()">&help.close;</button>
|
||||
|
||||
</body>
|
||||
|
||||
<script type="application/javascript;version=1.8">
|
||||
function closeHelp() {
|
||||
window.parent.postMessage(JSON.stringify({name:"closeHelp"}), "*");
|
||||
}
|
||||
|
||||
let a;
|
||||
|
||||
let link_usingAppMgr = "https://developer.mozilla.org/docs/Mozilla/Firefox_OS/Using_the_App_Manager";
|
||||
let link_configuringDevice = "https://developer.mozilla.org/docs/Mozilla/Firefox_OS/Using_the_App_Manager#Configuring_device";
|
||||
let link_troubleShooting = "https://developer.mozilla.org/docs/Mozilla/Firefox_OS/Using_the_App_Manager#Troubleshooting";
|
||||
let link_installSimulator = "https://developer.mozilla.org/docs/Mozilla/Firefox_OS/Using_the_App_Manager#Simulator";
|
||||
let link_installAdbHelper = "https://developer.mozilla.org/docs/Mozilla/Firefox_OS/Using_the_App_Manager#Adb_Helper_Add-on";
|
||||
|
||||
a = document.querySelector("#linkToAppMgrDoc > a");
|
||||
a.target = "mdn";
|
||||
a.href = link_usingAppMgr;
|
||||
|
||||
a = document.querySelector("#linkToConfiguringDevice > a");
|
||||
a.target = "mdn";
|
||||
a.href = link_configuringDevice;
|
||||
|
||||
a = document.querySelector("#linkToTroubleShooting > a");
|
||||
a.target = "mdn";
|
||||
a.href = link_troubleShooting;
|
||||
|
||||
a = document.querySelector("#linkToSimulatorAddon> a");
|
||||
a.target = "mdn";
|
||||
a.href = link_installSimulator;
|
||||
|
||||
a = document.querySelector("#linkToAdbHelperAddon > a");
|
||||
a.target = "mdn";
|
||||
a.href = link_installAdbHelper;
|
||||
|
||||
</script>
|
||||
</html>
|
||||
|
@ -7,21 +7,29 @@ Cu.import("resource:///modules/devtools/gDevTools.jsm");
|
||||
const {devtools} = Cu.import("resource://gre/modules/devtools/Loader.jsm", {});
|
||||
const {require} = devtools;
|
||||
const {ConnectionManager, Connection} = require("devtools/client/connection-manager");
|
||||
const prefs = require('sdk/preferences/service');
|
||||
|
||||
let connection;
|
||||
|
||||
window.addEventListener("message", function(event) {
|
||||
try {
|
||||
let json = JSON.parse(event.data);
|
||||
if (json.name == "connection") {
|
||||
let cid = +json.cid;
|
||||
for (let c of ConnectionManager.connections) {
|
||||
if (c.uid == cid) {
|
||||
connection = c;
|
||||
onNewConnection();
|
||||
break;
|
||||
switch (json.name) {
|
||||
case "connection":
|
||||
let cid = +json.cid;
|
||||
for (let c of ConnectionManager.connections) {
|
||||
if (c.uid == cid) {
|
||||
connection = c;
|
||||
onNewConnection();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "closeHelp":
|
||||
selectTab("projects");
|
||||
break;
|
||||
default:
|
||||
Cu.reportError("Unknown message: " + json.name);
|
||||
}
|
||||
} catch(e) { Cu.reportError(e); }
|
||||
|
||||
@ -45,10 +53,18 @@ function selectTab(id) {
|
||||
for (let type of ["button", "panel"]) {
|
||||
let oldSelection = document.querySelector("." + type + "[selected]");
|
||||
let newSelection = document.querySelector("." + id + "-" + type);
|
||||
if (!newSelection) continue;
|
||||
if (oldSelection) oldSelection.removeAttribute("selected");
|
||||
newSelection.setAttribute("selected", "true");
|
||||
if (newSelection) newSelection.setAttribute("selected", "true");
|
||||
}
|
||||
if (id != "help") {
|
||||
// Might be the first time the user is accessing the actual app manager
|
||||
prefs.set("devtools.appmanager.firstrun", false);
|
||||
}
|
||||
}
|
||||
selectTab("projects");
|
||||
|
||||
let firstRun = prefs.get("devtools.appmanager.firstrun");
|
||||
if (firstRun) {
|
||||
selectTab("help");
|
||||
} else {
|
||||
selectTab("projects");
|
||||
}
|
||||
|
@ -20,15 +20,18 @@
|
||||
width="800" height="600"
|
||||
persist="screenX screenY width height sizemode">
|
||||
|
||||
<vbox flex="1">
|
||||
<vbox id="root" flex="1">
|
||||
<hbox id="content" flex="1">
|
||||
<vbox id="tabs">
|
||||
<button class="button projects-button" onclick="selectTab('projects')">&index.projects2;</button>
|
||||
<button class="button device-button" onclick="selectTab('device')">&index.device2;</button>
|
||||
<spacer flex="1"/>
|
||||
<button class="button help-button" onclick="selectTab('help')">&index.help;</button>
|
||||
</vbox>
|
||||
<hbox id="tab-panels" flex="1">
|
||||
<iframe flex="1" class="panel projects-panel" src="chrome://browser/content/devtools/app-manager/projects.xhtml"/>
|
||||
<iframe flex="1" class="panel device-panel" src="chrome://browser/content/devtools/app-manager/device.xhtml"/>
|
||||
<iframe flex="1" class="panel help-panel" src="chrome://browser/content/devtools/app-manager/help.xhtml"></iframe>
|
||||
</hbox>
|
||||
</hbox>
|
||||
<iframe id="connection-footer" src="chrome://browser/content/devtools/app-manager/connection-footer.xhtml"></iframe>
|
||||
|
@ -116,41 +116,59 @@ let UI = {
|
||||
|
||||
validate: function(project) {
|
||||
let validation = new AppValidator(project);
|
||||
validation.validate()
|
||||
.then(function () {
|
||||
if (validation.manifest) {
|
||||
project.name = validation.manifest.name;
|
||||
project.icon = UI._getLocalIconURL(project, validation.manifest);
|
||||
project.manifest = validation.manifest;
|
||||
}
|
||||
return validation.validate()
|
||||
.then(function () {
|
||||
if (validation.manifest) {
|
||||
project.name = validation.manifest.name;
|
||||
project.icon = UI._getLocalIconURL(project, validation.manifest);
|
||||
project.manifest = validation.manifest;
|
||||
}
|
||||
|
||||
project.validationStatus = "valid";
|
||||
project.validationStatus = "valid";
|
||||
|
||||
if (validation.warnings.length > 0) {
|
||||
project.warningsCount = validation.warnings.length;
|
||||
project.warnings = validation.warnings.join(",\n ");
|
||||
project.validationStatus = "warning";
|
||||
} else {
|
||||
project.warnings = "";
|
||||
project.warningsCount = 0;
|
||||
}
|
||||
if (validation.warnings.length > 0) {
|
||||
project.warningsCount = validation.warnings.length;
|
||||
project.warnings = validation.warnings.join(",\n ");
|
||||
project.validationStatus = "warning";
|
||||
} else {
|
||||
project.warnings = "";
|
||||
project.warningsCount = 0;
|
||||
}
|
||||
|
||||
if (validation.errors.length > 0) {
|
||||
project.errorsCount = validation.errors.length;
|
||||
project.errors = validation.errors.join(",\n ");
|
||||
project.validationStatus = "error";
|
||||
} else {
|
||||
project.errors = "";
|
||||
project.errorsCount = 0;
|
||||
}
|
||||
if (validation.errors.length > 0) {
|
||||
project.errorsCount = validation.errors.length;
|
||||
project.errors = validation.errors.join(",\n ");
|
||||
project.validationStatus = "error";
|
||||
} else {
|
||||
project.errors = "";
|
||||
project.errorsCount = 0;
|
||||
}
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
update: function(location) {
|
||||
update: function(button, location) {
|
||||
button.disabled = true;
|
||||
let project = AppProjects.get(location);
|
||||
this.validate(project);
|
||||
this.validate(project)
|
||||
.then(() => {
|
||||
// Install the app to the device if we are connected,
|
||||
// and there is no error
|
||||
if (project.errorsCount == 0 && this.listTabsResponse) {
|
||||
return this.install(project);
|
||||
}
|
||||
})
|
||||
.then(
|
||||
() => {
|
||||
button.disabled = false;
|
||||
},
|
||||
(res) => {
|
||||
button.disabled = false;
|
||||
let message = res.error + ": " + res.message;
|
||||
alert(message);
|
||||
this.connection.log(message);
|
||||
});
|
||||
},
|
||||
|
||||
remove: function(location) {
|
||||
@ -165,11 +183,7 @@ let UI = {
|
||||
}
|
||||
},
|
||||
|
||||
install: function(button, location) {
|
||||
button.dataset.originalTextContent = button.textContent;
|
||||
button.textContent = Utils.l10n("project.installing");
|
||||
button.disabled = true;
|
||||
let project = AppProjects.get(location);
|
||||
install: function(project) {
|
||||
let install;
|
||||
if (project.type == "packaged") {
|
||||
install = installPackaged(this.connection.client, this.listTabsResponse.webappsActor, project.location, project.packagedAppOrigin);
|
||||
@ -183,43 +197,37 @@ let UI = {
|
||||
};
|
||||
install = installHosted(this.connection.client, this.listTabsResponse.webappsActor, appId, metadata, project.manifest);
|
||||
}
|
||||
install.then(function () {
|
||||
button.disabled = false;
|
||||
button.textContent = Utils.l10n("project.installed");
|
||||
setTimeout(function() {
|
||||
button.textContent = button.dataset.originalTextContent;
|
||||
}, 1500);
|
||||
},
|
||||
function (res) {
|
||||
button.disabled = false;
|
||||
let message = res.error + ": " + res.message;
|
||||
alert(message);
|
||||
this.connection.log(message);
|
||||
});
|
||||
return install;
|
||||
},
|
||||
|
||||
start: function(location) {
|
||||
let project = AppProjects.get(location);
|
||||
start: function(project) {
|
||||
let deferred = promise.defer();
|
||||
let request = {
|
||||
to: this.listTabsResponse.webappsActor,
|
||||
type: "launch",
|
||||
manifestURL: this._getProjectManifestURL(project)
|
||||
};
|
||||
this.connection.client.request(request, (res) => {
|
||||
|
||||
if (res.error)
|
||||
deferred.reject(res.error);
|
||||
else
|
||||
deferred.resolve(res);
|
||||
});
|
||||
return deferred.promise;
|
||||
},
|
||||
|
||||
stop: function(location) {
|
||||
let project = AppProjects.get(location);
|
||||
let deferred = promise.defer();
|
||||
let request = {
|
||||
to: this.listTabsResponse.webappsActor,
|
||||
type: "close",
|
||||
manifestURL: this._getProjectManifestURL(project)
|
||||
};
|
||||
this.connection.client.request(request, (res) => {
|
||||
|
||||
promive.resolve(res);
|
||||
});
|
||||
return deferred.promise;
|
||||
},
|
||||
|
||||
_getTargetForApp: function(manifest) { // FIXME <- will be implemented in bug 912476
|
||||
@ -252,8 +260,39 @@ let UI = {
|
||||
return deferred.promise;
|
||||
},
|
||||
|
||||
openToolbox: function(location) {
|
||||
debug: function(button, location) {
|
||||
button.disabled = true;
|
||||
let project = AppProjects.get(location);
|
||||
// First try to open the app
|
||||
this.start(project)
|
||||
.then(
|
||||
null,
|
||||
(error) => {
|
||||
// If not installed, install and open it
|
||||
if (error == "NO_SUCH_APP") {
|
||||
return this.install(project)
|
||||
.then(() => this.start(project));
|
||||
} else {
|
||||
throw error;
|
||||
}
|
||||
})
|
||||
.then(() => {
|
||||
// Finally, when it's finally opened, display the toolbox
|
||||
return this.openToolbox(project)
|
||||
})
|
||||
.then(() => {
|
||||
// And only when the toolbox is opened, release the button
|
||||
button.disabled = false;
|
||||
},
|
||||
(msg) => {
|
||||
button.disabled = false;
|
||||
alert(msg);
|
||||
this.connection.log(msg);
|
||||
});
|
||||
},
|
||||
|
||||
openToolbox: function(project) {
|
||||
let deferred = promise.defer();
|
||||
let manifest = this._getProjectManifestURL(project);
|
||||
this._getTargetForApp(manifest).then((target) => {
|
||||
gDevTools.showToolbox(target,
|
||||
@ -262,11 +301,12 @@ let UI = {
|
||||
this.connection.once(Connection.Events.DISCONNECTED, () => {
|
||||
toolbox.destroy();
|
||||
});
|
||||
deferred.resolve();
|
||||
});
|
||||
}, console.error);
|
||||
}, deferred.reject);
|
||||
return deferred.promise;
|
||||
},
|
||||
|
||||
|
||||
reveal: function(location) {
|
||||
let project = AppProjects.get(location);
|
||||
if (project.type == "packaged") {
|
||||
|
@ -70,11 +70,8 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="project-buttons">
|
||||
<button class="project-button-refresh" onclick="UI.update(this.dataset.location)" template='{"type":"attribute","path":"location","name":"data-location"}'>&projects.reloadFiles;</button>
|
||||
<button class="device-action project-button-install" onclick="UI.install(this, this.dataset.location)" template='{"type":"attribute","path":"location","name":"data-location"}'>&projects.installApp;</button>
|
||||
<button class="device-action project-button-start" onclick="UI.start(this.dataset.location)" template='{"type":"attribute","path":"location","name":"data-location"}'>&projects.startApp;</button>
|
||||
<button class="device-action project-button-stop" onclick="UI.stop(this.dataset.location)" template='{"type":"attribute","path":"location","name":"data-location"}'>&projects.stopApp;</button>
|
||||
<button class="device-action project-button-debug" onclick="UI.openToolbox(this.dataset.location)" template='{"type":"attribute","path":"location","name":"data-location"}'>&projects.debugApp;</button>
|
||||
<button class="project-button-update" onclick="UI.update(this, this.dataset.location)" template='{"type":"attribute","path":"location","name":"data-location"}' title="&projects.updateAppTooltip;">&projects.updateApp;</button>
|
||||
<button class="device-action project-button-debug" onclick="UI.debug(this, this.dataset.location)" template='{"type":"attribute","path":"location","name":"data-location"}' title="&projects.debugAppTooltip;">&projects.debugApp;</button>
|
||||
</div>
|
||||
<div class="project-errors" template='{"type":"textContent","path":"errors"}'></div>
|
||||
<div class="project-warnings" template='{"type":"textContent","path":"warnings"}'></div>
|
||||
|
@ -1270,6 +1270,7 @@ Breakpoints.prototype = {
|
||||
*/
|
||||
_added: new Map(),
|
||||
_removing: new Map(),
|
||||
_disabled: new Map(),
|
||||
|
||||
/**
|
||||
* Adds the source editor breakpoint handlers.
|
||||
@ -1362,7 +1363,7 @@ Breakpoints.prototype = {
|
||||
* are received via the _onNewSource and _onSourcesAdded event listeners.
|
||||
*/
|
||||
updateEditorBreakpoints: function() {
|
||||
for (let [, breakpointPromise] of this._added) {
|
||||
for (let breakpointPromise of this._addedOrDisabled) {
|
||||
breakpointPromise.then(aBreakpointClient => {
|
||||
let currentSourceUrl = DebuggerView.Sources.selectedValue;
|
||||
let breakpointUrl = aBreakpointClient.location.url;
|
||||
@ -1382,7 +1383,7 @@ Breakpoints.prototype = {
|
||||
* _onSourcesAdded event listeners.
|
||||
*/
|
||||
updatePaneBreakpoints: function() {
|
||||
for (let [, breakpointPromise] of this._added) {
|
||||
for (let breakpointPromise of this._addedOrDisabled) {
|
||||
breakpointPromise.then(aBreakpointClient => {
|
||||
let container = DebuggerView.Sources;
|
||||
let breakpointUrl = aBreakpointClient.location.url;
|
||||
@ -1435,7 +1436,7 @@ Breakpoints.prototype = {
|
||||
let deferred = promise.defer();
|
||||
|
||||
// Remember the breakpoint initialization promise in the store.
|
||||
let identifier = this._getIdentifier(aLocation);
|
||||
let identifier = this.getIdentifier(aLocation);
|
||||
this._added.set(identifier, deferred.promise);
|
||||
|
||||
// Try adding the breakpoint.
|
||||
@ -1445,7 +1446,7 @@ Breakpoints.prototype = {
|
||||
if (aResponse.actualLocation) {
|
||||
// Remember the initialization promise for the new location instead.
|
||||
let oldIdentifier = identifier;
|
||||
let newIdentifier = this._getIdentifier(aResponse.actualLocation);
|
||||
let newIdentifier = identifier = this.getIdentifier(aResponse.actualLocation);
|
||||
this._added.delete(oldIdentifier);
|
||||
this._added.set(newIdentifier, deferred.promise);
|
||||
|
||||
@ -1455,6 +1456,11 @@ Breakpoints.prototype = {
|
||||
aBreakpointClient.location = aResponse.actualLocation;
|
||||
}
|
||||
|
||||
// By default, new breakpoints are always enabled. Disabled breakpoints
|
||||
// are, in fact, removed from the server but preserved in the frontend,
|
||||
// so that they may not be forgotten across target navigations.
|
||||
this._disabled.delete(identifier);
|
||||
|
||||
// Preserve information about the breakpoint's line text, to display it
|
||||
// in the sources pane without requiring fetching the source (for example,
|
||||
// after the target navigated). Note that this will get out of sync
|
||||
@ -1507,7 +1513,7 @@ Breakpoints.prototype = {
|
||||
let deferred = promise.defer();
|
||||
|
||||
// Remember the breakpoint removal promise in the store.
|
||||
let identifier = this._getIdentifier(aLocation);
|
||||
let identifier = this.getIdentifier(aLocation);
|
||||
this._removing.set(identifier, deferred.promise);
|
||||
|
||||
// Retrieve the corresponding breakpoint client first.
|
||||
@ -1521,6 +1527,15 @@ Breakpoints.prototype = {
|
||||
return void this._removing.delete(identifier);
|
||||
}
|
||||
|
||||
// When a breakpoint is removed, the frontend may wish to preserve some
|
||||
// details about it, so that it can be easily re-added later. In such
|
||||
// cases, breakpoints are marked and stored as disabled, so that they
|
||||
// may not be forgotten across target navigations.
|
||||
if (aOptions.rememberDisabled) {
|
||||
aBreakpointClient.disabled = true;
|
||||
this._disabled.set(identifier, promise.resolve(aBreakpointClient));
|
||||
}
|
||||
|
||||
// Forget both the initialization and removal promises from the store.
|
||||
this._added.delete(identifier);
|
||||
this._removing.delete(identifier);
|
||||
@ -1538,7 +1553,7 @@ Breakpoints.prototype = {
|
||||
},
|
||||
|
||||
/**
|
||||
* Removes all breakpoints.
|
||||
* Removes all the currently enabled breakpoints.
|
||||
*
|
||||
* @return object
|
||||
* A promise that is resolved after all breakpoints are removed, or
|
||||
@ -1576,8 +1591,8 @@ Breakpoints.prototype = {
|
||||
* Information about the breakpoint to be shown.
|
||||
* This object must have the following properties:
|
||||
* - location: the breakpoint's source location and line number
|
||||
* - disabled: the breakpoint's disabled state, boolean
|
||||
* - text: the breakpoint's line text to be displayed
|
||||
* - actor: the breakpoint's corresponding actor id
|
||||
* @param object aOptions [optional]
|
||||
* @see DebuggerController.Breakpoints.addBreakpoint
|
||||
*/
|
||||
@ -1586,7 +1601,7 @@ Breakpoints.prototype = {
|
||||
let location = aBreakpointData.location;
|
||||
|
||||
// Update the editor if required.
|
||||
if (!aOptions.noEditorUpdate) {
|
||||
if (!aOptions.noEditorUpdate && !aBreakpointData.disabled) {
|
||||
if (location.url == currentSourceUrl) {
|
||||
DebuggerView.editor.addBreakpoint(location.line - 1);
|
||||
}
|
||||
@ -1622,6 +1637,16 @@ Breakpoints.prototype = {
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets all Promises for the BreakpointActor client objects that are
|
||||
* either enabled (added to the server) or disabled (removed from the server,
|
||||
* but for which some details are preserved).
|
||||
*/
|
||||
get _addedOrDisabled() {
|
||||
for (let [, value] of this._added) yield value;
|
||||
for (let [, value] of this._disabled) yield value;
|
||||
},
|
||||
|
||||
/**
|
||||
* Get a Promise for the BreakpointActor client object which is already added
|
||||
* or currently being added at the given location.
|
||||
@ -1633,7 +1658,7 @@ Breakpoints.prototype = {
|
||||
* null if no breakpoint was found.
|
||||
*/
|
||||
_getAdded: function(aLocation) {
|
||||
return this._added.get(this._getIdentifier(aLocation));
|
||||
return this._added.get(this.getIdentifier(aLocation));
|
||||
},
|
||||
|
||||
/**
|
||||
@ -1647,7 +1672,7 @@ Breakpoints.prototype = {
|
||||
* null if no breakpoint was found.
|
||||
*/
|
||||
_getRemoving: function(aLocation) {
|
||||
return this._removing.get(this._getIdentifier(aLocation));
|
||||
return this._removing.get(this.getIdentifier(aLocation));
|
||||
},
|
||||
|
||||
/**
|
||||
@ -1659,7 +1684,7 @@ Breakpoints.prototype = {
|
||||
* @return string
|
||||
* The identifier string.
|
||||
*/
|
||||
_getIdentifier: function(aLocation) {
|
||||
getIdentifier: function(aLocation) {
|
||||
return aLocation.url + ":" + aLocation.line;
|
||||
}
|
||||
};
|
||||
|
@ -135,18 +135,18 @@ SourcesView.prototype = Heritage.extend(WidgetMethods, {
|
||||
* Information about the breakpoint to be shown.
|
||||
* This object must have the following properties:
|
||||
* - location: the breakpoint's source location and line number
|
||||
* - disabled: the breakpoint's disabled state, boolean
|
||||
* - text: the breakpoint's line text to be displayed
|
||||
* - actor: the breakpoint's corresponding actor id
|
||||
* @param object aOptions [optional]
|
||||
* @see DebuggerController.Breakpoints.addBreakpoint
|
||||
*/
|
||||
addBreakpoint: function(aBreakpointData, aOptions = {}) {
|
||||
let { location, actor } = aBreakpointData;
|
||||
let { location, disabled } = aBreakpointData;
|
||||
|
||||
// Make sure we're not duplicating anything. If a breakpoint at the
|
||||
// specified source url and line already exists, just enable it.
|
||||
// specified source url and line already exists, just toggle it.
|
||||
if (this.getBreakpoint(location)) {
|
||||
this.enableBreakpoint(location, { id: actor });
|
||||
this[disabled ? "disableBreakpoint" : "enableBreakpoint"](location);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -220,17 +220,18 @@ SourcesView.prototype = Heritage.extend(WidgetMethods, {
|
||||
/**
|
||||
* Returns all breakpoints which are not at the specified source url and line.
|
||||
*
|
||||
* @param string aId
|
||||
* The original breakpoint client actor.
|
||||
* @param object aLocation [optional]
|
||||
* @see DebuggerController.Breakpoints.addBreakpoint
|
||||
* @param array aStore [optional]
|
||||
* A list in which to store the corresponding breakpoints.
|
||||
* @return array
|
||||
* The corresponding breakpoints if found, an empty array otherwise.
|
||||
*/
|
||||
getOtherBreakpoints: function(aId, aStore = []) {
|
||||
getOtherBreakpoints: function(aLocation = {}, aStore = []) {
|
||||
for (let source in this) {
|
||||
for (let breakpointItem in source) {
|
||||
if (breakpointItem.attachment.actor != aId) {
|
||||
let { url, line } = breakpointItem.attachment;
|
||||
if (url != aLocation.url || line != aLocation.line) {
|
||||
aStore.push(breakpointItem);
|
||||
}
|
||||
}
|
||||
@ -245,7 +246,6 @@ SourcesView.prototype = Heritage.extend(WidgetMethods, {
|
||||
* @see DebuggerController.Breakpoints.addBreakpoint
|
||||
* @param object aOptions [optional]
|
||||
* Additional options or flags supported by this operation:
|
||||
* - id: a new id to be applied to the corresponding element node
|
||||
* - silent: pass true to not update the checkbox checked state;
|
||||
* this is usually necessary when the checked state will
|
||||
* be updated automatically (e.g: on a checkbox click).
|
||||
@ -265,15 +265,12 @@ SourcesView.prototype = Heritage.extend(WidgetMethods, {
|
||||
|
||||
// Update the corresponding menu items to reflect the enabled state.
|
||||
let prefix = "bp-cMenu-"; // "breakpoints context menu"
|
||||
let enableSelfId = prefix + "enableSelf-" + attachment.actor + "-menuitem";
|
||||
let disableSelfId = prefix + "disableSelf-" + attachment.actor + "-menuitem";
|
||||
let identifier = DebuggerController.Breakpoints.getIdentifier(attachment);
|
||||
let enableSelfId = prefix + "enableSelf-" + identifier + "-menuitem";
|
||||
let disableSelfId = prefix + "disableSelf-" + identifier + "-menuitem";
|
||||
document.getElementById(enableSelfId).setAttribute("hidden", "true");
|
||||
document.getElementById(disableSelfId).removeAttribute("hidden");
|
||||
|
||||
// Set a new id to the corresponding breakpoint element if required.
|
||||
if (aOptions.id) {
|
||||
attachment.view.container.id = "breakpoint-" + aOptions.id;
|
||||
}
|
||||
// Update the checkbox state if necessary.
|
||||
if (!aOptions.silent) {
|
||||
attachment.view.checkbox.setAttribute("checked", "true");
|
||||
@ -312,8 +309,9 @@ SourcesView.prototype = Heritage.extend(WidgetMethods, {
|
||||
|
||||
// Update the corresponding menu items to reflect the disabled state.
|
||||
let prefix = "bp-cMenu-"; // "breakpoints context menu"
|
||||
let enableSelfId = prefix + "enableSelf-" + attachment.actor + "-menuitem";
|
||||
let disableSelfId = prefix + "disableSelf-" + attachment.actor + "-menuitem";
|
||||
let identifier = DebuggerController.Breakpoints.getIdentifier(attachment);
|
||||
let enableSelfId = prefix + "enableSelf-" + identifier + "-menuitem";
|
||||
let disableSelfId = prefix + "disableSelf-" + identifier + "-menuitem";
|
||||
document.getElementById(enableSelfId).removeAttribute("hidden");
|
||||
document.getElementById(disableSelfId).setAttribute("hidden", "true");
|
||||
|
||||
@ -325,7 +323,10 @@ SourcesView.prototype = Heritage.extend(WidgetMethods, {
|
||||
return DebuggerController.Breakpoints.removeBreakpoint(aLocation, {
|
||||
// No need to update this pane, since this method is invoked because
|
||||
// a breakpoint's view was interacted with.
|
||||
noPaneUpdate: true
|
||||
noPaneUpdate: true,
|
||||
// Mark this breakpoint as being "disabled", not completely removed.
|
||||
// This makes sure it will not be forgotten across target navigations.
|
||||
rememberDisabled: true
|
||||
});
|
||||
},
|
||||
|
||||
@ -448,32 +449,35 @@ SourcesView.prototype = Heritage.extend(WidgetMethods, {
|
||||
* @param object aOptions
|
||||
* A couple of options or flags supported by this operation:
|
||||
* - location: the breakpoint's source location and line number
|
||||
* - text: the breakpoint's line text to be displayed.
|
||||
* - actor: a breakpoint identifier specified by the controller.
|
||||
* - disabled: the breakpoint's disabled state, boolean
|
||||
* - text: the breakpoint's line text to be displayed
|
||||
* @return object
|
||||
* An object containing the breakpoint container, checkbox,
|
||||
* line number and line text nodes.
|
||||
*/
|
||||
_createBreakpointView: function(aOptions) {
|
||||
let { location, disabled, text } = aOptions;
|
||||
let identifier = DebuggerController.Breakpoints.getIdentifier(location);
|
||||
|
||||
let checkbox = document.createElement("checkbox");
|
||||
checkbox.setAttribute("checked", "true");
|
||||
checkbox.setAttribute("checked", !disabled);
|
||||
checkbox.className = "dbg-breakpoint-checkbox";
|
||||
|
||||
let lineNumberNode = document.createElement("label");
|
||||
lineNumberNode.className = "plain dbg-breakpoint-line";
|
||||
lineNumberNode.setAttribute("value", aOptions.location.line);
|
||||
lineNumberNode.setAttribute("value", location.line);
|
||||
|
||||
let lineTextNode = document.createElement("label");
|
||||
lineTextNode.className = "plain dbg-breakpoint-text";
|
||||
lineTextNode.setAttribute("value", aOptions.text);
|
||||
lineTextNode.setAttribute("value", text);
|
||||
lineTextNode.setAttribute("crop", "end");
|
||||
lineTextNode.setAttribute("flex", "1");
|
||||
|
||||
let tooltip = aOptions.text.substr(0, BREAKPOINT_LINE_TOOLTIP_MAX_LENGTH);
|
||||
let tooltip = text.substr(0, BREAKPOINT_LINE_TOOLTIP_MAX_LENGTH);
|
||||
lineTextNode.setAttribute("tooltiptext", tooltip);
|
||||
|
||||
let container = document.createElement("hbox");
|
||||
container.id = "breakpoint-" + aOptions.actor;
|
||||
container.id = "breakpoint-" + identifier;
|
||||
container.className = "dbg-breakpoint side-menu-widget-item-other";
|
||||
container.classList.add("devtools-monospace");
|
||||
container.setAttribute("align", "center");
|
||||
@ -497,23 +501,24 @@ SourcesView.prototype = Heritage.extend(WidgetMethods, {
|
||||
/**
|
||||
* Creates a context menu for a breakpoint element.
|
||||
*
|
||||
* @param aOptions
|
||||
* @param object aOptions
|
||||
* A couple of options or flags supported by this operation:
|
||||
* - actor: a breakpoint identifier specified by the controller.
|
||||
* - location: the breakpoint's source location and line number
|
||||
* - disabled: the breakpoint's disabled state, boolean
|
||||
* @return object
|
||||
* An object containing the breakpoint commandset and menu popup ids.
|
||||
*/
|
||||
_createContextMenu: function(aOptions) {
|
||||
let commandsetId = "bp-cSet-" + aOptions.actor;
|
||||
let menupopupId = "bp-mPop-" + aOptions.actor;
|
||||
let { location, disabled } = aOptions;
|
||||
let identifier = DebuggerController.Breakpoints.getIdentifier(location);
|
||||
|
||||
let commandset = document.createElement("commandset");
|
||||
let menupopup = document.createElement("menupopup");
|
||||
commandset.id = commandsetId;
|
||||
menupopup.id = menupopupId;
|
||||
commandset.id = "bp-cSet-" + identifier;
|
||||
menupopup.id = "bp-mPop-" + identifier;
|
||||
|
||||
createMenuItem.call(this, "enableSelf", true);
|
||||
createMenuItem.call(this, "disableSelf");
|
||||
createMenuItem.call(this, "enableSelf", !disabled);
|
||||
createMenuItem.call(this, "disableSelf", disabled);
|
||||
createMenuItem.call(this, "deleteSelf");
|
||||
createMenuSeparator();
|
||||
createMenuItem.call(this, "setConditional");
|
||||
@ -531,8 +536,8 @@ SourcesView.prototype = Heritage.extend(WidgetMethods, {
|
||||
this._commandset.appendChild(commandset);
|
||||
|
||||
return {
|
||||
commandsetId: commandsetId,
|
||||
menupopupId: menupopupId
|
||||
commandsetId: commandset.id,
|
||||
menupopupId: menupopup.id
|
||||
};
|
||||
|
||||
/**
|
||||
@ -549,15 +554,15 @@ SourcesView.prototype = Heritage.extend(WidgetMethods, {
|
||||
let command = document.createElement("command");
|
||||
|
||||
let prefix = "bp-cMenu-"; // "breakpoints context menu"
|
||||
let commandId = prefix + aName + "-" + aOptions.actor + "-command";
|
||||
let menuitemId = prefix + aName + "-" + aOptions.actor + "-menuitem";
|
||||
let commandId = prefix + aName + "-" + identifier + "-command";
|
||||
let menuitemId = prefix + aName + "-" + identifier + "-menuitem";
|
||||
|
||||
let label = L10N.getStr("breakpointMenuItem." + aName);
|
||||
let func = "_on" + aName.charAt(0).toUpperCase() + aName.slice(1);
|
||||
|
||||
command.id = commandId;
|
||||
command.setAttribute("label", label);
|
||||
command.addEventListener("command", () => this[func](aOptions.actor), false);
|
||||
command.addEventListener("command", () => this[func](location), false);
|
||||
|
||||
menuitem.id = menuitemId;
|
||||
menuitem.setAttribute("command", commandId);
|
||||
@ -842,69 +847,57 @@ SourcesView.prototype = Heritage.extend(WidgetMethods, {
|
||||
/**
|
||||
* Function invoked on the "setConditional" menuitem command.
|
||||
*
|
||||
* @param string aId
|
||||
* The original breakpoint client actor.
|
||||
* @param object aLocation
|
||||
* @see DebuggerController.Breakpoints.addBreakpoint
|
||||
*/
|
||||
_onSetConditional: function(aId) {
|
||||
let targetBreakpoint = this.getItemForPredicate(aItem => aItem.attachment.actor == aId);
|
||||
let attachment = targetBreakpoint.attachment;
|
||||
|
||||
_onSetConditional: function(aLocation) {
|
||||
// Highlight the breakpoint and show a conditional expression popup.
|
||||
this.highlightBreakpoint(attachment, { openPopup: true });
|
||||
this.highlightBreakpoint(aLocation, { openPopup: true });
|
||||
},
|
||||
|
||||
/**
|
||||
* Function invoked on the "enableSelf" menuitem command.
|
||||
*
|
||||
* @param string aId
|
||||
* The original breakpoint client actor.
|
||||
* @param object aLocation
|
||||
* @see DebuggerController.Breakpoints.addBreakpoint
|
||||
*/
|
||||
_onEnableSelf: function(aId) {
|
||||
let targetBreakpoint = this.getItemForPredicate(aItem => aItem.attachment.actor == aId);
|
||||
let attachment = targetBreakpoint.attachment;
|
||||
|
||||
_onEnableSelf: function(aLocation) {
|
||||
// Enable the breakpoint, in this container and the controller store.
|
||||
this.enableBreakpoint(attachment);
|
||||
this.enableBreakpoint(aLocation);
|
||||
},
|
||||
|
||||
/**
|
||||
* Function invoked on the "disableSelf" menuitem command.
|
||||
*
|
||||
* @param string aId
|
||||
* The original breakpoint client actor.
|
||||
* @param object aLocation
|
||||
* @see DebuggerController.Breakpoints.addBreakpoint
|
||||
*/
|
||||
_onDisableSelf: function(aId) {
|
||||
let targetBreakpoint = this.getItemForPredicate(aItem => aItem.attachment.actor == aId);
|
||||
let attachment = targetBreakpoint.attachment;
|
||||
|
||||
_onDisableSelf: function(aLocation) {
|
||||
// Disable the breakpoint, in this container and the controller store.
|
||||
this.disableBreakpoint(attachment);
|
||||
this.disableBreakpoint(aLocation);
|
||||
},
|
||||
|
||||
/**
|
||||
* Function invoked on the "deleteSelf" menuitem command.
|
||||
*
|
||||
* @param string aId
|
||||
* The original breakpoint client actor.
|
||||
* @param object aLocation
|
||||
* @see DebuggerController.Breakpoints.addBreakpoint
|
||||
*/
|
||||
_onDeleteSelf: function(aId) {
|
||||
let targetBreakpoint = this.getItemForPredicate(aItem => aItem.attachment.actor == aId);
|
||||
let attachment = targetBreakpoint.attachment;
|
||||
|
||||
_onDeleteSelf: function(aLocation) {
|
||||
// Remove the breakpoint, from this container and the controller store.
|
||||
this.removeBreakpoint(attachment);
|
||||
DebuggerController.Breakpoints.removeBreakpoint(attachment);
|
||||
this.removeBreakpoint(aLocation);
|
||||
DebuggerController.Breakpoints.removeBreakpoint(aLocation);
|
||||
},
|
||||
|
||||
/**
|
||||
* Function invoked on the "enableOthers" menuitem command.
|
||||
*
|
||||
* @param string aId
|
||||
* The original breakpoint client actor.
|
||||
* @param object aLocation
|
||||
* @see DebuggerController.Breakpoints.addBreakpoint
|
||||
*/
|
||||
_onEnableOthers: function(aId) {
|
||||
let enableOthers = (aCallback) => {
|
||||
let other = this.getOtherBreakpoints(aId);
|
||||
_onEnableOthers: function(aLocation) {
|
||||
let enableOthers = aCallback => {
|
||||
let other = this.getOtherBreakpoints(aLocation);
|
||||
let outstanding = other.map(e => this.enableBreakpoint(e.attachment));
|
||||
promise.all(outstanding).then(aCallback);
|
||||
}
|
||||
@ -922,44 +915,44 @@ SourcesView.prototype = Heritage.extend(WidgetMethods, {
|
||||
/**
|
||||
* Function invoked on the "disableOthers" menuitem command.
|
||||
*
|
||||
* @param string aId
|
||||
* The original breakpoint client actor.
|
||||
* @param object aLocation
|
||||
* @see DebuggerController.Breakpoints.addBreakpoint
|
||||
*/
|
||||
_onDisableOthers: function(aId) {
|
||||
let other = this.getOtherBreakpoints(aId);
|
||||
other.forEach(e => this._onDisableSelf(e.attachment.actor));
|
||||
_onDisableOthers: function(aLocation) {
|
||||
let other = this.getOtherBreakpoints(aLocation);
|
||||
other.forEach(e => this._onDisableSelf(e.attachment));
|
||||
},
|
||||
|
||||
/**
|
||||
* Function invoked on the "deleteOthers" menuitem command.
|
||||
*
|
||||
* @param string aId
|
||||
* The original breakpoint client actor.
|
||||
* @param object aLocation
|
||||
* @see DebuggerController.Breakpoints.addBreakpoint
|
||||
*/
|
||||
_onDeleteOthers: function(aId) {
|
||||
let other = this.getOtherBreakpoints(aId);
|
||||
other.forEach(e => this._onDeleteSelf(e.attachment.actor));
|
||||
_onDeleteOthers: function(aLocation) {
|
||||
let other = this.getOtherBreakpoints(aLocation);
|
||||
other.forEach(e => this._onDeleteSelf(e.attachment));
|
||||
},
|
||||
|
||||
/**
|
||||
* Function invoked on the "enableAll" menuitem command.
|
||||
*/
|
||||
_onEnableAll: function() {
|
||||
this._onEnableOthers(null);
|
||||
this._onEnableOthers(undefined);
|
||||
},
|
||||
|
||||
/**
|
||||
* Function invoked on the "disableAll" menuitem command.
|
||||
*/
|
||||
_onDisableAll: function() {
|
||||
this._onDisableOthers(null);
|
||||
this._onDisableOthers(undefined);
|
||||
},
|
||||
|
||||
/**
|
||||
* Function invoked on the "deleteAll" menuitem command.
|
||||
*/
|
||||
_onDeleteAll: function() {
|
||||
this._onDeleteOthers(null);
|
||||
this._onDeleteOthers(undefined);
|
||||
},
|
||||
|
||||
_commandset: null,
|
||||
|
@ -15,6 +15,7 @@ MOCHITEST_BROWSER_TESTS = \
|
||||
browser_dbg_breadcrumbs-access.js \
|
||||
browser_dbg_breakpoints-actual-location.js \
|
||||
browser_dbg_breakpoints-contextmenu.js \
|
||||
browser_dbg_breakpoints-disabled-reload.js \
|
||||
browser_dbg_breakpoints-editor.js \
|
||||
browser_dbg_breakpoints-highlight.js \
|
||||
browser_dbg_breakpoints-new-script.js \
|
||||
|
@ -113,10 +113,10 @@ function test() {
|
||||
is(!!breakpoint.attachment.disabled, false,
|
||||
"All breakpoints should initially be enabled.");
|
||||
|
||||
let actor = breakpoint.attachment.actor;
|
||||
let prefix = "bp-cMenu-"; // "breakpoints context menu"
|
||||
let enableSelfId = prefix + "enableSelf-" + actor + "-menuitem";
|
||||
let disableSelfId = prefix + "disableSelf-" + actor + "-menuitem";
|
||||
let identifier = gBreakpoints.getIdentifier(breakpoint.attachment);
|
||||
let enableSelfId = prefix + "enableSelf-" + identifier + "-menuitem";
|
||||
let disableSelfId = prefix + "disableSelf-" + identifier + "-menuitem";
|
||||
|
||||
is(gDebugger.document.getElementById(enableSelfId).getAttribute("hidden"), "true",
|
||||
"The 'Enable breakpoint' context menu item should initially be hidden'.");
|
||||
@ -151,10 +151,10 @@ function test() {
|
||||
"There should be a breakpoint client available as a promise.");
|
||||
});
|
||||
|
||||
let actor = selectedBreakpoint.attachment.actor;
|
||||
let prefix = "bp-cMenu-"; // "breakpoints context menu"
|
||||
let enableSelfId = prefix + "enableSelf-" + actor + "-menuitem";
|
||||
let disableSelfId = prefix + "disableSelf-" + actor + "-menuitem";
|
||||
let identifier = gBreakpoints.getIdentifier(selectedBreakpoint.attachment);
|
||||
let enableSelfId = prefix + "enableSelf-" + identifier + "-menuitem";
|
||||
let disableSelfId = prefix + "disableSelf-" + identifier + "-menuitem";
|
||||
|
||||
is(gDebugger.document.getElementById(enableSelfId).getAttribute("hidden"), "true",
|
||||
"The 'Enable breakpoint' context menu item should be hidden'.");
|
||||
@ -176,7 +176,7 @@ function test() {
|
||||
});
|
||||
|
||||
// Test re-disabling this breakpoint.
|
||||
gSources._onEnableSelf(selectedBreakpoint.attachment.actor);
|
||||
gSources._onEnableSelf(selectedBreakpoint.attachment);
|
||||
is(selectedBreakpoint.attachment.disabled, false,
|
||||
"The current breakpoint should now be enabled.")
|
||||
|
||||
@ -189,7 +189,7 @@ function test() {
|
||||
});
|
||||
|
||||
// Test disabling this breakpoint.
|
||||
gSources._onDisableSelf(selectedBreakpoint.attachment.actor);
|
||||
gSources._onDisableSelf(selectedBreakpoint.attachment);
|
||||
is(selectedBreakpoint.attachment.disabled, true,
|
||||
"The current breakpoint should now be disabled.")
|
||||
|
||||
@ -305,10 +305,10 @@ function test() {
|
||||
}
|
||||
|
||||
function disableOthers() {
|
||||
gSources._onDisableOthers(gSources._selectedBreakpointItem.attachment.actor);
|
||||
gSources._onDisableOthers(gSources._selectedBreakpointItem.attachment);
|
||||
}
|
||||
function enableOthers() {
|
||||
gSources._onEnableOthers(gSources._selectedBreakpointItem.attachment.actor);
|
||||
gSources._onEnableOthers(gSources._selectedBreakpointItem.attachment);
|
||||
}
|
||||
function disableAll() {
|
||||
gSources._onDisableAll();
|
||||
|
@ -0,0 +1,115 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Test that disabled breakpoints survive target navigation.
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_script-switching-01.html";
|
||||
|
||||
function test() {
|
||||
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
|
||||
let gDebugger = aPanel.panelWin;
|
||||
let gEvents = gDebugger.EVENTS;
|
||||
let gEditor = gDebugger.DebuggerView.editor;
|
||||
let gSources = gDebugger.DebuggerView.Sources;
|
||||
let gBreakpoints = gDebugger.DebuggerController.Breakpoints;
|
||||
let gBreakpointLocation = { url: EXAMPLE_URL + "code_script-switching-01.js", line: 5 };
|
||||
|
||||
Task.spawn(function() {
|
||||
yield waitForSourceShown(aPanel, "-01.js");
|
||||
yield aPanel.addBreakpoint(gBreakpointLocation);
|
||||
|
||||
yield ensureThreadClientState(aPanel, "resumed");
|
||||
yield testWhenBreakpointEnabledAndFirstSourceShown();
|
||||
|
||||
yield reloadActiveTab(aPanel, gEvents.SOURCE_SHOWN);
|
||||
yield testWhenBreakpointEnabledAndSecondSourceShown();
|
||||
|
||||
yield gSources.disableBreakpoint(gBreakpointLocation);
|
||||
yield reloadActiveTab(aPanel, gEvents.SOURCE_SHOWN);
|
||||
yield testWhenBreakpointDisabledAndSecondSourceShown();
|
||||
|
||||
yield gSources.enableBreakpoint(gBreakpointLocation);
|
||||
yield reloadActiveTab(aPanel, gEvents.SOURCE_SHOWN);
|
||||
yield testWhenBreakpointEnabledAndSecondSourceShown();
|
||||
|
||||
yield resumeDebuggerThenCloseAndFinish(aPanel);
|
||||
});
|
||||
|
||||
function verifyView({ disabled, visible }) {
|
||||
return Task.spawn(function() {
|
||||
// It takes a tick for the checkbox in the SideMenuWidget and the
|
||||
// gutter in the SourceEditor to get updated.
|
||||
yield waitForTick();
|
||||
|
||||
let breakpointItem = gSources.getBreakpoint(gBreakpointLocation);
|
||||
let visibleBreakpoints = gEditor.getBreakpoints();
|
||||
is(!!breakpointItem.attachment.disabled, disabled,
|
||||
"The selected brekapoint state was correct.");
|
||||
is(breakpointItem.attachment.view.checkbox.hasAttribute("checked"), !disabled,
|
||||
"The selected brekapoint's checkbox state was correct.");
|
||||
|
||||
// Source editor starts counting line and column numbers from 0.
|
||||
let breakpointLine = breakpointItem.attachment.line - 1;
|
||||
let matchedBreakpoints = visibleBreakpoints.filter(e => e.line == breakpointLine);
|
||||
is(!!matchedBreakpoints.length, visible,
|
||||
"The selected breakpoint's visibility in the editor was correct.");
|
||||
});
|
||||
}
|
||||
|
||||
// All the following executeSoon()'s are required to spin the event loop
|
||||
// before causing the debuggee to pause, to allow functions to yield first.
|
||||
|
||||
function testWhenBreakpointEnabledAndFirstSourceShown() {
|
||||
return Task.spawn(function() {
|
||||
yield ensureSourceIs(aPanel, "-01.js");
|
||||
yield verifyView({ disabled: false, visible: true });
|
||||
|
||||
executeSoon(() => aDebuggee.firstCall());
|
||||
yield waitForDebuggerEvents(aPanel, gEvents.FETCHED_SCOPES);
|
||||
yield ensureSourceIs(aPanel, "-01.js");
|
||||
yield ensureCaretAt(aPanel, 5);
|
||||
yield verifyView({ disabled: false, visible: true });
|
||||
|
||||
executeSoon(() => gDebugger.gThreadClient.resume());
|
||||
yield waitForSourceAndCaretAndScopes(aPanel, "-02.js", 6);
|
||||
yield verifyView({ disabled: false, visible: false });
|
||||
});
|
||||
}
|
||||
|
||||
function testWhenBreakpointEnabledAndSecondSourceShown() {
|
||||
return Task.spawn(function() {
|
||||
yield ensureSourceIs(aPanel, "-02.js");
|
||||
yield verifyView({ disabled: false, visible: false });
|
||||
|
||||
executeSoon(() => aDebuggee.firstCall());
|
||||
yield waitForSourceAndCaretAndScopes(aPanel, "-01.js", 5);
|
||||
yield verifyView({ disabled: false, visible: true });
|
||||
|
||||
executeSoon(() => gDebugger.gThreadClient.resume());
|
||||
yield waitForSourceAndCaretAndScopes(aPanel, "-02.js", 6);
|
||||
yield verifyView({ disabled: false, visible: false });
|
||||
});
|
||||
}
|
||||
|
||||
function testWhenBreakpointDisabledAndSecondSourceShown() {
|
||||
return Task.spawn(function() {
|
||||
yield ensureSourceIs(aPanel, "-02.js");
|
||||
yield verifyView({ disabled: true, visible: false });
|
||||
|
||||
executeSoon(() => aDebuggee.firstCall());
|
||||
yield waitForDebuggerEvents(aPanel, gEvents.FETCHED_SCOPES);
|
||||
yield ensureSourceIs(aPanel, "-02.js");
|
||||
yield ensureCaretAt(aPanel, 6);
|
||||
yield verifyView({ disabled: true, visible: false });
|
||||
|
||||
executeSoon(() => gDebugger.gThreadClient.resume());
|
||||
yield waitForDebuggerEvents(aPanel, gEvents.AFTER_FRAMES_CLEARED);
|
||||
yield ensureSourceIs(aPanel, "-02.js");
|
||||
yield ensureCaretAt(aPanel, 6);
|
||||
yield verifyView({ disabled: true, visible: false });
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
@ -227,14 +227,14 @@ function test() {
|
||||
? "Should have added a breakpoint in the pane."
|
||||
: "Should have the same number of breakpoints in the pane.");
|
||||
|
||||
let id = "breakpoint-" + aBreakpointClient.actor;
|
||||
let node = gDebugger.document.getElementById(id);
|
||||
let identifier = gBreakpoints.getIdentifier(aBreakpointClient.location);
|
||||
let node = gDebugger.document.getElementById("breakpoint-" + identifier);
|
||||
let line = node.getElementsByClassName("dbg-breakpoint-line")[0];
|
||||
let text = node.getElementsByClassName("dbg-breakpoint-text")[0];
|
||||
let check = node.querySelector("checkbox");
|
||||
|
||||
is(node.id, id,
|
||||
"Breakpoint element " + id + " found successfully.");
|
||||
ok(node,
|
||||
"Breakpoint element found successfully.");
|
||||
is(line.getAttribute("value"), aTestData.line,
|
||||
"The expected information wasn't found in the breakpoint element.");
|
||||
is(text.getAttribute("value"), aTestData.text,
|
||||
|
@ -136,6 +136,8 @@ function testFocusFirst() {
|
||||
}
|
||||
|
||||
function testRemoveTab() {
|
||||
let deferred = promise.defer();
|
||||
|
||||
gNewWindow.close();
|
||||
removeTab(gNewTab);
|
||||
|
||||
@ -148,7 +150,11 @@ function testRemoveTab() {
|
||||
|
||||
is(aResponse.selected, 0,
|
||||
"The original tab is selected.");
|
||||
|
||||
deferred.resolve();
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function closeConnection() {
|
||||
|
@ -256,6 +256,15 @@ function performTest() {
|
||||
"The 'someProp5' item should be focused.");
|
||||
is(gVariablesView.getFocusedItem().expanded, true,
|
||||
"The 'someProp5' item should now be expanded.");
|
||||
is(gVariablesView.getFocusedItem()._store.size, 9,
|
||||
"There should be 9 properties in the selected variable.");
|
||||
is(gVariablesView.getFocusedItem()._enumItems.length, 7,
|
||||
"There should be 7 enumerable properties in the selected variable.");
|
||||
is(gVariablesView.getFocusedItem()._nonEnumItems.length, 2,
|
||||
"There should be 2 non-enumerable properties in the selected variable.");
|
||||
|
||||
yield waitForChildNodes(gVariablesView.getFocusedItem()._enum, 7);
|
||||
yield waitForChildNodes(gVariablesView.getFocusedItem()._nonenum, 2);
|
||||
|
||||
EventUtils.sendKey("RIGHT", gDebugger);
|
||||
is(gVariablesView.getFocusedItem().name, "0",
|
||||
@ -276,6 +285,15 @@ function performTest() {
|
||||
"The '5' item should be focused.");
|
||||
is(gVariablesView.getFocusedItem().expanded, true,
|
||||
"The '5' item should now be expanded.");
|
||||
is(gVariablesView.getFocusedItem()._store.size, 5,
|
||||
"There should be 5 properties in the selected variable.");
|
||||
is(gVariablesView.getFocusedItem()._enumItems.length, 3,
|
||||
"There should be 3 enumerable properties in the selected variable.");
|
||||
is(gVariablesView.getFocusedItem()._nonEnumItems.length, 2,
|
||||
"There should be 2 non-enumerable properties in the selected variable.");
|
||||
|
||||
yield waitForChildNodes(gVariablesView.getFocusedItem()._enum, 3);
|
||||
yield waitForChildNodes(gVariablesView.getFocusedItem()._nonenum, 2);
|
||||
|
||||
EventUtils.sendKey("RIGHT", gDebugger);
|
||||
is(gVariablesView.getFocusedItem().name, "0",
|
||||
@ -291,13 +309,42 @@ function performTest() {
|
||||
is(gVariablesView.getFocusedItem().expanded, false,
|
||||
"The '6' item should not be expanded yet.");
|
||||
|
||||
// Part 9: Test that the RIGHT key collapses elements as intended.
|
||||
yield synthesizeKeyAndWaitForTick("VK_RIGHT", {});
|
||||
is(gVariablesView.getFocusedItem().name, "6",
|
||||
"The '6' item should be focused.");
|
||||
is(gVariablesView.getFocusedItem().expanded, true,
|
||||
"The '6' item should now be expanded.");
|
||||
is(gVariablesView.getFocusedItem()._store.size, 3,
|
||||
"There should be 3 properties in the selected variable.");
|
||||
is(gVariablesView.getFocusedItem()._enumItems.length, 2,
|
||||
"There should be 2 enumerable properties in the selected variable.");
|
||||
is(gVariablesView.getFocusedItem()._nonEnumItems.length, 1,
|
||||
"There should be 1 non-enumerable properties in the selected variable.");
|
||||
|
||||
EventUtils.sendKey("DOWN", gDebugger);
|
||||
EventUtils.sendKey("DOWN", gDebugger);
|
||||
EventUtils.sendKey("DOWN", gDebugger);
|
||||
yield waitForChildNodes(gVariablesView.getFocusedItem()._enum, 2);
|
||||
yield waitForChildNodes(gVariablesView.getFocusedItem()._nonenum, 1);
|
||||
|
||||
EventUtils.sendKey("RIGHT", gDebugger);
|
||||
is(gVariablesView.getFocusedItem().name, "prop1",
|
||||
"The 'prop1' item should be focused.");
|
||||
|
||||
if (gVariablesView.getFocusedItem().name != "prop1") {
|
||||
gDebugger.DebuggerView.toggleInstrumentsPane({ visible: true, animated: false })
|
||||
yield promise.defer().promise;
|
||||
yield closeDebuggerAndFinish(gPanel);
|
||||
}
|
||||
|
||||
EventUtils.sendKey("RIGHT", gDebugger);
|
||||
is(gVariablesView.getFocusedItem().name, "prop1",
|
||||
"The 'prop1' item should still be focused.");
|
||||
|
||||
EventUtils.sendKey("PAGE_DOWN", gDebugger);
|
||||
is(gVariablesView.getFocusedItem().name, "someProp6",
|
||||
"The 'someProp6' item should be focused.");
|
||||
is(gVariablesView.getFocusedItem().expanded, false,
|
||||
"The 'someProp6' item should not be expanded yet.");
|
||||
|
||||
// Part 9: Test that the RIGHT key collapses elements as intended.
|
||||
|
||||
EventUtils.sendKey("LEFT", gDebugger);
|
||||
is(gVariablesView.getFocusedItem().name, "someProp6",
|
||||
@ -457,13 +504,19 @@ function synthesizeKeyAndWaitForTick(aKey, aModifiers) {
|
||||
return waitForTick();
|
||||
}
|
||||
|
||||
function waitForTick() {
|
||||
let deferred = promise.defer();
|
||||
executeSoon(deferred.resolve);
|
||||
return deferred.promise;
|
||||
function waitForElement(aSelector, aExistence) {
|
||||
return waitForPredicate(() => {
|
||||
return !!gVariablesView._list.querySelector(aSelector) == aExistence;
|
||||
});
|
||||
}
|
||||
|
||||
function waitForElement(aSelector, aExistence, aInterval = 10) {
|
||||
function waitForChildNodes(aTarget, aCount) {
|
||||
return waitForPredicate(() => {
|
||||
return aTarget.childNodes.length == aCount;
|
||||
});
|
||||
}
|
||||
|
||||
function waitForPredicate(aPredicate, aInterval = 10) {
|
||||
let deferred = promise.defer();
|
||||
|
||||
// Poll every few milliseconds until the element is retrieved.
|
||||
@ -475,8 +528,8 @@ function waitForElement(aSelector, aExistence, aInterval = 10) {
|
||||
window.clearInterval(intervalID);
|
||||
return;
|
||||
}
|
||||
// Check if the existence condition is fulfilled.
|
||||
if (!!gVariablesView._list.querySelector(aSelector) != aExistence) {
|
||||
// Check if the predicate condition is fulfilled.
|
||||
if (!aPredicate()) {
|
||||
return;
|
||||
}
|
||||
// We got the element, it's safe to callback.
|
||||
|
@ -205,6 +205,12 @@ function once(aTarget, aEventName, aUseCapture = false) {
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function waitForTick() {
|
||||
let deferred = promise.defer();
|
||||
executeSoon(deferred.resolve);
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function waitForSourceShown(aPanel, aUrl) {
|
||||
return waitForDebuggerEvents(aPanel, aPanel.panelWin.EVENTS.SOURCE_SHOWN).then(aSource => {
|
||||
let sourceUrl = aSource.url;
|
||||
|
@ -75,3 +75,4 @@ browser.jar:
|
||||
content/browser/devtools/app-manager/projects.xhtml (app-manager/content/projects.xhtml)
|
||||
content/browser/devtools/app-manager/index.xul (app-manager/content/index.xul)
|
||||
content/browser/devtools/app-manager/index.js (app-manager/content/index.js)
|
||||
content/browser/devtools/app-manager/help.xhtml (app-manager/content/help.xhtml)
|
||||
|
@ -429,6 +429,8 @@ social.turnOff.accesskey=T
|
||||
# LOCALIZATION NOTE (social.turnOn.label): %S is the name of the social provider
|
||||
social.turnOn.label=Turn on %S
|
||||
social.turnOn.accesskey=T
|
||||
social.turnOffAll.label=Turn off all Services
|
||||
social.turnOnAll.label=Turn on all Services
|
||||
|
||||
# LOCALIZATION NOTE (social.markpageMenu.label): %S is the name of the social provider
|
||||
social.markpageMenu.label=Save Page to %S
|
||||
|
@ -5,6 +5,7 @@
|
||||
<!ENTITY index.title "App Manager">
|
||||
<!ENTITY index.projects2 "Apps">
|
||||
<!ENTITY index.device2 "Device">
|
||||
<!ENTITY index.help "Help">
|
||||
|
||||
<!ENTITY device.screenshot "Screenshot">
|
||||
<!ENTITY device.screenshotTooltip "Open a screenshot of the current state of the device in a new tab.">
|
||||
@ -36,8 +37,9 @@
|
||||
<!ENTITY connection.connectTooltip "Connect to the device.">
|
||||
<!ENTITY connection.disconnect "Disconnect">
|
||||
<!ENTITY connection.disconnectTooltip "Disconnect from the current device or simulator.">
|
||||
<!ENTITY connection.showDeviceCtrlCenter "Click for More Details">
|
||||
<!ENTITY connection.notConnected "Not Connected">
|
||||
<!ENTITY connection.notConnected2 "Not Connected.">
|
||||
<!ENTITY connection.connectTo "Connect to:">
|
||||
<!ENTITY connection.noDeviceFound "No device found. Plug a device">
|
||||
<!ENTITY connection.changeHostAndPort "Change">
|
||||
<!ENTITY connection.changeHostAndPortTooltip "Change the host and port used to connect to the device. (Defaults to localhost:6000)">
|
||||
<!ENTITY connection.startSimulator "Start Simulator">
|
||||
@ -65,10 +67,19 @@
|
||||
<!ENTITY projects.title "Local Apps">
|
||||
<!ENTITY projects.appDetails "App Details">
|
||||
<!ENTITY projects.removeAppFromList "Remove this app from the list of apps you are working on. This will not remove it from a device or a simulator.">
|
||||
<!ENTITY projects.reloadFiles "Refresh">
|
||||
<!ENTITY projects.installApp "Install">
|
||||
<!ENTITY projects.startApp "Start">
|
||||
<!ENTITY projects.stopApp "Stop">
|
||||
<!ENTITY projects.updateApp "Update">
|
||||
<!ENTITY projects.updateAppTooltip "Execute validation checks and update the app to the connected device">
|
||||
<!ENTITY projects.debugApp "Debug">
|
||||
<!ENTITY projects.debugAppTooltip "Open Developer Tools connected to this app">
|
||||
<!ENTITY projects.hostedManifestPlaceHolder2 "http://example.com/app/manifest.webapp">
|
||||
<!ENTITY projects.noProjects "No projects. Add a new packaged app below (local directory) or a hosted app (link to a manifest file).">
|
||||
|
||||
<!ENTITY help.title "App Manager">
|
||||
<!ENTITY help.close "Close">
|
||||
<!ENTITY help.intro "This tool will help you build and install web apps on compatible devices (i.e Firefox OS). The <strong>Apps</strong> tab will assist you in the validation and installation process of your app. The <strong>Device</strong> tab will give you information about the connected device. Use the bottom toolbar to connect to a device or start the simulator.">
|
||||
<!ENTITY help.usefullLinks "Useful links:">
|
||||
<!ENTITY help.linkToAppMgrDoc "<a>Documentation: Using the App Manager</a>">
|
||||
<!ENTITY help.linkToConfiguringDevice "<a>How to setup your Firefox OS device</a>">
|
||||
<!ENTITY help.linkToTroubleShooting "<a>Troubleshooting</a>">
|
||||
<!ENTITY help.linkToSimulatorAddon "<a>Install Simulator Add-on</a>">
|
||||
<!ENTITY help.linkToAdbHelperAddon "<a>Install Adb Helper Add-on</a>">
|
||||
|
@ -34,9 +34,8 @@ function prefObserver(subject, topic, data) {
|
||||
if (enable && !Social.provider) {
|
||||
// this will result in setting Social.provider
|
||||
SocialService.getOrderedProviderList(function(providers) {
|
||||
Social._updateProviderCache(providers);
|
||||
Social.enabled = true;
|
||||
Services.obs.notifyObservers(null, "social:providers-changed", null);
|
||||
Social._updateProviderCache(providers);
|
||||
});
|
||||
} else if (!enable && Social.provider) {
|
||||
Social.provider = null;
|
||||
@ -168,7 +167,7 @@ this.Social = {
|
||||
// Retrieve the current set of providers, and set the current provider.
|
||||
SocialService.getOrderedProviderList(function (providers) {
|
||||
Social._updateProviderCache(providers);
|
||||
Social._updateWorkerState(true);
|
||||
Social._updateWorkerState(SocialService.enabled);
|
||||
});
|
||||
}
|
||||
|
||||
@ -181,10 +180,16 @@ this.Social = {
|
||||
Services.obs.notifyObservers(null, "social:" + topic, origin);
|
||||
return;
|
||||
}
|
||||
if (topic == "provider-enabled" || topic == "provider-disabled") {
|
||||
if (topic == "provider-enabled") {
|
||||
Social._updateProviderCache(providers);
|
||||
Social._updateWorkerState(Social.enabled);
|
||||
Services.obs.notifyObservers(null, "social:" + topic, origin);
|
||||
return;
|
||||
}
|
||||
if (topic == "provider-disabled") {
|
||||
// a provider was removed from the list of providers, that does not
|
||||
// affect worker state for other providers
|
||||
Social._updateProviderCache(providers);
|
||||
Social._updateWorkerState(true);
|
||||
Services.obs.notifyObservers(null, "social:providers-changed", null);
|
||||
Services.obs.notifyObservers(null, "social:" + topic, origin);
|
||||
return;
|
||||
}
|
||||
@ -194,7 +199,6 @@ this.Social = {
|
||||
Social._updateProviderCache(providers);
|
||||
let provider = Social._getProviderFromOrigin(origin);
|
||||
provider.reload();
|
||||
Services.obs.notifyObservers(null, "social:providers-changed", null);
|
||||
}
|
||||
});
|
||||
},
|
||||
@ -210,6 +214,7 @@ this.Social = {
|
||||
// Called to update our cache of providers and set the current provider
|
||||
_updateProviderCache: function (providers) {
|
||||
this.providers = providers;
|
||||
Services.obs.notifyObservers(null, "social:providers-changed", null);
|
||||
|
||||
// If social is currently disabled there's nothing else to do other than
|
||||
// to notify about the lack of a provider.
|
||||
|
@ -4,4 +4,4 @@
|
||||
# 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/.
|
||||
|
||||
DIRS += ['chrome']
|
||||
DIRS += ['chrome', 'unit']
|
||||
|
9
browser/modules/test/unit/moz.build
Normal file
9
browser/modules/test/unit/moz.build
Normal file
@ -0,0 +1,9 @@
|
||||
# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
|
||||
# vim: set filetype=python:
|
||||
# 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/.
|
||||
|
||||
DIRS += ['social']
|
||||
|
||||
XPCSHELL_TESTS_MANIFESTS += ['social/xpcshell.ini']
|
11
browser/modules/test/unit/social/Makefile.in
Normal file
11
browser/modules/test/unit/social/Makefile.in
Normal file
@ -0,0 +1,11 @@
|
||||
# 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/.
|
||||
|
||||
XPCSHELL_RESOURCES = \
|
||||
xpcshell.ini \
|
||||
head.js \
|
||||
blocklist.xml \
|
||||
test_social.js \
|
||||
test_socialDisabledStartup.js \
|
||||
$(NULL)
|
6
browser/modules/test/unit/social/blocklist.xml
Normal file
6
browser/modules/test/unit/social/blocklist.xml
Normal file
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0"?>
|
||||
<blocklist xmlns="http://www.mozilla.org/2006/addons-blocklist">
|
||||
<emItems>
|
||||
<emItem blockID="s1" id="bad.com@services.mozilla.org"></emItem>
|
||||
</emItems>
|
||||
</blocklist>
|
146
browser/modules/test/unit/social/head.js
Normal file
146
browser/modules/test/unit/social/head.js
Normal file
@ -0,0 +1,146 @@
|
||||
/* 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/. */
|
||||
|
||||
const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
var Social, SocialService;
|
||||
|
||||
let manifests = [
|
||||
{
|
||||
name: "provider 1",
|
||||
origin: "https://example1.com",
|
||||
sidebarURL: "https://example1.com/sidebar/",
|
||||
},
|
||||
{
|
||||
name: "provider 2",
|
||||
origin: "https://example2.com",
|
||||
sidebarURL: "https://example1.com/sidebar/",
|
||||
}
|
||||
];
|
||||
|
||||
const MANIFEST_PREFS = Services.prefs.getBranch("social.manifest.");
|
||||
|
||||
// SocialProvider class relies on blocklisting being enabled. To enable
|
||||
// blocklisting, we have to setup an app and initialize the blocklist (see
|
||||
// initApp below).
|
||||
const gProfD = do_get_profile();
|
||||
|
||||
const XULAPPINFO_CONTRACTID = "@mozilla.org/xre/app-info;1";
|
||||
const XULAPPINFO_CID = Components.ID("{c763b610-9d49-455a-bbd2-ede71682a1ac}");
|
||||
|
||||
function createAppInfo(id, name, version, platformVersion) {
|
||||
gAppInfo = {
|
||||
// nsIXULAppInfo
|
||||
vendor: "Mozilla",
|
||||
name: name,
|
||||
ID: id,
|
||||
version: version,
|
||||
appBuildID: "2007010101",
|
||||
platformVersion: platformVersion ? platformVersion : "1.0",
|
||||
platformBuildID: "2007010101",
|
||||
|
||||
// nsIXULRuntime
|
||||
inSafeMode: false,
|
||||
logConsoleErrors: true,
|
||||
OS: "XPCShell",
|
||||
XPCOMABI: "noarch-spidermonkey",
|
||||
invalidateCachesOnRestart: function invalidateCachesOnRestart() {
|
||||
// Do nothing
|
||||
},
|
||||
|
||||
// nsICrashReporter
|
||||
annotations: {},
|
||||
|
||||
annotateCrashReport: function(key, data) {
|
||||
this.annotations[key] = data;
|
||||
},
|
||||
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIXULAppInfo,
|
||||
Ci.nsIXULRuntime,
|
||||
Ci.nsICrashReporter,
|
||||
Ci.nsISupports])
|
||||
};
|
||||
|
||||
var XULAppInfoFactory = {
|
||||
createInstance: function (outer, iid) {
|
||||
if (outer != null)
|
||||
throw Components.results.NS_ERROR_NO_AGGREGATION;
|
||||
return gAppInfo.QueryInterface(iid);
|
||||
}
|
||||
};
|
||||
var registrar = Components.manager.QueryInterface(Ci.nsIComponentRegistrar);
|
||||
registrar.registerFactory(XULAPPINFO_CID, "XULAppInfo",
|
||||
XULAPPINFO_CONTRACTID, XULAppInfoFactory);
|
||||
}
|
||||
|
||||
function initApp() {
|
||||
createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "1.9");
|
||||
// prepare a blocklist file for the blocklist service
|
||||
var blocklistFile = gProfD.clone();
|
||||
blocklistFile.append("blocklist.xml");
|
||||
if (blocklistFile.exists())
|
||||
blocklistFile.remove(false);
|
||||
var source = do_get_file("blocklist.xml");
|
||||
source.copyTo(gProfD, "blocklist.xml");
|
||||
}
|
||||
|
||||
function setManifestPref(manifest) {
|
||||
let string = Cc["@mozilla.org/supports-string;1"].
|
||||
createInstance(Ci.nsISupportsString);
|
||||
string.data = JSON.stringify(manifest);
|
||||
Services.prefs.setComplexValue("social.manifest." + manifest.origin, Ci.nsISupportsString, string);
|
||||
}
|
||||
|
||||
function do_wait_observer(topic, cb) {
|
||||
function observer(subject, topic, data) {
|
||||
Services.obs.removeObserver(observer, topic);
|
||||
cb();
|
||||
}
|
||||
Services.obs.addObserver(observer, topic, false);
|
||||
}
|
||||
|
||||
function do_initialize_social(enabledOnStartup, cb) {
|
||||
initApp();
|
||||
|
||||
manifests.forEach(function (manifest) {
|
||||
setManifestPref(manifest);
|
||||
});
|
||||
// Set both providers active and flag the first one as "current"
|
||||
let activeVal = Cc["@mozilla.org/supports-string;1"].
|
||||
createInstance(Ci.nsISupportsString);
|
||||
let active = {};
|
||||
for (let m of manifests)
|
||||
active[m.origin] = 1;
|
||||
activeVal.data = JSON.stringify(active);
|
||||
Services.prefs.setComplexValue("social.activeProviders",
|
||||
Ci.nsISupportsString, activeVal);
|
||||
Services.prefs.setCharPref("social.provider.current", manifests[0].origin);
|
||||
Services.prefs.setBoolPref("social.enabled", enabledOnStartup);
|
||||
|
||||
do_register_cleanup(function() {
|
||||
manifests.forEach(function (manifest) {
|
||||
Services.prefs.clearUserPref("social.manifest." + manifest.origin);
|
||||
});
|
||||
Services.prefs.clearUserPref("social.enabled");
|
||||
Services.prefs.clearUserPref("social.provider.current");
|
||||
Services.prefs.clearUserPref("social.activeProviders");
|
||||
});
|
||||
|
||||
// expecting 2 providers installed
|
||||
do_wait_observer("social:providers-changed", function() {
|
||||
do_check_eq(Social.providers.length, 2, "2 providers installed");
|
||||
cb();
|
||||
});
|
||||
|
||||
// import and initialize everything
|
||||
SocialService = Cu.import("resource://gre/modules/SocialService.jsm", {}).SocialService;
|
||||
do_check_eq(SocialService.enabled, enabledOnStartup, "service is doing its thing");
|
||||
do_check_true(SocialService.hasEnabledProviders, "Service has enabled providers");
|
||||
Social = Cu.import("resource:///modules/Social.jsm", {}).Social;
|
||||
do_check_false(Social.initialized, "Social is not initialized");
|
||||
Social.init();
|
||||
do_check_true(Social.initialized, "Social is initialized");
|
||||
}
|
6
browser/modules/test/unit/social/moz.build
Normal file
6
browser/modules/test/unit/social/moz.build
Normal file
@ -0,0 +1,6 @@
|
||||
# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
|
||||
# vim: set filetype=python:
|
||||
# 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/.
|
||||
|
34
browser/modules/test/unit/social/test_social.js
Normal file
34
browser/modules/test/unit/social/test_social.js
Normal file
@ -0,0 +1,34 @@
|
||||
/* 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/. */
|
||||
|
||||
function run_test() {
|
||||
// we are testing worker startup specifically
|
||||
Services.prefs.setBoolPref("social.allowMultipleWorkers", true);
|
||||
do_register_cleanup(function() {
|
||||
Services.prefs.clearUserPref("social.allowMultipleWorkers");
|
||||
});
|
||||
do_test_pending();
|
||||
add_test(testStartupEnabled);
|
||||
add_test(testDisableAfterStartup);
|
||||
do_initialize_social(true, run_next_test);
|
||||
}
|
||||
|
||||
function testStartupEnabled() {
|
||||
// wait on startup before continuing
|
||||
do_check_eq(Social.providers.length, 2, "two social providers enabled");
|
||||
do_check_true(Social.providers[0].enabled, "provider is enabled");
|
||||
do_check_true(Social.providers[1].enabled, "provider is enabled");
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
function testDisableAfterStartup() {
|
||||
do_wait_observer("social:provider-set", function() {
|
||||
do_check_eq(Social.enabled, false, "Social is disabled");
|
||||
do_check_false(Social.providers[0].enabled, "provider is enabled");
|
||||
do_check_false(Social.providers[1].enabled, "provider is enabled");
|
||||
do_test_finished();
|
||||
run_next_test();
|
||||
});
|
||||
Social.enabled = false;
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
/* 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/. */
|
||||
|
||||
function run_test() {
|
||||
// we are testing worker startup specifically
|
||||
Services.prefs.setBoolPref("social.allowMultipleWorkers", true);
|
||||
do_register_cleanup(function() {
|
||||
Services.prefs.clearUserPref("social.allowMultipleWorkers");
|
||||
});
|
||||
do_test_pending();
|
||||
add_test(testStartupDisabled);
|
||||
add_test(testEnableAfterStartup);
|
||||
do_initialize_social(false, run_next_test);
|
||||
}
|
||||
|
||||
function testStartupDisabled() {
|
||||
// wait on startup before continuing
|
||||
do_check_eq(Social.providers.length, 2, "two social providers available");
|
||||
do_check_false(Social.providers[0].enabled, "provider is enabled");
|
||||
do_check_false(Social.providers[1].enabled, "provider is enabled");
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
function testEnableAfterStartup() {
|
||||
do_wait_observer("social:provider-set", function() {
|
||||
do_check_true(Social.enabled, "Social is enabled");
|
||||
do_check_eq(Social.providers.length, 2, "two social providers available");
|
||||
do_check_true(Social.providers[0].enabled, "provider is enabled");
|
||||
do_check_true(Social.providers[1].enabled, "provider is enabled");
|
||||
do_test_finished();
|
||||
run_next_test();
|
||||
});
|
||||
Social.enabled = true;
|
||||
}
|
8
browser/modules/test/unit/social/xpcshell.ini
Normal file
8
browser/modules/test/unit/social/xpcshell.ini
Normal file
@ -0,0 +1,8 @@
|
||||
[DEFAULT]
|
||||
head = head.js
|
||||
tail =
|
||||
firefox-appdir = browser
|
||||
|
||||
[test_social.js]
|
||||
|
||||
[test_socialDisabledStartup.js]
|
@ -230,6 +230,7 @@ browser.jar:
|
||||
skin/classic/browser/devtools/app-manager/index.css (../shared/devtools/app-manager/index.css)
|
||||
skin/classic/browser/devtools/app-manager/device.css (../shared/devtools/app-manager/device.css)
|
||||
skin/classic/browser/devtools/app-manager/projects.css (../shared/devtools/app-manager/projects.css)
|
||||
skin/classic/browser/devtools/app-manager/help.css (../shared/devtools/app-manager/help.css)
|
||||
skin/classic/browser/devtools/app-manager/warning.svg (../shared/devtools/app-manager/images/warning.svg)
|
||||
skin/classic/browser/devtools/app-manager/error.svg (../shared/devtools/app-manager/images/error.svg)
|
||||
skin/classic/browser/devtools/app-manager/plus.svg (../shared/devtools/app-manager/images/plus.svg)
|
||||
|
@ -320,6 +320,7 @@ browser.jar:
|
||||
skin/classic/browser/devtools/app-manager/index.css (../shared/devtools/app-manager/index.css)
|
||||
skin/classic/browser/devtools/app-manager/device.css (../shared/devtools/app-manager/device.css)
|
||||
skin/classic/browser/devtools/app-manager/projects.css (../shared/devtools/app-manager/projects.css)
|
||||
skin/classic/browser/devtools/app-manager/help.css (../shared/devtools/app-manager/help.css)
|
||||
skin/classic/browser/devtools/app-manager/warning.svg (../shared/devtools/app-manager/images/warning.svg)
|
||||
skin/classic/browser/devtools/app-manager/error.svg (../shared/devtools/app-manager/images/error.svg)
|
||||
skin/classic/browser/devtools/app-manager/plus.svg (../shared/devtools/app-manager/images/plus.svg)
|
||||
|
@ -206,3 +206,17 @@ button.action-cancel {
|
||||
#banner-simulators:not([simulator-count="0"]) .no-simulator {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#connection-no-device,
|
||||
[device-count="0"] > #connection-found-device,
|
||||
#connection-manual,
|
||||
#connection-assisted {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#connection-found-device,
|
||||
[device-count="0"] > #connection-no-device,
|
||||
[adb-available="true"] > #connection-assisted,
|
||||
[adb-available="false"] > #connection-manual {
|
||||
display: inline;
|
||||
}
|
||||
|
40
browser/themes/shared/devtools/app-manager/help.css
Normal file
40
browser/themes/shared/devtools/app-manager/help.css
Normal file
@ -0,0 +1,40 @@
|
||||
/* 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/. */
|
||||
|
||||
html, body {
|
||||
margin: 0;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
color: #555;
|
||||
font-family: Lucida Grande, Helvetica, Helvetica Neue, sans-serif;
|
||||
overflow: hidden;
|
||||
max-width: 600px;
|
||||
margin: auto;
|
||||
padding: 20px 0;
|
||||
background-color: #FFF;
|
||||
}
|
||||
|
||||
button {
|
||||
border: 1px solid #CCC;
|
||||
padding: 5px 15px;
|
||||
cursor: pointer;
|
||||
background: rgba(255,255,255,0.4);
|
||||
text-transform: uppercase;
|
||||
color: #3498DB;
|
||||
}
|
||||
|
||||
button:hover {
|
||||
background-color: #3498DB;
|
||||
color: #FFF;
|
||||
}
|
||||
|
||||
a, a:visited {
|
||||
color: rgb(39,109,163);
|
||||
}
|
||||
|
||||
#close-button {
|
||||
float: right;
|
||||
}
|
@ -1,55 +1,81 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 17.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
width="160px" height="160px" viewBox="0 0 160 160" enable-background="new 0 0 160 160" xml:space="preserve">
|
||||
<rect display="none" fill="#22272D" width="84" height="160"/>
|
||||
<rect x="80.75" display="none" fill="#194866" width="84" height="160"/>
|
||||
<path fill="#414042" d="M40,21.799c-2.044,0.001-6.042,6.745-7.404,13.436L28,39.83v12l3.204,0l4.467-4.467
|
||||
c0.457,0.478,0.96,0.88,1.5,1.199h5.652c0.543-0.318,1.05-0.719,1.507-1.199l4.466,4.467l3.204,0v-12l-4.597-4.596
|
||||
C46.042,28.544,42.044,21.799,40,21.799z M40.005,28.834c0.712,0,1.965,2,2.746,4.392c-0.846-0.157-1.747-0.244-2.686-0.244
|
||||
c-0.987,0-1.933,0.099-2.815,0.271C38.03,30.849,39.289,28.834,40.005,28.834z"/>
|
||||
<path fill="#414042" d="M41.436,51.63c0,1.41-1.094,2.553-1.459,2.553c-0.364,0-1.459-1.144-1.459-2.553
|
||||
c0-0.546,0.099-1.051,0.266-1.466h-1.69c-0.198,0.731-0.31,1.549-0.31,2.412c0,3.108,2.411,5.627,3.215,5.627
|
||||
s3.216-2.519,3.215-5.626c0-0.864-0.112-1.681-0.31-2.413l-1.734,0C41.337,50.578,41.436,51.083,41.436,51.63z"/>
|
||||
<g>
|
||||
<g>
|
||||
<path fill="#B2B5B9" d="M40,21.799c-2.044,0.001-6.042,6.745-7.404,13.436L28,39.83v12l3.204,0l4.467-4.467
|
||||
c0.457,0.478,0.96,0.88,1.5,1.199h5.652c0.543-0.318,1.05-0.719,1.507-1.199l4.466,4.467l3.204,0v-12l-4.597-4.596
|
||||
C46.042,28.544,42.044,21.799,40,21.799z M40.005,28.834c0.712,0,1.965,2,2.746,4.392c-0.846-0.157-1.747-0.244-2.686-0.244
|
||||
c-0.987,0-1.933,0.099-2.815,0.271C38.03,30.849,39.289,28.834,40.005,28.834z"/>
|
||||
<path fill="#B2B5B9" d="M41.436,51.63c0,1.41-1.094,2.553-1.459,2.553c-0.364,0-1.459-1.144-1.459-2.553
|
||||
c0-0.546,0.099-1.051,0.266-1.466h-1.69c-0.198,0.731-0.31,1.549-0.31,2.412c0,3.108,2.411,5.627,3.215,5.627
|
||||
s3.216-2.519,3.215-5.626c0-0.864-0.112-1.681-0.31-2.413l-1.734,0C41.337,50.578,41.436,51.083,41.436,51.63z"/>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<path fill="#DCE8F3" d="M120,21.799c-2.044,0.001-6.042,6.745-7.404,13.436L108,39.83v12l3.204,0l4.467-4.467
|
||||
c0.457,0.478,0.96,0.88,1.5,1.199h5.652c0.543-0.318,1.05-0.719,1.507-1.199l4.467,4.467l3.204,0v-12l-4.597-4.596
|
||||
C126.042,28.544,122.044,21.799,120,21.799z M120.005,28.834c0.712,0,1.965,2,2.746,4.392c-0.846-0.157-1.747-0.244-2.686-0.244
|
||||
c-0.987,0-1.933,0.099-2.815,0.271C118.03,30.849,119.289,28.834,120.005,28.834z"/>
|
||||
<path fill="#DCE8F3" d="M121.436,51.63c0,1.41-1.094,2.553-1.459,2.553c-0.364,0-1.459-1.144-1.459-2.553
|
||||
c0-0.546,0.099-1.051,0.266-1.466h-1.69c-0.198,0.731-0.31,1.549-0.31,2.412c0,3.108,2.411,5.627,3.215,5.627
|
||||
s3.216-2.519,3.215-5.626c0-0.864-0.112-1.681-0.31-2.413l-1.734,0C121.337,50.578,121.436,51.083,121.436,51.63z"/>
|
||||
</g>
|
||||
<g>
|
||||
<g>
|
||||
<path fill="#B2B5B9" d="M52.5,136.667c0,2.279-1.888,4.167-4.167,4.167H31.667c-2.279,0-4.167-1.888-4.167-4.167v-33.333
|
||||
c0-2.279,1.888-4.167,4.167-4.167h16.667c2.279,0,4.167,1.888,4.167,4.167V136.667z M49.375,108.542
|
||||
c0-0.554-0.488-1.042-1.042-1.042H31.667c-0.553,0-1.042,0.488-1.042,1.042v22.917c0,0.554,0.488,1.042,1.042,1.042h16.667
|
||||
c0.553,0,1.042-0.488,1.042-1.042V108.542z M42.604,103.333h-5.208c-0.293,0-0.521,0.228-0.521,0.521
|
||||
c0,0.293,0.228,0.521,0.521,0.521h5.208c0.293,0,0.521-0.228,0.521-0.521C43.125,103.561,42.897,103.333,42.604,103.333z
|
||||
M40,134.062c-1.432,0-2.604,1.171-2.604,2.604c0,1.433,1.172,2.604,2.604,2.604s2.604-1.171,2.604-2.604
|
||||
C42.604,135.234,41.432,134.062,40,134.062z"/>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<path fill="#DCE8F3" d="M132.5,136.667c0,2.279-1.888,4.167-4.167,4.167h-16.667c-2.279,0-4.167-1.888-4.167-4.167v-33.333
|
||||
c0-2.279,1.888-4.167,4.167-4.167h16.667c2.279,0,4.167,1.888,4.167,4.167V136.667z M129.375,108.542
|
||||
c0-0.554-0.488-1.042-1.042-1.042h-16.667c-0.553,0-1.042,0.488-1.042,1.042v22.917c0,0.554,0.488,1.042,1.042,1.042h16.667
|
||||
c0.553,0,1.042-0.488,1.042-1.042V108.542z M122.604,103.333h-5.208c-0.293,0-0.521,0.228-0.521,0.521
|
||||
c0,0.293,0.228,0.521,0.521,0.521h5.208c0.293,0,0.521-0.228,0.521-0.521C123.125,103.561,122.897,103.333,122.604,103.333z
|
||||
M120,134.062c-1.432,0-2.604,1.171-2.604,2.604c0,1.433,1.172,2.604,2.604,2.604s2.604-1.171,2.604-2.604
|
||||
C122.604,135.234,121.432,134.062,120,134.062z"/>
|
||||
</g>
|
||||
</svg>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 17.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
width="160px" height="240px" viewBox="0 0 160 240" enable-background="new 0 0 160 240" xml:space="preserve">
|
||||
<rect y="40" display="none" fill="#22272D" width="84" height="160"/>
|
||||
<rect x="80.75" y="40" display="none" fill="#194866" width="84" height="160"/>
|
||||
<path fill="#414042" d="M40,21.149c-2.044,0.001-6.042,6.745-7.404,13.436L28,39.181v12l3.204,0l4.467-4.466
|
||||
c0.457,0.478,0.96,0.88,1.5,1.199h5.652c0.543-0.318,1.05-0.719,1.507-1.199l4.466,4.466l3.204,0v-12l-4.597-4.596
|
||||
C46.042,27.895,42.044,21.149,40,21.149z M40.005,28.185c0.712,0,1.965,2,2.746,4.392c-0.846-0.157-1.747-0.244-2.686-0.244
|
||||
c-0.987,0-1.933,0.099-2.815,0.271C38.03,30.199,39.289,28.185,40.005,28.185z"/>
|
||||
<path fill="#414042" d="M41.436,50.98c0,1.41-1.094,2.553-1.459,2.553c-0.364,0-1.459-1.144-1.459-2.553
|
||||
c0-0.546,0.099-1.051,0.266-1.466h-1.69c-0.198,0.731-0.31,1.549-0.31,2.412c0,3.108,2.411,5.627,3.215,5.627
|
||||
s3.216-2.519,3.215-5.626c0-0.864-0.112-1.681-0.31-2.413l-1.734,0C41.337,49.929,41.436,50.434,41.436,50.98z"/>
|
||||
<g>
|
||||
<g>
|
||||
<path fill="#B2B5B9" d="M40,21.149c-2.044,0.001-6.042,6.745-7.404,13.436L28,39.181v12l3.204,0l4.467-4.466
|
||||
c0.457,0.478,0.96,0.88,1.5,1.199h5.652c0.543-0.318,1.05-0.719,1.507-1.199l4.466,4.466l3.204,0v-12l-4.597-4.596
|
||||
C46.042,27.895,42.044,21.149,40,21.149z M40.005,28.185c0.712,0,1.965,2,2.746,4.392c-0.846-0.157-1.747-0.244-2.686-0.244
|
||||
c-0.987,0-1.933,0.099-2.815,0.271C38.03,30.199,39.289,28.185,40.005,28.185z"/>
|
||||
<path fill="#B2B5B9" d="M41.436,50.98c0,1.41-1.094,2.553-1.459,2.553c-0.364,0-1.459-1.144-1.459-2.553
|
||||
c0-0.546,0.099-1.051,0.266-1.466h-1.69c-0.198,0.731-0.31,1.549-0.31,2.412c0,3.108,2.411,5.627,3.215,5.627
|
||||
s3.216-2.519,3.215-5.626c0-0.864-0.112-1.681-0.31-2.413l-1.734,0C41.337,49.929,41.436,50.434,41.436,50.98z"/>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<path fill="#DCE8F3" d="M120,21.149c-2.044,0.001-6.042,6.745-7.404,13.436L108,39.181v12l3.204,0l4.467-4.466
|
||||
c0.457,0.478,0.96,0.88,1.5,1.199h5.652c0.543-0.318,1.05-0.719,1.507-1.199l4.467,4.466l3.204,0v-12l-4.597-4.596
|
||||
C126.042,27.895,122.044,21.149,120,21.149z M120.005,28.185c0.712,0,1.965,2,2.746,4.392c-0.846-0.157-1.747-0.244-2.686-0.244
|
||||
c-0.987,0-1.933,0.099-2.815,0.271C118.03,30.199,119.289,28.185,120.005,28.185z"/>
|
||||
<path fill="#DCE8F3" d="M121.436,50.98c0,1.41-1.094,2.553-1.459,2.553c-0.364,0-1.459-1.144-1.459-2.553
|
||||
c0-0.546,0.099-1.051,0.266-1.466h-1.69c-0.198,0.731-0.31,1.549-0.31,2.412c0,3.108,2.411,5.627,3.215,5.627
|
||||
s3.216-2.519,3.215-5.626c0-0.864-0.112-1.681-0.31-2.413l-1.734,0C121.337,49.929,121.436,50.434,121.436,50.98z"/>
|
||||
</g>
|
||||
<g>
|
||||
<g>
|
||||
<path fill="#B2B5B9" d="M52.5,136.017c0,2.279-1.888,4.167-4.167,4.167H31.667c-2.279,0-4.167-1.888-4.167-4.167v-33.333
|
||||
c0-2.279,1.888-4.167,4.167-4.167h16.667c2.279,0,4.167,1.888,4.167,4.167V136.017z M49.375,107.892
|
||||
c0-0.554-0.488-1.042-1.042-1.042H31.667c-0.553,0-1.042,0.488-1.042,1.042v22.917c0,0.554,0.488,1.042,1.042,1.042h16.667
|
||||
c0.553,0,1.042-0.488,1.042-1.042V107.892z M42.604,102.684h-5.208c-0.293,0-0.521,0.228-0.521,0.521
|
||||
c0,0.293,0.228,0.521,0.521,0.521h5.208c0.293,0,0.521-0.228,0.521-0.521C43.125,102.912,42.897,102.684,42.604,102.684z
|
||||
M40,133.413c-1.432,0-2.604,1.171-2.604,2.604c0,1.433,1.172,2.604,2.604,2.604s2.604-1.171,2.604-2.604
|
||||
C42.604,134.585,41.432,133.413,40,133.413z"/>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<path fill="#DCE8F3" d="M132.5,136.017c0,2.279-1.888,4.167-4.167,4.167h-16.667c-2.279,0-4.167-1.888-4.167-4.167v-33.333
|
||||
c0-2.279,1.888-4.167,4.167-4.167h16.667c2.279,0,4.167,1.888,4.167,4.167V136.017z M129.375,107.892
|
||||
c0-0.554-0.488-1.042-1.042-1.042h-16.667c-0.553,0-1.042,0.488-1.042,1.042v22.917c0,0.554,0.488,1.042,1.042,1.042h16.667
|
||||
c0.553,0,1.042-0.488,1.042-1.042V107.892z M122.604,102.684h-5.208c-0.293,0-0.521,0.228-0.521,0.521
|
||||
c0,0.293,0.228,0.521,0.521,0.521h5.208c0.293,0,0.521-0.228,0.521-0.521C123.125,102.912,122.897,102.684,122.604,102.684z
|
||||
M120,133.413c-1.432,0-2.604,1.171-2.604,2.604c0,1.433,1.172,2.604,2.604,2.604s2.604-1.171,2.604-2.604
|
||||
C122.604,134.585,121.432,133.413,120,133.413z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path fill="#B2B5B9" d="M40,185.388c8.121,0,14.729,6.607,14.729,14.729S48.121,214.845,40,214.845s-14.729-6.607-14.729-14.729
|
||||
S31.879,185.388,40,185.388 M40,182.75c-9.591,0-17.367,7.775-17.367,17.367c0,9.591,7.775,17.367,17.367,17.367
|
||||
s17.367-7.775,17.367-17.367C57.367,190.525,49.591,182.75,40,182.75L40,182.75z"/>
|
||||
<g>
|
||||
<path fill="#B2B5B9" d="M39.565,204.504c-0.688,0-1.196-0.508-1.286-1.195l-0.299-2.57c-0.12-0.808,0.359-1.405,1.166-1.495
|
||||
c2.81-0.269,4.364-1.345,4.364-3.229v-0.06c0-1.674-1.285-2.84-3.438-2.84c-1.584,0-2.87,0.568-4.065,1.645
|
||||
c-0.299,0.239-0.688,0.418-1.106,0.418c-0.926,0-1.674-0.747-1.674-1.644c0-0.448,0.18-0.927,0.598-1.285
|
||||
c1.584-1.495,3.587-2.481,6.337-2.481c4.185,0,7.024,2.331,7.024,6.068v0.06c0,3.767-2.72,5.47-6.038,6.038l-0.12,1.375
|
||||
c-0.12,0.657-0.598,1.195-1.285,1.195H39.565z M39.565,206.687c1.226,0,2.122,0.896,2.122,2.062v0.299
|
||||
c0,1.166-0.896,2.062-2.122,2.062s-2.123-0.896-2.123-2.062v-0.299C37.442,207.583,38.339,206.687,39.565,206.687z"/>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<path fill="#DCE8F3" d="M120,185.388c8.121,0,14.729,6.607,14.729,14.729s-6.607,14.729-14.729,14.729s-14.729-6.607-14.729-14.729
|
||||
S111.879,185.388,120,185.388 M120,182.75c-9.591,0-17.367,7.775-17.367,17.367c0,9.591,7.775,17.367,17.367,17.367
|
||||
s17.367-7.775,17.367-17.367C137.367,190.525,129.591,182.75,120,182.75L120,182.75z"/>
|
||||
<g>
|
||||
<path fill="#DCE8F3" d="M119.564,204.504c-0.688,0-1.195-0.508-1.285-1.195l-0.299-2.57c-0.12-0.808,0.358-1.405,1.166-1.495
|
||||
c2.81-0.269,4.363-1.345,4.363-3.229v-0.06c0-1.674-1.285-2.84-3.438-2.84c-1.584,0-2.869,0.568-4.064,1.645
|
||||
c-0.3,0.239-0.688,0.418-1.106,0.418c-0.927,0-1.674-0.747-1.674-1.644c0-0.448,0.18-0.927,0.598-1.285
|
||||
c1.584-1.495,3.587-2.481,6.337-2.481c4.186,0,7.024,2.331,7.024,6.068v0.06c0,3.767-2.72,5.47-6.038,6.038l-0.119,1.375
|
||||
c-0.12,0.657-0.598,1.195-1.285,1.195H119.564z M119.564,206.687c1.226,0,2.122,0.896,2.122,2.062v0.299
|
||||
c0,1.166-0.896,2.062-2.122,2.062s-2.122-0.896-2.122-2.062v-0.299C117.442,207.583,118.339,206.687,119.564,206.687z"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 4.3 KiB After Width: | Height: | Size: 6.3 KiB |
@ -67,13 +67,25 @@
|
||||
background-image: url('chrome://browser/skin/devtools/app-manager/index-icons.svg');
|
||||
background-position: left -85px, top left;
|
||||
background-repeat: no-repeat, no-repeat;
|
||||
background-size: 160px 160px, 2px 80px;
|
||||
background-size: 160px 240px, 2px 80px;
|
||||
}
|
||||
|
||||
.device-button[selected] {
|
||||
background-position: right -85px, top left;
|
||||
}
|
||||
|
||||
.help-button {
|
||||
border-bottom: 0;
|
||||
background-image: url('chrome://browser/skin/devtools/app-manager/index-icons.svg');
|
||||
background-position: left -165px, top left;
|
||||
background-repeat: no-repeat, no-repeat;
|
||||
background-size: 160px 240px, 2px 80px;
|
||||
}
|
||||
|
||||
.help-button[selected] {
|
||||
background-position: right -165px, top left;
|
||||
}
|
||||
|
||||
#connection-footer {
|
||||
border-width: 0;
|
||||
height: 50px;
|
||||
|
@ -22,7 +22,6 @@ body {
|
||||
color: #333;
|
||||
background-color: white;
|
||||
font-family: Lucida Grande, Helvetica, Helvetica Neue, sans-serif;
|
||||
display: flex;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
@ -359,31 +358,11 @@ strong {
|
||||
color: #FFF;
|
||||
}
|
||||
|
||||
.project-button-install,
|
||||
.project-button-start {
|
||||
color: #18BC9C
|
||||
}
|
||||
|
||||
.project-button-install:hover,
|
||||
.project-button-start:hover {
|
||||
background-color: #18BC9C;
|
||||
color: #FFF;
|
||||
}
|
||||
|
||||
.project-button-stop {
|
||||
color: #E74C3C;
|
||||
}
|
||||
|
||||
.project-button-stop:hover {
|
||||
background-color: #E74C3C;
|
||||
color: #FFF;
|
||||
}
|
||||
|
||||
.project-button-refresh {
|
||||
.project-button-update {
|
||||
color: #777;
|
||||
}
|
||||
|
||||
.project-button-refresh:hover {
|
||||
.project-button-update:hover {
|
||||
background-color: #777;
|
||||
color: #FFF;
|
||||
}
|
||||
|
@ -257,6 +257,7 @@ browser.jar:
|
||||
skin/classic/browser/devtools/app-manager/index.css (../shared/devtools/app-manager/index.css)
|
||||
skin/classic/browser/devtools/app-manager/device.css (../shared/devtools/app-manager/device.css)
|
||||
skin/classic/browser/devtools/app-manager/projects.css (../shared/devtools/app-manager/projects.css)
|
||||
skin/classic/browser/devtools/app-manager/help.css (../shared/devtools/app-manager/help.css)
|
||||
skin/classic/browser/devtools/app-manager/warning.svg (../shared/devtools/app-manager/images/warning.svg)
|
||||
skin/classic/browser/devtools/app-manager/error.svg (../shared/devtools/app-manager/images/error.svg)
|
||||
skin/classic/browser/devtools/app-manager/plus.svg (../shared/devtools/app-manager/images/plus.svg)
|
||||
@ -531,6 +532,7 @@ browser.jar:
|
||||
skin/classic/aero/browser/devtools/app-manager/index.css (../shared/devtools/app-manager/index.css)
|
||||
skin/classic/aero/browser/devtools/app-manager/device.css (../shared/devtools/app-manager/device.css)
|
||||
skin/classic/aero/browser/devtools/app-manager/projects.css (../shared/devtools/app-manager/projects.css)
|
||||
skin/classic/aero/browser/devtools/app-manager/help.css (../shared/devtools/app-manager/help.css)
|
||||
skin/classic/aero/browser/devtools/app-manager/warning.svg (../shared/devtools/app-manager/images/warning.svg)
|
||||
skin/classic/aero/browser/devtools/app-manager/error.svg (../shared/devtools/app-manager/images/error.svg)
|
||||
skin/classic/aero/browser/devtools/app-manager/plus.svg (../shared/devtools/app-manager/images/plus.svg)
|
||||
|
@ -325,6 +325,8 @@ BluetoothA2dpManager::HandleSinkPropertyChanged(const BluetoothSignal& aSignal)
|
||||
OnDisconnect(EmptyString());
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -341,7 +343,7 @@ BluetoothA2dpManager::NotifyConnectionStatusChanged()
|
||||
if (NS_FAILED(obs->NotifyObservers(this,
|
||||
BLUETOOTH_A2DP_STATUS_CHANGED_ID,
|
||||
mDeviceAddress.get()))) {
|
||||
NS_WARNING("Failed to notify bluetooth-a2dp-status-changed observsers!");
|
||||
BT_WARNING("Failed to notify bluetooth-a2dp-status-changed observsers!");
|
||||
}
|
||||
|
||||
// Dispatch an event of status change
|
||||
|
@ -44,10 +44,15 @@ public:
|
||||
virtual void OnConnect(const nsAString& aErrorStr) MOZ_OVERRIDE;
|
||||
virtual void OnDisconnect(const nsAString& aErrorStr) MOZ_OVERRIDE;
|
||||
|
||||
// A2DP member functions
|
||||
virtual void GetName(nsACString& aName)
|
||||
{
|
||||
aName.AssignLiteral("A2DP");
|
||||
}
|
||||
|
||||
// A2DP-specific functions
|
||||
void HandleSinkPropertyChanged(const BluetoothSignal& aSignal);
|
||||
|
||||
// AVRCP member functions
|
||||
// AVRCP-specific functions
|
||||
void SetAvrcpConnected(bool aConnected);
|
||||
bool IsAvrcpConnected();
|
||||
void UpdateMetaData(const nsAString& aTitle,
|
||||
|
@ -73,7 +73,7 @@ public:
|
||||
|
||||
const BluetoothValue& v = mReply->get_BluetoothReplySuccess().value();
|
||||
if (v.type() != BluetoothValue::TArrayOfBluetoothNamedValue) {
|
||||
NS_WARNING("Not a BluetoothNamedValue array!");
|
||||
BT_WARNING("Not a BluetoothNamedValue array!");
|
||||
SetError(NS_LITERAL_STRING("BluetoothReplyTypeError"));
|
||||
return false;
|
||||
}
|
||||
@ -86,7 +86,7 @@ public:
|
||||
for (uint32_t i = 0; i < values.Length(); i++) {
|
||||
const BluetoothValue properties = values[i].value();
|
||||
if (properties.type() != BluetoothValue::TArrayOfBluetoothNamedValue) {
|
||||
NS_WARNING("Not a BluetoothNamedValue array!");
|
||||
BT_WARNING("Not a BluetoothNamedValue array!");
|
||||
SetError(NS_LITERAL_STRING("BluetoothReplyTypeError"));
|
||||
return false;
|
||||
}
|
||||
@ -100,7 +100,7 @@ public:
|
||||
nsresult rv;
|
||||
nsIScriptContext* sc = mAdapterPtr->GetContextForEventHandlers(&rv);
|
||||
if (!sc) {
|
||||
NS_WARNING("Cannot create script context!");
|
||||
BT_WARNING("Cannot create script context!");
|
||||
SetError(NS_LITERAL_STRING("BluetoothScriptContextError"));
|
||||
return false;
|
||||
}
|
||||
@ -108,7 +108,7 @@ public:
|
||||
AutoPushJSContext cx(sc->GetNativeContext());
|
||||
rv = nsTArrayToJSArray(cx, devices, &JsDevices);
|
||||
if (!JsDevices) {
|
||||
NS_WARNING("Cannot create JS array!");
|
||||
BT_WARNING("Cannot create JS array!");
|
||||
SetError(NS_LITERAL_STRING("BluetoothError"));
|
||||
return false;
|
||||
}
|
||||
@ -142,7 +142,7 @@ public:
|
||||
|
||||
const BluetoothValue& v = mReply->get_BluetoothReplySuccess().value();
|
||||
if (v.type() != BluetoothValue::Tbool) {
|
||||
NS_WARNING("Not a boolean!");
|
||||
BT_WARNING("Not a boolean!");
|
||||
SetError(NS_LITERAL_STRING("BluetoothReplyTypeError"));
|
||||
return false;
|
||||
}
|
||||
@ -252,7 +252,7 @@ BluetoothAdapter::SetPropertyByValue(const BluetoothNamedValue& aValue)
|
||||
AutoPushJSContext cx(sc->GetNativeContext());
|
||||
JS::Rooted<JSObject*> uuids(cx);
|
||||
if (NS_FAILED(nsTArrayToJSArray(cx, mUuids, uuids.address()))) {
|
||||
NS_WARNING("Cannot set JS UUIDs object!");
|
||||
BT_WARNING("Cannot set JS UUIDs object!");
|
||||
return;
|
||||
}
|
||||
mJsUuids = uuids;
|
||||
@ -273,7 +273,7 @@ BluetoothAdapter::SetPropertyByValue(const BluetoothNamedValue& aValue)
|
||||
JS::Rooted<JSObject*> deviceAddresses(cx);
|
||||
if (NS_FAILED(nsTArrayToJSArray(cx, mDeviceAddresses,
|
||||
deviceAddresses.address()))) {
|
||||
NS_WARNING("Cannot set JS Devices object!");
|
||||
BT_WARNING("Cannot set JS Devices object!");
|
||||
return;
|
||||
}
|
||||
mJsDeviceAddresses = deviceAddresses;
|
||||
@ -283,7 +283,7 @@ BluetoothAdapter::SetPropertyByValue(const BluetoothNamedValue& aValue)
|
||||
nsCString warningMsg;
|
||||
warningMsg.AssignLiteral("Not handling adapter property: ");
|
||||
warningMsg.Append(NS_ConvertUTF16toUTF8(name));
|
||||
NS_WARNING(warningMsg.get());
|
||||
BT_WARNING(warningMsg.get());
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@ -304,7 +304,7 @@ BluetoothAdapter::Notify(const BluetoothSignal& aData)
|
||||
{
|
||||
InfallibleTArray<BluetoothNamedValue> arr;
|
||||
|
||||
BT_LOG("[A] %s: %s", __FUNCTION__, NS_ConvertUTF16toUTF8(aData.name()).get());
|
||||
BT_LOGD("[A] %s: %s", __FUNCTION__, NS_ConvertUTF16toUTF8(aData.name()).get());
|
||||
|
||||
BluetoothValue v = aData.value();
|
||||
if (aData.name().EqualsLiteral("DeviceFound")) {
|
||||
@ -359,7 +359,7 @@ BluetoothAdapter::Notify(const BluetoothSignal& aData)
|
||||
nsCString warningMsg;
|
||||
warningMsg.AssignLiteral("Not handling adapter signal: ");
|
||||
warningMsg.Append(NS_ConvertUTF16toUTF8(aData.name()));
|
||||
NS_WARNING(warningMsg.get());
|
||||
BT_WARNING(warningMsg.get());
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@ -389,7 +389,7 @@ BluetoothAdapter::StartStopDiscovery(bool aStart, ErrorResult& aRv)
|
||||
rv = bs->StopDiscoveryInternal(results);
|
||||
}
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("Start/Stop Discovery failed!");
|
||||
BT_WARNING("Start/Stop Discovery failed!");
|
||||
aRv.Throw(rv);
|
||||
return nullptr;
|
||||
}
|
||||
@ -416,7 +416,7 @@ JS::Value
|
||||
BluetoothAdapter::GetDevices(JSContext* aContext, ErrorResult& aRv)
|
||||
{
|
||||
if (!mJsDeviceAddresses) {
|
||||
NS_WARNING("Devices not yet set!\n");
|
||||
BT_WARNING("Devices not yet set!\n");
|
||||
aRv.Throw(NS_ERROR_FAILURE);
|
||||
return JS::NullValue();
|
||||
}
|
||||
@ -429,7 +429,7 @@ JS::Value
|
||||
BluetoothAdapter::GetUuids(JSContext* aContext, ErrorResult& aRv)
|
||||
{
|
||||
if (!mJsUuids) {
|
||||
NS_WARNING("UUIDs not yet set!\n");
|
||||
BT_WARNING("UUIDs not yet set!\n");
|
||||
aRv.Throw(NS_ERROR_FAILURE);
|
||||
return JS::NullValue();
|
||||
}
|
||||
@ -559,7 +559,7 @@ BluetoothAdapter::PairUnpair(bool aPair, BluetoothDevice& aDevice,
|
||||
rv = bs->RemoveDeviceInternal(addr, results);
|
||||
}
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("Pair/Unpair failed!");
|
||||
BT_WARNING("Pair/Unpair failed!");
|
||||
aRv.Throw(rv);
|
||||
return nullptr;
|
||||
}
|
||||
@ -599,7 +599,7 @@ BluetoothAdapter::SetPinCode(const nsAString& aDeviceAddress,
|
||||
return nullptr;
|
||||
}
|
||||
if (!bs->SetPinCodeInternal(aDeviceAddress, aPinCode, results)) {
|
||||
NS_WARNING("SetPinCode failed!");
|
||||
BT_WARNING("SetPinCode failed!");
|
||||
aRv.Throw(NS_ERROR_FAILURE);
|
||||
return nullptr;
|
||||
}
|
||||
@ -627,7 +627,7 @@ BluetoothAdapter::SetPasskey(const nsAString& aDeviceAddress, uint32_t aPasskey,
|
||||
return nullptr;
|
||||
}
|
||||
if (bs->SetPasskeyInternal(aDeviceAddress, aPasskey, results)) {
|
||||
NS_WARNING("SetPasskeyInternal failed!");
|
||||
BT_WARNING("SetPasskeyInternal failed!");
|
||||
aRv.Throw(NS_ERROR_FAILURE);
|
||||
return nullptr;
|
||||
}
|
||||
@ -657,7 +657,7 @@ BluetoothAdapter::SetPairingConfirmation(const nsAString& aDeviceAddress,
|
||||
if (!bs->SetPairingConfirmationInternal(aDeviceAddress,
|
||||
aConfirmation,
|
||||
results)) {
|
||||
NS_WARNING("SetPairingConfirmation failed!");
|
||||
BT_WARNING("SetPairingConfirmation failed!");
|
||||
aRv.Throw(NS_ERROR_FAILURE);
|
||||
return nullptr;
|
||||
}
|
||||
@ -747,7 +747,7 @@ BluetoothAdapter::SendFile(const nsAString& aDeviceAddress,
|
||||
BlobChild* actor =
|
||||
ContentChild::GetSingleton()->GetOrCreateActorForBlob(aBlob);
|
||||
if (!actor) {
|
||||
NS_WARNING("Can't create actor");
|
||||
BT_WARNING("Can't create actor");
|
||||
aRv.Throw(NS_ERROR_FAILURE);
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -8,6 +8,7 @@
|
||||
#define mozilla_dom_bluetooth_bluetoothcommon_h__
|
||||
|
||||
#include "mozilla/Observer.h"
|
||||
#include "nsPrintfCString.h"
|
||||
#include "nsStringGlue.h"
|
||||
#include "nsTArray.h"
|
||||
|
||||
@ -18,24 +19,38 @@ extern bool gBluetoothDebugFlag;
|
||||
#undef BT_LOG
|
||||
#if defined(MOZ_WIDGET_GONK)
|
||||
#include <android/log.h>
|
||||
#define BT_LOG(args...) \
|
||||
/**
|
||||
* Prints 'D'EBUG build logs, which show in DEBUG build only when
|
||||
* developer setting 'Bluetooth output in adb' is enabled.
|
||||
*/
|
||||
#define BT_LOGD(args...) \
|
||||
do { \
|
||||
if (gBluetoothDebugFlag) { \
|
||||
__android_log_print(ANDROID_LOG_INFO, "GeckoBluetooth", args); \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
/**
|
||||
* Prints 'R'ELEASE build logs, which show in both RELEASE and DEBUG builds.
|
||||
*/
|
||||
#define BT_LOGR(args...) \
|
||||
__android_log_print(ANDROID_LOG_INFO, "GeckoBluetooth", args) \
|
||||
|
||||
/**
|
||||
* Prints DEBUG build warnings, which show in DEBUG build only.
|
||||
*/
|
||||
#define BT_WARNING(args...) \
|
||||
__android_log_print(ANDROID_LOG_WARN, "GeckoBluetooth", args)
|
||||
NS_WARNING(nsPrintfCString(args).get()) \
|
||||
|
||||
#else
|
||||
#define BT_LOG(args, ...) \
|
||||
#define BT_LOGD(args, ...) \
|
||||
do { \
|
||||
if (gBluetoothDebugFlag) { \
|
||||
printf(args, ##__VA_ARGS__); \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
#define BT_LOGR(args, ...) printf(args, ##__VA_ARGS__)
|
||||
#define BT_WARNING(args, ...) printf(args, ##__VA_ARGS__)
|
||||
#endif
|
||||
|
||||
|
@ -130,7 +130,7 @@ BluetoothDevice::SetPropertyByValue(const BluetoothNamedValue& aValue)
|
||||
|
||||
JS::Rooted<JSObject*> uuids(cx);
|
||||
if (NS_FAILED(nsTArrayToJSArray(cx, mUuids, uuids.address()))) {
|
||||
NS_WARNING("Cannot set JS UUIDs object!");
|
||||
BT_WARNING("Cannot set JS UUIDs object!");
|
||||
return;
|
||||
}
|
||||
mJsUuids = uuids;
|
||||
@ -145,7 +145,7 @@ BluetoothDevice::SetPropertyByValue(const BluetoothNamedValue& aValue)
|
||||
|
||||
JS::Rooted<JSObject*> services(cx);
|
||||
if (NS_FAILED(nsTArrayToJSArray(cx, mServices, services.address()))) {
|
||||
NS_WARNING("Cannot set JS Services object!");
|
||||
BT_WARNING("Cannot set JS Services object!");
|
||||
return;
|
||||
}
|
||||
mJsServices = services;
|
||||
@ -154,7 +154,7 @@ BluetoothDevice::SetPropertyByValue(const BluetoothNamedValue& aValue)
|
||||
nsCString warningMsg;
|
||||
warningMsg.AssignLiteral("Not handling device property: ");
|
||||
warningMsg.Append(NS_ConvertUTF16toUTF8(name));
|
||||
NS_WARNING(warningMsg.get());
|
||||
BT_WARNING(warningMsg.get());
|
||||
}
|
||||
}
|
||||
|
||||
@ -175,7 +175,7 @@ BluetoothDevice::Create(nsPIDOMWindow* aWindow,
|
||||
void
|
||||
BluetoothDevice::Notify(const BluetoothSignal& aData)
|
||||
{
|
||||
BT_LOG("[D] %s: %s", __FUNCTION__, NS_ConvertUTF16toUTF8(aData.name()).get());
|
||||
BT_LOGD("[D] %s: %s", __FUNCTION__, NS_ConvertUTF16toUTF8(aData.name()).get());
|
||||
|
||||
BluetoothValue v = aData.value();
|
||||
if (aData.name().EqualsLiteral("PropertyChanged")) {
|
||||
@ -192,7 +192,7 @@ BluetoothDevice::Notify(const BluetoothSignal& aData)
|
||||
nsCString warningMsg;
|
||||
warningMsg.AssignLiteral("Not handling device signal: ");
|
||||
warningMsg.Append(NS_ConvertUTF16toUTF8(aData.name()));
|
||||
NS_WARNING(warningMsg.get());
|
||||
BT_WARNING(warningMsg.get());
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@ -201,7 +201,7 @@ JS::Value
|
||||
BluetoothDevice::GetUuids(JSContext* aCx, ErrorResult& aRv)
|
||||
{
|
||||
if (!mJsUuids) {
|
||||
NS_WARNING("UUIDs not yet set!\n");
|
||||
BT_WARNING("UUIDs not yet set!");
|
||||
aRv.Throw(NS_ERROR_FAILURE);
|
||||
return JS::NullValue();
|
||||
}
|
||||
@ -214,7 +214,7 @@ JS::Value
|
||||
BluetoothDevice::GetServices(JSContext* aCx, ErrorResult& aRv)
|
||||
{
|
||||
if (!mJsServices) {
|
||||
NS_WARNING("Services not yet set!\n");
|
||||
BT_WARNING("Services not yet set!");
|
||||
aRv.Throw(NS_ERROR_FAILURE);
|
||||
return JS::Value(JSVAL_NULL);
|
||||
}
|
||||
|
@ -171,7 +171,7 @@ public:
|
||||
NS_ENSURE_TRUE(cx, NS_OK);
|
||||
|
||||
if (!aResult.isNumber()) {
|
||||
NS_WARNING("'" AUDIO_VOLUME_BT_SCO_ID "' is not a number!");
|
||||
BT_WARNING("'" AUDIO_VOLUME_BT_SCO_ID "' is not a number!");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -184,7 +184,7 @@ public:
|
||||
NS_IMETHOD
|
||||
HandleError(const nsAString& aName)
|
||||
{
|
||||
NS_WARNING("Unable to get value for '" AUDIO_VOLUME_BT_SCO_ID "'");
|
||||
BT_WARNING("Unable to get value for '" AUDIO_VOLUME_BT_SCO_ID "'");
|
||||
return NS_OK;
|
||||
}
|
||||
};
|
||||
@ -255,7 +255,7 @@ public:
|
||||
}
|
||||
|
||||
if (!sBluetoothHfpManager) {
|
||||
NS_WARNING("BluetoothHfpManager no longer exists, cannot send ring!");
|
||||
BT_WARNING("BluetoothHfpManager no longer exists, cannot send ring!");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -375,7 +375,7 @@ BluetoothHfpManager::Init()
|
||||
|
||||
mListener = new BluetoothRilListener();
|
||||
if (!mListener->StartListening()) {
|
||||
NS_WARNING("Failed to start listening RIL");
|
||||
BT_WARNING("Failed to start listening RIL");
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -405,7 +405,7 @@ BluetoothHfpManager::Init()
|
||||
BluetoothHfpManager::~BluetoothHfpManager()
|
||||
{
|
||||
if (!mListener->StopListening()) {
|
||||
NS_WARNING("Failed to stop listening RIL");
|
||||
BT_WARNING("Failed to stop listening RIL");
|
||||
}
|
||||
mListener = nullptr;
|
||||
|
||||
@ -454,7 +454,7 @@ BluetoothHfpManager::NotifyConnectionStatusChanged(const nsAString& aType)
|
||||
|
||||
if (NS_FAILED(obs->NotifyObservers(this, NS_ConvertUTF16toUTF8(aType).get(),
|
||||
mDeviceAddress.get()))) {
|
||||
NS_WARNING("Failed to notify observsers!");
|
||||
BT_WARNING("Failed to notify observsers!");
|
||||
}
|
||||
|
||||
// Dispatch an event of status change
|
||||
@ -487,7 +487,7 @@ BluetoothHfpManager::NotifyDialer(const nsAString& aCommand)
|
||||
parameters.AppendElement(BluetoothNamedValue(name, v));
|
||||
|
||||
if (!BroadcastSystemMessage(type, parameters)) {
|
||||
NS_WARNING("Failed to broadcast system message to dialer");
|
||||
BT_WARNING("Failed to broadcast system message to dialer");
|
||||
}
|
||||
}
|
||||
|
||||
@ -566,7 +566,7 @@ BluetoothHfpManager::HandleVoiceConnectionChanged()
|
||||
JS::Value value;
|
||||
voiceInfo->GetRelSignalStrength(&value);
|
||||
if (!value.isNumber()) {
|
||||
NS_WARNING("Failed to get relSignalStrength in BluetoothHfpManager");
|
||||
BT_WARNING("Failed to get relSignalStrength in BluetoothHfpManager");
|
||||
return;
|
||||
}
|
||||
signal = ceil(value.toNumber() / 20.0);
|
||||
@ -600,7 +600,7 @@ BluetoothHfpManager::HandleVoiceConnectionChanged()
|
||||
//
|
||||
// Please see Bug 871366 for more information.
|
||||
if (mOperatorName.Length() > 16) {
|
||||
NS_WARNING("The operator name was longer than 16 characters. We cut it.");
|
||||
BT_WARNING("The operator name was longer than 16 characters. We cut it.");
|
||||
mOperatorName.Left(mOperatorName, 16);
|
||||
}
|
||||
}
|
||||
@ -670,14 +670,14 @@ BluetoothHfpManager::ReceiveSocketData(BluetoothSocket* aSocket,
|
||||
ParseAtCommand(msg, 8, atCommandValues);
|
||||
|
||||
if (atCommandValues.Length() < 4) {
|
||||
NS_WARNING("Could't get the value of command [AT+CMER=]");
|
||||
BT_WARNING("Could't get the value of command [AT+CMER=]");
|
||||
goto respond_with_ok;
|
||||
}
|
||||
|
||||
if (!atCommandValues[0].EqualsLiteral("3") ||
|
||||
!atCommandValues[1].EqualsLiteral("0") ||
|
||||
!atCommandValues[2].EqualsLiteral("0")) {
|
||||
NS_WARNING("Wrong value of CMER");
|
||||
BT_WARNING("Wrong value of CMER");
|
||||
goto respond_with_ok;
|
||||
}
|
||||
|
||||
@ -686,7 +686,7 @@ BluetoothHfpManager::ReceiveSocketData(BluetoothSocket* aSocket,
|
||||
ParseAtCommand(msg, 8, atCommandValues);
|
||||
|
||||
if (atCommandValues.IsEmpty()) {
|
||||
NS_WARNING("Could't get the value of command [AT+CMEE=]");
|
||||
BT_WARNING("Could't get the value of command [AT+CMEE=]");
|
||||
goto respond_with_ok;
|
||||
}
|
||||
|
||||
@ -698,7 +698,7 @@ BluetoothHfpManager::ReceiveSocketData(BluetoothSocket* aSocket,
|
||||
ParseAtCommand(msg, 8, atCommandValues);
|
||||
|
||||
if (atCommandValues.Length() != 2) {
|
||||
NS_WARNING("Could't get the value of command [AT+COPS=]");
|
||||
BT_WARNING("Could't get the value of command [AT+COPS=]");
|
||||
goto respond_with_ok;
|
||||
}
|
||||
|
||||
@ -723,7 +723,7 @@ BluetoothHfpManager::ReceiveSocketData(BluetoothSocket* aSocket,
|
||||
ParseAtCommand(msg, 7, atCommandValues);
|
||||
|
||||
if (atCommandValues.Length() != 1) {
|
||||
NS_WARNING("Couldn't get the value of command [AT+VTS=]");
|
||||
BT_WARNING("Couldn't get the value of command [AT+VTS=]");
|
||||
goto respond_with_ok;
|
||||
}
|
||||
|
||||
@ -736,14 +736,14 @@ BluetoothHfpManager::ReceiveSocketData(BluetoothSocket* aSocket,
|
||||
ParseAtCommand(msg, 7, atCommandValues);
|
||||
|
||||
if (atCommandValues.IsEmpty()) {
|
||||
NS_WARNING("Couldn't get the value of command [AT+VGM]");
|
||||
BT_WARNING("Couldn't get the value of command [AT+VGM]");
|
||||
goto respond_with_ok;
|
||||
}
|
||||
|
||||
nsresult rv;
|
||||
int vgm = atCommandValues[0].ToInteger(&rv);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("Failed to extract microphone volume from bluetooth headset!");
|
||||
BT_WARNING("Failed to extract microphone volume from bluetooth headset!");
|
||||
goto respond_with_ok;
|
||||
}
|
||||
|
||||
@ -755,7 +755,7 @@ BluetoothHfpManager::ReceiveSocketData(BluetoothSocket* aSocket,
|
||||
ParseAtCommand(msg, 8, atCommandValues);
|
||||
|
||||
if (atCommandValues.IsEmpty()) {
|
||||
NS_WARNING("Could't get the value of command [AT+CHLD=]");
|
||||
BT_WARNING("Could't get the value of command [AT+CHLD=]");
|
||||
goto respond_with_ok;
|
||||
}
|
||||
|
||||
@ -776,10 +776,10 @@ BluetoothHfpManager::ReceiveSocketData(BluetoothSocket* aSocket,
|
||||
char chld = atCommandValues[0][0];
|
||||
bool valid = true;
|
||||
if (atCommandValues[0].Length() > 1) {
|
||||
NS_WARNING("No index should be included in command [AT+CHLD]");
|
||||
BT_WARNING("No index should be included in command [AT+CHLD]");
|
||||
valid = false;
|
||||
} else if (chld == '3' || chld == '4') {
|
||||
NS_WARNING("The value of command [AT+CHLD] is not supported");
|
||||
BT_WARNING("The value of command [AT+CHLD] is not supported");
|
||||
valid = false;
|
||||
} else if (chld == '0') {
|
||||
// We need to rename these dialer commands for better readability
|
||||
@ -791,7 +791,7 @@ BluetoothHfpManager::ReceiveSocketData(BluetoothSocket* aSocket,
|
||||
} else if (chld == '2') {
|
||||
NotifyDialer(NS_LITERAL_STRING("CHLD=2"));
|
||||
} else {
|
||||
NS_WARNING("Wrong value of command [AT+CHLD]");
|
||||
BT_WARNING("Wrong value of command [AT+CHLD]");
|
||||
valid = false;
|
||||
}
|
||||
|
||||
@ -805,14 +805,14 @@ BluetoothHfpManager::ReceiveSocketData(BluetoothSocket* aSocket,
|
||||
ParseAtCommand(msg, 7, atCommandValues);
|
||||
|
||||
if (atCommandValues.IsEmpty()) {
|
||||
NS_WARNING("Could't get the value of command [AT+VGS=]");
|
||||
BT_WARNING("Could't get the value of command [AT+VGS=]");
|
||||
goto respond_with_ok;
|
||||
}
|
||||
|
||||
nsresult rv;
|
||||
int newVgs = atCommandValues[0].ToInteger(&rv);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("Failed to extract volume value from bluetooth headset!");
|
||||
BT_WARNING("Failed to extract volume value from bluetooth headset!");
|
||||
goto respond_with_ok;
|
||||
}
|
||||
|
||||
@ -855,7 +855,7 @@ BluetoothHfpManager::ReceiveSocketData(BluetoothSocket* aSocket,
|
||||
nsAutoCString message(msg), newMsg;
|
||||
int end = message.FindChar(';');
|
||||
if (end < 0) {
|
||||
NS_WARNING("Could't get the value of command [ATD]");
|
||||
BT_WARNING("Could't get the value of command [ATD]");
|
||||
goto respond_with_ok;
|
||||
}
|
||||
|
||||
@ -865,7 +865,7 @@ BluetoothHfpManager::ReceiveSocketData(BluetoothSocket* aSocket,
|
||||
ParseAtCommand(msg, 8, atCommandValues);
|
||||
|
||||
if (atCommandValues.IsEmpty()) {
|
||||
NS_WARNING("Could't get the value of command [AT+CLIP=]");
|
||||
BT_WARNING("Could't get the value of command [AT+CLIP=]");
|
||||
goto respond_with_ok;
|
||||
}
|
||||
|
||||
@ -874,7 +874,7 @@ BluetoothHfpManager::ReceiveSocketData(BluetoothSocket* aSocket,
|
||||
ParseAtCommand(msg, 8, atCommandValues);
|
||||
|
||||
if (atCommandValues.IsEmpty()) {
|
||||
NS_WARNING("Could't get the value of command [AT+CCWA=]");
|
||||
BT_WARNING("Could't get the value of command [AT+CCWA=]");
|
||||
goto respond_with_ok;
|
||||
}
|
||||
|
||||
@ -907,7 +907,7 @@ BluetoothHfpManager::ReceiveSocketData(BluetoothSocket* aSocket,
|
||||
// (2) A SCO link exists
|
||||
// (3) This is the very first AT+CKPD=200 of this session
|
||||
// It is the case of Figure 4.3, Bluetooth HSP spec. Do nothing.
|
||||
NS_WARNING("AT+CKPD=200: Do nothing");
|
||||
BT_WARNING("AT+CKPD=200: Do nothing");
|
||||
}
|
||||
}
|
||||
|
||||
@ -956,7 +956,7 @@ BluetoothHfpManager::ReceiveSocketData(BluetoothSocket* aSocket,
|
||||
warningMsg.Append(NS_LITERAL_CSTRING("Unsupported AT command: "));
|
||||
warningMsg.Append(msg);
|
||||
warningMsg.Append(NS_LITERAL_CSTRING(", reply with ERROR"));
|
||||
NS_WARNING(warningMsg.get());
|
||||
BT_WARNING(warningMsg.get());
|
||||
|
||||
SendLine("ERROR");
|
||||
return;
|
||||
@ -1026,12 +1026,12 @@ BluetoothHfpManager::Listen()
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
if (sInShutdown) {
|
||||
NS_WARNING("Listen called while in shutdown!");
|
||||
BT_WARNING("Listen called while in shutdown!");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mSocket) {
|
||||
NS_WARNING("mSocket exists. Failed to listen.");
|
||||
BT_WARNING("mSocket exists. Failed to listen.");
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1041,7 +1041,7 @@ BluetoothHfpManager::Listen()
|
||||
|
||||
if (!mHandsfreeSocket->Listen(
|
||||
BluetoothReservedChannels::CHANNEL_HANDSFREE_AG)) {
|
||||
NS_WARNING("[HFP] Can't listen on RFCOMM socket!");
|
||||
BT_WARNING("[HFP] Can't listen on RFCOMM socket!");
|
||||
mHandsfreeSocket = nullptr;
|
||||
return false;
|
||||
}
|
||||
@ -1053,7 +1053,7 @@ BluetoothHfpManager::Listen()
|
||||
|
||||
if (!mHeadsetSocket->Listen(
|
||||
BluetoothReservedChannels::CHANNEL_HEADSET_AG)) {
|
||||
NS_WARNING("[HSP] Can't listen on RFCOMM socket!");
|
||||
BT_WARNING("[HSP] Can't listen on RFCOMM socket!");
|
||||
mHandsfreeSocket->Disconnect();
|
||||
mHandsfreeSocket = nullptr;
|
||||
mHeadsetSocket = nullptr;
|
||||
@ -1101,7 +1101,7 @@ bool
|
||||
BluetoothHfpManager::SendCommand(const char* aCommand, uint32_t aValue)
|
||||
{
|
||||
if (!IsConnected()) {
|
||||
NS_WARNING("Trying to SendCommand() without a SLC");
|
||||
BT_WARNING("Trying to SendCommand() without a SLC");
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1115,7 +1115,7 @@ BluetoothHfpManager::SendCommand(const char* aCommand, uint32_t aValue)
|
||||
}
|
||||
|
||||
if ((aValue < 1) || (aValue > ArrayLength(sCINDItems) - 1)) {
|
||||
NS_WARNING("unexpected CINDType for CIEV command");
|
||||
BT_WARNING("unexpected CINDType for CIEV command");
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1183,7 +1183,7 @@ BluetoothHfpManager::SendCommand(const char* aCommand, uint32_t aValue)
|
||||
}
|
||||
break;
|
||||
default:
|
||||
NS_WARNING("Not handling call status for CLCC");
|
||||
BT_WARNING("Not handling call status for CLCC");
|
||||
break;
|
||||
}
|
||||
message.AppendLiteral(",0,0,\"");
|
||||
@ -1343,7 +1343,7 @@ BluetoothHfpManager::HandleCallStateChanged(uint32_t aCallIndex,
|
||||
UpdateCIND(CINDType::CALLSETUP, CallSetupState::NO_CALLSETUP, aSend);
|
||||
break;
|
||||
default:
|
||||
NS_WARNING("Not handling state changed");
|
||||
BT_WARNING("Not handling state changed");
|
||||
}
|
||||
|
||||
// = Handle callheld separately =
|
||||
@ -1382,7 +1382,7 @@ BluetoothHfpManager::HandleCallStateChanged(uint32_t aCallIndex,
|
||||
}
|
||||
break;
|
||||
default:
|
||||
NS_WARNING("Not handling state changed");
|
||||
BT_WARNING("Not handling state changed");
|
||||
}
|
||||
|
||||
// Handle held calls separately
|
||||
@ -1412,7 +1412,7 @@ BluetoothHfpManager::HandleCallStateChanged(uint32_t aCallIndex,
|
||||
}
|
||||
break;
|
||||
default:
|
||||
NS_WARNING("Not handling state changed");
|
||||
BT_WARNING("Not handling state changed");
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -1621,12 +1621,12 @@ BluetoothHfpManager::ConnectSco(BluetoothReplyRunnable* aRunnable)
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
if (sInShutdown) {
|
||||
NS_WARNING("ConnecteSco called while in shutdown!");
|
||||
BT_WARNING("ConnecteSco called while in shutdown!");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!IsConnected()) {
|
||||
NS_WARNING("BluetoothHfpManager is not connected");
|
||||
BT_WARNING("BluetoothHfpManager is not connected");
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1634,7 +1634,7 @@ BluetoothHfpManager::ConnectSco(BluetoothReplyRunnable* aRunnable)
|
||||
if (status == SocketConnectionStatus::SOCKET_CONNECTED ||
|
||||
status == SocketConnectionStatus::SOCKET_CONNECTING ||
|
||||
(mScoRunnable && (mScoRunnable != aRunnable))) {
|
||||
NS_WARNING("SCO connection exists or is being established");
|
||||
BT_WARNING("SCO connection exists or is being established");
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1654,13 +1654,13 @@ bool
|
||||
BluetoothHfpManager::DisconnectSco()
|
||||
{
|
||||
if (!IsConnected()) {
|
||||
NS_WARNING("BluetoothHfpManager is not connected");
|
||||
BT_WARNING("BluetoothHfpManager is not connected");
|
||||
return false;
|
||||
}
|
||||
|
||||
SocketConnectionStatus status = mScoSocket->GetConnectionStatus();
|
||||
if (status != SOCKET_CONNECTED && status != SOCKET_CONNECTING) {
|
||||
NS_WARNING("No SCO exists");
|
||||
BT_WARNING("No SCO exists");
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1674,20 +1674,20 @@ BluetoothHfpManager::ListenSco()
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
if (sInShutdown) {
|
||||
NS_WARNING("ListenSco called while in shutdown!");
|
||||
BT_WARNING("ListenSco called while in shutdown!");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mScoSocket->GetConnectionStatus() ==
|
||||
SocketConnectionStatus::SOCKET_LISTENING) {
|
||||
NS_WARNING("SCO socket has been already listening");
|
||||
BT_WARNING("SCO socket has been already listening");
|
||||
return false;
|
||||
}
|
||||
|
||||
mScoSocket->Disconnect();
|
||||
|
||||
if (!mScoSocket->Listen(-1)) {
|
||||
NS_WARNING("Can't listen on SCO socket!");
|
||||
BT_WARNING("Can't listen on SCO socket!");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -81,6 +81,11 @@ public:
|
||||
virtual void OnConnect(const nsAString& aErrorStr) MOZ_OVERRIDE;
|
||||
virtual void OnDisconnect(const nsAString& AErrorStr) MOZ_OVERRIDE;
|
||||
|
||||
virtual void GetName(nsACString& aName)
|
||||
{
|
||||
aName.AssignLiteral("HFP/HSP");
|
||||
}
|
||||
|
||||
bool Listen();
|
||||
bool ConnectSco(BluetoothReplyRunnable* aRunnable = nullptr);
|
||||
bool DisconnectSco();
|
||||
|
@ -236,7 +236,7 @@ BluetoothHidManager::NotifyStatusChanged()
|
||||
BluetoothNamedValue(NS_LITERAL_STRING("address"), v));
|
||||
|
||||
if (!BroadcastSystemMessage(type, parameters)) {
|
||||
NS_WARNING("Failed to broadcast system message to settings");
|
||||
BT_WARNING("Failed to broadcast system message to settings");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -37,6 +37,12 @@ public:
|
||||
virtual void OnConnect(const nsAString& aErrorStr) MOZ_OVERRIDE;
|
||||
virtual void OnDisconnect(const nsAString& aErrorStr) MOZ_OVERRIDE;
|
||||
|
||||
virtual void GetName(nsACString& aName)
|
||||
{
|
||||
aName.AssignLiteral("HID");
|
||||
}
|
||||
|
||||
// HID-specific functions
|
||||
void HandleInputPropertyChanged(const BluetoothSignal& aSignal);
|
||||
|
||||
private:
|
||||
|
@ -48,7 +48,7 @@ public:
|
||||
|
||||
const BluetoothValue& v = mReply->get_BluetoothReplySuccess().value();
|
||||
if (v.type() != BluetoothValue::TArrayOfBluetoothNamedValue) {
|
||||
NS_WARNING("Not a BluetoothNamedValue array!");
|
||||
BT_WARNING("Not a BluetoothNamedValue array!");
|
||||
SetError(NS_LITERAL_STRING("BluetoothReplyTypeError"));
|
||||
return false;
|
||||
}
|
||||
@ -61,7 +61,7 @@ public:
|
||||
nsresult rv;
|
||||
nsIScriptContext* sc = mManagerPtr->GetContextForEventHandlers(&rv);
|
||||
if (!sc) {
|
||||
NS_WARNING("Cannot create script context!");
|
||||
BT_WARNING("Cannot create script context!");
|
||||
SetError(NS_LITERAL_STRING("BluetoothScriptContextError"));
|
||||
return false;
|
||||
}
|
||||
@ -71,7 +71,7 @@ public:
|
||||
JS::Rooted<JSObject*> global(cx, sc->GetWindowProxy());
|
||||
rv = nsContentUtils::WrapNative(cx, global, adapter, aValue);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("Cannot create native object!");
|
||||
BT_WARNING("Cannot create native object!");
|
||||
SetError(NS_LITERAL_STRING("BluetoothNativeObjectError"));
|
||||
return false;
|
||||
}
|
||||
@ -120,7 +120,7 @@ BluetoothManager::SetPropertyByValue(const BluetoothNamedValue& aValue)
|
||||
nsCString warningMsg;
|
||||
warningMsg.AssignLiteral("Not handling manager property: ");
|
||||
warningMsg.Append(NS_ConvertUTF16toUTF8(name));
|
||||
NS_WARNING(warningMsg.get());
|
||||
BT_WARNING(warningMsg.get());
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -197,7 +197,7 @@ BluetoothManager::CheckPermission(nsPIDOMWindow* aWindow)
|
||||
void
|
||||
BluetoothManager::Notify(const BluetoothSignal& aData)
|
||||
{
|
||||
BT_LOG("[M] %s: %s", __FUNCTION__, NS_ConvertUTF16toUTF8(aData.name()).get());
|
||||
BT_LOGD("[M] %s: %s", __FUNCTION__, NS_ConvertUTF16toUTF8(aData.name()).get());
|
||||
|
||||
if (aData.name().EqualsLiteral("AdapterAdded")) {
|
||||
DispatchTrustedEvent(NS_LITERAL_STRING("adapteradded"));
|
||||
@ -210,7 +210,7 @@ BluetoothManager::Notify(const BluetoothSignal& aData)
|
||||
nsCString warningMsg;
|
||||
warningMsg.AssignLiteral("Not handling manager signal: ");
|
||||
warningMsg.Append(NS_ConvertUTF16toUTF8(aData.name()));
|
||||
NS_WARNING(warningMsg.get());
|
||||
BT_WARNING(warningMsg.get());
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
@ -113,7 +113,7 @@ public:
|
||||
nsresult rv = mInputStream->Read(buf, mAvailablePacketSize, &numRead);
|
||||
if (NS_FAILED(rv)) {
|
||||
// Needs error handling here
|
||||
NS_WARNING("Failed to read from input stream");
|
||||
BT_WARNING("Failed to read from input stream");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
@ -123,7 +123,7 @@ public:
|
||||
nsRefPtr<SendSocketDataTask> task =
|
||||
new SendSocketDataTask((uint8_t*)buf.forget(), numRead);
|
||||
if (NS_FAILED(NS_DispatchToMainThread(task))) {
|
||||
NS_WARNING("Failed to dispatch to main thread!");
|
||||
BT_WARNING("Failed to dispatch to main thread!");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
}
|
||||
@ -308,7 +308,7 @@ BluetoothOppManager::Listen()
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
if (mSocket) {
|
||||
NS_WARNING("mSocket exists. Failed to listen.");
|
||||
BT_WARNING("mSocket exists. Failed to listen.");
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -317,7 +317,7 @@ BluetoothOppManager::Listen()
|
||||
new BluetoothSocket(this, BluetoothSocketType::RFCOMM, true, true);
|
||||
|
||||
if (!mRfcommSocket->Listen(BluetoothReservedChannels::CHANNEL_OPUSH)) {
|
||||
NS_WARNING("[OPP] Can't listen on RFCOMM socket!");
|
||||
BT_WARNING("[OPP] Can't listen on RFCOMM socket!");
|
||||
mRfcommSocket = nullptr;
|
||||
return false;
|
||||
}
|
||||
@ -328,7 +328,7 @@ BluetoothOppManager::Listen()
|
||||
new BluetoothSocket(this, BluetoothSocketType::EL2CAP, true, true);
|
||||
|
||||
if (!mL2capSocket->Listen(BluetoothReservedChannels::CHANNEL_OPUSH_L2CAP)) {
|
||||
NS_WARNING("[OPP] Can't listen on L2CAP socket!");
|
||||
BT_WARNING("[OPP] Can't listen on L2CAP socket!");
|
||||
mRfcommSocket->Disconnect();
|
||||
mRfcommSocket = nullptr;
|
||||
mL2capSocket = nullptr;
|
||||
@ -450,7 +450,7 @@ BluetoothOppManager::AfterOppConnected()
|
||||
if (!AcquireSdcardMountLock()) {
|
||||
// If we fail to get a mount lock, abort this transaction
|
||||
// Directly sending disconnect-request is better than abort-request
|
||||
NS_WARNING("BluetoothOPPManager couldn't get a mount lock!");
|
||||
BT_WARNING("BluetoothOPPManager couldn't get a mount lock!");
|
||||
Disconnect(nullptr);
|
||||
}
|
||||
}
|
||||
@ -580,7 +580,7 @@ BluetoothOppManager::ExtractBlobHeaders()
|
||||
|
||||
nsresult rv = mBlob->GetType(mContentType);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("Can't get content type");
|
||||
BT_WARNING("Can't get content type");
|
||||
SendDisconnectRequest();
|
||||
return false;
|
||||
}
|
||||
@ -588,7 +588,7 @@ BluetoothOppManager::ExtractBlobHeaders()
|
||||
uint64_t fileLength;
|
||||
rv = mBlob->GetSize(&fileLength);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("Can't get file size");
|
||||
BT_WARNING("Can't get file size");
|
||||
SendDisconnectRequest();
|
||||
return false;
|
||||
}
|
||||
@ -599,7 +599,7 @@ BluetoothOppManager::ExtractBlobHeaders()
|
||||
// larger than UINT32_MAX, it needs to parse another OBEX Header
|
||||
// and I would like to leave it as a feature.
|
||||
if (fileLength > (uint64_t)UINT32_MAX) {
|
||||
NS_WARNING("The file size is too large for now");
|
||||
BT_WARNING("The file size is too large for now");
|
||||
SendDisconnectRequest();
|
||||
return false;
|
||||
}
|
||||
@ -607,7 +607,7 @@ BluetoothOppManager::ExtractBlobHeaders()
|
||||
mFileLength = fileLength;
|
||||
rv = NS_NewThread(getter_AddRefs(mReadFileThread));
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("Can't create thread");
|
||||
BT_WARNING("Can't create thread");
|
||||
SendDisconnectRequest();
|
||||
return false;
|
||||
}
|
||||
@ -829,10 +829,10 @@ BluetoothOppManager::ServerDataHandler(UnixSocketRawData* aMessage)
|
||||
opCode == ObexRequestCode::GetFinal ||
|
||||
opCode == ObexRequestCode::SetPath) {
|
||||
ReplyError(ObexResponseCode::BadRequest);
|
||||
NS_WARNING("Unsupported ObexRequestCode");
|
||||
BT_WARNING("Unsupported ObexRequestCode");
|
||||
} else {
|
||||
ReplyError(ObexResponseCode::NotImplemented);
|
||||
NS_WARNING("Unrecognized ObexRequestCode");
|
||||
BT_WARNING("Unrecognized ObexRequestCode");
|
||||
}
|
||||
}
|
||||
|
||||
@ -878,7 +878,7 @@ BluetoothOppManager::ClientDataHandler(UnixSocketRawData* aMessage)
|
||||
str += "[OPP] 0x";
|
||||
str.AppendInt(mLastCommand, 16);
|
||||
str += " failed";
|
||||
NS_WARNING(str.get());
|
||||
BT_WARNING(str.get());
|
||||
FileTransferComplete();
|
||||
return;
|
||||
}
|
||||
@ -942,7 +942,7 @@ BluetoothOppManager::ClientDataHandler(UnixSocketRawData* aMessage)
|
||||
if (!mInputStream) {
|
||||
rv = mBlob->GetInternalStream(getter_AddRefs(mInputStream));
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("Can't get internal stream of blob");
|
||||
BT_WARNING("Can't get internal stream of blob");
|
||||
SendDisconnectRequest();
|
||||
return;
|
||||
}
|
||||
@ -952,11 +952,11 @@ BluetoothOppManager::ClientDataHandler(UnixSocketRawData* aMessage)
|
||||
mRemoteMaxPacketLength);
|
||||
rv = mReadFileThread->Dispatch(task, NS_DISPATCH_NORMAL);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("Cannot dispatch read file task!");
|
||||
BT_WARNING("Cannot dispatch read file task!");
|
||||
SendDisconnectRequest();
|
||||
}
|
||||
} else {
|
||||
NS_WARNING("Unhandled ObexRequestCode");
|
||||
BT_WARNING("Unhandled ObexRequestCode");
|
||||
}
|
||||
}
|
||||
|
||||
@ -1029,7 +1029,7 @@ BluetoothOppManager::SendPutRequest(uint8_t* aFileBody,
|
||||
|
||||
if (!mConnected) return;
|
||||
if (aFileBodyLength > packetLeftSpace) {
|
||||
NS_WARNING("Not allowed such a small MaxPacketLength value");
|
||||
BT_WARNING("Not allowed such a small MaxPacketLength value");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1234,7 +1234,7 @@ BluetoothOppManager::FileTransferComplete()
|
||||
parameters.AppendElement(BluetoothNamedValue(name, v));
|
||||
|
||||
if (!BroadcastSystemMessage(type, parameters)) {
|
||||
NS_WARNING("Failed to broadcast [bluetooth-opp-transfer-complete]");
|
||||
BT_WARNING("Failed to broadcast [bluetooth-opp-transfer-complete]");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1270,7 +1270,7 @@ BluetoothOppManager::StartFileTransfer()
|
||||
parameters.AppendElement(BluetoothNamedValue(name, v));
|
||||
|
||||
if (!BroadcastSystemMessage(type, parameters)) {
|
||||
NS_WARNING("Failed to broadcast [bluetooth-opp-transfer-start]");
|
||||
BT_WARNING("Failed to broadcast [bluetooth-opp-transfer-start]");
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -1300,7 +1300,7 @@ BluetoothOppManager::UpdateProgress()
|
||||
parameters.AppendElement(BluetoothNamedValue(name, v));
|
||||
|
||||
if (!BroadcastSystemMessage(type, parameters)) {
|
||||
NS_WARNING("Failed to broadcast [bluetooth-opp-update-progress]");
|
||||
BT_WARNING("Failed to broadcast [bluetooth-opp-update-progress]");
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -1330,7 +1330,7 @@ BluetoothOppManager::ReceivingFileConfirmation()
|
||||
parameters.AppendElement(BluetoothNamedValue(name, v));
|
||||
|
||||
if (!BroadcastSystemMessage(type, parameters)) {
|
||||
NS_WARNING("Failed to send [bluetooth-opp-receiving-file-confirmation]");
|
||||
BT_WARNING("Failed to send [bluetooth-opp-receiving-file-confirmation]");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -78,6 +78,11 @@ public:
|
||||
virtual void GetAddress(nsAString& aDeviceAddress) MOZ_OVERRIDE;
|
||||
virtual bool IsConnected() MOZ_OVERRIDE;
|
||||
|
||||
virtual void GetName(nsACString& aName)
|
||||
{
|
||||
aName.AssignLiteral("OPP");
|
||||
}
|
||||
|
||||
/*
|
||||
* If an application wants to send a file, first, it needs to
|
||||
* call Connect() to create a valid RFCOMM connection. After
|
||||
|
@ -17,6 +17,14 @@
|
||||
|
||||
USING_BLUETOOTH_NAMESPACE
|
||||
|
||||
#define BT_LOGR_PROFILE(mgr, args...) \
|
||||
do { \
|
||||
nsCString name; \
|
||||
mgr->GetName(name); \
|
||||
BT_LOGR("%s: [%s] %s", __FUNCTION__, name.get(), \
|
||||
nsPrintfCString(args).get()); \
|
||||
} while(0)
|
||||
|
||||
BluetoothProfileController::BluetoothProfileController(
|
||||
const nsAString& aDeviceAddress,
|
||||
BluetoothReplyRunnable* aRunnable,
|
||||
@ -120,7 +128,6 @@ BluetoothProfileController::Connect(uint32_t aCod)
|
||||
* It's almost impossible to send file to a remote device which is an Audio
|
||||
* device or a Rendering device, so we won't connect OPP in that case.
|
||||
*/
|
||||
BluetoothProfileManagerBase* profile;
|
||||
if (hasAudio) {
|
||||
AddProfile(BluetoothHfpManager::Get());
|
||||
}
|
||||
@ -144,6 +151,7 @@ BluetoothProfileController::ConnectNext()
|
||||
|
||||
if (++mProfilesIndex < mProfiles.Length()) {
|
||||
MOZ_ASSERT(!mDeviceAddress.IsEmpty());
|
||||
BT_LOGR_PROFILE(mProfiles[mProfilesIndex], "");
|
||||
|
||||
mProfiles[mProfilesIndex]->Connect(mDeviceAddress, this);
|
||||
return;
|
||||
@ -166,6 +174,8 @@ void
|
||||
BluetoothProfileController::OnConnect(const nsAString& aErrorStr)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
BT_LOGR_PROFILE(mProfiles[mProfilesIndex], "<%s>",
|
||||
NS_ConvertUTF16toUTF8(aErrorStr).get());
|
||||
|
||||
if (!aErrorStr.IsEmpty()) {
|
||||
BT_WARNING(NS_ConvertUTF16toUTF8(aErrorStr).get());
|
||||
@ -203,6 +213,8 @@ BluetoothProfileController::DisconnectNext()
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
if (++mProfilesIndex < mProfiles.Length()) {
|
||||
BT_LOGR_PROFILE(mProfiles[mProfilesIndex], "");
|
||||
|
||||
mProfiles[mProfilesIndex]->Disconnect(this);
|
||||
return;
|
||||
}
|
||||
@ -224,6 +236,8 @@ void
|
||||
BluetoothProfileController::OnDisconnect(const nsAString& aErrorStr)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
BT_LOGR_PROFILE(mProfiles[mProfilesIndex], "<%s>",
|
||||
NS_ConvertUTF16toUTF8(aErrorStr).get());
|
||||
|
||||
if (!aErrorStr.IsEmpty()) {
|
||||
BT_WARNING(NS_ConvertUTF16toUTF8(aErrorStr).get());
|
||||
@ -233,4 +247,3 @@ BluetoothProfileController::OnDisconnect(const nsAString& aErrorStr)
|
||||
|
||||
DisconnectNext();
|
||||
}
|
||||
|
||||
|
@ -63,6 +63,11 @@ public:
|
||||
*/
|
||||
virtual void OnConnect(const nsAString& aErrorStr) = 0;
|
||||
virtual void OnDisconnect(const nsAString& aErrorStr) = 0;
|
||||
|
||||
/**
|
||||
* Returns string of profile name
|
||||
*/
|
||||
virtual void GetName(nsACString& aName) = 0;
|
||||
};
|
||||
|
||||
END_BLUETOOTH_NAMESPACE
|
||||
|
@ -41,7 +41,7 @@ BluetoothPropertyContainer::SetProperty(nsIDOMWindow* aOwner,
|
||||
|
||||
BluetoothService* bs = BluetoothService::Get();
|
||||
if (!bs) {
|
||||
NS_WARNING("Bluetooth service not available!");
|
||||
BT_WARNING("Bluetooth service not available!");
|
||||
aRv.Throw(NS_ERROR_FAILURE);
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -73,7 +73,7 @@ BluetoothReplyRunnable::Run()
|
||||
}
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("Could not fire DOMRequest!");
|
||||
BT_WARNING("Could not fire DOMRequest!");
|
||||
}
|
||||
|
||||
ReleaseMembers();
|
||||
|
@ -192,10 +192,10 @@ TelephonyListener::NotifyError(int32_t aCallIndex,
|
||||
hfp->HandleCallStateChanged(aCallIndex,
|
||||
nsITelephonyProvider::CALL_STATE_DISCONNECTED,
|
||||
aError, EmptyString(), false, true);
|
||||
NS_WARNING("Reset the call state due to call transition ends abnormally");
|
||||
BT_WARNING("Reset the call state due to call transition ends abnormally");
|
||||
}
|
||||
|
||||
NS_WARNING(NS_ConvertUTF16toUTF8(aError).get());
|
||||
BT_WARNING(NS_ConvertUTF16toUTF8(aError).get());
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -186,17 +186,17 @@ public:
|
||||
* Please see bug 892392 for more information.
|
||||
*/
|
||||
if (!mIsStartup && mEnabled == gBluetoothService->IsEnabledInternal()) {
|
||||
NS_WARNING("Bluetooth has already been enabled/disabled before.");
|
||||
BT_WARNING("Bluetooth has already been enabled/disabled before.");
|
||||
} else {
|
||||
// Switch on/off bluetooth
|
||||
if (mEnabled) {
|
||||
if (NS_FAILED(gBluetoothService->StartInternal())) {
|
||||
NS_WARNING("Bluetooth service failed to start!");
|
||||
BT_WARNING("Bluetooth service failed to start!");
|
||||
mEnabled = !mEnabled;
|
||||
}
|
||||
} else {
|
||||
if (NS_FAILED(gBluetoothService->StopInternal())) {
|
||||
NS_WARNING("Bluetooth service failed to stop!");
|
||||
BT_WARNING("Bluetooth service failed to stop!");
|
||||
mEnabled = !mEnabled;
|
||||
}
|
||||
}
|
||||
@ -211,13 +211,13 @@ public:
|
||||
// been toggled.
|
||||
#if defined(MOZ_WIDGET_GONK)
|
||||
if (property_set(PROP_BLUETOOTH_ENABLED, mEnabled ? "true" : "false") != 0) {
|
||||
NS_WARNING("Failed to set bluetooth enabled property");
|
||||
BT_WARNING("Failed to set bluetooth enabled property");
|
||||
}
|
||||
#endif
|
||||
|
||||
nsCOMPtr<nsIRunnable> ackTask = new BluetoothService::ToggleBtAck(mEnabled);
|
||||
if (NS_FAILED(NS_DispatchToMainThread(ackTask))) {
|
||||
NS_WARNING("Failed to dispatch to main thread!");
|
||||
BT_WARNING("Failed to dispatch to main thread!");
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
@ -238,7 +238,7 @@ public:
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
if (!aResult.isBoolean()) {
|
||||
NS_WARNING("Setting for '" BLUETOOTH_ENABLED_SETTING "' is not a boolean!");
|
||||
BT_WARNING("Setting for '" BLUETOOTH_ENABLED_SETTING "' is not a boolean!");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -253,7 +253,7 @@ public:
|
||||
|
||||
NS_IMETHOD HandleError(const nsAString& aName)
|
||||
{
|
||||
NS_WARNING("Unable to get value for '" BLUETOOTH_ENABLED_SETTING "'");
|
||||
BT_WARNING("Unable to get value for '" BLUETOOTH_ENABLED_SETTING "'");
|
||||
return NS_OK;
|
||||
}
|
||||
};
|
||||
@ -307,7 +307,7 @@ BluetoothService::Create()
|
||||
#elif defined(MOZ_BLUETOOTH_DBUS)
|
||||
return new BluetoothDBusService();
|
||||
#endif
|
||||
NS_WARNING("No platform support for bluetooth!");
|
||||
BT_WARNING("No platform support for bluetooth!");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@ -321,14 +321,14 @@ BluetoothService::Init()
|
||||
|
||||
if (NS_FAILED(obs->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID,
|
||||
false))) {
|
||||
NS_WARNING("Failed to add shutdown observer!");
|
||||
BT_WARNING("Failed to add shutdown observer!");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Only the main process should observe bluetooth settings changes.
|
||||
if (IsMainProcess() &&
|
||||
NS_FAILED(obs->AddObserver(this, MOZSETTINGS_CHANGED_ID, false))) {
|
||||
NS_WARNING("Failed to add settings change observer!");
|
||||
BT_WARNING("Failed to add settings change observer!");
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -344,7 +344,7 @@ BluetoothService::Cleanup()
|
||||
if (obs &&
|
||||
(NS_FAILED(obs->RemoveObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID)) ||
|
||||
NS_FAILED(obs->RemoveObserver(this, MOZSETTINGS_CHANGED_ID)))) {
|
||||
NS_WARNING("Can't unregister observers!");
|
||||
BT_WARNING("Can't unregister observers!");
|
||||
}
|
||||
}
|
||||
|
||||
@ -356,7 +356,7 @@ BluetoothService::RegisterBluetoothSignalHandler(
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(aHandler);
|
||||
|
||||
BT_LOG("[S] %s: %s", __FUNCTION__, NS_ConvertUTF16toUTF8(aNodeName).get());
|
||||
BT_LOGD("[S] %s: %s", __FUNCTION__, NS_ConvertUTF16toUTF8(aNodeName).get());
|
||||
|
||||
BluetoothSignalObserverList* ol;
|
||||
if (!mBluetoothSignalObserverTable.Get(aNodeName, &ol)) {
|
||||
@ -375,7 +375,7 @@ BluetoothService::UnregisterBluetoothSignalHandler(
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(aHandler);
|
||||
|
||||
BT_LOG("[S] %s: %s", __FUNCTION__, NS_ConvertUTF16toUTF8(aNodeName).get());
|
||||
BT_LOGD("[S] %s: %s", __FUNCTION__, NS_ConvertUTF16toUTF8(aNodeName).get());
|
||||
|
||||
BluetoothSignalObserverList* ol;
|
||||
if (mBluetoothSignalObserverTable.Get(aNodeName, &ol)) {
|
||||
@ -389,7 +389,7 @@ BluetoothService::UnregisterBluetoothSignalHandler(
|
||||
}
|
||||
}
|
||||
else {
|
||||
NS_WARNING("Node was never registered!");
|
||||
BT_WARNING("Node was never registered!");
|
||||
}
|
||||
}
|
||||
|
||||
@ -434,7 +434,7 @@ BluetoothService::DistributeSignal(const BluetoothSignal& aSignal)
|
||||
#if DEBUG
|
||||
nsAutoCString msg("No observer registered for path ");
|
||||
msg.Append(NS_ConvertUTF16toUTF8(aSignal.path()));
|
||||
NS_WARNING(msg.get());
|
||||
BT_WARNING(msg.get());
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
@ -529,7 +529,7 @@ BluetoothService::SetEnabled(bool aEnabled)
|
||||
* aEnabled: expected status of bluetooth
|
||||
*/
|
||||
if (mEnabled == aEnabled) {
|
||||
NS_WARNING("Bluetooth has already been enabled/disabled before\
|
||||
BT_WARNING("Bluetooth has already been enabled/disabled before\
|
||||
or the toggling is failed.");
|
||||
}
|
||||
|
||||
@ -735,7 +735,7 @@ BluetoothService::Get()
|
||||
|
||||
// If we're in shutdown, don't create a new instance
|
||||
if (gInShutdown) {
|
||||
NS_WARNING("BluetoothService can't be created during shutdown");
|
||||
BT_WARNING("BluetoothService can't be created during shutdown");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@ -784,11 +784,11 @@ BluetoothService::Notify(const BluetoothSignal& aData)
|
||||
NS_ENSURE_TRUE_VOID(obj);
|
||||
|
||||
if (!SetJsObject(cx, aData.value(), obj)) {
|
||||
NS_WARNING("Failed to set properties of system message!");
|
||||
BT_WARNING("Failed to set properties of system message!");
|
||||
return;
|
||||
}
|
||||
|
||||
BT_LOG("[S] %s: %s", __FUNCTION__, NS_ConvertUTF16toUTF8(aData.name()).get());
|
||||
BT_LOGD("[S] %s: %s", __FUNCTION__, NS_ConvertUTF16toUTF8(aData.name()).get());
|
||||
|
||||
if (aData.name().EqualsLiteral("RequestConfirmation")) {
|
||||
MOZ_ASSERT(aData.value().get_ArrayOfBluetoothNamedValue().Length() == 4,
|
||||
@ -811,7 +811,7 @@ BluetoothService::Notify(const BluetoothSignal& aData)
|
||||
nsCString warningMsg;
|
||||
warningMsg.AssignLiteral("Not handling service signal: ");
|
||||
warningMsg.Append(NS_ConvertUTF16toUTF8(aData.name()));
|
||||
NS_WARNING(warningMsg.get());
|
||||
BT_WARNING(warningMsg.get());
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -37,7 +37,7 @@ BluetoothSocket::Connect(const nsACString& aDeviceAddress, int aChannel)
|
||||
if (!ConnectSocket(c.forget(), aDeviceAddress.BeginReading())) {
|
||||
nsAutoString addr;
|
||||
GetAddress(addr);
|
||||
BT_LOG("%s failed. Current connected device address: %s",
|
||||
BT_LOGD("%s failed. Current connected device address: %s",
|
||||
__FUNCTION__, NS_ConvertUTF16toUTF8(addr).get());
|
||||
return false;
|
||||
}
|
||||
@ -56,7 +56,7 @@ BluetoothSocket::Listen(int aChannel)
|
||||
if (!ListenSocket(c.forget())) {
|
||||
nsAutoString addr;
|
||||
GetAddress(addr);
|
||||
BT_LOG("%s failed. Current connected device address: %s",
|
||||
BT_LOGD("%s failed. Current connected device address: %s",
|
||||
__FUNCTION__, NS_ConvertUTF16toUTF8(addr).get());
|
||||
return false;
|
||||
}
|
||||
|
@ -99,13 +99,13 @@ BluetoothUnixSocketConnector::SetUp(int aFd)
|
||||
if (lm) {
|
||||
if (mType == BluetoothSocketType::RFCOMM) {
|
||||
if (setsockopt(aFd, SOL_RFCOMM, RFCOMM_LM, &lm, sizeof(lm))) {
|
||||
NS_WARNING("setsockopt(RFCOMM_LM) failed, throwing");
|
||||
BT_WARNING("setsockopt(RFCOMM_LM) failed, throwing");
|
||||
return false;
|
||||
}
|
||||
} else if (mType == BluetoothSocketType::L2CAP ||
|
||||
mType == BluetoothSocketType::EL2CAP) {
|
||||
if (setsockopt(aFd, SOL_L2CAP, L2CAP_LM, &lm, sizeof(lm))) {
|
||||
NS_WARNING("setsockopt(L2CAP_LM) failed, throwing");
|
||||
BT_WARNING("setsockopt(L2CAP_LM) failed, throwing");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -114,7 +114,7 @@ BluetoothUnixSocketConnector::SetUp(int aFd)
|
||||
if (mType == BluetoothSocketType::RFCOMM) {
|
||||
sndbuf = RFCOMM_SO_SNDBUF;
|
||||
if (setsockopt(aFd, SOL_SOCKET, SO_SNDBUF, &sndbuf, sizeof(sndbuf))) {
|
||||
NS_WARNING("setsockopt(SO_SNDBUF) failed, throwing");
|
||||
BT_WARNING("setsockopt(SO_SNDBUF) failed, throwing");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -146,13 +146,13 @@ BluetoothUnixSocketConnector::SetUp(int aFd)
|
||||
if (mType == BluetoothSocketType::EL2CAP) {
|
||||
sndbuf = L2CAP_SO_SNDBUF;
|
||||
if (setsockopt(aFd, SOL_SOCKET, SO_SNDBUF, &sndbuf, sizeof(sndbuf))) {
|
||||
NS_WARNING("setsockopt(SO_SNDBUF) failed, throwing");
|
||||
BT_WARNING("setsockopt(SO_SNDBUF) failed, throwing");
|
||||
return false;
|
||||
}
|
||||
|
||||
rcvbuf = L2CAP_SO_RCVBUF;
|
||||
if (setsockopt(aFd, SOL_SOCKET, SO_RCVBUF, &rcvbuf, sizeof(rcvbuf))) {
|
||||
NS_WARNING("setsockopt(SO_RCVBUF) failed, throwing");
|
||||
BT_WARNING("setsockopt(SO_RCVBUF) failed, throwing");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -185,12 +185,12 @@ BluetoothUnixSocketConnector::Create()
|
||||
}
|
||||
|
||||
if (fd < 0) {
|
||||
NS_WARNING("Could not open bluetooth socket!");
|
||||
BT_WARNING("Could not open bluetooth socket!");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!SetUp(fd)) {
|
||||
NS_WARNING("Could not set up socket!");
|
||||
BT_WARNING("Could not set up socket!");
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -208,7 +208,7 @@ BluetoothUnixSocketConnector::CreateAddr(bool aIsServer,
|
||||
|
||||
if (!aIsServer && aAddress && strlen(aAddress) > 0) {
|
||||
if (get_bdaddr(aAddress, &bd_address_obj)) {
|
||||
NS_WARNING("Can't get bluetooth address!");
|
||||
BT_WARNING("Can't get bluetooth address!");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -239,7 +239,7 @@ BluetoothUnixSocketConnector::CreateAddr(bool aIsServer,
|
||||
memcpy(&aAddr.sco.sco_bdaddr, &bd_address_obj, sizeof(bd_address_obj));
|
||||
break;
|
||||
default:
|
||||
NS_WARNING("Socket type unknown!");
|
||||
BT_WARNING("Socket type unknown!");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
@ -29,7 +29,7 @@ SetJsObject(JSContext* aContext,
|
||||
MOZ_ASSERT(aContext && aObj);
|
||||
|
||||
if (aValue.type() != BluetoothValue::TArrayOfBluetoothNamedValue) {
|
||||
NS_WARNING("SetJsObject: Invalid parameter type");
|
||||
BT_WARNING("SetJsObject: Invalid parameter type");
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -56,14 +56,14 @@ SetJsObject(JSContext* aContext,
|
||||
val = BOOLEAN_TO_JSVAL(v.get_bool());
|
||||
break;
|
||||
default:
|
||||
NS_WARNING("SetJsObject: Parameter is not handled");
|
||||
BT_WARNING("SetJsObject: Parameter is not handled");
|
||||
break;
|
||||
}
|
||||
|
||||
if (!JS_SetProperty(aContext, aObj,
|
||||
NS_ConvertUTF16toUTF8(arr[i].name()).get(),
|
||||
val)) {
|
||||
NS_WARNING("Failed to set property");
|
||||
BT_WARNING("Failed to set property");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -112,12 +112,12 @@ BroadcastSystemMessage(const nsAString& aType,
|
||||
|
||||
JS::RootedObject obj(cx, JS_NewObject(cx, NULL, NULL, NULL));
|
||||
if (!obj) {
|
||||
NS_WARNING("Failed to new JSObject for system message!");
|
||||
BT_WARNING("Failed to new JSObject for system message!");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!SetJsObject(cx, aData, obj)) {
|
||||
NS_WARNING("Failed to set properties of system message!");
|
||||
BT_WARNING("Failed to set properties of system message!");
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -149,7 +149,7 @@ DispatchBluetoothReply(BluetoothReplyRunnable* aRunnable,
|
||||
|
||||
aRunnable->SetReply(reply);
|
||||
if (NS_FAILED(NS_DispatchToMainThread(aRunnable))) {
|
||||
NS_WARNING("Failed to dispatch to main thread!");
|
||||
BT_WARNING("Failed to dispatch to main thread!");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -99,10 +99,11 @@ StartStopGonkBluetooth(bool aShouldEnable)
|
||||
// if isEnabled < 0, this means we brought up the firmware, but something
|
||||
// went wrong with bluetoothd. Post a warning message, but try to proceed
|
||||
// with firmware unloading if that was requested, so we can retry later.
|
||||
NS_WARNING("Bluetooth firmware up, but cannot connect to HCI socket! Check bluetoothd and try stopping/starting bluetooth again.");
|
||||
BT_WARNING("Bluetooth firmware up, but cannot connect to HCI socket! "
|
||||
"Check bluetoothd and try stopping/starting bluetooth again.");
|
||||
// Just disable now, return an error.
|
||||
if (sBluedroidFunctions.bt_disable() != 0) {
|
||||
NS_WARNING("Problem shutting down bluetooth after error in bringup!");
|
||||
BT_WARNING("Problem shutting down bluetooth after error in bringup!");
|
||||
}
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
@ -110,7 +111,7 @@ StartStopGonkBluetooth(bool aShouldEnable)
|
||||
result = (sBluedroidFunctions.bt_disable() == 0) ? true : false;
|
||||
}
|
||||
if (!result) {
|
||||
NS_WARNING("Could not set gonk bluetooth firmware!");
|
||||
BT_WARNING("Could not set gonk bluetooth firmware!");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
|
@ -48,7 +48,7 @@ public:
|
||||
mRequest->RequestComplete();
|
||||
|
||||
if (!mRequest->Send__delete__(mRequest, *mReply)) {
|
||||
NS_WARNING("Failed to send response to child process!");
|
||||
BT_WARNING("Failed to send response to child process!");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
}
|
||||
|
@ -35,7 +35,6 @@
|
||||
#include "nsThreadUtils.h"
|
||||
#include "nsDebug.h"
|
||||
#include "nsDataHashtable.h"
|
||||
#include "nsPrintfCString.h"
|
||||
#include "mozilla/Atomics.h"
|
||||
#include "mozilla/dom/bluetooth/BluetoothTypes.h"
|
||||
#include "mozilla/Hal.h"
|
||||
@ -170,7 +169,6 @@ static const char* sBluetoothDBusSignals[] =
|
||||
/**
|
||||
* DBus Connection held for the BluetoothCommandThread to use. Should never be
|
||||
* used by any other thread.
|
||||
*
|
||||
*/
|
||||
static nsRefPtr<RawDBusConnection> gThreadConnection;
|
||||
static nsDataHashtable<nsStringHashKey, DBusMessage* >* sPairingReqTable;
|
||||
@ -206,7 +204,7 @@ GetPairedDevicesFilter(const BluetoothValue& aValue)
|
||||
{
|
||||
// Check property 'Paired' and only paired device will be returned
|
||||
if (aValue.type() != BluetoothValue::TArrayOfBluetoothNamedValue) {
|
||||
NS_WARNING("Not a BluetoothNamedValue array!");
|
||||
BT_WARNING("Not a BluetoothNamedValue array!");
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -368,30 +366,6 @@ IsDBusMessageError(DBusMessage* aMsg, DBusError* aErr, nsAString& aErrorStr)
|
||||
return false;
|
||||
}
|
||||
|
||||
static void
|
||||
UnpackIntMessage(DBusMessage* aMsg, DBusError* aErr,
|
||||
BluetoothValue& aValue, nsAString& aErrorStr)
|
||||
{
|
||||
MOZ_ASSERT(aMsg);
|
||||
|
||||
DBusError err;
|
||||
dbus_error_init(&err);
|
||||
if (!IsDBusMessageError(aMsg, aErr, aErrorStr)) {
|
||||
MOZ_ASSERT(dbus_message_get_type(aMsg) == DBUS_MESSAGE_TYPE_METHOD_RETURN,
|
||||
"Got dbus callback that's not a METHOD_RETURN!");
|
||||
int i;
|
||||
if (!dbus_message_get_args(aMsg, &err, DBUS_TYPE_INT32,
|
||||
&i, DBUS_TYPE_INVALID)) {
|
||||
if (dbus_error_is_set(&err)) {
|
||||
aErrorStr = NS_ConvertUTF8toUTF16(err.message);
|
||||
LOG_AND_FREE_DBUS_ERROR(&err);
|
||||
}
|
||||
} else {
|
||||
aValue = (uint32_t)i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
UnpackObjectPathMessage(DBusMessage* aMsg, DBusError* aErr,
|
||||
BluetoothValue& aValue, nsAString& aErrorStr)
|
||||
@ -422,13 +396,13 @@ public:
|
||||
{
|
||||
BluetoothHfpManager* hfp = BluetoothHfpManager::Get();
|
||||
if (!hfp || !hfp->Listen()) {
|
||||
NS_WARNING("Failed to start listening for BluetoothHfpManager!");
|
||||
BT_WARNING("Failed to start listening for BluetoothHfpManager!");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
BluetoothOppManager* opp = BluetoothOppManager::Get();
|
||||
if (!opp || !opp->Listen()) {
|
||||
NS_WARNING("Failed to start listening for BluetoothOppManager!");
|
||||
BT_WARNING("Failed to start listening for BluetoothOppManager!");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
@ -651,9 +625,9 @@ GetProperty(DBusMessageIter aIter, Properties* aPropertyTypes,
|
||||
}
|
||||
|
||||
if ((receivedType != expectedType) && !convert) {
|
||||
NS_WARNING(nsPrintfCString("Iterator not type we expect! Property name: %s,
|
||||
Property Type Expected: %d, Property Type Received: %d",
|
||||
NS_ConvertUTF16toUTF8(propertyName).get(), expectedType, receivedType).get());
|
||||
BT_WARNING("Iterator not type we expect! Property name: %s,"
|
||||
"Property Type Expected: %d, Property Type Received: %d",
|
||||
NS_ConvertUTF16toUTF8(propertyName).get(), expectedType, receivedType);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -742,7 +716,7 @@ ParseProperties(DBusMessageIter* aIter,
|
||||
if (!GetProperty(dict_entry, aPropertyTypes, aPropertyTypeLen, &prop_index,
|
||||
props)) {
|
||||
aErrorStr.AssignLiteral("Can't Create Property!");
|
||||
NS_WARNING("Can't create property!");
|
||||
BT_WARNING("Can't create property!");
|
||||
return;
|
||||
}
|
||||
} while (dbus_message_iter_next(&dict));
|
||||
@ -802,13 +776,13 @@ ParsePropertyChange(DBusMessage* aMsg, BluetoothValue& aValue,
|
||||
|
||||
dbus_error_init(&err);
|
||||
if (!dbus_message_iter_init(aMsg, &iter)) {
|
||||
NS_WARNING("Can't create iterator!");
|
||||
BT_WARNING("Can't create iterator!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!GetProperty(iter, aPropertyTypes, aPropertyTypeLen,
|
||||
&prop_index, props)) {
|
||||
NS_WARNING("Can't get property!");
|
||||
BT_WARNING("Can't get property!");
|
||||
aErrorStr.AssignLiteral("Can't get property!");
|
||||
return;
|
||||
}
|
||||
@ -939,7 +913,7 @@ AgentEventFilter(DBusConnection *conn, DBusMessage *msg, void *data)
|
||||
DBusError err;
|
||||
dbus_error_init(&err);
|
||||
|
||||
BT_LOG("%s: %s, %s", __FUNCTION__,
|
||||
BT_LOGD("%s: %s, %s", __FUNCTION__,
|
||||
dbus_message_get_path(msg),
|
||||
dbus_message_get_member(msg));
|
||||
|
||||
@ -991,7 +965,7 @@ AgentEventFilter(DBusConnection *conn, DBusMessage *msg, void *data)
|
||||
goto handle_error;
|
||||
}
|
||||
|
||||
DBusMessage* reply;
|
||||
DBusMessage* reply = nullptr;
|
||||
int i;
|
||||
int length = sAuthorizedServiceClass.Length();
|
||||
for (i = 0; i < length; i++) {
|
||||
@ -1199,7 +1173,7 @@ public:
|
||||
ExtractHandles(aReply, handles);
|
||||
|
||||
if(!RegisterAgent(&sAgentVTable)) {
|
||||
NS_WARNING("Failed to register agent");
|
||||
BT_WARNING("Failed to register agent");
|
||||
}
|
||||
}
|
||||
|
||||
@ -1380,7 +1354,7 @@ EventFilter(DBusConnection* aConn, DBusMessage* aMsg, void* aData)
|
||||
nsAutoString signalName;
|
||||
nsAutoString signalInterface;
|
||||
|
||||
BT_LOG("%s: %s, %s, %s", __FUNCTION__,
|
||||
BT_LOGD("%s: %s, %s, %s", __FUNCTION__,
|
||||
dbus_message_get_interface(aMsg),
|
||||
dbus_message_get_path(aMsg),
|
||||
dbus_message_get_member(aMsg));
|
||||
@ -1406,7 +1380,7 @@ EventFilter(DBusConnection* aConn, DBusMessage* aMsg, void* aData)
|
||||
DBusMessageIter iter;
|
||||
|
||||
if (!dbus_message_iter_init(aMsg, &iter)) {
|
||||
NS_WARNING("Can't create iterator!");
|
||||
BT_WARNING("Can't create iterator!");
|
||||
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
|
||||
}
|
||||
|
||||
@ -1583,7 +1557,7 @@ EventFilter(DBusConnection* aConn, DBusMessage* aMsg, void* aData)
|
||||
}
|
||||
|
||||
if (!errorStr.IsEmpty()) {
|
||||
NS_WARNING(NS_ConvertUTF16toUTF8(errorStr).get());
|
||||
BT_WARNING(NS_ConvertUTF16toUTF8(errorStr).get());
|
||||
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
|
||||
}
|
||||
|
||||
@ -1633,7 +1607,7 @@ bool
|
||||
BluetoothDBusService::IsReady()
|
||||
{
|
||||
if (!IsEnabled() || !mConnection || !gThreadConnection || IsToggling()) {
|
||||
NS_WARNING("Bluetooth service is not ready yet!");
|
||||
BT_WARNING("Bluetooth service is not ready yet!");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@ -1646,7 +1620,7 @@ BluetoothDBusService::StartInternal()
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
|
||||
if (!StartDBus()) {
|
||||
NS_WARNING("Cannot start DBus thread!");
|
||||
BT_WARNING("Cannot start DBus thread!");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
@ -1655,7 +1629,7 @@ BluetoothDBusService::StartInternal()
|
||||
}
|
||||
|
||||
if (NS_FAILED(EstablishDBusConnection())) {
|
||||
NS_WARNING("Cannot start Main Thread DBus connection!");
|
||||
BT_WARNING("Cannot start Main Thread DBus connection!");
|
||||
StopDBus();
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
@ -1663,7 +1637,7 @@ BluetoothDBusService::StartInternal()
|
||||
gThreadConnection = new RawDBusConnection();
|
||||
|
||||
if (NS_FAILED(gThreadConnection->EstablishDBusConnection())) {
|
||||
NS_WARNING("Cannot start Sync Thread DBus connection!");
|
||||
BT_WARNING("Cannot start Sync Thread DBus connection!");
|
||||
StopDBus();
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
@ -1687,7 +1661,7 @@ BluetoothDBusService::StartInternal()
|
||||
// Add a filter for all incoming messages_base
|
||||
if (!dbus_connection_add_filter(mConnection, EventFilter,
|
||||
NULL, NULL)) {
|
||||
NS_WARNING("Cannot create DBus Event Filter for DBus Thread!");
|
||||
BT_WARNING("Cannot create DBus Event Filter for DBus Thread!");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
@ -1704,7 +1678,7 @@ BluetoothDBusService::StartInternal()
|
||||
// Adapter path has been ready. let's do PrepareAdapterRunnable now
|
||||
nsRefPtr<PrepareAdapterRunnable> b = new PrepareAdapterRunnable(v.get_nsString());
|
||||
if (NS_FAILED(NS_DispatchToMainThread(b))) {
|
||||
NS_WARNING("Failed to dispatch to main thread!");
|
||||
BT_WARNING("Failed to dispatch to main thread!");
|
||||
}
|
||||
}
|
||||
|
||||
@ -2276,7 +2250,7 @@ BluetoothDBusService::SetProperty(BluetoothObjectType aType,
|
||||
"SetProperty");
|
||||
|
||||
if (!msg) {
|
||||
NS_WARNING("Could not allocate D-Bus message object!");
|
||||
BT_WARNING("Could not allocate D-Bus message object!");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
@ -2284,7 +2258,7 @@ BluetoothDBusService::SetProperty(BluetoothObjectType aType,
|
||||
const char* propName = intermediatePropName.get();
|
||||
if (!dbus_message_append_args(msg, DBUS_TYPE_STRING, &propName,
|
||||
DBUS_TYPE_INVALID)) {
|
||||
NS_WARNING("Couldn't append arguments to dbus message!");
|
||||
BT_WARNING("Couldn't append arguments to dbus message!");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
@ -2306,7 +2280,7 @@ BluetoothDBusService::SetProperty(BluetoothObjectType aType,
|
||||
val = &(tmp_int);
|
||||
type = DBUS_TYPE_BOOLEAN;
|
||||
} else {
|
||||
NS_WARNING("Property type not handled!");
|
||||
BT_WARNING("Property type not handled!");
|
||||
dbus_message_unref(msg);
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
@ -2318,7 +2292,7 @@ BluetoothDBusService::SetProperty(BluetoothObjectType aType,
|
||||
var_type, &value_iter) ||
|
||||
!dbus_message_iter_append_basic(&value_iter, type, val) ||
|
||||
!dbus_message_iter_close_container(&iter, &value_iter)) {
|
||||
NS_WARNING("Could not append argument to method call!");
|
||||
BT_WARNING("Could not append argument to method call!");
|
||||
dbus_message_unref(msg);
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
@ -2331,7 +2305,7 @@ BluetoothDBusService::SetProperty(BluetoothObjectType aType,
|
||||
1000,
|
||||
GetVoidCallback,
|
||||
(void*)aRunnable)) {
|
||||
NS_WARNING("Could not start async function!");
|
||||
BT_WARNING("Could not start async function!");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
runnable.forget();
|
||||
@ -2413,7 +2387,7 @@ BluetoothDBusService::CreatePairedDeviceInternal(
|
||||
DBUS_TYPE_STRING, &capabilities,
|
||||
DBUS_TYPE_INVALID);
|
||||
if (!ret) {
|
||||
NS_WARNING("Could not start async function!");
|
||||
BT_WARNING("Could not start async function!");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
@ -2677,7 +2651,7 @@ BluetoothDBusService::IsConnected(const uint16_t aServiceUuid)
|
||||
BluetoothProfileManagerBase* profile =
|
||||
BluetoothUuidHelper::GetBluetoothProfileManager(aServiceUuid);
|
||||
if (!profile) {
|
||||
NS_WARNING(ERR_UNKNOWN_PROFILE);
|
||||
BT_WARNING(ERR_UNKNOWN_PROFILE);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -4,8 +4,8 @@
|
||||
* 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/. */
|
||||
|
||||
#ifndef mozilla_dom_bluetooth_bluetoothdbuseventservice_h__
|
||||
#define mozilla_dom_bluetooth_bluetoothdbuseventservice_h__
|
||||
#ifndef mozilla_dom_bluetooth_bluetoothdbusservice_h__
|
||||
#define mozilla_dom_bluetooth_bluetoothdbusservice_h__
|
||||
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "BluetoothCommon.h"
|
||||
|
@ -812,12 +812,12 @@ add_test(function test_PduHelper_parseHeaders() {
|
||||
|
||||
// Parse ends with Content-Type
|
||||
let expect = {};
|
||||
expect["x-mms-mms-version"] = MMS_VERSION;
|
||||
expect["x-mms-mms-version"] = MMS_VERSION_1_3;
|
||||
expect["content-type"] = {
|
||||
media: "application/vnd.wap.multipart.related",
|
||||
params: null,
|
||||
};
|
||||
parse([0x80 | 0x0D, 0x80 | MMS_VERSION, // X-Mms-Mms-Version: 1.3
|
||||
parse([0x80 | 0x0D, 0x80 | MMS_VERSION_1_3, // X-Mms-Mms-Version: 1.3
|
||||
0x80 | 0x04, 0x80 | 0x33, // Content-Type: application/vnd.wap.multipart.related
|
||||
0x80 | 0x0C, MMS_PDU_TYPE_SEND_REQ // X-Mms-Message-Type: M-Send.req
|
||||
], expect);
|
||||
@ -904,7 +904,7 @@ add_test(function test_PduHelper_encodeHeaders() {
|
||||
|
||||
let headers = {};
|
||||
headers["x-mms-message-type"] = MMS_PDU_TYPE_SEND_REQ;
|
||||
headers["x-mms-mms-version"] = MMS_VERSION;
|
||||
headers["x-mms-mms-version"] = MMS_VERSION_1_3;
|
||||
headers["x-mms-transaction-id"] = "asdf";
|
||||
headers["to"] = { address: "+123", type: "PLMN" };
|
||||
headers["content-type"] = {
|
||||
@ -913,7 +913,7 @@ add_test(function test_PduHelper_encodeHeaders() {
|
||||
wsp_encode_test_ex(func, headers,
|
||||
Array.concat([0x80 | 0x0C, MMS_PDU_TYPE_SEND_REQ])
|
||||
.concat([0x80 | 0x18]).concat(strToCharCodeArray(headers["x-mms-transaction-id"]))
|
||||
.concat([0x80 | 0x0D, 0x80 | MMS_VERSION])
|
||||
.concat([0x80 | 0x0D, 0x80 | MMS_VERSION_1_3])
|
||||
.concat([0x80 | 0x17]).concat(strToCharCodeArray("+123/TYPE=PLMN"))
|
||||
.concat([0x80 | 0x04, 0x80 | 0x33]));
|
||||
|
||||
|
@ -345,7 +345,7 @@ XPCOMUtils.defineLazyGetter(this, "gMessageManager", function () {
|
||||
// already forgotten its permissions so we need to unregister the target
|
||||
// for every permission.
|
||||
this._unregisterMessageTarget(null, msg.target);
|
||||
return;
|
||||
return null;
|
||||
}
|
||||
|
||||
if (RIL_IPC_MOBILECONNECTION_MSG_NAMES.indexOf(msg.name) != -1) {
|
||||
@ -388,16 +388,16 @@ XPCOMUtils.defineLazyGetter(this, "gMessageManager", function () {
|
||||
switch (msg.name) {
|
||||
case "RIL:RegisterMobileConnectionMsg":
|
||||
this._registerMessageTarget("mobileconnection", msg.target);
|
||||
return;
|
||||
return null;
|
||||
case "RIL:RegisterIccMsg":
|
||||
this._registerMessageTarget("icc", msg.target);
|
||||
return;
|
||||
return null;
|
||||
case "RIL:RegisterVoicemailMsg":
|
||||
this._registerMessageTarget("voicemail", msg.target);
|
||||
return;
|
||||
return null;
|
||||
case "RIL:RegisterCellBroadcastMsg":
|
||||
this._registerMessageTarget("cellbroadcast", msg.target);
|
||||
return;
|
||||
return null;
|
||||
}
|
||||
|
||||
let clientId = msg.json.clientId || 0;
|
||||
@ -914,6 +914,7 @@ RadioInterface.prototype = {
|
||||
this.workerMessenger.sendWithIPCMessage(msg, "queryVoicePrivacyMode");
|
||||
break;
|
||||
}
|
||||
return null;
|
||||
},
|
||||
|
||||
handleUnsolicitedWorkerMessage: function handleUnsolicitedWorkerMessage(message) {
|
||||
|
@ -53,13 +53,6 @@ if (!this.debug) {
|
||||
};
|
||||
}
|
||||
|
||||
const INT32_MAX = 2147483647;
|
||||
const UINT8_SIZE = 1;
|
||||
const UINT16_SIZE = 2;
|
||||
const UINT32_SIZE = 4;
|
||||
|
||||
const PDU_HEX_OCTET_SIZE = 4;
|
||||
|
||||
const DEFAULT_EMERGENCY_NUMBERS = ["112", "911"];
|
||||
|
||||
// Timeout value for emergency callback mode.
|
||||
@ -150,7 +143,7 @@ let Buf = {
|
||||
return;
|
||||
}
|
||||
|
||||
RIL.handleParcel(request_type, this.mReadAvailable, options);
|
||||
RIL.handleParcel(request_type, this.readAvailable, options);
|
||||
},
|
||||
|
||||
/**
|
||||
@ -166,7 +159,7 @@ let Buf = {
|
||||
if (DEBUG) debug("New outgoing parcel of type " + type);
|
||||
|
||||
// We're going to leave room for the parcel size at the beginning.
|
||||
this.mOutgoingIndex = this.PARCEL_SIZE_SIZE;
|
||||
this.outgoingIndex = this.PARCEL_SIZE_SIZE;
|
||||
this.writeUint32(type);
|
||||
this.writeUint32(this.mToken);
|
||||
|
||||
@ -3976,7 +3969,7 @@ let RIL = {
|
||||
Buf.newParcel(REQUEST_STK_SEND_ENVELOPE_WITH_STATUS, options);
|
||||
|
||||
Buf.seekIncoming(-1 * (Buf.getCurrentParcelSize() - Buf.getReadAvailable()
|
||||
- 2 * UINT32_SIZE)); // Skip response_type & request_type.
|
||||
- 2 * Buf.UINT32_SIZE)); // Skip response_type & request_type.
|
||||
let messageStringLength = Buf.readUint32(); // In semi-octets
|
||||
let smscLength = GsmPDUHelper.readHexOctet(); // In octets, inclusive of TOA
|
||||
let tpduLength = (messageStringLength / 2) - (smscLength + 1); // In octets
|
||||
@ -4009,7 +4002,7 @@ let RIL = {
|
||||
if (smscLength) {
|
||||
GsmPDUHelper.writeHexOctet(COMPREHENSIONTLV_TAG_ADDRESS);
|
||||
GsmPDUHelper.writeHexOctet(smscLength);
|
||||
Buf.copyIncomingToOutgoing(PDU_HEX_OCTET_SIZE * smscLength);
|
||||
Buf.copyIncomingToOutgoing(Buf.PDU_HEX_OCTET_SIZE * smscLength);
|
||||
}
|
||||
|
||||
// SMS TPDU-TLV
|
||||
@ -4019,7 +4012,7 @@ let RIL = {
|
||||
GsmPDUHelper.writeHexOctet(0x81);
|
||||
}
|
||||
GsmPDUHelper.writeHexOctet(tpduLength);
|
||||
Buf.copyIncomingToOutgoing(PDU_HEX_OCTET_SIZE * tpduLength);
|
||||
Buf.copyIncomingToOutgoing(Buf.PDU_HEX_OCTET_SIZE * tpduLength);
|
||||
|
||||
// Write 2 string delimitors for the total string length must be even.
|
||||
Buf.writeStringDelimiter(0);
|
||||
@ -4068,7 +4061,7 @@ let RIL = {
|
||||
GsmPDUHelper.writeHexOctet(responsePduLen);
|
||||
}
|
||||
// TP-UD
|
||||
Buf.copyIncomingToOutgoing(PDU_HEX_OCTET_SIZE * responsePduLen);
|
||||
Buf.copyIncomingToOutgoing(Buf.PDU_HEX_OCTET_SIZE * responsePduLen);
|
||||
// Write 2 string delimitors for the total string length must be even.
|
||||
Buf.writeStringDelimiter(0);
|
||||
|
||||
@ -4085,19 +4078,19 @@ let RIL = {
|
||||
Buf.writeUint32(EFSMS_STATUS_FREE);
|
||||
|
||||
Buf.seekIncoming(-1 * (Buf.getCurrentParcelSize() - Buf.getReadAvailable()
|
||||
- 2 * UINT32_SIZE)); // Skip response_type & request_type.
|
||||
- 2 * Buf.UINT32_SIZE)); // Skip response_type & request_type.
|
||||
let messageStringLength = Buf.readUint32(); // In semi-octets
|
||||
let smscLength = GsmPDUHelper.readHexOctet(); // In octets, inclusive of TOA
|
||||
let pduLength = (messageStringLength / 2) - (smscLength + 1); // In octets
|
||||
|
||||
// 1. Write PDU first.
|
||||
if (smscLength > 0) {
|
||||
Buf.seekIncoming(smscLength * PDU_HEX_OCTET_SIZE);
|
||||
Buf.seekIncoming(smscLength * Buf.PDU_HEX_OCTET_SIZE);
|
||||
}
|
||||
// Write EFsms PDU string length
|
||||
Buf.writeUint32(2 * pduLength); // In semi-octets
|
||||
if (pduLength) {
|
||||
Buf.copyIncomingToOutgoing(PDU_HEX_OCTET_SIZE * pduLength);
|
||||
Buf.copyIncomingToOutgoing(Buf.PDU_HEX_OCTET_SIZE * pduLength);
|
||||
}
|
||||
// Write 2 string delimitors for the total string length must be even.
|
||||
Buf.writeStringDelimiter(0);
|
||||
@ -4110,9 +4103,9 @@ let RIL = {
|
||||
// Write TOA & SMSC Address
|
||||
if (smscLength) {
|
||||
Buf.seekIncoming(-1 * (Buf.getCurrentParcelSize() - Buf.getReadAvailable()
|
||||
- 2 * UINT32_SIZE // Skip response_type, request_type.
|
||||
- 2 * PDU_HEX_OCTET_SIZE)); // Skip messageStringLength & smscLength.
|
||||
Buf.copyIncomingToOutgoing(PDU_HEX_OCTET_SIZE * smscLength);
|
||||
- 2 * Buf.UINT32_SIZE // Skip response_type, request_type.
|
||||
- 2 * Buf.PDU_HEX_OCTET_SIZE)); // Skip messageStringLength & smscLength.
|
||||
Buf.copyIncomingToOutgoing(Buf.PDU_HEX_OCTET_SIZE * smscLength);
|
||||
}
|
||||
// Write 2 string delimitors for the total string length must be even.
|
||||
Buf.writeStringDelimiter(0);
|
||||
@ -4129,7 +4122,8 @@ let RIL = {
|
||||
* @return A failure cause defined in 3GPP 23.040 clause 9.2.3.22.
|
||||
*/
|
||||
_processSmsMultipart: function _processSmsMultipart(message) {
|
||||
if (message.header && (message.header.segmentMaxSeq > 1)) {
|
||||
if (message.header && message.header.segmentMaxSeq &&
|
||||
(message.header.segmentMaxSeq > 1)) {
|
||||
message = this._processReceivedSmsSegment(message);
|
||||
} else {
|
||||
if (message.encoding == PDU_DCS_MSG_CODING_8BITS_ALPHABET) {
|
||||
@ -6583,7 +6577,7 @@ let GsmPDUHelper = {
|
||||
}
|
||||
}
|
||||
|
||||
Buf.seekIncoming((numOctets - i) * PDU_HEX_OCTET_SIZE);
|
||||
Buf.seekIncoming((numOctets - i) * Buf.PDU_HEX_OCTET_SIZE);
|
||||
return ret;
|
||||
},
|
||||
|
||||
@ -6695,7 +6689,7 @@ let GsmPDUHelper = {
|
||||
}
|
||||
|
||||
// Skip trailing 0xff
|
||||
Buf.seekIncoming((numOctets - i) * PDU_HEX_OCTET_SIZE);
|
||||
Buf.seekIncoming((numOctets - i) * Buf.PDU_HEX_OCTET_SIZE);
|
||||
break;
|
||||
case 0x81: // Fall through
|
||||
case 0x82:
|
||||
@ -6749,14 +6743,14 @@ let GsmPDUHelper = {
|
||||
}
|
||||
// Unread.
|
||||
// +1 for the GSM alphabet indexed at i,
|
||||
Buf.seekIncoming(-1 * (count + 1) * PDU_HEX_OCTET_SIZE);
|
||||
Buf.seekIncoming(-1 * (count + 1) * Buf.PDU_HEX_OCTET_SIZE);
|
||||
str += this.read8BitUnpackedToString(count + 1 - gotUCS2);
|
||||
i += count - gotUCS2;
|
||||
}
|
||||
}
|
||||
|
||||
// Skipping trailing 0xff
|
||||
Buf.seekIncoming((numOctets - len - headerLen) * PDU_HEX_OCTET_SIZE);
|
||||
Buf.seekIncoming((numOctets - len - headerLen) * Buf.PDU_HEX_OCTET_SIZE);
|
||||
break;
|
||||
}
|
||||
return str;
|
||||
@ -7026,7 +7020,7 @@ let GsmPDUHelper = {
|
||||
let number = this.readNumberWithLength();
|
||||
|
||||
// Skip 2 unused octets, CCP and EXT1.
|
||||
Buf.seekIncoming(2 * PDU_HEX_OCTET_SIZE);
|
||||
Buf.seekIncoming(2 * Buf.PDU_HEX_OCTET_SIZE);
|
||||
Buf.readStringDelimiter(length);
|
||||
|
||||
let contact = null;
|
||||
@ -7088,7 +7082,7 @@ let GsmPDUHelper = {
|
||||
numOctets--;
|
||||
return this.readICCUCS2String(temp, numOctets);
|
||||
} else {
|
||||
Buf.seekIncoming(-1 * PDU_HEX_OCTET_SIZE);
|
||||
Buf.seekIncoming(-1 * Buf.PDU_HEX_OCTET_SIZE);
|
||||
return this.read8BitUnpackedToString(numOctets);
|
||||
}
|
||||
},
|
||||
@ -7192,9 +7186,9 @@ let GsmPDUHelper = {
|
||||
}
|
||||
|
||||
number = this.readDiallingNumber(numLen);
|
||||
Buf.seekIncoming((ADN_MAX_BCD_NUMBER_BYTES - numLen) * PDU_HEX_OCTET_SIZE);
|
||||
Buf.seekIncoming((ADN_MAX_BCD_NUMBER_BYTES - numLen) * Buf.PDU_HEX_OCTET_SIZE);
|
||||
} else {
|
||||
Buf.seekIncoming(ADN_MAX_BCD_NUMBER_BYTES * PDU_HEX_OCTET_SIZE);
|
||||
Buf.seekIncoming(ADN_MAX_BCD_NUMBER_BYTES * Buf.PDU_HEX_OCTET_SIZE);
|
||||
}
|
||||
|
||||
return number;
|
||||
@ -9860,7 +9854,7 @@ let StkProactiveCmdHelper = {
|
||||
if (DEBUG) {
|
||||
debug("Unknown comprehension tag " + tag.toString(16));
|
||||
}
|
||||
Buf.seekIncoming(length * PDU_HEX_OCTET_SIZE);
|
||||
Buf.seekIncoming(length * Buf.PDU_HEX_OCTET_SIZE);
|
||||
return null;
|
||||
}
|
||||
return method.call(this, length);
|
||||
@ -10826,7 +10820,7 @@ let ICCIOHelper = {
|
||||
// The format is from TS 51.011, clause 9.2.1
|
||||
|
||||
// Skip RFU, data[0] data[1]
|
||||
Buf.seekIncoming(2 * PDU_HEX_OCTET_SIZE);
|
||||
Buf.seekIncoming(2 * Buf.PDU_HEX_OCTET_SIZE);
|
||||
|
||||
// File size, data[2], data[3]
|
||||
options.fileSize = (GsmPDUHelper.readHexOctet() << 8) |
|
||||
@ -10851,7 +10845,7 @@ let ICCIOHelper = {
|
||||
// 1 byte File status, data[11],
|
||||
// 1 byte Length of the following data, data[12].
|
||||
Buf.seekIncoming(((RESPONSE_DATA_STRUCTURE - RESPONSE_DATA_FILE_TYPE - 1) *
|
||||
PDU_HEX_OCTET_SIZE));
|
||||
Buf.PDU_HEX_OCTET_SIZE));
|
||||
|
||||
// Read Structure of EF, data[13]
|
||||
let efType = GsmPDUHelper.readHexOctet();
|
||||
@ -10865,7 +10859,7 @@ let ICCIOHelper = {
|
||||
options.recordSize = GsmPDUHelper.readHexOctet();
|
||||
options.totalRecords = options.fileSize / options.recordSize;
|
||||
} else {
|
||||
Buf.seekIncoming(1 * PDU_HEX_OCTET_SIZE);
|
||||
Buf.seekIncoming(1 * Buf.PDU_HEX_OCTET_SIZE);
|
||||
}
|
||||
|
||||
Buf.readStringDelimiter(strLen);
|
||||
@ -11258,7 +11252,7 @@ let ICCRecordHelper = {
|
||||
let tag = GsmPDUHelper.readHexOctet();
|
||||
if (tag == 0xff) {
|
||||
readLen++;
|
||||
Buf.seekIncoming((octetLen - readLen) * PDU_HEX_OCTET_SIZE);
|
||||
Buf.seekIncoming((octetLen - readLen) * Buf.PDU_HEX_OCTET_SIZE);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -11402,7 +11396,7 @@ let ICCRecordHelper = {
|
||||
email = GsmPDUHelper.read8BitUnpackedToString(octetLen - 2);
|
||||
|
||||
// Consumes the remaining buffer
|
||||
Buf.seekIncoming(2 * PDU_HEX_OCTET_SIZE); // For ADN SFI and Record Identifier
|
||||
Buf.seekIncoming(2 * Buf.PDU_HEX_OCTET_SIZE); // For ADN SFI and Record Identifier
|
||||
}
|
||||
|
||||
Buf.readStringDelimiter(strLen);
|
||||
@ -11480,17 +11474,17 @@ let ICCRecordHelper = {
|
||||
this._anrRecordSize = options.recordSize;
|
||||
|
||||
// Skip EF_AAS Record ID.
|
||||
Buf.seekIncoming(1 * PDU_HEX_OCTET_SIZE);
|
||||
Buf.seekIncoming(1 * Buf.PDU_HEX_OCTET_SIZE);
|
||||
|
||||
number = GsmPDUHelper.readNumberWithLength();
|
||||
|
||||
// Skip 2 unused octets, CCP and EXT1.
|
||||
Buf.seekIncoming(2 * PDU_HEX_OCTET_SIZE);
|
||||
Buf.seekIncoming(2 * Buf.PDU_HEX_OCTET_SIZE);
|
||||
|
||||
// For Type 2 there are two extra octets.
|
||||
if (fileType == ICC_USIM_TYPE2_TAG) {
|
||||
// Skip 2 unused octets, ADN SFI and Record Identifier.
|
||||
Buf.seekIncoming(2 * PDU_HEX_OCTET_SIZE);
|
||||
Buf.seekIncoming(2 * Buf.PDU_HEX_OCTET_SIZE);
|
||||
}
|
||||
|
||||
Buf.readStringDelimiter(strLen);
|
||||
@ -11587,7 +11581,7 @@ let ICCRecordHelper = {
|
||||
}
|
||||
|
||||
// Consume unread octets.
|
||||
Buf.seekIncoming((octetLen - readLen) * PDU_HEX_OCTET_SIZE);
|
||||
Buf.seekIncoming((octetLen - readLen) * Buf.PDU_HEX_OCTET_SIZE);
|
||||
Buf.readStringDelimiter(strLen);
|
||||
|
||||
if (DEBUG) debug("SPDI: " + JSON.stringify(RIL.iccInfoPrivate.SPDI));
|
||||
@ -11763,7 +11757,7 @@ let ICCRecordHelper = {
|
||||
}
|
||||
opl.push(oplElement);
|
||||
} else {
|
||||
Buf.seekIncoming(5 * PDU_HEX_OCTET_SIZE);
|
||||
Buf.seekIncoming(5 * Buf.PDU_HEX_OCTET_SIZE);
|
||||
}
|
||||
Buf.readStringDelimiter(strLen);
|
||||
|
||||
@ -11797,7 +11791,7 @@ let ICCRecordHelper = {
|
||||
if (tlvTag == 0xFF) {
|
||||
// Unused byte
|
||||
readLen++;
|
||||
Buf.seekIncoming((octetLen - readLen) * PDU_HEX_OCTET_SIZE);
|
||||
Buf.seekIncoming((octetLen - readLen) * Buf.PDU_HEX_OCTET_SIZE);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -11814,7 +11808,7 @@ let ICCRecordHelper = {
|
||||
pnnElement.shortName = GsmPDUHelper.readNetworkName(tlvLen);
|
||||
break;
|
||||
default:
|
||||
Buf.seekIncoming(tlvLen * PDU_HEX_OCTET_SIZE);
|
||||
Buf.seekIncoming(tlvLen * Buf.PDU_HEX_OCTET_SIZE);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -11872,7 +11866,7 @@ let ICCRecordHelper = {
|
||||
}
|
||||
return;
|
||||
} else {
|
||||
Buf.seekIncoming((octetLen - readLen) * PDU_HEX_OCTET_SIZE);
|
||||
Buf.seekIncoming((octetLen - readLen) * Buf.PDU_HEX_OCTET_SIZE);
|
||||
}
|
||||
|
||||
Buf.readStringDelimiter(strLen);
|
||||
@ -12925,7 +12919,7 @@ let RuimRecordHelper = {
|
||||
cdmaHomeNetworkId.push(((GsmPDUHelper.readHexOctet() & 0xff) << 8) | tempOctet);
|
||||
|
||||
// Consuming the last octet: band class.
|
||||
Buf.seekIncoming(PDU_HEX_OCTET_SIZE);
|
||||
Buf.seekIncoming(Buf.PDU_HEX_OCTET_SIZE);
|
||||
|
||||
Buf.readStringDelimiter(strLen);
|
||||
if (options.p1 < options.totalRecords) {
|
||||
@ -12982,7 +12976,7 @@ let RuimRecordHelper = {
|
||||
let displayCondition = GsmPDUHelper.readHexOctet();
|
||||
let codingScheme = GsmPDUHelper.readHexOctet();
|
||||
// Skip one octet: language indicator.
|
||||
Buf.seekIncoming(PDU_HEX_OCTET_SIZE);
|
||||
Buf.seekIncoming(Buf.PDU_HEX_OCTET_SIZE);
|
||||
let readLen = 3;
|
||||
|
||||
// SPN String ends up with 0xff.
|
||||
@ -13018,7 +13012,7 @@ let RuimRecordHelper = {
|
||||
", Display condition: " + displayCondition);
|
||||
}
|
||||
RIL.iccInfoPrivate.spnDisplayCondition = displayCondition;
|
||||
Buf.seekIncoming((octetLen - readLen) * PDU_HEX_OCTET_SIZE);
|
||||
Buf.seekIncoming((octetLen - readLen) * Buf.PDU_HEX_OCTET_SIZE);
|
||||
Buf.readStringDelimiter(strLen);
|
||||
}
|
||||
|
||||
|
@ -25,7 +25,10 @@ function newWorker(custom_ns) {
|
||||
let worker_ns = {
|
||||
importScripts: function fakeImportScripts() {
|
||||
Array.slice(arguments).forEach(function (script) {
|
||||
subscriptLoader.loadSubScript("resource://gre/modules/" + script, this);
|
||||
if (!script.startsWith("resource:")) {
|
||||
script = "resource://gre/modules/" + script;
|
||||
}
|
||||
subscriptLoader.loadSubScript(script, this);
|
||||
}, this);
|
||||
},
|
||||
|
||||
@ -54,6 +57,22 @@ function newWorker(custom_ns) {
|
||||
worker_ns[key] = custom_ns[key];
|
||||
}
|
||||
|
||||
// fake require() for toolkit/components/workerloader/require.js
|
||||
let require = (function() {
|
||||
return function require(script) {
|
||||
worker_ns.module = {};
|
||||
worker_ns.importScripts(script);
|
||||
return worker_ns;
|
||||
}
|
||||
})();
|
||||
|
||||
Object.freeze(require);
|
||||
Object.defineProperty(worker_ns, "require", {
|
||||
value: require,
|
||||
enumerable: true,
|
||||
configurable: false
|
||||
});
|
||||
|
||||
// Load the RIL worker itself.
|
||||
worker_ns.importScripts("ril_worker.js");
|
||||
|
||||
@ -123,15 +142,16 @@ function newIncomingParcel(fakeParcelSize, response, request, data) {
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function newRadioInterfaceLayer() {
|
||||
let ril_ns = {
|
||||
ChromeWorker: function ChromeWorker() {
|
||||
// Stub function
|
||||
},
|
||||
};
|
||||
let ril_ns;
|
||||
function newRadioInterface() {
|
||||
if (!ril_ns) {
|
||||
ril_ns = {};
|
||||
subscriptLoader.loadSubScript("resource://gre/components/RadioInterfaceLayer.js", ril_ns);
|
||||
}
|
||||
|
||||
subscriptLoader.loadSubScript("resource://gre/components/RadioInterfaceLayer.js", ril_ns);
|
||||
return new ril_ns.RadioInterfaceLayer();
|
||||
return {
|
||||
__proto__: ril_ns.RadioInterface.prototype,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -32,7 +32,8 @@ function add_test_incoming_parcel(parcel, handler) {
|
||||
}
|
||||
|
||||
// supports only requests less or equal than UINT8_MAX(255).
|
||||
let request = parcel[worker.PARCEL_SIZE_SIZE + worker.UINT32_SIZE];
|
||||
let buf = worker.Buf;
|
||||
let request = parcel[buf.PARCEL_SIZE_SIZE + buf.UINT32_SIZE];
|
||||
worker.RIL[request] = function ril_request_handler() {
|
||||
handler(worker);
|
||||
worker.postMessage();
|
||||
@ -111,19 +112,19 @@ add_test(function test_incoming_parcel_buffer_overwritten() {
|
||||
|
||||
// Prepare two parcels, whose sizes are both smaller than the incoming buffer
|
||||
// size but larger when combined, to trigger the bug.
|
||||
let pA_dataLength = buf.INCOMING_BUFFER_LENGTH / 2;
|
||||
let pA_dataLength = buf.incomingBufferLength / 2;
|
||||
let pA = newIncomingParcel(-1,
|
||||
worker.RESPONSE_TYPE_UNSOLICITED,
|
||||
request,
|
||||
calloc(pA_dataLength, 1));
|
||||
let pA_parcelSize = pA.length - worker.PARCEL_SIZE_SIZE;
|
||||
let pA_parcelSize = pA.length - buf.PARCEL_SIZE_SIZE;
|
||||
|
||||
let pB_dataLength = buf.INCOMING_BUFFER_LENGTH * 3 / 4;
|
||||
let pB_dataLength = buf.incomingBufferLength * 3 / 4;
|
||||
let pB = newIncomingParcel(-1,
|
||||
worker.RESPONSE_TYPE_UNSOLICITED,
|
||||
request,
|
||||
calloc(pB_dataLength, 1));
|
||||
let pB_parcelSize = pB.length - worker.PARCEL_SIZE_SIZE;
|
||||
let pB_parcelSize = pB.length - buf.PARCEL_SIZE_SIZE;
|
||||
|
||||
// First, send an incomplete pA and verifies related data pointer:
|
||||
let p1 = pA.subarray(0, pA.length - 1);
|
||||
@ -134,7 +135,7 @@ add_test(function test_incoming_parcel_buffer_overwritten() {
|
||||
// than 4 octets.
|
||||
do_check_eq(buf.currentParcelSize, pA_parcelSize);
|
||||
// buf.readIncoming should contains remaining unconsumed octets count.
|
||||
do_check_eq(buf.readIncoming, p1.length - worker.PARCEL_SIZE_SIZE);
|
||||
do_check_eq(buf.readIncoming, p1.length - buf.PARCEL_SIZE_SIZE);
|
||||
// buf.incomingWriteIndex should be ready to accept the last octet.
|
||||
do_check_eq(buf.incomingWriteIndex, p1.length);
|
||||
|
||||
|
@ -5,527 +5,11 @@ subscriptLoader.loadSubScript("resource://gre/modules/ril_consts.js", this);
|
||||
|
||||
const ESCAPE = "\uffff";
|
||||
const RESCTL = "\ufffe";
|
||||
const LF = "\n";
|
||||
const CR = "\r";
|
||||
const SP = " ";
|
||||
const FF = "\u000c";
|
||||
|
||||
function run_test() {
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify validity of the national language tables
|
||||
*/
|
||||
add_test(function test_nl_locking_shift_tables_validity() {
|
||||
for (let lst = 0; lst < PDU_NL_LOCKING_SHIFT_TABLES.length; lst++) {
|
||||
do_print("Verifying PDU_NL_LOCKING_SHIFT_TABLES[" + lst + "]");
|
||||
|
||||
let table = PDU_NL_LOCKING_SHIFT_TABLES[lst];
|
||||
|
||||
// Make sure table length is 128, or it will break table lookup algorithm.
|
||||
do_check_eq(table.length, 128);
|
||||
|
||||
// Make sure special values are preserved.
|
||||
do_check_eq(table[PDU_NL_EXTENDED_ESCAPE], ESCAPE);
|
||||
do_check_eq(table[PDU_NL_LINE_FEED], LF);
|
||||
do_check_eq(table[PDU_NL_CARRIAGE_RETURN], CR);
|
||||
do_check_eq(table[PDU_NL_SPACE], SP);
|
||||
}
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
add_test(function test_nl_single_shift_tables_validity() {
|
||||
for (let sst = 0; sst < PDU_NL_SINGLE_SHIFT_TABLES.length; sst++) {
|
||||
do_print("Verifying PDU_NL_SINGLE_SHIFT_TABLES[" + sst + "]");
|
||||
|
||||
let table = PDU_NL_SINGLE_SHIFT_TABLES[sst];
|
||||
|
||||
// Make sure table length is 128, or it will break table lookup algorithm.
|
||||
do_check_eq(table.length, 128);
|
||||
|
||||
// Make sure special values are preserved.
|
||||
do_check_eq(table[PDU_NL_EXTENDED_ESCAPE], ESCAPE);
|
||||
do_check_eq(table[PDU_NL_PAGE_BREAK], FF);
|
||||
do_check_eq(table[PDU_NL_RESERVED_CONTROL], RESCTL);
|
||||
}
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
add_test(function test_gsm_sms_strict_7bit_charmap_validity() {
|
||||
let defaultTable = PDU_NL_LOCKING_SHIFT_TABLES[PDU_NL_IDENTIFIER_DEFAULT];
|
||||
let defaultShiftTable = PDU_NL_SINGLE_SHIFT_TABLES[PDU_NL_IDENTIFIER_DEFAULT];
|
||||
for (let from in GSM_SMS_STRICT_7BIT_CHARMAP) {
|
||||
let to = GSM_SMS_STRICT_7BIT_CHARMAP[from];
|
||||
do_print("Verifying GSM_SMS_STRICT_7BIT_CHARMAP[\"\\u0x"
|
||||
+ from.charCodeAt(0).toString(16) + "\"] => \"\\u"
|
||||
+ to.charCodeAt(0).toString(16) + "\"");
|
||||
|
||||
// Make sure "from" is not in default table
|
||||
do_check_eq(defaultTable.indexOf(from), -1);
|
||||
do_check_eq(defaultShiftTable.indexOf(from), -1);
|
||||
// Make sure "to" is in default table
|
||||
if ((defaultTable.indexOf(to) < 0)
|
||||
&& (defaultShiftTable.indexOf(to) < 0)) {
|
||||
do_check_eq(false, true);
|
||||
}
|
||||
}
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
/**
|
||||
* Verify GsmPDUHelper#readDataCodingScheme.
|
||||
*/
|
||||
add_test(function test_GsmPDUHelper_readDataCodingScheme() {
|
||||
let worker = newWorker({
|
||||
postRILMessage: function fakePostRILMessage(data) {
|
||||
// Do nothing
|
||||
},
|
||||
postMessage: function fakePostMessage(message) {
|
||||
// Do nothing
|
||||
}
|
||||
});
|
||||
|
||||
let helper = worker.GsmPDUHelper;
|
||||
function test_dcs(dcs, encoding, messageClass, mwi) {
|
||||
helper.readHexOctet = function () {
|
||||
return dcs;
|
||||
}
|
||||
|
||||
let msg = {};
|
||||
helper.readDataCodingScheme(msg);
|
||||
|
||||
do_check_eq(msg.dcs, dcs);
|
||||
do_check_eq(msg.encoding, encoding);
|
||||
do_check_eq(msg.messageClass, messageClass);
|
||||
do_check_eq(msg.mwi == null, mwi == null);
|
||||
if (mwi != null) {
|
||||
do_check_eq(msg.mwi.active, mwi.active);
|
||||
do_check_eq(msg.mwi.discard, mwi.discard);
|
||||
do_check_eq(msg.mwi.msgCount, mwi.msgCount);
|
||||
}
|
||||
}
|
||||
|
||||
// Group 00xx
|
||||
// Bit 3 and 2 indicate the character set being used.
|
||||
test_dcs(0x00, PDU_DCS_MSG_CODING_7BITS_ALPHABET,
|
||||
GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_NORMAL]);
|
||||
test_dcs(0x04, PDU_DCS_MSG_CODING_8BITS_ALPHABET,
|
||||
GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_NORMAL]);
|
||||
test_dcs(0x08, PDU_DCS_MSG_CODING_16BITS_ALPHABET,
|
||||
GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_NORMAL]);
|
||||
test_dcs(0x0C, PDU_DCS_MSG_CODING_7BITS_ALPHABET,
|
||||
GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_NORMAL]);
|
||||
// Bit 4, if set to 0, indicates that bits 1 to 0 are reserved and have no
|
||||
// message class meaning.
|
||||
test_dcs(0x01, PDU_DCS_MSG_CODING_7BITS_ALPHABET,
|
||||
GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_NORMAL]);
|
||||
test_dcs(0x02, PDU_DCS_MSG_CODING_7BITS_ALPHABET,
|
||||
GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_NORMAL]);
|
||||
test_dcs(0x03, PDU_DCS_MSG_CODING_7BITS_ALPHABET,
|
||||
GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_NORMAL]);
|
||||
// Bit 4, if set to 1, indicates that bits 1 to 0 have a message class meaning.
|
||||
test_dcs(0x10, PDU_DCS_MSG_CODING_7BITS_ALPHABET,
|
||||
GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_0]);
|
||||
test_dcs(0x11, PDU_DCS_MSG_CODING_7BITS_ALPHABET,
|
||||
GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_1]);
|
||||
test_dcs(0x12, PDU_DCS_MSG_CODING_7BITS_ALPHABET,
|
||||
GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_2]);
|
||||
test_dcs(0x13, PDU_DCS_MSG_CODING_7BITS_ALPHABET,
|
||||
GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_3]);
|
||||
|
||||
// Group 01xx
|
||||
test_dcs(0x50, PDU_DCS_MSG_CODING_7BITS_ALPHABET,
|
||||
GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_0]);
|
||||
|
||||
// Group 1000..1011: reserved
|
||||
test_dcs(0x8F, PDU_DCS_MSG_CODING_7BITS_ALPHABET,
|
||||
GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_NORMAL]);
|
||||
test_dcs(0x9F, PDU_DCS_MSG_CODING_7BITS_ALPHABET,
|
||||
GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_NORMAL]);
|
||||
test_dcs(0xAF, PDU_DCS_MSG_CODING_7BITS_ALPHABET,
|
||||
GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_NORMAL]);
|
||||
test_dcs(0xBF, PDU_DCS_MSG_CODING_7BITS_ALPHABET,
|
||||
GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_NORMAL]);
|
||||
|
||||
// Group 1100: Message Waiting Indication Group: Discard Message
|
||||
// Bit 3 indicates Indication Sense:
|
||||
test_dcs(0xC0, PDU_DCS_MSG_CODING_7BITS_ALPHABET,
|
||||
GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_NORMAL],
|
||||
{active: false, discard: true, msgCount: 0});
|
||||
test_dcs(0xC8, PDU_DCS_MSG_CODING_7BITS_ALPHABET,
|
||||
GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_NORMAL],
|
||||
{active: true, discard: true, msgCount: -1});
|
||||
// Bit 2 is reserved, and set to 0:
|
||||
test_dcs(0xCC, PDU_DCS_MSG_CODING_7BITS_ALPHABET,
|
||||
GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_NORMAL],
|
||||
{active: true, discard: true, msgCount: -1});
|
||||
|
||||
// Group 1101: Message Waiting Indication Group: Store Message
|
||||
// Bit 3 indicates Indication Sense:
|
||||
test_dcs(0xD0, PDU_DCS_MSG_CODING_7BITS_ALPHABET,
|
||||
GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_NORMAL],
|
||||
{active: false, discard: false, msgCount: 0});
|
||||
test_dcs(0xD8, PDU_DCS_MSG_CODING_7BITS_ALPHABET,
|
||||
GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_NORMAL],
|
||||
{active: true, discard: false, msgCount: -1});
|
||||
// Bit 2 is reserved, and set to 0:
|
||||
test_dcs(0xDC, PDU_DCS_MSG_CODING_7BITS_ALPHABET,
|
||||
GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_NORMAL],
|
||||
{active: true, discard: false, msgCount: -1});
|
||||
|
||||
// Group 1110: Message Waiting Indication Group: Store Message, UCS2
|
||||
// Bit 3 indicates Indication Sense:
|
||||
test_dcs(0xE0, PDU_DCS_MSG_CODING_16BITS_ALPHABET,
|
||||
GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_NORMAL],
|
||||
{active: false, discard: false, msgCount: 0});
|
||||
test_dcs(0xE8, PDU_DCS_MSG_CODING_16BITS_ALPHABET,
|
||||
GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_NORMAL],
|
||||
{active: true, discard: false, msgCount: -1});
|
||||
// Bit 2 is reserved, and set to 0:
|
||||
test_dcs(0xEC, PDU_DCS_MSG_CODING_16BITS_ALPHABET,
|
||||
GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_NORMAL],
|
||||
{active: true, discard: false, msgCount: -1});
|
||||
|
||||
// Group 1111
|
||||
test_dcs(0xF0, PDU_DCS_MSG_CODING_7BITS_ALPHABET,
|
||||
GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_0]);
|
||||
test_dcs(0xF1, PDU_DCS_MSG_CODING_7BITS_ALPHABET,
|
||||
GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_1]);
|
||||
test_dcs(0xF2, PDU_DCS_MSG_CODING_7BITS_ALPHABET,
|
||||
GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_2]);
|
||||
test_dcs(0xF3, PDU_DCS_MSG_CODING_7BITS_ALPHABET,
|
||||
GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_3]);
|
||||
test_dcs(0xF4, PDU_DCS_MSG_CODING_8BITS_ALPHABET,
|
||||
GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_0]);
|
||||
test_dcs(0xF5, PDU_DCS_MSG_CODING_8BITS_ALPHABET,
|
||||
GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_1]);
|
||||
test_dcs(0xF6, PDU_DCS_MSG_CODING_8BITS_ALPHABET,
|
||||
GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_2]);
|
||||
test_dcs(0xF7, PDU_DCS_MSG_CODING_8BITS_ALPHABET,
|
||||
GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_3]);
|
||||
// Bit 3 is reserved and should be set to 0, but if it doesn't we should
|
||||
// ignore it.
|
||||
test_dcs(0xF8, PDU_DCS_MSG_CODING_7BITS_ALPHABET,
|
||||
GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_0]);
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
/**
|
||||
* Verify RadioInterfaceLayer#_countGsm7BitSeptets() and
|
||||
* GsmPDUHelper#writeStringAsSeptets() algorithm match each other.
|
||||
*/
|
||||
add_test(function test_RadioInterfaceLayer__countGsm7BitSeptets() {
|
||||
let ril = newRadioInterfaceLayer();
|
||||
|
||||
let worker = newWorker({
|
||||
postRILMessage: function fakePostRILMessage(data) {
|
||||
// Do nothing
|
||||
},
|
||||
postMessage: function fakePostMessage(message) {
|
||||
// Do nothing
|
||||
}
|
||||
});
|
||||
|
||||
let helper = worker.GsmPDUHelper;
|
||||
helper.resetOctetWritten = function () {
|
||||
helper.octetsWritten = 0;
|
||||
};
|
||||
helper.writeHexOctet = function () {
|
||||
helper.octetsWritten++;
|
||||
};
|
||||
|
||||
function do_check_calc(str, expectedCalcLen, lst, sst, strict7BitEncoding, strToWrite) {
|
||||
do_check_eq(expectedCalcLen,
|
||||
ril._countGsm7BitSeptets(str,
|
||||
PDU_NL_LOCKING_SHIFT_TABLES[lst],
|
||||
PDU_NL_SINGLE_SHIFT_TABLES[sst],
|
||||
strict7BitEncoding));
|
||||
|
||||
helper.resetOctetWritten();
|
||||
strToWrite = strToWrite || str;
|
||||
helper.writeStringAsSeptets(strToWrite, 0, lst, sst);
|
||||
do_check_eq(Math.ceil(expectedCalcLen * 7 / 8), helper.octetsWritten);
|
||||
}
|
||||
|
||||
// Test calculation encoded message length using both locking/single shift tables.
|
||||
for (let lst = 0; lst < PDU_NL_LOCKING_SHIFT_TABLES.length; lst++) {
|
||||
let langTable = PDU_NL_LOCKING_SHIFT_TABLES[lst];
|
||||
|
||||
let str = langTable.substring(0, PDU_NL_EXTENDED_ESCAPE)
|
||||
+ langTable.substring(PDU_NL_EXTENDED_ESCAPE + 1);
|
||||
|
||||
for (let sst = 0; sst < PDU_NL_SINGLE_SHIFT_TABLES.length; sst++) {
|
||||
let langShiftTable = PDU_NL_SINGLE_SHIFT_TABLES[sst];
|
||||
|
||||
// <escape>, <resctrl> should be ignored.
|
||||
do_check_calc(ESCAPE + RESCTL, 0, lst, sst);
|
||||
|
||||
// Characters defined in locking shift table should be encoded directly.
|
||||
do_check_calc(str, str.length, lst, sst);
|
||||
|
||||
let [str1, str2] = ["", ""];
|
||||
for (let i = 0; i < langShiftTable.length; i++) {
|
||||
if ((i == PDU_NL_EXTENDED_ESCAPE) || (i == PDU_NL_RESERVED_CONTROL)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let c = langShiftTable[i];
|
||||
if (langTable.indexOf(c) >= 0) {
|
||||
str1 += c;
|
||||
} else {
|
||||
str2 += c;
|
||||
}
|
||||
}
|
||||
|
||||
// Characters found in both locking/single shift tables should be
|
||||
// directly encoded.
|
||||
do_check_calc(str1, str1.length, lst, sst);
|
||||
|
||||
// Characters found only in single shift tables should be encoded as
|
||||
// <escape><code>, therefore doubles its original length.
|
||||
do_check_calc(str2, str2.length * 2, lst, sst);
|
||||
}
|
||||
}
|
||||
|
||||
// Bug 790192: support strict GSM SMS 7-Bit encoding
|
||||
let str = "", strToWrite = "", gsmLen = 0;
|
||||
for (let c in GSM_SMS_STRICT_7BIT_CHARMAP) {
|
||||
str += c;
|
||||
strToWrite += GSM_SMS_STRICT_7BIT_CHARMAP[c];
|
||||
if (PDU_NL_LOCKING_SHIFT_TABLES.indexOf(GSM_SMS_STRICT_7BIT_CHARMAP[c])) {
|
||||
gsmLen += 1;
|
||||
} else {
|
||||
gsmLen += 2;
|
||||
}
|
||||
}
|
||||
do_check_calc(str, gsmLen,
|
||||
PDU_NL_IDENTIFIER_DEFAULT, PDU_NL_IDENTIFIER_DEFAULT,
|
||||
true, strToWrite);
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
/**
|
||||
* Verify RadioInterfaceLayer#calculateUserDataLength handles national language
|
||||
* selection correctly.
|
||||
*/
|
||||
add_test(function test_RadioInterfaceLayer__calculateUserDataLength() {
|
||||
let ril = newRadioInterfaceLayer();
|
||||
|
||||
function test_calc(str, expected, enabledGsmTableTuples, strict7BitEncoding) {
|
||||
ril.enabledGsmTableTuples = enabledGsmTableTuples;
|
||||
let options = ril._calculateUserDataLength(str, strict7BitEncoding);
|
||||
|
||||
do_check_eq(expected[0], options.dcs);
|
||||
do_check_eq(expected[1], options.encodedFullBodyLength);
|
||||
do_check_eq(expected[2], options.userDataHeaderLength);
|
||||
do_check_eq(expected[3], options.langIndex);
|
||||
do_check_eq(expected[4], options.langShiftIndex);
|
||||
}
|
||||
|
||||
// Test UCS fallback
|
||||
// - No any default enabled nl tables
|
||||
test_calc("A", [PDU_DCS_MSG_CODING_16BITS_ALPHABET, 2, 0,], []);
|
||||
// - Character not defined in enabled nl tables
|
||||
test_calc("A", [PDU_DCS_MSG_CODING_16BITS_ALPHABET, 2, 0,], [[2, 2]]);
|
||||
|
||||
// With GSM default nl tables
|
||||
test_calc("A", [PDU_DCS_MSG_CODING_7BITS_ALPHABET, 1, 0, 0, 0], [[0, 0]]);
|
||||
// - SP is defined in both locking/single shift tables, should be directly
|
||||
// encoded.
|
||||
test_calc(SP, [PDU_DCS_MSG_CODING_7BITS_ALPHABET, 1, 0, 0, 0], [[0, 0]]);
|
||||
// - '^' is only defined in single shift table, should be encoded as
|
||||
// <escape>^.
|
||||
test_calc("^", [PDU_DCS_MSG_CODING_7BITS_ALPHABET, 2, 0, 0, 0], [[0, 0]]);
|
||||
|
||||
// Test userDataHeaderLength calculation
|
||||
// - Header contains both IEIs
|
||||
test_calc("A", [PDU_DCS_MSG_CODING_7BITS_ALPHABET, 1, 6, 1, 1], [[1, 1]]);
|
||||
// - Header contains only locking shift table IEI
|
||||
test_calc("A", [PDU_DCS_MSG_CODING_7BITS_ALPHABET, 1, 3, 1, 0], [[1, 0]]);
|
||||
// - Header contains only single shift table IEI
|
||||
test_calc("^", [PDU_DCS_MSG_CODING_7BITS_ALPHABET, 2, 3, 0, 1], [[0, 1]]);
|
||||
|
||||
// Test minimum cost nl tables selection
|
||||
// - 'A' is defined in locking shift table
|
||||
test_calc("A", [PDU_DCS_MSG_CODING_7BITS_ALPHABET, 1, 3, 1, 0], [[1, 0], [2, 0]]);
|
||||
test_calc("A", [PDU_DCS_MSG_CODING_7BITS_ALPHABET, 1, 3, 1, 0], [[2, 0], [1, 0]]);
|
||||
// - 'A' is defined in single shift table
|
||||
test_calc("A", [PDU_DCS_MSG_CODING_7BITS_ALPHABET, 2, 6, 2, 4], [[2, 0], [2, 4]]);
|
||||
test_calc("A", [PDU_DCS_MSG_CODING_7BITS_ALPHABET, 2, 6, 2, 4], [[2, 4], [2, 0]]);
|
||||
// - 'A' is defined in locking shift table of one tuple and in single shift
|
||||
// table of another.
|
||||
test_calc("A", [PDU_DCS_MSG_CODING_7BITS_ALPHABET, 1, 3, 1, 0], [[1, 0], [2, 4]]);
|
||||
test_calc("A", [PDU_DCS_MSG_CODING_7BITS_ALPHABET, 1, 3, 1, 0], [[2, 4], [1, 0]]);
|
||||
|
||||
// Test Bug 733981
|
||||
// - Case 1, headerLen is in octets, not septets. "\\" is defined in default
|
||||
// single shift table and Portuguese locking shift table. The original code
|
||||
// will add headerLen 7(octets), which should be 8(septets), to calculated
|
||||
// cost and gets 14, which should be 15 in total for the first run. As for
|
||||
// the second run, it will be undoubtedly 14 in total. With correct fix,
|
||||
// the best choice should be the second one.
|
||||
test_calc("\\\\\\\\\\\\\\",
|
||||
[PDU_DCS_MSG_CODING_7BITS_ALPHABET, 14, 0, 0, 0], [[3, 1], [0, 0]]);
|
||||
// - Case 2, possible early return non-best choice. The original code will
|
||||
// get total cost 6 in the first run and returns immediately. With correct
|
||||
// fix, the best choice should be the second one.
|
||||
test_calc(ESCAPE + ESCAPE + ESCAPE + ESCAPE + ESCAPE + "\\",
|
||||
[PDU_DCS_MSG_CODING_7BITS_ALPHABET, 2, 0, 0, 0], [[3, 0], [0, 0]]);
|
||||
|
||||
// Test Bug 790192: support strict GSM SMS 7-Bit encoding
|
||||
let str = "", gsmLen = 0, udhl = 0;
|
||||
for (let c in GSM_SMS_STRICT_7BIT_CHARMAP) {
|
||||
str += c;
|
||||
if (PDU_NL_LOCKING_SHIFT_TABLES.indexOf(GSM_SMS_STRICT_7BIT_CHARMAP[c])) {
|
||||
gsmLen += 1;
|
||||
} else {
|
||||
gsmLen += 2;
|
||||
}
|
||||
}
|
||||
if (str.length > PDU_MAX_USER_DATA_UCS2) {
|
||||
udhl = 5;
|
||||
}
|
||||
test_calc(str, [PDU_DCS_MSG_CODING_7BITS_ALPHABET, gsmLen, 0, 0, 0], [[0, 0]], true);
|
||||
test_calc(str, [PDU_DCS_MSG_CODING_16BITS_ALPHABET, str.length * 2, udhl], [[0, 0]]);
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
function generateStringOfLength(str, length) {
|
||||
while (str.length < length) {
|
||||
if (str.length < (length / 2)) {
|
||||
str = str + str;
|
||||
} else {
|
||||
str = str + str.substr(0, length - str.length);
|
||||
}
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify RadioInterfaceLayer#_calculateUserDataLength7Bit multipart handling.
|
||||
*/
|
||||
add_test(function test_RadioInterfaceLayer__calculateUserDataLength7Bit_multipart() {
|
||||
let ril = newRadioInterfaceLayer();
|
||||
|
||||
function test_calc(str, expected) {
|
||||
let options = ril._calculateUserDataLength7Bit(str);
|
||||
|
||||
do_check_eq(expected[0], options.encodedFullBodyLength);
|
||||
do_check_eq(expected[1], options.userDataHeaderLength);
|
||||
do_check_eq(expected[2], options.segmentMaxSeq);
|
||||
}
|
||||
|
||||
test_calc(generateStringOfLength("A", PDU_MAX_USER_DATA_7BIT),
|
||||
[PDU_MAX_USER_DATA_7BIT, 0, 1]);
|
||||
test_calc(generateStringOfLength("A", PDU_MAX_USER_DATA_7BIT + 1),
|
||||
[PDU_MAX_USER_DATA_7BIT + 1, 5, 2]);
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
/**
|
||||
* Verify RadioInterfaceLayer#_fragmentText().
|
||||
*/
|
||||
add_test(function test_RadioInterfaceLayer__fragmentText7Bit() {
|
||||
let ril = newRadioInterfaceLayer();
|
||||
|
||||
function test_calc(str, strict7BitEncoding, expectedSegments) {
|
||||
expectedSegments = expectedSegments || 1;
|
||||
let options = ril._fragmentText(str, null, strict7BitEncoding);
|
||||
do_check_eq(expectedSegments, options.segments.length);
|
||||
}
|
||||
|
||||
// 7-Bit
|
||||
|
||||
// Boundary checks
|
||||
test_calc(generateStringOfLength("A", PDU_MAX_USER_DATA_7BIT), false);
|
||||
test_calc(generateStringOfLength("A", PDU_MAX_USER_DATA_7BIT), true);
|
||||
test_calc(generateStringOfLength("A", PDU_MAX_USER_DATA_7BIT + 1), false, 2);
|
||||
test_calc(generateStringOfLength("A", PDU_MAX_USER_DATA_7BIT + 1), true, 2);
|
||||
|
||||
// Escaped character
|
||||
test_calc(generateStringOfLength("{", PDU_MAX_USER_DATA_7BIT / 2), false);
|
||||
test_calc(generateStringOfLength("{", PDU_MAX_USER_DATA_7BIT / 2 + 1), false, 2);
|
||||
// Escaped character cannot be separated
|
||||
test_calc(generateStringOfLength("{", (PDU_MAX_USER_DATA_7BIT - 7) * 2 / 2), false, 3);
|
||||
|
||||
// Test headerLen, 7 = Math.ceil(6 * 8 / 7), 6 = headerLen + 1
|
||||
test_calc(generateStringOfLength("A", PDU_MAX_USER_DATA_7BIT - 7));
|
||||
test_calc(generateStringOfLength("A", (PDU_MAX_USER_DATA_7BIT - 7) * 2), false, 2);
|
||||
test_calc(generateStringOfLength("A", (PDU_MAX_USER_DATA_7BIT - 7) * 3), false, 3);
|
||||
|
||||
// UCS-2
|
||||
|
||||
// Boundary checks
|
||||
test_calc(generateStringOfLength("\ua2db", PDU_MAX_USER_DATA_UCS2));
|
||||
test_calc(generateStringOfLength("\ua2db", PDU_MAX_USER_DATA_UCS2), true);
|
||||
test_calc(generateStringOfLength("\ua2db", PDU_MAX_USER_DATA_UCS2 + 1), false, 2);
|
||||
// Bug 816082: when strict GSM SMS 7-Bit encoding is enabled, replace unicode
|
||||
// chars with '*'.
|
||||
test_calc(generateStringOfLength("\ua2db", PDU_MAX_USER_DATA_UCS2 + 1), true, 1);
|
||||
|
||||
// UCS2 character cannot be separated
|
||||
ril.segmentRef16Bit = true;
|
||||
test_calc(generateStringOfLength("\ua2db", (PDU_MAX_USER_DATA_UCS2 * 2 - 7) * 2 / 2), false, 3);
|
||||
ril.segmentRef16Bit = false;
|
||||
|
||||
// Test Bug 790192: support strict GSM SMS 7-Bit encoding
|
||||
for (let c in GSM_SMS_STRICT_7BIT_CHARMAP) {
|
||||
test_calc(generateStringOfLength(c, PDU_MAX_USER_DATA_7BIT), false, 3);
|
||||
test_calc(generateStringOfLength(c, PDU_MAX_USER_DATA_7BIT), true);
|
||||
test_calc(generateStringOfLength(c, PDU_MAX_USER_DATA_UCS2), false);
|
||||
}
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
/**
|
||||
* Verify GsmPDUHelper#writeStringAsSeptets() padding bits handling.
|
||||
*/
|
||||
add_test(function test_GsmPDUHelper_writeStringAsSeptets() {
|
||||
let worker = newWorker({
|
||||
postRILMessage: function fakePostRILMessage(data) {
|
||||
// Do nothing
|
||||
},
|
||||
postMessage: function fakePostMessage(message) {
|
||||
// Do nothing
|
||||
}
|
||||
});
|
||||
|
||||
let helper = worker.GsmPDUHelper;
|
||||
helper.resetOctetWritten = function () {
|
||||
helper.octetsWritten = 0;
|
||||
};
|
||||
helper.writeHexOctet = function () {
|
||||
helper.octetsWritten++;
|
||||
};
|
||||
|
||||
let base = "AAAAAAAA"; // Base string of 8 characters long
|
||||
for (let len = 0; len < 8; len++) {
|
||||
let str = base.substring(0, len);
|
||||
|
||||
for (let paddingBits = 0; paddingBits < 8; paddingBits++) {
|
||||
do_print("Verifying GsmPDUHelper.writeStringAsSeptets("
|
||||
+ str + ", " + paddingBits + ", <default>, <default>)");
|
||||
helper.resetOctetWritten();
|
||||
helper.writeStringAsSeptets(str, paddingBits, PDU_NL_IDENTIFIER_DEFAULT,
|
||||
PDU_NL_IDENTIFIER_DEFAULT);
|
||||
do_check_eq(Math.ceil(((len * 7) + paddingBits) / 8),
|
||||
helper.octetsWritten);
|
||||
}
|
||||
}
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
/**
|
||||
* Verify receiving SMS-DELIVERY messages
|
||||
*/
|
||||
@ -648,8 +132,8 @@ function add_test_receiving_sms(expected, pdu) {
|
||||
// Do nothing
|
||||
},
|
||||
postMessage: function fakePostMessage(message) {
|
||||
do_print("body: " + message.body);
|
||||
do_check_eq(expected, message.body)
|
||||
do_print("fullBody: " + message.fullBody);
|
||||
do_check_eq(expected, message.fullBody)
|
||||
}
|
||||
});
|
||||
|
||||
@ -661,10 +145,15 @@ function add_test_receiving_sms(expected, pdu) {
|
||||
});
|
||||
}
|
||||
|
||||
let test_receiving_7bit_alphabets__ril;
|
||||
let test_receiving_7bit_alphabets__worker;
|
||||
function test_receiving_7bit_alphabets(lst, sst) {
|
||||
let ril = newRadioInterfaceLayer();
|
||||
|
||||
let worker = newWriteHexOctetAsUint8Worker();
|
||||
if (!test_receiving_7bit_alphabets__ril) {
|
||||
test_receiving_7bit_alphabets__ril = newRadioInterface();
|
||||
test_receiving_7bit_alphabets__worker = newWriteHexOctetAsUint8Worker();
|
||||
}
|
||||
let ril = test_receiving_7bit_alphabets__ril;
|
||||
let worker = test_receiving_7bit_alphabets__worker;
|
||||
let helper = worker.GsmPDUHelper;
|
||||
let buf = worker.Buf;
|
||||
|
||||
@ -693,7 +182,7 @@ function test_receiving_7bit_alphabets(lst, sst) {
|
||||
}
|
||||
|
||||
function test_receiving_ucs2_alphabets(text) {
|
||||
let worker = newWriteHexOctetAsUint8Worker();
|
||||
let worker = test_receiving_7bit_alphabets__worker;
|
||||
let buf = worker.Buf;
|
||||
|
||||
function getUCS2RawBytes(expected) {
|
||||
@ -772,50 +261,3 @@ add_test(function test_sendSMS_UCS2_without_langIndex_langShiftIndex_defined() {
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* Verify GsmPDUHelper#readAddress
|
||||
*/
|
||||
add_test(function test_GsmPDUHelper_readAddress() {
|
||||
let worker = newWorker({
|
||||
postRILMessage: function fakePostRILMessage(data) {
|
||||
// Do nothing
|
||||
},
|
||||
postMessage: function fakePostMessage(message) {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
let helper = worker.GsmPDUHelper;
|
||||
function test_address(addrHex, addrString) {
|
||||
let uint16Array = [];
|
||||
let ix = 0;
|
||||
for (let i = 0; i < addrHex.length; ++i) {
|
||||
uint16Array[i] = addrHex[i].charCodeAt();
|
||||
}
|
||||
|
||||
worker.Buf.readUint16 = function (){
|
||||
if(ix >= uint16Array.length) {
|
||||
do_throw("out of range in uint16Array");
|
||||
}
|
||||
return uint16Array[ix++];
|
||||
}
|
||||
let length = helper.readHexOctet();
|
||||
let parsedAddr = helper.readAddress(length);
|
||||
do_check_eq(parsedAddr, addrString);
|
||||
}
|
||||
|
||||
// For AlphaNumeric
|
||||
test_address("04D01100", "_@");
|
||||
test_address("04D01000", "\u0394@");
|
||||
|
||||
// Direct prepand
|
||||
test_address("0B914151245584F6", "+14154255486");
|
||||
test_address("0E914151245584B633", "+14154255486#33");
|
||||
|
||||
// PDU_TOA_NATIONAL
|
||||
test_address("0BA14151245584F6", "14154255486");
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
233
dom/system/gonk/tests/test_ril_worker_sms_gsmpduhelper.js
Normal file
233
dom/system/gonk/tests/test_ril_worker_sms_gsmpduhelper.js
Normal file
@ -0,0 +1,233 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
subscriptLoader.loadSubScript("resource://gre/modules/ril_consts.js", this);
|
||||
|
||||
function run_test() {
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify GsmPDUHelper#readDataCodingScheme.
|
||||
*/
|
||||
add_test(function test_GsmPDUHelper_readDataCodingScheme() {
|
||||
let worker = newWorker({
|
||||
postRILMessage: function fakePostRILMessage(data) {
|
||||
// Do nothing
|
||||
},
|
||||
postMessage: function fakePostMessage(message) {
|
||||
// Do nothing
|
||||
}
|
||||
});
|
||||
|
||||
let helper = worker.GsmPDUHelper;
|
||||
function test_dcs(dcs, encoding, messageClass, mwi) {
|
||||
helper.readHexOctet = function () {
|
||||
return dcs;
|
||||
}
|
||||
|
||||
let msg = {};
|
||||
helper.readDataCodingScheme(msg);
|
||||
|
||||
do_check_eq(msg.dcs, dcs);
|
||||
do_check_eq(msg.encoding, encoding);
|
||||
do_check_eq(msg.messageClass, messageClass);
|
||||
do_check_eq(msg.mwi == null, mwi == null);
|
||||
if (mwi != null) {
|
||||
do_check_eq(msg.mwi.active, mwi.active);
|
||||
do_check_eq(msg.mwi.discard, mwi.discard);
|
||||
do_check_eq(msg.mwi.msgCount, mwi.msgCount);
|
||||
}
|
||||
}
|
||||
|
||||
// Group 00xx
|
||||
// Bit 3 and 2 indicate the character set being used.
|
||||
test_dcs(0x00, PDU_DCS_MSG_CODING_7BITS_ALPHABET,
|
||||
GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_NORMAL]);
|
||||
test_dcs(0x04, PDU_DCS_MSG_CODING_8BITS_ALPHABET,
|
||||
GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_NORMAL]);
|
||||
test_dcs(0x08, PDU_DCS_MSG_CODING_16BITS_ALPHABET,
|
||||
GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_NORMAL]);
|
||||
test_dcs(0x0C, PDU_DCS_MSG_CODING_7BITS_ALPHABET,
|
||||
GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_NORMAL]);
|
||||
// Bit 4, if set to 0, indicates that bits 1 to 0 are reserved and have no
|
||||
// message class meaning.
|
||||
test_dcs(0x01, PDU_DCS_MSG_CODING_7BITS_ALPHABET,
|
||||
GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_NORMAL]);
|
||||
test_dcs(0x02, PDU_DCS_MSG_CODING_7BITS_ALPHABET,
|
||||
GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_NORMAL]);
|
||||
test_dcs(0x03, PDU_DCS_MSG_CODING_7BITS_ALPHABET,
|
||||
GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_NORMAL]);
|
||||
// Bit 4, if set to 1, indicates that bits 1 to 0 have a message class meaning.
|
||||
test_dcs(0x10, PDU_DCS_MSG_CODING_7BITS_ALPHABET,
|
||||
GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_0]);
|
||||
test_dcs(0x11, PDU_DCS_MSG_CODING_7BITS_ALPHABET,
|
||||
GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_1]);
|
||||
test_dcs(0x12, PDU_DCS_MSG_CODING_7BITS_ALPHABET,
|
||||
GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_2]);
|
||||
test_dcs(0x13, PDU_DCS_MSG_CODING_7BITS_ALPHABET,
|
||||
GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_3]);
|
||||
|
||||
// Group 01xx
|
||||
test_dcs(0x50, PDU_DCS_MSG_CODING_7BITS_ALPHABET,
|
||||
GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_0]);
|
||||
|
||||
// Group 1000..1011: reserved
|
||||
test_dcs(0x8F, PDU_DCS_MSG_CODING_7BITS_ALPHABET,
|
||||
GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_NORMAL]);
|
||||
test_dcs(0x9F, PDU_DCS_MSG_CODING_7BITS_ALPHABET,
|
||||
GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_NORMAL]);
|
||||
test_dcs(0xAF, PDU_DCS_MSG_CODING_7BITS_ALPHABET,
|
||||
GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_NORMAL]);
|
||||
test_dcs(0xBF, PDU_DCS_MSG_CODING_7BITS_ALPHABET,
|
||||
GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_NORMAL]);
|
||||
|
||||
// Group 1100: Message Waiting Indication Group: Discard Message
|
||||
// Bit 3 indicates Indication Sense:
|
||||
test_dcs(0xC0, PDU_DCS_MSG_CODING_7BITS_ALPHABET,
|
||||
GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_NORMAL],
|
||||
{active: false, discard: true, msgCount: 0});
|
||||
test_dcs(0xC8, PDU_DCS_MSG_CODING_7BITS_ALPHABET,
|
||||
GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_NORMAL],
|
||||
{active: true, discard: true, msgCount: -1});
|
||||
// Bit 2 is reserved, and set to 0:
|
||||
test_dcs(0xCC, PDU_DCS_MSG_CODING_7BITS_ALPHABET,
|
||||
GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_NORMAL],
|
||||
{active: true, discard: true, msgCount: -1});
|
||||
|
||||
// Group 1101: Message Waiting Indication Group: Store Message
|
||||
// Bit 3 indicates Indication Sense:
|
||||
test_dcs(0xD0, PDU_DCS_MSG_CODING_7BITS_ALPHABET,
|
||||
GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_NORMAL],
|
||||
{active: false, discard: false, msgCount: 0});
|
||||
test_dcs(0xD8, PDU_DCS_MSG_CODING_7BITS_ALPHABET,
|
||||
GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_NORMAL],
|
||||
{active: true, discard: false, msgCount: -1});
|
||||
// Bit 2 is reserved, and set to 0:
|
||||
test_dcs(0xDC, PDU_DCS_MSG_CODING_7BITS_ALPHABET,
|
||||
GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_NORMAL],
|
||||
{active: true, discard: false, msgCount: -1});
|
||||
|
||||
// Group 1110: Message Waiting Indication Group: Store Message, UCS2
|
||||
// Bit 3 indicates Indication Sense:
|
||||
test_dcs(0xE0, PDU_DCS_MSG_CODING_16BITS_ALPHABET,
|
||||
GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_NORMAL],
|
||||
{active: false, discard: false, msgCount: 0});
|
||||
test_dcs(0xE8, PDU_DCS_MSG_CODING_16BITS_ALPHABET,
|
||||
GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_NORMAL],
|
||||
{active: true, discard: false, msgCount: -1});
|
||||
// Bit 2 is reserved, and set to 0:
|
||||
test_dcs(0xEC, PDU_DCS_MSG_CODING_16BITS_ALPHABET,
|
||||
GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_NORMAL],
|
||||
{active: true, discard: false, msgCount: -1});
|
||||
|
||||
// Group 1111
|
||||
test_dcs(0xF0, PDU_DCS_MSG_CODING_7BITS_ALPHABET,
|
||||
GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_0]);
|
||||
test_dcs(0xF1, PDU_DCS_MSG_CODING_7BITS_ALPHABET,
|
||||
GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_1]);
|
||||
test_dcs(0xF2, PDU_DCS_MSG_CODING_7BITS_ALPHABET,
|
||||
GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_2]);
|
||||
test_dcs(0xF3, PDU_DCS_MSG_CODING_7BITS_ALPHABET,
|
||||
GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_3]);
|
||||
test_dcs(0xF4, PDU_DCS_MSG_CODING_8BITS_ALPHABET,
|
||||
GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_0]);
|
||||
test_dcs(0xF5, PDU_DCS_MSG_CODING_8BITS_ALPHABET,
|
||||
GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_1]);
|
||||
test_dcs(0xF6, PDU_DCS_MSG_CODING_8BITS_ALPHABET,
|
||||
GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_2]);
|
||||
test_dcs(0xF7, PDU_DCS_MSG_CODING_8BITS_ALPHABET,
|
||||
GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_3]);
|
||||
// Bit 3 is reserved and should be set to 0, but if it doesn't we should
|
||||
// ignore it.
|
||||
test_dcs(0xF8, PDU_DCS_MSG_CODING_7BITS_ALPHABET,
|
||||
GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_0]);
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
/**
|
||||
* Verify GsmPDUHelper#writeStringAsSeptets() padding bits handling.
|
||||
*/
|
||||
add_test(function test_GsmPDUHelper_writeStringAsSeptets() {
|
||||
let worker = newWorker({
|
||||
postRILMessage: function fakePostRILMessage(data) {
|
||||
// Do nothing
|
||||
},
|
||||
postMessage: function fakePostMessage(message) {
|
||||
// Do nothing
|
||||
}
|
||||
});
|
||||
|
||||
let helper = worker.GsmPDUHelper;
|
||||
helper.resetOctetWritten = function () {
|
||||
helper.octetsWritten = 0;
|
||||
};
|
||||
helper.writeHexOctet = function () {
|
||||
helper.octetsWritten++;
|
||||
};
|
||||
|
||||
let base = "AAAAAAAA"; // Base string of 8 characters long
|
||||
for (let len = 0; len < 8; len++) {
|
||||
let str = base.substring(0, len);
|
||||
|
||||
for (let paddingBits = 0; paddingBits < 8; paddingBits++) {
|
||||
do_print("Verifying GsmPDUHelper.writeStringAsSeptets("
|
||||
+ str + ", " + paddingBits + ", <default>, <default>)");
|
||||
helper.resetOctetWritten();
|
||||
helper.writeStringAsSeptets(str, paddingBits, PDU_NL_IDENTIFIER_DEFAULT,
|
||||
PDU_NL_IDENTIFIER_DEFAULT);
|
||||
do_check_eq(Math.ceil(((len * 7) + paddingBits) / 8),
|
||||
helper.octetsWritten);
|
||||
}
|
||||
}
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
/**
|
||||
* Verify GsmPDUHelper#readAddress
|
||||
*/
|
||||
add_test(function test_GsmPDUHelper_readAddress() {
|
||||
let worker = newWorker({
|
||||
postRILMessage: function fakePostRILMessage(data) {
|
||||
// Do nothing
|
||||
},
|
||||
postMessage: function fakePostMessage(message) {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
let helper = worker.GsmPDUHelper;
|
||||
function test_address(addrHex, addrString) {
|
||||
let uint16Array = [];
|
||||
let ix = 0;
|
||||
for (let i = 0; i < addrHex.length; ++i) {
|
||||
uint16Array[i] = addrHex[i].charCodeAt();
|
||||
}
|
||||
|
||||
worker.Buf.readUint16 = function (){
|
||||
if(ix >= uint16Array.length) {
|
||||
do_throw("out of range in uint16Array");
|
||||
}
|
||||
return uint16Array[ix++];
|
||||
}
|
||||
let length = helper.readHexOctet();
|
||||
let parsedAddr = helper.readAddress(length);
|
||||
do_check_eq(parsedAddr, addrString);
|
||||
}
|
||||
|
||||
// For AlphaNumeric
|
||||
test_address("04D01100", "_@");
|
||||
test_address("04D01000", "\u0394@");
|
||||
|
||||
// Direct prepand
|
||||
test_address("0B914151245584F6", "+14154255486");
|
||||
test_address("0E914151245584B633", "+14154255486#33");
|
||||
|
||||
// PDU_TOA_NATIONAL
|
||||
test_address("0BA14151245584F6", "14154255486");
|
||||
|
||||
run_next_test();
|
||||
});
|
77
dom/system/gonk/tests/test_ril_worker_sms_nl_tables.js
Normal file
77
dom/system/gonk/tests/test_ril_worker_sms_nl_tables.js
Normal file
@ -0,0 +1,77 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
subscriptLoader.loadSubScript("resource://gre/modules/ril_consts.js", this);
|
||||
|
||||
const ESCAPE = "\uffff";
|
||||
const RESCTL = "\ufffe";
|
||||
const LF = "\n";
|
||||
const CR = "\r";
|
||||
const SP = " ";
|
||||
const FF = "\u000c";
|
||||
|
||||
function run_test() {
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify validity of the national language tables
|
||||
*/
|
||||
add_test(function test_nl_locking_shift_tables_validity() {
|
||||
for (let lst = 0; lst < PDU_NL_LOCKING_SHIFT_TABLES.length; lst++) {
|
||||
do_print("Verifying PDU_NL_LOCKING_SHIFT_TABLES[" + lst + "]");
|
||||
|
||||
let table = PDU_NL_LOCKING_SHIFT_TABLES[lst];
|
||||
|
||||
// Make sure table length is 128, or it will break table lookup algorithm.
|
||||
do_check_eq(table.length, 128);
|
||||
|
||||
// Make sure special values are preserved.
|
||||
do_check_eq(table[PDU_NL_EXTENDED_ESCAPE], ESCAPE);
|
||||
do_check_eq(table[PDU_NL_LINE_FEED], LF);
|
||||
do_check_eq(table[PDU_NL_CARRIAGE_RETURN], CR);
|
||||
do_check_eq(table[PDU_NL_SPACE], SP);
|
||||
}
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
add_test(function test_nl_single_shift_tables_validity() {
|
||||
for (let sst = 0; sst < PDU_NL_SINGLE_SHIFT_TABLES.length; sst++) {
|
||||
do_print("Verifying PDU_NL_SINGLE_SHIFT_TABLES[" + sst + "]");
|
||||
|
||||
let table = PDU_NL_SINGLE_SHIFT_TABLES[sst];
|
||||
|
||||
// Make sure table length is 128, or it will break table lookup algorithm.
|
||||
do_check_eq(table.length, 128);
|
||||
|
||||
// Make sure special values are preserved.
|
||||
do_check_eq(table[PDU_NL_EXTENDED_ESCAPE], ESCAPE);
|
||||
do_check_eq(table[PDU_NL_PAGE_BREAK], FF);
|
||||
do_check_eq(table[PDU_NL_RESERVED_CONTROL], RESCTL);
|
||||
}
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
add_test(function test_gsm_sms_strict_7bit_charmap_validity() {
|
||||
let defaultTable = PDU_NL_LOCKING_SHIFT_TABLES[PDU_NL_IDENTIFIER_DEFAULT];
|
||||
let defaultShiftTable = PDU_NL_SINGLE_SHIFT_TABLES[PDU_NL_IDENTIFIER_DEFAULT];
|
||||
for (let from in GSM_SMS_STRICT_7BIT_CHARMAP) {
|
||||
let to = GSM_SMS_STRICT_7BIT_CHARMAP[from];
|
||||
do_print("Verifying GSM_SMS_STRICT_7BIT_CHARMAP[\"\\u0x"
|
||||
+ from.charCodeAt(0).toString(16) + "\"] => \"\\u"
|
||||
+ to.charCodeAt(0).toString(16) + "\"");
|
||||
|
||||
// Make sure "from" is not in default table
|
||||
do_check_eq(defaultTable.indexOf(from), -1);
|
||||
do_check_eq(defaultShiftTable.indexOf(from), -1);
|
||||
// Make sure "to" is in default table
|
||||
if ((defaultTable.indexOf(to) < 0)
|
||||
&& (defaultShiftTable.indexOf(to) < 0)) {
|
||||
do_check_eq(false, true);
|
||||
}
|
||||
}
|
||||
|
||||
run_next_test();
|
||||
});
|
284
dom/system/gonk/tests/test_ril_worker_sms_segment_info.js
Normal file
284
dom/system/gonk/tests/test_ril_worker_sms_segment_info.js
Normal file
@ -0,0 +1,284 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
subscriptLoader.loadSubScript("resource://gre/modules/ril_consts.js", this);
|
||||
|
||||
const ESCAPE = "\uffff";
|
||||
const RESCTL = "\ufffe";
|
||||
const SP = " ";
|
||||
|
||||
function run_test() {
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify RadioInterface#_countGsm7BitSeptets() and
|
||||
* GsmPDUHelper#writeStringAsSeptets() algorithm match each other.
|
||||
*/
|
||||
add_test(function test_RadioInterface__countGsm7BitSeptets() {
|
||||
let ril = newRadioInterface();
|
||||
|
||||
let worker = newWorker({
|
||||
postRILMessage: function fakePostRILMessage(data) {
|
||||
// Do nothing
|
||||
},
|
||||
postMessage: function fakePostMessage(message) {
|
||||
// Do nothing
|
||||
}
|
||||
});
|
||||
|
||||
let helper = worker.GsmPDUHelper;
|
||||
helper.resetOctetWritten = function () {
|
||||
helper.octetsWritten = 0;
|
||||
};
|
||||
helper.writeHexOctet = function () {
|
||||
helper.octetsWritten++;
|
||||
};
|
||||
|
||||
function do_check_calc(str, expectedCalcLen, lst, sst, strict7BitEncoding, strToWrite) {
|
||||
do_check_eq(expectedCalcLen,
|
||||
ril._countGsm7BitSeptets(str,
|
||||
PDU_NL_LOCKING_SHIFT_TABLES[lst],
|
||||
PDU_NL_SINGLE_SHIFT_TABLES[sst],
|
||||
strict7BitEncoding));
|
||||
|
||||
helper.resetOctetWritten();
|
||||
strToWrite = strToWrite || str;
|
||||
helper.writeStringAsSeptets(strToWrite, 0, lst, sst);
|
||||
do_check_eq(Math.ceil(expectedCalcLen * 7 / 8), helper.octetsWritten);
|
||||
}
|
||||
|
||||
// Test calculation encoded message length using both locking/single shift tables.
|
||||
for (let lst = 0; lst < PDU_NL_LOCKING_SHIFT_TABLES.length; lst++) {
|
||||
let langTable = PDU_NL_LOCKING_SHIFT_TABLES[lst];
|
||||
|
||||
let str = langTable.substring(0, PDU_NL_EXTENDED_ESCAPE)
|
||||
+ langTable.substring(PDU_NL_EXTENDED_ESCAPE + 1);
|
||||
|
||||
for (let sst = 0; sst < PDU_NL_SINGLE_SHIFT_TABLES.length; sst++) {
|
||||
let langShiftTable = PDU_NL_SINGLE_SHIFT_TABLES[sst];
|
||||
|
||||
// <escape>, <resctrl> should be ignored.
|
||||
do_check_calc(ESCAPE + RESCTL, 0, lst, sst);
|
||||
|
||||
// Characters defined in locking shift table should be encoded directly.
|
||||
do_check_calc(str, str.length, lst, sst);
|
||||
|
||||
let [str1, str2] = ["", ""];
|
||||
for (let i = 0; i < langShiftTable.length; i++) {
|
||||
if ((i == PDU_NL_EXTENDED_ESCAPE) || (i == PDU_NL_RESERVED_CONTROL)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let c = langShiftTable[i];
|
||||
if (langTable.indexOf(c) >= 0) {
|
||||
str1 += c;
|
||||
} else {
|
||||
str2 += c;
|
||||
}
|
||||
}
|
||||
|
||||
// Characters found in both locking/single shift tables should be
|
||||
// directly encoded.
|
||||
do_check_calc(str1, str1.length, lst, sst);
|
||||
|
||||
// Characters found only in single shift tables should be encoded as
|
||||
// <escape><code>, therefore doubles its original length.
|
||||
do_check_calc(str2, str2.length * 2, lst, sst);
|
||||
}
|
||||
}
|
||||
|
||||
// Bug 790192: support strict GSM SMS 7-Bit encoding
|
||||
let str = "", strToWrite = "", gsmLen = 0;
|
||||
for (let c in GSM_SMS_STRICT_7BIT_CHARMAP) {
|
||||
str += c;
|
||||
strToWrite += GSM_SMS_STRICT_7BIT_CHARMAP[c];
|
||||
if (PDU_NL_LOCKING_SHIFT_TABLES.indexOf(GSM_SMS_STRICT_7BIT_CHARMAP[c])) {
|
||||
gsmLen += 1;
|
||||
} else {
|
||||
gsmLen += 2;
|
||||
}
|
||||
}
|
||||
do_check_calc(str, gsmLen,
|
||||
PDU_NL_IDENTIFIER_DEFAULT, PDU_NL_IDENTIFIER_DEFAULT,
|
||||
true, strToWrite);
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
/**
|
||||
* Verify RadioInterface#calculateUserDataLength handles national language
|
||||
* selection correctly.
|
||||
*/
|
||||
add_test(function test_RadioInterface__calculateUserDataLength() {
|
||||
let ril = newRadioInterface();
|
||||
|
||||
function test_calc(str, expected, enabledGsmTableTuples, strict7BitEncoding) {
|
||||
ril.enabledGsmTableTuples = enabledGsmTableTuples;
|
||||
let options = ril._calculateUserDataLength(str, strict7BitEncoding);
|
||||
|
||||
do_check_eq(expected[0], options.dcs);
|
||||
do_check_eq(expected[1], options.encodedFullBodyLength);
|
||||
do_check_eq(expected[2], options.userDataHeaderLength);
|
||||
do_check_eq(expected[3], options.langIndex);
|
||||
do_check_eq(expected[4], options.langShiftIndex);
|
||||
}
|
||||
|
||||
// Test UCS fallback
|
||||
// - No any default enabled nl tables
|
||||
test_calc("A", [PDU_DCS_MSG_CODING_16BITS_ALPHABET, 2, 0,], []);
|
||||
// - Character not defined in enabled nl tables
|
||||
test_calc("A", [PDU_DCS_MSG_CODING_16BITS_ALPHABET, 2, 0,], [[2, 2]]);
|
||||
|
||||
// With GSM default nl tables
|
||||
test_calc("A", [PDU_DCS_MSG_CODING_7BITS_ALPHABET, 1, 0, 0, 0], [[0, 0]]);
|
||||
// - SP is defined in both locking/single shift tables, should be directly
|
||||
// encoded.
|
||||
test_calc(SP, [PDU_DCS_MSG_CODING_7BITS_ALPHABET, 1, 0, 0, 0], [[0, 0]]);
|
||||
// - '^' is only defined in single shift table, should be encoded as
|
||||
// <escape>^.
|
||||
test_calc("^", [PDU_DCS_MSG_CODING_7BITS_ALPHABET, 2, 0, 0, 0], [[0, 0]]);
|
||||
|
||||
// Test userDataHeaderLength calculation
|
||||
// - Header contains both IEIs
|
||||
test_calc("A", [PDU_DCS_MSG_CODING_7BITS_ALPHABET, 1, 6, 1, 1], [[1, 1]]);
|
||||
// - Header contains only locking shift table IEI
|
||||
test_calc("A", [PDU_DCS_MSG_CODING_7BITS_ALPHABET, 1, 3, 1, 0], [[1, 0]]);
|
||||
// - Header contains only single shift table IEI
|
||||
test_calc("^", [PDU_DCS_MSG_CODING_7BITS_ALPHABET, 2, 3, 0, 1], [[0, 1]]);
|
||||
|
||||
// Test minimum cost nl tables selection
|
||||
// - 'A' is defined in locking shift table
|
||||
test_calc("A", [PDU_DCS_MSG_CODING_7BITS_ALPHABET, 1, 3, 1, 0], [[1, 0], [2, 0]]);
|
||||
test_calc("A", [PDU_DCS_MSG_CODING_7BITS_ALPHABET, 1, 3, 1, 0], [[2, 0], [1, 0]]);
|
||||
// - 'A' is defined in single shift table
|
||||
test_calc("A", [PDU_DCS_MSG_CODING_7BITS_ALPHABET, 2, 6, 2, 4], [[2, 0], [2, 4]]);
|
||||
test_calc("A", [PDU_DCS_MSG_CODING_7BITS_ALPHABET, 2, 6, 2, 4], [[2, 4], [2, 0]]);
|
||||
// - 'A' is defined in locking shift table of one tuple and in single shift
|
||||
// table of another.
|
||||
test_calc("A", [PDU_DCS_MSG_CODING_7BITS_ALPHABET, 1, 3, 1, 0], [[1, 0], [2, 4]]);
|
||||
test_calc("A", [PDU_DCS_MSG_CODING_7BITS_ALPHABET, 1, 3, 1, 0], [[2, 4], [1, 0]]);
|
||||
|
||||
// Test Bug 733981
|
||||
// - Case 1, headerLen is in octets, not septets. "\\" is defined in default
|
||||
// single shift table and Portuguese locking shift table. The original code
|
||||
// will add headerLen 7(octets), which should be 8(septets), to calculated
|
||||
// cost and gets 14, which should be 15 in total for the first run. As for
|
||||
// the second run, it will be undoubtedly 14 in total. With correct fix,
|
||||
// the best choice should be the second one.
|
||||
test_calc("\\\\\\\\\\\\\\",
|
||||
[PDU_DCS_MSG_CODING_7BITS_ALPHABET, 14, 0, 0, 0], [[3, 1], [0, 0]]);
|
||||
// - Case 2, possible early return non-best choice. The original code will
|
||||
// get total cost 6 in the first run and returns immediately. With correct
|
||||
// fix, the best choice should be the second one.
|
||||
test_calc(ESCAPE + ESCAPE + ESCAPE + ESCAPE + ESCAPE + "\\",
|
||||
[PDU_DCS_MSG_CODING_7BITS_ALPHABET, 2, 0, 0, 0], [[3, 0], [0, 0]]);
|
||||
|
||||
// Test Bug 790192: support strict GSM SMS 7-Bit encoding
|
||||
let str = "", gsmLen = 0, udhl = 0;
|
||||
for (let c in GSM_SMS_STRICT_7BIT_CHARMAP) {
|
||||
str += c;
|
||||
if (PDU_NL_LOCKING_SHIFT_TABLES.indexOf(GSM_SMS_STRICT_7BIT_CHARMAP[c])) {
|
||||
gsmLen += 1;
|
||||
} else {
|
||||
gsmLen += 2;
|
||||
}
|
||||
}
|
||||
if (str.length > PDU_MAX_USER_DATA_UCS2) {
|
||||
udhl = 5;
|
||||
}
|
||||
test_calc(str, [PDU_DCS_MSG_CODING_7BITS_ALPHABET, gsmLen, 0, 0, 0], [[0, 0]], true);
|
||||
test_calc(str, [PDU_DCS_MSG_CODING_16BITS_ALPHABET, str.length * 2, udhl], [[0, 0]]);
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
function generateStringOfLength(str, length) {
|
||||
while (str.length < length) {
|
||||
if (str.length < (length / 2)) {
|
||||
str = str + str;
|
||||
} else {
|
||||
str = str + str.substr(0, length - str.length);
|
||||
}
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify RadioInterface#_calculateUserDataLength7Bit multipart handling.
|
||||
*/
|
||||
add_test(function test_RadioInterface__calculateUserDataLength7Bit_multipart() {
|
||||
let ril = newRadioInterface();
|
||||
|
||||
function test_calc(str, expected) {
|
||||
let options = ril._calculateUserDataLength7Bit(str);
|
||||
|
||||
do_check_eq(expected[0], options.encodedFullBodyLength);
|
||||
do_check_eq(expected[1], options.userDataHeaderLength);
|
||||
do_check_eq(expected[2], options.segmentMaxSeq);
|
||||
}
|
||||
|
||||
test_calc(generateStringOfLength("A", PDU_MAX_USER_DATA_7BIT),
|
||||
[PDU_MAX_USER_DATA_7BIT, 0, 1]);
|
||||
test_calc(generateStringOfLength("A", PDU_MAX_USER_DATA_7BIT + 1),
|
||||
[PDU_MAX_USER_DATA_7BIT + 1, 5, 2]);
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
/**
|
||||
* Verify RadioInterface#_fragmentText().
|
||||
*/
|
||||
add_test(function test_RadioInterface__fragmentText7Bit() {
|
||||
let ril = newRadioInterface();
|
||||
|
||||
function test_calc(str, strict7BitEncoding, expectedSegments) {
|
||||
expectedSegments = expectedSegments || 1;
|
||||
let options = ril._fragmentText(str, null, strict7BitEncoding);
|
||||
do_check_eq(expectedSegments, options.segments.length);
|
||||
}
|
||||
|
||||
// 7-Bit
|
||||
|
||||
// Boundary checks
|
||||
test_calc(generateStringOfLength("A", PDU_MAX_USER_DATA_7BIT), false);
|
||||
test_calc(generateStringOfLength("A", PDU_MAX_USER_DATA_7BIT), true);
|
||||
test_calc(generateStringOfLength("A", PDU_MAX_USER_DATA_7BIT + 1), false, 2);
|
||||
test_calc(generateStringOfLength("A", PDU_MAX_USER_DATA_7BIT + 1), true, 2);
|
||||
|
||||
// Escaped character
|
||||
test_calc(generateStringOfLength("{", PDU_MAX_USER_DATA_7BIT / 2), false);
|
||||
test_calc(generateStringOfLength("{", PDU_MAX_USER_DATA_7BIT / 2 + 1), false, 2);
|
||||
// Escaped character cannot be separated
|
||||
test_calc(generateStringOfLength("{", (PDU_MAX_USER_DATA_7BIT - 7) * 2 / 2), false, 3);
|
||||
|
||||
// Test headerLen, 7 = Math.ceil(6 * 8 / 7), 6 = headerLen + 1
|
||||
test_calc(generateStringOfLength("A", PDU_MAX_USER_DATA_7BIT - 7));
|
||||
test_calc(generateStringOfLength("A", (PDU_MAX_USER_DATA_7BIT - 7) * 2), false, 2);
|
||||
test_calc(generateStringOfLength("A", (PDU_MAX_USER_DATA_7BIT - 7) * 3), false, 3);
|
||||
|
||||
// UCS-2
|
||||
|
||||
// Boundary checks
|
||||
test_calc(generateStringOfLength("\ua2db", PDU_MAX_USER_DATA_UCS2));
|
||||
test_calc(generateStringOfLength("\ua2db", PDU_MAX_USER_DATA_UCS2), true);
|
||||
test_calc(generateStringOfLength("\ua2db", PDU_MAX_USER_DATA_UCS2 + 1), false, 2);
|
||||
// Bug 816082: when strict GSM SMS 7-Bit encoding is enabled, replace unicode
|
||||
// chars with '*'.
|
||||
test_calc(generateStringOfLength("\ua2db", PDU_MAX_USER_DATA_UCS2 + 1), true, 1);
|
||||
|
||||
// UCS2 character cannot be separated
|
||||
ril.segmentRef16Bit = true;
|
||||
test_calc(generateStringOfLength("\ua2db", (PDU_MAX_USER_DATA_UCS2 * 2 - 7) * 2 / 2), false, 3);
|
||||
ril.segmentRef16Bit = false;
|
||||
|
||||
// Test Bug 790192: support strict GSM SMS 7-Bit encoding
|
||||
for (let c in GSM_SMS_STRICT_7BIT_CHARMAP) {
|
||||
test_calc(generateStringOfLength(c, PDU_MAX_USER_DATA_7BIT), false, 3);
|
||||
test_calc(generateStringOfLength(c, PDU_MAX_USER_DATA_7BIT), true);
|
||||
test_calc(generateStringOfLength(c, PDU_MAX_USER_DATA_UCS2), false);
|
||||
}
|
||||
|
||||
run_next_test();
|
||||
});
|
@ -5,6 +5,11 @@ tail =
|
||||
[test_ril_worker_buf.js]
|
||||
[test_ril_worker_icc.js]
|
||||
[test_ril_worker_sms.js]
|
||||
# Bug 916067 - B2G RIL: test_ril_worker_sms.js takes too long to finish
|
||||
skip-if = true
|
||||
[test_ril_worker_sms_nl_tables.js]
|
||||
[test_ril_worker_sms_gsmpduhelper.js]
|
||||
[test_ril_worker_sms_segment_info.js]
|
||||
[test_ril_worker_mmi.js]
|
||||
[test_ril_worker_cf.js]
|
||||
[test_ril_worker_cellbroadcast_config.js]
|
||||
|
@ -2,10 +2,6 @@
|
||||
* 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/. */
|
||||
|
||||
const INT32_MAX = 2147483647;
|
||||
const UINT8_SIZE = 1;
|
||||
const UINT16_SIZE = 2;
|
||||
const UINT32_SIZE = 4;
|
||||
|
||||
/**
|
||||
* This object contains helpers buffering incoming data & deconstructing it
|
||||
@ -21,95 +17,100 @@ const UINT32_SIZE = 4;
|
||||
*/
|
||||
|
||||
let Buf = {
|
||||
PARCEL_SIZE_SIZE: UINT32_SIZE,
|
||||
INT32_MAX: 2147483647,
|
||||
UINT8_SIZE: 1,
|
||||
UINT16_SIZE: 2,
|
||||
UINT32_SIZE: 4,
|
||||
PARCEL_SIZE_SIZE: 4,
|
||||
PDU_HEX_OCTET_SIZE: 4,
|
||||
|
||||
mIncomingBufferLength: 1024,
|
||||
mIncomingBuffer: null,
|
||||
mIncomingBytes: null,
|
||||
mIncomingWriteIndex: 0,
|
||||
mIncomingReadIndex: 0,
|
||||
mReadIncoming: 0,
|
||||
mReadAvailable: 0,
|
||||
mCurrentParcelSize: 0,
|
||||
incomingBufferLength: 1024,
|
||||
incomingBuffer: null,
|
||||
incomingBytes: null,
|
||||
incomingWriteIndex: 0,
|
||||
incomingReadIndex: 0,
|
||||
readIncoming: 0,
|
||||
readAvailable: 0,
|
||||
currentParcelSize: 0,
|
||||
|
||||
mOutgoingBufferLength: 1024,
|
||||
mOutgoingBuffer: null,
|
||||
mOutgoingBytes: null,
|
||||
mOutgoingIndex: 0,
|
||||
mOutgoingBufferCalSizeQueue: null,
|
||||
outgoingBufferLength: 1024,
|
||||
outgoingBuffer: null,
|
||||
outgoingBytes: null,
|
||||
outgoingIndex: 0,
|
||||
outgoingBufferCalSizeQueue: null,
|
||||
|
||||
_init: function _init() {
|
||||
this.mIncomingBuffer = new ArrayBuffer(this.mIncomingBufferLength);
|
||||
this.mOutgoingBuffer = new ArrayBuffer(this.mOutgoingBufferLength);
|
||||
this.incomingBuffer = new ArrayBuffer(this.incomingBufferLength);
|
||||
this.outgoingBuffer = new ArrayBuffer(this.outgoingBufferLength);
|
||||
|
||||
this.mIncomingBytes = new Uint8Array(this.mIncomingBuffer);
|
||||
this.mOutgoingBytes = new Uint8Array(this.mOutgoingBuffer);
|
||||
this.incomingBytes = new Uint8Array(this.incomingBuffer);
|
||||
this.outgoingBytes = new Uint8Array(this.outgoingBuffer);
|
||||
|
||||
// Track where incoming data is read from and written to.
|
||||
this.mIncomingWriteIndex = 0;
|
||||
this.mIncomingReadIndex = 0;
|
||||
this.incomingWriteIndex = 0;
|
||||
this.incomingReadIndex = 0;
|
||||
|
||||
// Leave room for the parcel size for outgoing parcels.
|
||||
this.mOutgoingIndex = this.PARCEL_SIZE_SIZE;
|
||||
this.outgoingIndex = this.PARCEL_SIZE_SIZE;
|
||||
|
||||
// How many bytes we've read for this parcel so far.
|
||||
this.mReadIncoming = 0;
|
||||
this.readIncoming = 0;
|
||||
|
||||
// How many bytes available as parcel data.
|
||||
this.mReadAvailable = 0;
|
||||
this.readAvailable = 0;
|
||||
|
||||
// Size of the incoming parcel. If this is zero, we're expecting a new
|
||||
// parcel.
|
||||
this.mCurrentParcelSize = 0;
|
||||
this.currentParcelSize = 0;
|
||||
|
||||
// Queue for storing outgoing override points
|
||||
this.mOutgoingBufferCalSizeQueue = [];
|
||||
this.outgoingBufferCalSizeQueue = [];
|
||||
},
|
||||
|
||||
/**
|
||||
* Mark current mOutgoingIndex as start point for calculation length of data
|
||||
* written to mOutgoingBuffer.
|
||||
* Mark current outgoingIndex as start point for calculation length of data
|
||||
* written to outgoingBuffer.
|
||||
* Mark can be nested for here uses queue to remember marks.
|
||||
*
|
||||
* @param writeFunction
|
||||
* Function to write data length into mOutgoingBuffer, this function is
|
||||
* Function to write data length into outgoingBuffer, this function is
|
||||
* also used to allocate buffer for data length.
|
||||
* Raw data size(in Uint8) is provided as parameter calling writeFunction.
|
||||
* If raw data size is not in proper unit for writing, user can adjust
|
||||
* the length value in writeFunction before writing.
|
||||
**/
|
||||
startCalOutgoingSize: function startCalOutgoingSize(writeFunction) {
|
||||
let sizeInfo = {index: this.mOutgoingIndex,
|
||||
let sizeInfo = {index: this.outgoingIndex,
|
||||
write: writeFunction};
|
||||
|
||||
// Allocate buffer for data lemgtj.
|
||||
writeFunction.call(0);
|
||||
|
||||
// Get size of data length buffer for it is not counted into data size.
|
||||
sizeInfo.size = this.mOutgoingIndex - sizeInfo.index;
|
||||
sizeInfo.size = this.outgoingIndex - sizeInfo.index;
|
||||
|
||||
// Enqueue size calculation information.
|
||||
this.mOutgoingBufferCalSizeQueue.push(sizeInfo);
|
||||
this.outgoingBufferCalSizeQueue.push(sizeInfo);
|
||||
},
|
||||
|
||||
/**
|
||||
* Calculate data length since last mark, and write it into mark position.
|
||||
**/
|
||||
stopCalOutgoingSize: function stopCalOutgoingSize() {
|
||||
let sizeInfo = this.mOutgoingBufferCalSizeQueue.pop();
|
||||
let sizeInfo = this.outgoingBufferCalSizeQueue.pop();
|
||||
|
||||
// Remember current mOutgoingIndex.
|
||||
let currentOutgoingIndex = this.mOutgoingIndex;
|
||||
// Remember current outgoingIndex.
|
||||
let currentOutgoingIndex = this.outgoingIndex;
|
||||
// Calculate data length, in uint8.
|
||||
let writeSize = this.mOutgoingIndex - sizeInfo.index - sizeInfo.size;
|
||||
let writeSize = this.outgoingIndex - sizeInfo.index - sizeInfo.size;
|
||||
|
||||
// Write data length to mark, use same function for allocating buffer to make
|
||||
// sure there is no buffer overloading.
|
||||
this.mOutgoingIndex = sizeInfo.index;
|
||||
this.outgoingIndex = sizeInfo.index;
|
||||
sizeInfo.write(writeSize);
|
||||
|
||||
// Restore mOutgoingIndex.
|
||||
this.mOutgoingIndex = currentOutgoingIndex;
|
||||
// Restore outgoingIndex.
|
||||
this.outgoingIndex = currentOutgoingIndex;
|
||||
},
|
||||
|
||||
/**
|
||||
@ -121,34 +122,34 @@ let Buf = {
|
||||
*/
|
||||
growIncomingBuffer: function growIncomingBuffer(min_size) {
|
||||
if (DEBUG) {
|
||||
debug("Current buffer of " + this.mIncomingBufferLength +
|
||||
debug("Current buffer of " + this.incomingBufferLength +
|
||||
" can't handle incoming " + min_size + " bytes.");
|
||||
}
|
||||
let oldBytes = this.mIncomingBytes;
|
||||
this.mIncomingBufferLength =
|
||||
let oldBytes = this.incomingBytes;
|
||||
this.incomingBufferLength =
|
||||
2 << Math.floor(Math.log(min_size)/Math.log(2));
|
||||
if (DEBUG) debug("New incoming buffer size: " + this.mIncomingBufferLength);
|
||||
this.mIncomingBuffer = new ArrayBuffer(this.mIncomingBufferLength);
|
||||
this.mIncomingBytes = new Uint8Array(this.mIncomingBuffer);
|
||||
if (this.mIncomingReadIndex <= this.mIncomingWriteIndex) {
|
||||
if (DEBUG) debug("New incoming buffer size: " + this.incomingBufferLength);
|
||||
this.incomingBuffer = new ArrayBuffer(this.incomingBufferLength);
|
||||
this.incomingBytes = new Uint8Array(this.incomingBuffer);
|
||||
if (this.incomingReadIndex <= this.incomingWriteIndex) {
|
||||
// Read and write index are in natural order, so we can just copy
|
||||
// the old buffer over to the bigger one without having to worry
|
||||
// about the indexes.
|
||||
this.mIncomingBytes.set(oldBytes, 0);
|
||||
this.incomingBytes.set(oldBytes, 0);
|
||||
} else {
|
||||
// The write index has wrapped around but the read index hasn't yet.
|
||||
// Write whatever the read index has left to read until it would
|
||||
// circle around to the beginning of the new buffer, and the rest
|
||||
// behind that.
|
||||
let head = oldBytes.subarray(this.mIncomingReadIndex);
|
||||
let tail = oldBytes.subarray(0, this.mIncomingReadIndex);
|
||||
this.mIncomingBytes.set(head, 0);
|
||||
this.mIncomingBytes.set(tail, head.length);
|
||||
this.mIncomingReadIndex = 0;
|
||||
this.mIncomingWriteIndex += head.length;
|
||||
let head = oldBytes.subarray(this.incomingReadIndex);
|
||||
let tail = oldBytes.subarray(0, this.incomingReadIndex);
|
||||
this.incomingBytes.set(head, 0);
|
||||
this.incomingBytes.set(tail, head.length);
|
||||
this.incomingReadIndex = 0;
|
||||
this.incomingWriteIndex += head.length;
|
||||
}
|
||||
if (DEBUG) {
|
||||
debug("New incoming buffer size is " + this.mIncomingBufferLength);
|
||||
debug("New incoming buffer size is " + this.incomingBufferLength);
|
||||
}
|
||||
},
|
||||
|
||||
@ -161,17 +162,17 @@ let Buf = {
|
||||
*/
|
||||
growOutgoingBuffer: function growOutgoingBuffer(min_size) {
|
||||
if (DEBUG) {
|
||||
debug("Current buffer of " + this.mOutgoingBufferLength +
|
||||
debug("Current buffer of " + this.outgoingBufferLength +
|
||||
" is too small.");
|
||||
}
|
||||
let oldBytes = this.mOutgoingBytes;
|
||||
this.mOutgoingBufferLength =
|
||||
let oldBytes = this.outgoingBytes;
|
||||
this.outgoingBufferLength =
|
||||
2 << Math.floor(Math.log(min_size)/Math.log(2));
|
||||
this.mOutgoingBuffer = new ArrayBuffer(this.mOutgoingBufferLength);
|
||||
this.mOutgoingBytes = new Uint8Array(this.mOutgoingBuffer);
|
||||
this.mOutgoingBytes.set(oldBytes, 0);
|
||||
this.outgoingBuffer = new ArrayBuffer(this.outgoingBufferLength);
|
||||
this.outgoingBytes = new Uint8Array(this.outgoingBuffer);
|
||||
this.outgoingBytes.set(oldBytes, 0);
|
||||
if (DEBUG) {
|
||||
debug("New outgoing buffer size is " + this.mOutgoingBufferLength);
|
||||
debug("New outgoing buffer size is " + this.outgoingBufferLength);
|
||||
}
|
||||
},
|
||||
|
||||
@ -186,10 +187,10 @@ let Buf = {
|
||||
*
|
||||
* @param index
|
||||
* Data position in incoming parcel, valid from 0 to
|
||||
* mCurrentParcelSize.
|
||||
* currentParcelSize.
|
||||
*/
|
||||
ensureIncomingAvailable: function ensureIncomingAvailable(index) {
|
||||
if (index >= this.mCurrentParcelSize) {
|
||||
if (index >= this.currentParcelSize) {
|
||||
throw new Error("Trying to read data beyond the parcel end!");
|
||||
} else if (index < 0) {
|
||||
throw new Error("Trying to read data before the parcel begin!");
|
||||
@ -203,48 +204,48 @@ let Buf = {
|
||||
* Seek offset in relative to current position.
|
||||
*/
|
||||
seekIncoming: function seekIncoming(offset) {
|
||||
// Translate to 0..mCurrentParcelSize
|
||||
let cur = this.mCurrentParcelSize - this.mReadAvailable;
|
||||
// Translate to 0..currentParcelSize
|
||||
let cur = this.currentParcelSize - this.readAvailable;
|
||||
|
||||
let newIndex = cur + offset;
|
||||
this.ensureIncomingAvailable(newIndex);
|
||||
|
||||
// ... mIncomingReadIndex -->|
|
||||
// 0 new cur mCurrentParcelSize
|
||||
// ... incomingReadIndex -->|
|
||||
// 0 new cur currentParcelSize
|
||||
// |================|=======|====================|
|
||||
// |<-- cur -->|<- mReadAvailable ->|
|
||||
// |<-- newIndex -->|<-- new mReadAvailable -->|
|
||||
this.mReadAvailable = this.mCurrentParcelSize - newIndex;
|
||||
// |<-- cur -->|<- readAvailable ->|
|
||||
// |<-- newIndex -->|<-- new readAvailable -->|
|
||||
this.readAvailable = this.currentParcelSize - newIndex;
|
||||
|
||||
// Translate back:
|
||||
if (this.mIncomingReadIndex < cur) {
|
||||
// The mIncomingReadIndex is wrapped.
|
||||
newIndex += this.mIncomingBufferLength;
|
||||
if (this.incomingReadIndex < cur) {
|
||||
// The incomingReadIndex is wrapped.
|
||||
newIndex += this.incomingBufferLength;
|
||||
}
|
||||
newIndex += (this.mIncomingReadIndex - cur);
|
||||
newIndex %= this.mIncomingBufferLength;
|
||||
this.mIncomingReadIndex = newIndex;
|
||||
newIndex += (this.incomingReadIndex - cur);
|
||||
newIndex %= this.incomingBufferLength;
|
||||
this.incomingReadIndex = newIndex;
|
||||
},
|
||||
|
||||
readUint8Unchecked: function readUint8Unchecked() {
|
||||
let value = this.mIncomingBytes[this.mIncomingReadIndex];
|
||||
this.mIncomingReadIndex = (this.mIncomingReadIndex + 1) %
|
||||
this.mIncomingBufferLength;
|
||||
let value = this.incomingBytes[this.incomingReadIndex];
|
||||
this.incomingReadIndex = (this.incomingReadIndex + 1) %
|
||||
this.incomingBufferLength;
|
||||
return value;
|
||||
},
|
||||
|
||||
readUint8: function readUint8() {
|
||||
// Translate to 0..mCurrentParcelSize
|
||||
let cur = this.mCurrentParcelSize - this.mReadAvailable;
|
||||
// Translate to 0..currentParcelSize
|
||||
let cur = this.currentParcelSize - this.readAvailable;
|
||||
this.ensureIncomingAvailable(cur);
|
||||
|
||||
this.mReadAvailable--;
|
||||
this.readAvailable--;
|
||||
return this.readUint8Unchecked();
|
||||
},
|
||||
|
||||
readUint8Array: function readUint8Array(length) {
|
||||
// Translate to 0..mCurrentParcelSize
|
||||
let last = this.mCurrentParcelSize - this.mReadAvailable;
|
||||
// Translate to 0..currentParcelSize
|
||||
let last = this.currentParcelSize - this.readAvailable;
|
||||
last += (length - 1);
|
||||
this.ensureIncomingAvailable(last);
|
||||
|
||||
@ -253,7 +254,7 @@ let Buf = {
|
||||
array[i] = this.readUint8Unchecked();
|
||||
}
|
||||
|
||||
this.mReadAvailable -= length;
|
||||
this.readAvailable -= length;
|
||||
return array;
|
||||
},
|
||||
|
||||
@ -277,7 +278,7 @@ let Buf = {
|
||||
|
||||
readString: function readString() {
|
||||
let string_len = this.readUint32();
|
||||
if (string_len < 0 || string_len >= INT32_MAX) {
|
||||
if (string_len < 0 || string_len >= this.INT32_MAX) {
|
||||
return null;
|
||||
}
|
||||
let s = "";
|
||||
@ -328,19 +329,19 @@ let Buf = {
|
||||
*
|
||||
* @param index
|
||||
* Data position in outgoing parcel, valid from 0 to
|
||||
* mOutgoingBufferLength.
|
||||
* outgoingBufferLength.
|
||||
*/
|
||||
ensureOutgoingAvailable: function ensureOutgoingAvailable(index) {
|
||||
if (index >= this.mOutgoingBufferLength) {
|
||||
if (index >= this.outgoingBufferLength) {
|
||||
this.growOutgoingBuffer(index + 1);
|
||||
}
|
||||
},
|
||||
|
||||
writeUint8: function writeUint8(value) {
|
||||
this.ensureOutgoingAvailable(this.mOutgoingIndex);
|
||||
this.ensureOutgoingAvailable(this.outgoingIndex);
|
||||
|
||||
this.mOutgoingBytes[this.mOutgoingIndex] = value;
|
||||
this.mOutgoingIndex++;
|
||||
this.outgoingBytes[this.outgoingIndex] = value;
|
||||
this.outgoingIndex++;
|
||||
},
|
||||
|
||||
writeUint16: function writeUint16(value) {
|
||||
@ -390,13 +391,13 @@ let Buf = {
|
||||
* array, but the last thing written. Store the current index off
|
||||
* to a temporary to be reset after we write the size.
|
||||
*/
|
||||
let currentIndex = this.mOutgoingIndex;
|
||||
this.mOutgoingIndex = 0;
|
||||
let currentIndex = this.outgoingIndex;
|
||||
this.outgoingIndex = 0;
|
||||
this.writeUint8((value >> 24) & 0xff);
|
||||
this.writeUint8((value >> 16) & 0xff);
|
||||
this.writeUint8((value >> 8) & 0xff);
|
||||
this.writeUint8(value & 0xff);
|
||||
this.mOutgoingIndex = currentIndex;
|
||||
this.outgoingIndex = currentIndex;
|
||||
},
|
||||
|
||||
copyIncomingToOutgoing: function copyIncomingToOutgoing(length) {
|
||||
@ -405,36 +406,36 @@ let Buf = {
|
||||
}
|
||||
|
||||
let translatedReadIndexEnd =
|
||||
this.mCurrentParcelSize - this.mReadAvailable + length - 1;
|
||||
this.currentParcelSize - this.readAvailable + length - 1;
|
||||
this.ensureIncomingAvailable(translatedReadIndexEnd);
|
||||
|
||||
let translatedWriteIndexEnd = this.mOutgoingIndex + length - 1;
|
||||
let translatedWriteIndexEnd = this.outgoingIndex + length - 1;
|
||||
this.ensureOutgoingAvailable(translatedWriteIndexEnd);
|
||||
|
||||
let newIncomingReadIndex = this.mIncomingReadIndex + length;
|
||||
if (newIncomingReadIndex < this.mIncomingBufferLength) {
|
||||
let newIncomingReadIndex = this.incomingReadIndex + length;
|
||||
if (newIncomingReadIndex < this.incomingBufferLength) {
|
||||
// Reading won't cause wrapping, go ahead with builtin copy.
|
||||
this.mOutgoingBytes
|
||||
.set(this.mIncomingBytes.subarray(this.mIncomingReadIndex,
|
||||
newIncomingReadIndex),
|
||||
this.mOutgoingIndex);
|
||||
this.outgoingBytes
|
||||
.set(this.incomingBytes.subarray(this.incomingReadIndex,
|
||||
newIncomingReadIndex),
|
||||
this.outgoingIndex);
|
||||
} else {
|
||||
// Not so lucky.
|
||||
newIncomingReadIndex %= this.mIncomingBufferLength;
|
||||
this.mOutgoingBytes
|
||||
.set(this.mIncomingBytes.subarray(this.mIncomingReadIndex,
|
||||
this.mIncomingBufferLength),
|
||||
this.mOutgoingIndex);
|
||||
newIncomingReadIndex %= this.incomingBufferLength;
|
||||
this.outgoingBytes
|
||||
.set(this.incomingBytes.subarray(this.incomingReadIndex,
|
||||
this.incomingBufferLength),
|
||||
this.outgoingIndex);
|
||||
if (newIncomingReadIndex) {
|
||||
let firstPartLength = this.mIncomingBufferLength - this.mIncomingReadIndex;
|
||||
this.mOutgoingBytes.set(this.mIncomingBytes.subarray(0, newIncomingReadIndex),
|
||||
this.mOutgoingIndex + firstPartLength);
|
||||
let firstPartLength = this.incomingBufferLength - this.incomingReadIndex;
|
||||
this.outgoingBytes.set(this.incomingBytes.subarray(0, newIncomingReadIndex),
|
||||
this.outgoingIndex + firstPartLength);
|
||||
}
|
||||
}
|
||||
|
||||
this.mIncomingReadIndex = newIncomingReadIndex;
|
||||
this.mReadAvailable -= length;
|
||||
this.mOutgoingIndex += length;
|
||||
this.incomingReadIndex = newIncomingReadIndex;
|
||||
this.readAvailable -= length;
|
||||
this.outgoingIndex += length;
|
||||
},
|
||||
|
||||
/**
|
||||
@ -452,25 +453,25 @@ let Buf = {
|
||||
// we process any backlog in parcels immediately, before writing
|
||||
// new data to the buffer. So the only edge case we need to handle
|
||||
// is when the incoming data is larger than the buffer size.
|
||||
let minMustAvailableSize = incoming.length + this.mReadIncoming;
|
||||
if (minMustAvailableSize > this.mIncomingBufferLength) {
|
||||
let minMustAvailableSize = incoming.length + this.readIncoming;
|
||||
if (minMustAvailableSize > this.incomingBufferLength) {
|
||||
this.growIncomingBuffer(minMustAvailableSize);
|
||||
}
|
||||
|
||||
// We can let the typed arrays do the copying if the incoming data won't
|
||||
// wrap around the edges of the circular buffer.
|
||||
let remaining = this.mIncomingBufferLength - this.mIncomingWriteIndex;
|
||||
let remaining = this.incomingBufferLength - this.incomingWriteIndex;
|
||||
if (remaining >= incoming.length) {
|
||||
this.mIncomingBytes.set(incoming, this.mIncomingWriteIndex);
|
||||
this.incomingBytes.set(incoming, this.incomingWriteIndex);
|
||||
} else {
|
||||
// The incoming data would wrap around it.
|
||||
let head = incoming.subarray(0, remaining);
|
||||
let tail = incoming.subarray(remaining);
|
||||
this.mIncomingBytes.set(head, this.mIncomingWriteIndex);
|
||||
this.mIncomingBytes.set(tail, 0);
|
||||
this.incomingBytes.set(head, this.incomingWriteIndex);
|
||||
this.incomingBytes.set(tail, 0);
|
||||
}
|
||||
this.mIncomingWriteIndex = (this.mIncomingWriteIndex + incoming.length) %
|
||||
this.mIncomingBufferLength;
|
||||
this.incomingWriteIndex = (this.incomingWriteIndex + incoming.length) %
|
||||
this.incomingBufferLength;
|
||||
},
|
||||
|
||||
/**
|
||||
@ -482,73 +483,73 @@ let Buf = {
|
||||
processIncoming: function processIncoming(incoming) {
|
||||
if (DEBUG) {
|
||||
debug("Received " + incoming.length + " bytes.");
|
||||
debug("Already read " + this.mReadIncoming);
|
||||
debug("Already read " + this.readIncoming);
|
||||
}
|
||||
|
||||
this.writeToIncoming(incoming);
|
||||
this.mReadIncoming += incoming.length;
|
||||
this.readIncoming += incoming.length;
|
||||
while (true) {
|
||||
if (!this.mCurrentParcelSize) {
|
||||
if (!this.currentParcelSize) {
|
||||
// We're expecting a new parcel.
|
||||
if (this.mReadIncoming < this.PARCEL_SIZE_SIZE) {
|
||||
if (this.readIncoming < this.PARCEL_SIZE_SIZE) {
|
||||
// We don't know how big the next parcel is going to be, need more
|
||||
// data.
|
||||
if (DEBUG) debug("Next parcel size unknown, going to sleep.");
|
||||
return;
|
||||
}
|
||||
this.mCurrentParcelSize = this.readParcelSize();
|
||||
this.currentParcelSize = this.readParcelSize();
|
||||
if (DEBUG) {
|
||||
debug("New incoming parcel of size " + this.mCurrentParcelSize);
|
||||
debug("New incoming parcel of size " + this.currentParcelSize);
|
||||
}
|
||||
// The size itself is not included in the size.
|
||||
this.mReadIncoming -= this.PARCEL_SIZE_SIZE;
|
||||
this.readIncoming -= this.PARCEL_SIZE_SIZE;
|
||||
}
|
||||
|
||||
if (this.mReadIncoming < this.mCurrentParcelSize) {
|
||||
if (this.readIncoming < this.currentParcelSize) {
|
||||
// We haven't read enough yet in order to be able to process a parcel.
|
||||
if (DEBUG) debug("Read " + this.mReadIncoming + ", but parcel size is "
|
||||
+ this.mCurrentParcelSize + ". Going to sleep.");
|
||||
if (DEBUG) debug("Read " + this.readIncoming + ", but parcel size is "
|
||||
+ this.currentParcelSize + ". Going to sleep.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Alright, we have enough data to process at least one whole parcel.
|
||||
// Let's do that.
|
||||
let expectedAfterIndex = (this.mIncomingReadIndex + this.mCurrentParcelSize)
|
||||
% this.mIncomingBufferLength;
|
||||
let expectedAfterIndex = (this.incomingReadIndex + this.currentParcelSize)
|
||||
% this.incomingBufferLength;
|
||||
|
||||
if (DEBUG) {
|
||||
let parcel;
|
||||
if (expectedAfterIndex < this.mIncomingReadIndex) {
|
||||
let head = this.mIncomingBytes.subarray(this.mIncomingReadIndex);
|
||||
let tail = this.mIncomingBytes.subarray(0, expectedAfterIndex);
|
||||
if (expectedAfterIndex < this.incomingReadIndex) {
|
||||
let head = this.incomingBytes.subarray(this.incomingReadIndex);
|
||||
let tail = this.incomingBytes.subarray(0, expectedAfterIndex);
|
||||
parcel = Array.slice(head).concat(Array.slice(tail));
|
||||
} else {
|
||||
parcel = Array.slice(this.mIncomingBytes.subarray(
|
||||
this.mIncomingReadIndex, expectedAfterIndex));
|
||||
parcel = Array.slice(this.incomingBytes.subarray(
|
||||
this.incomingReadIndex, expectedAfterIndex));
|
||||
}
|
||||
debug("Parcel (size " + this.mCurrentParcelSize + "): " + parcel);
|
||||
debug("Parcel (size " + this.currentParcelSize + "): " + parcel);
|
||||
}
|
||||
|
||||
if (DEBUG) debug("We have at least one complete parcel.");
|
||||
try {
|
||||
this.mReadAvailable = this.mCurrentParcelSize;
|
||||
this.readAvailable = this.currentParcelSize;
|
||||
this.processParcel();
|
||||
} catch (ex) {
|
||||
if (DEBUG) debug("Parcel handling threw " + ex + "\n" + ex.stack);
|
||||
}
|
||||
|
||||
// Ensure that the whole parcel was consumed.
|
||||
if (this.mIncomingReadIndex != expectedAfterIndex) {
|
||||
if (this.incomingReadIndex != expectedAfterIndex) {
|
||||
if (DEBUG) {
|
||||
debug("Parcel handler didn't consume whole parcel, " +
|
||||
Math.abs(expectedAfterIndex - this.mIncomingReadIndex) +
|
||||
Math.abs(expectedAfterIndex - this.incomingReadIndex) +
|
||||
" bytes left over");
|
||||
}
|
||||
this.mIncomingReadIndex = expectedAfterIndex;
|
||||
this.incomingReadIndex = expectedAfterIndex;
|
||||
}
|
||||
this.mReadIncoming -= this.mCurrentParcelSize;
|
||||
this.mReadAvailable = 0;
|
||||
this.mCurrentParcelSize = 0;
|
||||
this.readIncoming -= this.currentParcelSize;
|
||||
this.readAvailable = 0;
|
||||
this.currentParcelSize = 0;
|
||||
}
|
||||
},
|
||||
|
||||
@ -559,23 +560,23 @@ let Buf = {
|
||||
// Compute the size of the parcel and write it to the front of the parcel
|
||||
// where we left room for it. Note that he parcel size does not include
|
||||
// the size itself.
|
||||
let parcelSize = this.mOutgoingIndex - this.PARCEL_SIZE_SIZE;
|
||||
let parcelSize = this.outgoingIndex - this.PARCEL_SIZE_SIZE;
|
||||
this.writeParcelSize(parcelSize);
|
||||
|
||||
// This assumes that postRILMessage will make a copy of the ArrayBufferView
|
||||
// right away!
|
||||
let parcel = this.mOutgoingBytes.subarray(0, this.mOutgoingIndex);
|
||||
let parcel = this.outgoingBytes.subarray(0, this.outgoingIndex);
|
||||
if (DEBUG) debug("Outgoing parcel: " + Array.slice(parcel));
|
||||
this.onSendParcel(parcel);
|
||||
this.mOutgoingIndex = this.PARCEL_SIZE_SIZE;
|
||||
this.outgoingIndex = this.PARCEL_SIZE_SIZE;
|
||||
},
|
||||
|
||||
getCurrentParcelSize: function getCurrentParcelSize() {
|
||||
return this.mCurrentParcelSize;
|
||||
return this.currentParcelSize;
|
||||
},
|
||||
|
||||
getReadAvailable: function getReadAvailable() {
|
||||
return this.mReadAvailable;
|
||||
return this.readAvailable;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -495,6 +495,7 @@ RES_LAYOUT = \
|
||||
res/layout/notification_progress_text.xml \
|
||||
res/layout/pin_bookmark_dialog.xml \
|
||||
res/layout/preference_rightalign_icon.xml \
|
||||
res/layout/preference_search_engine.xml \
|
||||
res/layout/preference_search_tip.xml \
|
||||
res/layout/site_setting_item.xml \
|
||||
res/layout/site_setting_title.xml \
|
||||
|
@ -166,7 +166,7 @@ class SearchEngineRow extends AnimatedHeightLayout {
|
||||
mSearchEngine = searchEngine;
|
||||
|
||||
// Set the search engine icon (e.g., Google) for the row
|
||||
mIconView.updateImage(mSearchEngine.icon, mSearchEngine.name);
|
||||
mIconView.updateAndScaleImage(mSearchEngine.icon, mSearchEngine.name);
|
||||
|
||||
// Set the initial content description
|
||||
setDescriptionOnSuggestion(mUserEnteredTextView, mUserEnteredTextView.getText().toString());
|
||||
|
@ -10,10 +10,10 @@ import android.content.DialogInterface;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.drawable.BitmapDrawable;
|
||||
import android.os.Build;
|
||||
import android.preference.Preference;
|
||||
import android.text.SpannableString;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
import org.json.JSONException;
|
||||
@ -21,6 +21,7 @@ import org.json.JSONObject;
|
||||
import org.mozilla.gecko.R;
|
||||
import org.mozilla.gecko.gfx.BitmapUtils;
|
||||
import org.mozilla.gecko.util.ThreadUtils;
|
||||
import org.mozilla.gecko.widget.FaviconView;
|
||||
|
||||
/**
|
||||
* Represents an element in the list of search engines on the preferences menu.
|
||||
@ -28,9 +29,6 @@ import org.mozilla.gecko.util.ThreadUtils;
|
||||
public class SearchEnginePreference extends Preference {
|
||||
private static final String LOGTAG = "SearchEnginePreference";
|
||||
|
||||
// Dimensions, in dp, of the icon to display for this engine.
|
||||
public static int sIconSize;
|
||||
|
||||
// Indices in button array of the AlertDialog of the three buttons.
|
||||
public static final int INDEX_SET_DEFAULT_BUTTON = 0;
|
||||
public static final int INDEX_REMOVE_BUTTON = 1;
|
||||
@ -51,6 +49,13 @@ public class SearchEnginePreference extends Preference {
|
||||
|
||||
private final SearchPreferenceCategory mParentCategory;
|
||||
|
||||
// The icon to display in the prompt when clicked.
|
||||
private BitmapDrawable mPromptIcon;
|
||||
// The bitmap backing the drawable above - needed separately for the FaviconView.
|
||||
private Bitmap mIconBitmap;
|
||||
|
||||
private FaviconView mFaviconView;
|
||||
|
||||
/**
|
||||
* Create a preference object to represent a search engine that is attached to category
|
||||
* containingCategory.
|
||||
@ -64,8 +69,9 @@ public class SearchEnginePreference extends Preference {
|
||||
|
||||
Resources res = getContext().getResources();
|
||||
|
||||
// Fetch the icon dimensions from the resource file.
|
||||
sIconSize = res.getDimensionPixelSize(R.dimen.searchpreferences_icon_size);
|
||||
// Set the layout resource for this preference - includes a FaviconView.
|
||||
setLayoutResource(R.layout.preference_search_engine);
|
||||
|
||||
setOnPreferenceClickListener(new OnPreferenceClickListener() {
|
||||
@Override
|
||||
public boolean onPreferenceClick(Preference preference) {
|
||||
@ -84,6 +90,20 @@ public class SearchEnginePreference extends Preference {
|
||||
res.getString(R.string.pref_search_remove) };
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by Android when we're bound to the custom view. Allows us to set the custom properties
|
||||
* of our custom view elements as we desire (We can now use findViewById on them).
|
||||
*
|
||||
* @param view The view instance for this Preference object.
|
||||
*/
|
||||
@Override
|
||||
protected void onBindView(View view) {
|
||||
super.onBindView(view);
|
||||
// Set the icon in the FaviconView.
|
||||
mFaviconView = ((FaviconView) view.findViewById(R.id.search_engine_icon));
|
||||
mFaviconView.updateAndScaleImage(mIconBitmap, getTitle().toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure this Preference object from the Gecko search engine JSON object.
|
||||
* @param geckoEngineJSON The Gecko-formatted JSON object representing the search engine.
|
||||
@ -91,7 +111,7 @@ public class SearchEnginePreference extends Preference {
|
||||
*/
|
||||
public void setSearchEngineFromJSON(JSONObject geckoEngineJSON) throws JSONException {
|
||||
final String engineName = geckoEngineJSON.getString("name");
|
||||
SpannableString titleSpannable = new SpannableString(engineName);
|
||||
final SpannableString titleSpannable = new SpannableString(engineName);
|
||||
mIsImmutableEngine = geckoEngineJSON.getBoolean("immutable");
|
||||
|
||||
if (mIsImmutableEngine) {
|
||||
@ -100,18 +120,14 @@ public class SearchEnginePreference extends Preference {
|
||||
}
|
||||
setTitle(titleSpannable);
|
||||
|
||||
// setIcon is only available on Honeycomb and up.
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
|
||||
// Create a drawable from the iconURI and assign it to this Preference for display.
|
||||
String iconURI = geckoEngineJSON.getString("iconURI");
|
||||
Bitmap iconBitmap = BitmapUtils.getBitmapFromDataURI(iconURI);
|
||||
// The favicon provided may be null or corrupt, if there was a network error or similar.
|
||||
if (iconBitmap == null) {
|
||||
return;
|
||||
}
|
||||
Bitmap scaledIconBitmap = Bitmap.createScaledBitmap(iconBitmap, sIconSize, sIconSize, false);
|
||||
BitmapDrawable drawable = new BitmapDrawable(scaledIconBitmap);
|
||||
setIcon(drawable);
|
||||
final String iconURI = geckoEngineJSON.getString("iconURI");
|
||||
// Keep a reference to the bitmap - we'll need it later in onBindView.
|
||||
try {
|
||||
mIconBitmap = BitmapUtils.getBitmapFromDataURI(iconURI);
|
||||
} catch (IllegalArgumentException e) {
|
||||
Log.e(LOGTAG, "IllegalArgumentException creating Bitmap. Most likely a zero-length bitmap.", e);
|
||||
} catch (NullPointerException e) {
|
||||
Log.e(LOGTAG, "NullPointerException creating Bitmap. Most likely a zero-length bitmap.", e);
|
||||
}
|
||||
}
|
||||
|
||||
@ -176,10 +192,12 @@ public class SearchEnginePreference extends Preference {
|
||||
}
|
||||
});
|
||||
|
||||
// Copy the icon, if any, from this object to the prompt we produce.
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
|
||||
builder.setIcon(getIcon());
|
||||
// Copy the icon from this object to the prompt we produce. We lazily create the drawable,
|
||||
// as the user may not ever actually tap this object.
|
||||
if (mPromptIcon == null && mIconBitmap != null) {
|
||||
mPromptIcon = new BitmapDrawable(mFaviconView.getBitmap());
|
||||
}
|
||||
builder.setIcon(mPromptIcon);
|
||||
|
||||
// We have to construct the dialog itself on the UI thread.
|
||||
ThreadUtils.postToUiThread(new Runnable() {
|
||||
@ -221,7 +239,7 @@ public class SearchEnginePreference extends Preference {
|
||||
*/
|
||||
private void configureShownDialog() {
|
||||
// If we are the default engine, disable the "Set as default" button.
|
||||
TextView defaultButton = (TextView) mDialog.getListView().getChildAt(INDEX_SET_DEFAULT_BUTTON);
|
||||
final TextView defaultButton = (TextView) mDialog.getListView().getChildAt(INDEX_SET_DEFAULT_BUTTON);
|
||||
// Disable "Set as default" button if we are already the default.
|
||||
if (mIsDefaultEngine) {
|
||||
defaultButton.setEnabled(false);
|
||||
|
@ -0,0 +1,47 @@
|
||||
<?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/. -->
|
||||
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:minHeight="?android:attr/listPreferredItemHeight"
|
||||
android:gravity="center_vertical"
|
||||
android:paddingLeft="15dp"
|
||||
android:paddingRight="?android:attr/scrollbarSize">
|
||||
|
||||
<org.mozilla.gecko.widget.FaviconView
|
||||
android:id="@+id/search_engine_icon"
|
||||
android:layout_width="@dimen/favicon_bg"
|
||||
android:layout_height="@dimen/favicon_bg"
|
||||
android:layout_gravity="center"
|
||||
android:minWidth="@dimen/favicon_bg"
|
||||
android:minHeight="@dimen/favicon_bg" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:layout_marginLeft="15dip"
|
||||
android:layout_marginRight="6dip"
|
||||
android:layout_marginTop="6dip"
|
||||
android:layout_marginBottom="6dip">
|
||||
|
||||
<TextView android:id="@+android:id/title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="?android:attr/textAppearanceMedium"
|
||||
android:singleLine="true"
|
||||
android:ellipsize="marquee"
|
||||
android:fadingEdge="horizontal" />
|
||||
|
||||
<TextView android:id="@+android:id/summary"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
android:maxLines="2" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
@ -24,36 +24,12 @@ import java.util.ArrayList;
|
||||
* To use any of these methods in your test make sure it extends AboutHomeTest instead of BaseTest
|
||||
*/
|
||||
abstract class AboutHomeTest extends BaseTest {
|
||||
protected enum BrowserDataType {BOOKMARKS, HISTORY};
|
||||
protected enum AboutHomeTabs {MOST_VISITED, MOST_RECENT, TABS_FROM_LAST_TIME, BOOKMARKS, READING_LIST};
|
||||
protected ArrayList<String> aboutHomeTabs = new ArrayList<String>() {{
|
||||
add("HISTORY");
|
||||
add("BOOKMARKS");
|
||||
add("READING_LIST");
|
||||
}};
|
||||
|
||||
// Labels for the about:home tabs
|
||||
protected static final String HISTORY_LABEL = "HISTORY";
|
||||
protected static final String BOOKMARKS_LABEL = "BOOKMARKS";
|
||||
protected static final String READING_LIST_LABEL = "READING LIST";
|
||||
protected static final String MOST_RECENT_LABEL = "Most recent";
|
||||
protected static final String TABS_FROM_LAST_TIME_LABEL = "Open all tabs from last time";
|
||||
|
||||
/**
|
||||
* This method can be used to check if an URL is present in the bookmarks database
|
||||
*/
|
||||
protected boolean isBookmark(String url) {
|
||||
try {
|
||||
ContentResolver resolver = getActivity().getContentResolver();
|
||||
ClassLoader classLoader = getActivity().getClassLoader();
|
||||
Class browserDB = classLoader.loadClass("org.mozilla.gecko.db.BrowserDB");
|
||||
Method isBookmarked = browserDB.getMethod("isBookmark", ContentResolver.class, String.class);
|
||||
return (Boolean)isBookmarked.invoke(null, resolver, url);
|
||||
} catch (Exception e) {
|
||||
mAsserter.ok(false, "Exception while checking if url is bookmarked: ", e.toString()); // Fail before returning
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* FIXME: Write new versions of these methods and update their consumers to use the new about:home pages.
|
||||
@ -65,18 +41,6 @@ abstract class AboutHomeTest extends BaseTest {
|
||||
return null;
|
||||
}
|
||||
|
||||
protected Uri buildUri(BrowserDataType dataType) {
|
||||
Uri uri = null;
|
||||
if (dataType == BrowserDataType.BOOKMARKS || dataType == BrowserDataType.HISTORY) {
|
||||
uri = Uri.parse("content://@ANDROID_PACKAGE_NAME@.db.browser/" + dataType.toString().toLowerCase());
|
||||
} else {
|
||||
mAsserter.ok(false, "The wrong data type has been provided = " + dataType.toString(), "Please provide a BrowserDataType value");
|
||||
}
|
||||
uri = uri.buildUpon().appendQueryParameter("profile", "default")
|
||||
.appendQueryParameter("sync", "true").build();
|
||||
return uri;
|
||||
}
|
||||
|
||||
/**
|
||||
* Waits for the given ListView to have a non-empty adapter.
|
||||
*
|
||||
@ -121,157 +85,6 @@ abstract class AboutHomeTest extends BaseTest {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a bookmark, or updates the bookmark title if the url already exists.
|
||||
*
|
||||
* The LocalBrowserDB.addBookmark implementation handles updating existing bookmarks.
|
||||
* Since we don't modify bookmark keywords in tests, we don't need a separate
|
||||
* implemention of updateBookmark.
|
||||
*/
|
||||
protected void addOrUpdateMobileBookmark(String title, String url) {
|
||||
try {
|
||||
ContentResolver resolver = getActivity().getContentResolver();
|
||||
ClassLoader classLoader = getActivity().getClassLoader();
|
||||
Class browserDB = classLoader.loadClass("org.mozilla.gecko.db.BrowserDB");
|
||||
Method addBookmark = browserDB.getMethod("addBookmark", ContentResolver.class, String.class, String.class);
|
||||
addBookmark.invoke(null, resolver, title, url);
|
||||
mAsserter.ok(true, "Inserting/updating a new bookmark", "Inserting/updating the bookmark with the title = " + title + " and the url = " + url);
|
||||
} catch (Exception e) {
|
||||
mAsserter.ok(false, "Exception adding bookmark: ", e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the title and keyword of a bookmark with the given URL.
|
||||
*
|
||||
* Warning: This method assumes that there's only one bookmark with the given URL.
|
||||
*/
|
||||
protected void updateBookmark(String url, String title, String keyword) {
|
||||
try {
|
||||
ContentResolver resolver = getActivity().getContentResolver();
|
||||
ClassLoader classLoader = getActivity().getClassLoader();
|
||||
Class browserDB = classLoader.loadClass("org.mozilla.gecko.db.BrowserDB");
|
||||
Method getBookmarkForUrl = browserDB.getMethod("getBookmarkForUrl", ContentResolver.class, String.class);
|
||||
|
||||
// Get the id for the bookmark with the given URL.
|
||||
Cursor c = null;
|
||||
try {
|
||||
c = (Cursor) getBookmarkForUrl.invoke(null, resolver, url);
|
||||
if (!c.moveToFirst()) {
|
||||
mAsserter.ok(false, "Getting bookmark with url", "Couldn't find bookmark with url = " + url);
|
||||
return;
|
||||
}
|
||||
|
||||
int id = c.getInt(c.getColumnIndexOrThrow("_id"));
|
||||
Method updateBookmark = browserDB.getMethod("updateBookmark", ContentResolver.class, int.class, String.class, String.class, String.class);
|
||||
updateBookmark.invoke(null, resolver, id, url, title, keyword);
|
||||
|
||||
mAsserter.ok(true, "Updating bookmark", "Updating bookmark with url = " + url);
|
||||
} finally {
|
||||
if (c != null) {
|
||||
c.close();
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
mAsserter.ok(false, "Exception updating bookmark: ", e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
protected void deleteBookmark(String url) {
|
||||
try {
|
||||
ContentResolver resolver = getActivity().getContentResolver();
|
||||
ClassLoader classLoader = getActivity().getClassLoader();
|
||||
Class browserDB = classLoader.loadClass("org.mozilla.gecko.db.BrowserDB");
|
||||
Method removeBookmark = browserDB.getMethod("removeBookmarksWithURL", ContentResolver.class, String.class);
|
||||
removeBookmark.invoke(null, resolver, url);
|
||||
} catch (Exception e) {
|
||||
mAsserter.ok(false, "Exception deleting bookmark: ", e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
protected void deleteHistoryItem(String url) {
|
||||
try {
|
||||
ContentResolver resolver = getActivity().getContentResolver();
|
||||
ClassLoader classLoader = getActivity().getClassLoader();
|
||||
Class browserDB = classLoader.loadClass("org.mozilla.gecko.db.BrowserDB");
|
||||
Method removeHistory = browserDB.getMethod("removeHistoryEntry", ContentResolver.class, String.class);
|
||||
removeHistory.invoke(null, resolver, url);
|
||||
} catch (Exception e) {
|
||||
mAsserter.ok(false, "Exception deleting history item: ", e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
protected Long getFolderId(String guid) {
|
||||
ContentResolver resolver = getActivity().getContentResolver();
|
||||
Long folderId = Long.valueOf(-1);
|
||||
Uri bookmarksUri = buildUri(BrowserDataType.BOOKMARKS);
|
||||
Cursor c = null;
|
||||
try {
|
||||
c = resolver.query(bookmarksUri,
|
||||
new String[] { "_id" },
|
||||
"guid = ?",
|
||||
new String[] { guid },
|
||||
null);
|
||||
if (c.moveToFirst()) {
|
||||
folderId = c.getLong(c.getColumnIndexOrThrow("_id"));
|
||||
}
|
||||
if (folderId == -1) {
|
||||
mAsserter.ok(false, "Making sure that we got the correct folder", "We didn't get the correct folder id");
|
||||
}
|
||||
} finally {
|
||||
if (c != null) {
|
||||
c.close();
|
||||
}
|
||||
}
|
||||
return folderId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param a BrowserDataType value - either HISTORY or BOOKMARKS
|
||||
* @return an ArrayList of the urls in the Firefox for Android Bookmarks or History databases
|
||||
*/
|
||||
protected ArrayList<String> getBrowserDBUrls(BrowserDataType dataType) {
|
||||
ArrayList<String> browserData = new ArrayList<String>();
|
||||
ContentResolver resolver = getActivity().getContentResolver();
|
||||
ClassLoader classLoader = getActivity().getClassLoader();
|
||||
Cursor cursor = null;
|
||||
Uri uri = buildUri(dataType);
|
||||
if (dataType == BrowserDataType.HISTORY) {
|
||||
try {
|
||||
Class browserDBClass = classLoader.loadClass("org.mozilla.gecko.db.BrowserDB");
|
||||
Method getAllVisitedHistory = browserDBClass.getMethod("getAllVisitedHistory", ContentResolver.class);
|
||||
cursor = (Cursor)getAllVisitedHistory.invoke(null, resolver);
|
||||
} catch (Exception e) {
|
||||
mAsserter.ok(false, "Exception while getting history", e.toString());
|
||||
}
|
||||
} else if (dataType == BrowserDataType.BOOKMARKS) {
|
||||
try {
|
||||
Class browserDBClass = classLoader.loadClass("org.mozilla.gecko.db.BrowserDB");
|
||||
Method getBookmarks = browserDBClass.getMethod("getBookmarksInFolder", ContentResolver.class, Long.TYPE);
|
||||
cursor = (Cursor)getBookmarks.invoke(null, resolver, getFolderId("mobile"));
|
||||
} catch (Exception e) {
|
||||
mAsserter.ok(false, "Exception while getting bookmarks", e.toString());
|
||||
}
|
||||
}
|
||||
if (cursor != null) {
|
||||
cursor.moveToFirst();
|
||||
for (int i = 0; i < cursor.getCount(); i++ ) {
|
||||
// The url field may be null for folders in the structure of the Bookmarks table for Firefox so we should eliminate those
|
||||
if (cursor.getString(cursor.getColumnIndex("url")) != null) {
|
||||
browserData.add(cursor.getString(cursor.getColumnIndex("url")));
|
||||
}
|
||||
if(!cursor.isLast()) {
|
||||
cursor.moveToNext();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
mAsserter.ok(false, "We could not retrieve any data from the database", "The cursor was null");
|
||||
}
|
||||
if (cursor != null) {
|
||||
cursor.close();
|
||||
}
|
||||
return browserData;
|
||||
}
|
||||
|
||||
/**
|
||||
* FIXME: rewrite this to work with fig when rewriting the testBookmarksTab test
|
||||
@ -352,44 +165,44 @@ abstract class AboutHomeTest extends BaseTest {
|
||||
ViewPager pager = (ViewPager)mSolo.getView(ViewPager.class, 0);
|
||||
switch (tab) {
|
||||
case BOOKMARKS : {
|
||||
mSolo.clickOnText(BOOKMARKS_LABEL);
|
||||
mSolo.clickOnText(StringHelper.BOOKMARKS_LABEL);
|
||||
waitForAboutHomeTab(aboutHomeTabs.indexOf(tab.toString()));
|
||||
break;
|
||||
}
|
||||
case MOST_RECENT: {
|
||||
mSolo.clickOnText(BOOKMARKS_LABEL);
|
||||
waitForAboutHomeTab(aboutHomeTabs.indexOf(BOOKMARKS_LABEL));
|
||||
mSolo.clickOnText(StringHelper.BOOKMARKS_LABEL);
|
||||
waitForAboutHomeTab(aboutHomeTabs.indexOf(StringHelper.BOOKMARKS_LABEL));
|
||||
mActions.drag(0, halfWidth, halfHeight, halfHeight);
|
||||
waitForAboutHomeTab(aboutHomeTabs.indexOf(HISTORY_LABEL));
|
||||
waitForAboutHomeTab(aboutHomeTabs.indexOf(StringHelper.HISTORY_LABEL));
|
||||
TabWidget tabwidget = (TabWidget)mSolo.getView(TabWidget.class, 0);
|
||||
mSolo.clickOnView(tabwidget.getChildAt(1));
|
||||
mAsserter.ok(waitForText(MOST_RECENT_LABEL), "Checking that we are in the most recent tab of about:home", "We are in the most recent tab");
|
||||
mAsserter.ok(waitForText(StringHelper.MOST_RECENT_LABEL), "Checking that we are in the most recent tab of about:home", "We are in the most recent tab");
|
||||
break;
|
||||
}
|
||||
case READING_LIST: {
|
||||
mSolo.clickOnText(BOOKMARKS_LABEL);
|
||||
waitForAboutHomeTab(aboutHomeTabs.indexOf(BOOKMARKS_LABEL));
|
||||
mSolo.clickOnText(StringHelper.BOOKMARKS_LABEL);
|
||||
waitForAboutHomeTab(aboutHomeTabs.indexOf(StringHelper.BOOKMARKS_LABEL));
|
||||
mActions.drag(halfWidth, 0, halfHeight, halfHeight);
|
||||
waitForAboutHomeTab(aboutHomeTabs.indexOf(tab.toString()));
|
||||
break;
|
||||
}
|
||||
case MOST_VISITED: {
|
||||
mSolo.clickOnText(BOOKMARKS_LABEL);
|
||||
waitForAboutHomeTab(aboutHomeTabs.indexOf(BOOKMARKS_LABEL));
|
||||
mSolo.clickOnText(StringHelper.BOOKMARKS_LABEL);
|
||||
waitForAboutHomeTab(aboutHomeTabs.indexOf(StringHelper.BOOKMARKS_LABEL));
|
||||
mActions.drag(0, halfWidth, halfHeight, halfHeight);
|
||||
waitForAboutHomeTab(aboutHomeTabs.indexOf(HISTORY_LABEL));
|
||||
waitForAboutHomeTab(aboutHomeTabs.indexOf(StringHelper.HISTORY_LABEL));
|
||||
TabWidget tabwidget = (TabWidget)mSolo.getView(TabWidget.class, 0);
|
||||
mSolo.clickOnView(tabwidget.getChildAt(0));
|
||||
break;
|
||||
}
|
||||
case TABS_FROM_LAST_TIME: {
|
||||
mSolo.clickOnText(BOOKMARKS_LABEL);
|
||||
waitForAboutHomeTab(aboutHomeTabs.indexOf(BOOKMARKS_LABEL));
|
||||
mSolo.clickOnText(StringHelper.BOOKMARKS_LABEL);
|
||||
waitForAboutHomeTab(aboutHomeTabs.indexOf(StringHelper.BOOKMARKS_LABEL));
|
||||
mActions.drag(0, halfWidth, halfHeight, halfHeight);
|
||||
waitForAboutHomeTab(aboutHomeTabs.indexOf(HISTORY_LABEL));
|
||||
waitForAboutHomeTab(aboutHomeTabs.indexOf(StringHelper.HISTORY_LABEL));
|
||||
TabWidget tabwidget = (TabWidget)mSolo.getView(TabWidget.class, 0);
|
||||
mSolo.clickOnView(tabwidget.getChildAt(2));
|
||||
mAsserter.ok(waitForText(TABS_FROM_LAST_TIME_LABEL), "Checking that we are in the Tabs from last time tab of about:home", "We are in the Tabs from last time tab");
|
||||
mAsserter.ok(waitForText(StringHelper.TABS_FROM_LAST_TIME_LABEL), "Checking that we are in the Tabs from last time tab of about:home", "We are in the Tabs from last time tab");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -52,28 +52,11 @@ abstract class BaseTest extends ActivityInstrumentationTestCase2<Activity> {
|
||||
private static final int MAX_WAIT_HOME_PAGER_HIDDEN_MS = 10000;
|
||||
public static final int MAX_WAIT_MS = 3000;
|
||||
|
||||
// Note: DEFAULT_BOOKMARKS_TITLES.length == DEFAULT_BOOKMARKS_URLS.length
|
||||
protected static final String[] DEFAULT_BOOKMARKS_TITLES = new String[] {
|
||||
"Firefox: About your browser",
|
||||
"Firefox: Support",
|
||||
"Firefox: Customize with add-ons"
|
||||
};
|
||||
protected static final String[] DEFAULT_BOOKMARKS_URLS = new String[] {
|
||||
"about:firefox",
|
||||
"http://support.mozilla.org/en-US/products/mobile",
|
||||
"https://addons.mozilla.org/en-US/android/"
|
||||
};
|
||||
protected static final int DEFAULT_BOOKMARKS_COUNT = DEFAULT_BOOKMARKS_TITLES.length;
|
||||
|
||||
// IDs for UI views
|
||||
private static final String BROWSER_TOOLBAR_ID = "browser_toolbar";
|
||||
protected static final String URL_EDIT_TEXT_ID = "url_edit_text";
|
||||
protected static final String URL_BAR_TITLE_ID = "url_bar_title";
|
||||
|
||||
// Settings menu paths
|
||||
protected static final String PRIVACY_LABEL = "Privacy";
|
||||
protected static final String CLEAR_PRIVATE_DATA_LABEL = "Clear private data";
|
||||
|
||||
private static Class<Activity> mLauncherActivityClass;
|
||||
private Activity mActivity;
|
||||
protected Solo mSolo;
|
||||
@ -85,6 +68,8 @@ abstract class BaseTest extends ActivityInstrumentationTestCase2<Activity> {
|
||||
private String mLogFile;
|
||||
protected String mProfile;
|
||||
public Device mDevice;
|
||||
protected DatabaseHelper mDatabaseHelper;
|
||||
protected StringHelper mStringHelper;
|
||||
|
||||
protected void blockForGeckoReady() {
|
||||
try {
|
||||
@ -154,6 +139,8 @@ abstract class BaseTest extends ActivityInstrumentationTestCase2<Activity> {
|
||||
mDriver = new FennecNativeDriver(mActivity, mSolo, rootPath);
|
||||
mActions = new FennecNativeActions(mActivity, mSolo, getInstrumentation(), mAsserter);
|
||||
mDevice = new Device();
|
||||
mDatabaseHelper = new DatabaseHelper(mActivity, mAsserter);
|
||||
mStringHelper = new StringHelper();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -617,7 +604,7 @@ abstract class BaseTest extends ActivityInstrumentationTestCase2<Activity> {
|
||||
}
|
||||
|
||||
public void clearPrivateData() {
|
||||
selectSettingsItem(PRIVACY_LABEL, CLEAR_PRIVATE_DATA_LABEL);
|
||||
selectSettingsItem(StringHelper.PRIVACY_SECTION_LABEL, StringHelper.CLEAR_PRIVATE_DATA_LABEL);
|
||||
Actions.EventExpecter clearData = mActions.expectGeckoEvent("Sanitize:Finished");
|
||||
mSolo.clickOnText("Clear data");
|
||||
clearData.blockForEvent();
|
||||
|
@ -10,7 +10,7 @@ import java.lang.reflect.Method;
|
||||
/**
|
||||
* This class covers interactions with the context menu opened from web content
|
||||
*/
|
||||
abstract class ContentContextMenuTest extends AboutHomeTest {
|
||||
abstract class ContentContextMenuTest extends BaseTest {
|
||||
private static final int MAX_TEST_TIMEOUT = 10000;
|
||||
|
||||
// This method opens the context menu of any web content. It assumes that the page is already loaded
|
||||
@ -88,6 +88,6 @@ abstract class ContentContextMenuTest extends AboutHomeTest {
|
||||
openWebContentContextMenu(bookmarkOption);
|
||||
mSolo.clickOnText(bookmarkOption);
|
||||
mAsserter.ok(waitForText("Bookmark added"), "Waiting for the Bookmark added toaster notification", "The notification has been displayed");
|
||||
mAsserter.ok(isBookmark(link), "Checking if the link has been added as a bookmark", "The link has been bookmarked");
|
||||
mAsserter.ok(mDatabaseHelper.isBookmark(link), "Checking if the link has been added as a bookmark", "The link has been bookmarked");
|
||||
}
|
||||
}
|
||||
|
201
mobile/android/base/tests/DatabaseHelper.java.in
Normal file
201
mobile/android/base/tests/DatabaseHelper.java.in
Normal file
@ -0,0 +1,201 @@
|
||||
#filter substitution
|
||||
package @ANDROID_PACKAGE_NAME@.tests;
|
||||
|
||||
import @ANDROID_PACKAGE_NAME@.*;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.ContentResolver;
|
||||
import android.database.Cursor;
|
||||
import android.net.Uri;
|
||||
import android.test.ActivityInstrumentationTestCase2;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
|
||||
class DatabaseHelper {
|
||||
protected enum BrowserDataType {BOOKMARKS, HISTORY};
|
||||
private Activity mActivity;
|
||||
private Assert mAsserter;
|
||||
|
||||
public DatabaseHelper(Activity activity, Assert asserter) {
|
||||
mActivity = activity;
|
||||
mAsserter = asserter;
|
||||
}
|
||||
/**
|
||||
* This method can be used to check if an URL is present in the bookmarks database
|
||||
*/
|
||||
protected boolean isBookmark(String url) {
|
||||
try {
|
||||
ContentResolver resolver = mActivity.getContentResolver();
|
||||
ClassLoader classLoader = mActivity.getClassLoader();
|
||||
Class browserDB = classLoader.loadClass("org.mozilla.gecko.db.BrowserDB");
|
||||
Method isBookmarked = browserDB.getMethod("isBookmark", ContentResolver.class, String.class);
|
||||
return (Boolean)isBookmarked.invoke(null, resolver, url);
|
||||
} catch (Exception e) {
|
||||
mAsserter.ok(false, "Exception while checking if url is bookmarked", e.toString());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
protected Uri buildUri(BrowserDataType dataType) {
|
||||
Uri uri = null;
|
||||
if (dataType == BrowserDataType.BOOKMARKS || dataType == BrowserDataType.HISTORY) {
|
||||
uri = Uri.parse("content://@ANDROID_PACKAGE_NAME@.db.browser/" + dataType.toString().toLowerCase());
|
||||
} else {
|
||||
mAsserter.ok(false, "The wrong data type has been provided = " + dataType.toString(), "Please provide the correct data type");
|
||||
}
|
||||
uri = uri.buildUpon().appendQueryParameter("profile", "default")
|
||||
.appendQueryParameter("sync", "true").build();
|
||||
return uri;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a bookmark, or updates the bookmark title if the url already exists.
|
||||
*
|
||||
* The LocalBrowserDB.addBookmark implementation handles updating existing bookmarks.
|
||||
*/
|
||||
protected void addOrUpdateMobileBookmark(String title, String url) {
|
||||
try {
|
||||
ContentResolver resolver = mActivity.getContentResolver();
|
||||
ClassLoader classLoader = mActivity.getClassLoader();
|
||||
Class browserDB = classLoader.loadClass("org.mozilla.gecko.db.BrowserDB");
|
||||
Method addBookmark = browserDB.getMethod("addBookmark", ContentResolver.class, String.class, String.class);
|
||||
addBookmark.invoke(null, resolver, title, url);
|
||||
mAsserter.ok(true, "Inserting/updating a new bookmark", "Inserting/updating the bookmark with the title = " + title + " and the url = " + url);
|
||||
} catch (Exception e) {
|
||||
mAsserter.ok(false, "Exception adding bookmark: ", e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the title and keyword of a bookmark with the given URL.
|
||||
*
|
||||
* Warning: This method assumes that there's only one bookmark with the given URL.
|
||||
*/
|
||||
protected void updateBookmark(String url, String title, String keyword) {
|
||||
try {
|
||||
ContentResolver resolver = mActivity.getContentResolver();
|
||||
ClassLoader classLoader = mActivity.getClassLoader();
|
||||
Class browserDB = classLoader.loadClass("org.mozilla.gecko.db.BrowserDB");
|
||||
Method getBookmarkForUrl = browserDB.getMethod("getBookmarkForUrl", ContentResolver.class, String.class);
|
||||
|
||||
// Get the id for the bookmark with the given URL.
|
||||
Cursor c = null;
|
||||
try {
|
||||
c = (Cursor) getBookmarkForUrl.invoke(null, resolver, url);
|
||||
if (!c.moveToFirst()) {
|
||||
mAsserter.ok(false, "Getting bookmark with url", "Couldn't find bookmark with url = " + url);
|
||||
return;
|
||||
}
|
||||
|
||||
int id = c.getInt(c.getColumnIndexOrThrow("_id"));
|
||||
Method updateBookmark = browserDB.getMethod("updateBookmark", ContentResolver.class, int.class, String.class, String.class, String.class);
|
||||
updateBookmark.invoke(null, resolver, id, url, title, keyword);
|
||||
|
||||
mAsserter.ok(true, "Updating bookmark", "Updating bookmark with url = " + url);
|
||||
} finally {
|
||||
if (c != null) {
|
||||
c.close();
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
mAsserter.ok(false, "Exception updating bookmark: ", e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
protected void deleteBookmark(String url) {
|
||||
try {
|
||||
ContentResolver resolver = mActivity.getContentResolver();
|
||||
ClassLoader classLoader = mActivity.getClassLoader();
|
||||
Class browserDB = classLoader.loadClass("org.mozilla.gecko.db.BrowserDB");
|
||||
Method removeBookmark = browserDB.getMethod("removeBookmarksWithURL", ContentResolver.class, String.class);
|
||||
removeBookmark.invoke(null, resolver, url);
|
||||
} catch (Exception e) {
|
||||
mAsserter.ok(false, "Exception deleting bookmark", e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
protected void deleteHistoryItem(String url) {
|
||||
try {
|
||||
ContentResolver resolver = mActivity.getContentResolver();
|
||||
ClassLoader classLoader = mActivity.getClassLoader();
|
||||
Class browserDB = classLoader.loadClass("org.mozilla.gecko.db.BrowserDB");
|
||||
Method removeHistory = browserDB.getMethod("removeHistoryEntry", ContentResolver.class, String.class);
|
||||
removeHistory.invoke(null, resolver, url);
|
||||
} catch (Exception e) {
|
||||
mAsserter.ok(false, "Exception deleting history item", e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
// About the same implementation as getFolderIdFromGuid from LocalBrowserDB because it is declared private and we can't use reflections to access it
|
||||
protected long getFolderIdFromGuid(String guid) {
|
||||
ContentResolver resolver = mActivity.getContentResolver();
|
||||
long folderId = Long.valueOf(-1);
|
||||
Uri bookmarksUri = buildUri(BrowserDataType.BOOKMARKS);
|
||||
Cursor c = null;
|
||||
try {
|
||||
c = resolver.query(bookmarksUri,
|
||||
new String[] { "_id" },
|
||||
"guid = ?",
|
||||
new String[] { guid },
|
||||
null);
|
||||
if (c.moveToFirst()) {
|
||||
folderId = c.getLong(c.getColumnIndexOrThrow("_id"));
|
||||
}
|
||||
if (folderId == -1) {
|
||||
mAsserter.ok(false, "Trying to get the folder id" ,"We did not get the correct folder id");
|
||||
}
|
||||
} finally {
|
||||
if (c != null) {
|
||||
c.close();
|
||||
}
|
||||
}
|
||||
return folderId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param a BrowserDataType value - either HISTORY or BOOKMARKS
|
||||
* @return an ArrayList of the urls in the Firefox for Android Bookmarks or History databases
|
||||
*/
|
||||
protected ArrayList<String> getBrowserDBUrls(BrowserDataType dataType) {
|
||||
ArrayList<String> browserData = new ArrayList<String>();
|
||||
ContentResolver resolver = mActivity.getContentResolver();
|
||||
ClassLoader classLoader = mActivity.getClassLoader();
|
||||
Cursor cursor = null;
|
||||
Uri uri = buildUri(dataType);
|
||||
if (dataType == BrowserDataType.HISTORY) {
|
||||
try {
|
||||
Class browserDBClass = classLoader.loadClass("org.mozilla.gecko.db.BrowserDB");
|
||||
Method getAllVisitedHistory = browserDBClass.getMethod("getAllVisitedHistory", ContentResolver.class);
|
||||
cursor = (Cursor)getAllVisitedHistory.invoke(null, resolver);
|
||||
} catch (Exception e) {
|
||||
mAsserter.ok(false, "Exception while getting history", e.toString());
|
||||
}
|
||||
} else if (dataType == BrowserDataType.BOOKMARKS) {
|
||||
try {
|
||||
Class browserDBClass = classLoader.loadClass("org.mozilla.gecko.db.BrowserDB");
|
||||
Method getBookmarks = browserDBClass.getMethod("getBookmarksInFolder", ContentResolver.class, Long.TYPE);
|
||||
cursor = (Cursor)getBookmarks.invoke(null, resolver, getFolderIdFromGuid("mobile"));
|
||||
} catch (Exception e) {
|
||||
mAsserter.ok(false, "Exception while getting bookmarks", e.toString());
|
||||
}
|
||||
}
|
||||
if (cursor != null) {
|
||||
cursor.moveToFirst();
|
||||
for (int i = 0; i < cursor.getCount(); i++ ) {
|
||||
// The url field may be null for folders in the structure of the Bookmarks table for Firefox so we should eliminate those
|
||||
if (cursor.getString(cursor.getColumnIndex("url")) != null) {
|
||||
browserData.add(cursor.getString(cursor.getColumnIndex("url")));
|
||||
}
|
||||
if(!cursor.isLast()) {
|
||||
cursor.moveToNext();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
mAsserter.ok(false, "We could not retrieve any data from the database", "The cursor was null");
|
||||
}
|
||||
if (cursor != null) {
|
||||
cursor.close();
|
||||
}
|
||||
return browserData;
|
||||
}
|
||||
}
|
125
mobile/android/base/tests/StringHelper.java.in
Normal file
125
mobile/android/base/tests/StringHelper.java.in
Normal file
@ -0,0 +1,125 @@
|
||||
#filter substitution
|
||||
package @ANDROID_PACKAGE_NAME@.tests;
|
||||
|
||||
import @ANDROID_PACKAGE_NAME@.*;
|
||||
|
||||
class StringHelper {
|
||||
// Note: DEFAULT_BOOKMARKS_TITLES.length == DEFAULT_BOOKMARKS_URLS.length
|
||||
public static final String[] DEFAULT_BOOKMARKS_TITLES = new String[] {
|
||||
"Firefox: About your browser",
|
||||
"Firefox: Support",
|
||||
"Firefox: Customize with add-ons"
|
||||
};
|
||||
public static final String[] DEFAULT_BOOKMARKS_URLS = new String[] {
|
||||
"about:firefox",
|
||||
"http://support.mozilla.org/en-US/products/mobile",
|
||||
"https://addons.mozilla.org/en-US/android/"
|
||||
};
|
||||
public static final int DEFAULT_BOOKMARKS_COUNT = DEFAULT_BOOKMARKS_TITLES.length;
|
||||
|
||||
// Robocop page urls
|
||||
// Note: please use getAbsoluteUrl(String url) on each robocop url to get the correct url
|
||||
public static final String ROBOCOP_BIG_LINK_URL = "/robocop/robocop_big_link.html";
|
||||
public static final String ROBOCOP_BIG_MAILTO_URL = "/robocop/robocop_big_mailto.html";
|
||||
public static final String ROBOCOP_BLANK_PAGE_01_URL = "/robocop/robocop_blank_01.html";
|
||||
public static final String ROBOCOP_BLANK_PAGE_02_URL = "/robocop/robocop_blank_02.html";
|
||||
public static final String ROBOCOP_BLANK_PAGE_03_URL = "/robocop/robocop_blank_03.html";
|
||||
public static final String ROBOCOP_BOXES_URL = "/robocop/robocop_boxes.html";
|
||||
public static final String ROBOCOP_GEOLOCATION_URL = "/robocop/robocop_geolocation.html";
|
||||
public static final String ROBOCOP_LOGIN_URL = "/robocop/robocop_login.html";
|
||||
public static final String ROBOCOP_OFFLINE_STORAGE_URL = "/robocop/robocop_offline_storage.html";
|
||||
public static final String ROBOCOP_PICTURE_LINK_URL = "/robocop/robocop_picture_link.html";
|
||||
public static final String ROBOCOP_SEARCH_URL = "/robocop/robocop_search.html";
|
||||
public static final String ROBOCOP_TEXT_PAGE_URL = "/robocop/robocop_text_page.html";
|
||||
|
||||
// Robocop page titles
|
||||
public static final String ROBOCOP_BIG_LINK_TITLE = "Big Link";
|
||||
public static final String ROBOCOP_BIG_MAILTO_TITLE = "Big Mailto";
|
||||
public static final String ROBOCOP_BLANK_PAGE_01_TITLE = "Browser Blank Page 01";
|
||||
public static final String ROBOCOP_BLANK_PAGE_02_TITLE = "Browser Blank Page 02";
|
||||
public static final String ROBOCOP_BLANK_PAGE_03_TITLE = "Browser Blank Page 03";
|
||||
public static final String ROBOCOP_BOXES_TITLE = "Browser Box test";
|
||||
public static final String ROBOCOP_GEOLOCATION_TITLE = "Geolocation Test Page";
|
||||
public static final String ROBOCOP_LOGIN_TITLE = "Robocop Login";
|
||||
public static final String ROBOCOP_OFFLINE_STORAGE_TITLE = "Robocop offline storage";
|
||||
public static final String ROBOCOP_PICTURE_LINK_TITLE = "Picture Link";
|
||||
public static final String ROBOCOP_SEARCH_TITLE = "Robocop Search Engine";
|
||||
public static final String ROBOCOP_TEXT_PAGE_TITLE = "Robocop Text Page";
|
||||
|
||||
// Settings menu strings
|
||||
// Section labels - ordered as found in the settings menu
|
||||
public static final String CUSTOMIZE_SECTION_LABEL = "Customize";
|
||||
public static final String DISPLAY_SECTION_LABEL = "Display";
|
||||
public static final String PRIVACY_SECTION_LABEL = "Privacy";
|
||||
public static final String MOZILLA_SECTION_LABEL = "Mozilla";
|
||||
public static final String DEVELOPER_TOOLS_SECTION_LABEL = "Developer tools";
|
||||
|
||||
// Option labels
|
||||
// Customize
|
||||
public static final String SYNC_LABEL = "Sync";
|
||||
public static final String SEARCH_SETTINGS_LABEL = "Search settings";
|
||||
public static final String IMPORT_FROM_ANDROID_LABEL = "Import from Android";
|
||||
public static final String TABS_LABEL = "Tabs";
|
||||
|
||||
// Display
|
||||
public static final String TEXT_SIZE_LABEL = "Text size";
|
||||
public static final String TITLE_BAR_LABEL = "Title bar";
|
||||
public static final String TEXT_REFLOW_LABEL = "Text reflow";
|
||||
public static final String CHARACTER_ENCODING_LABEL = "Character encoding";
|
||||
public static final String PLUGINS_LABEL = "Plugins";
|
||||
|
||||
// Privacy
|
||||
public static final String TRACKING_LABEL = "Tracking";
|
||||
public static final String COOKIES_LABEL = "Cookies";
|
||||
public static final String REMEMBER_PASSWORDS_LABEL = "Remeber passwords";
|
||||
public static final String MASTER_PASWSWORD_LABEL = "Use master password";
|
||||
public static final String CLEAR_PRIVATE_DATA_LABEL = "Clear private data";
|
||||
|
||||
// Mozilla
|
||||
public static final String ABOUT_LABEL = "About (Fennec|Nightly|Aurora|Firefox Beta|Firefox)";
|
||||
public static final String FAQS_LABEL = "FAQs";
|
||||
public static final String FEEDBACK_LABEL = "Give feedback";
|
||||
public static final String PRODUCT_ANNOUNCEMENTS_LABEL = "Show product announcements";
|
||||
public static final String LOCATION_SERVICES_LABEL = "Mozilla location services";
|
||||
public static final String HELTH_REPORT_LABEL = "(Fennec|Nightly|Aurora|Firefox Beta|Firefox) Health Report";
|
||||
public static final String MY_HEALTH_REPORT_LABEL = "View my Health Report";
|
||||
|
||||
// Developer tools
|
||||
public static final String REMOTE_DEBUGGING_LABEL = "Remote debugging";
|
||||
public static final String LEARN_MORE_LABEL = "Learn more";
|
||||
|
||||
// Labels for the about:home tabs
|
||||
public static final String HISTORY_LABEL = "HISTORY";
|
||||
public static final String BOOKMARKS_LABEL = "BOOKMARKS";
|
||||
public static final String READING_LIST_LABEL = "READING LIST";
|
||||
public static final String MOST_RECENT_LABEL = "Most recent";
|
||||
public static final String TABS_FROM_LAST_TIME_LABEL = "Open all tabs from last time";
|
||||
|
||||
// Desktop default bookmarks folders
|
||||
public static final String DESKTOP_FOLDER_LABEL = "Desktop Bookmarks";
|
||||
public static final String TOOLBAR_FOLDER_LABEL = "Bookmarks Toolbar";
|
||||
public static final String BOOKMARKS_MENU_FOLDER_LABEL = "Bookmarks Menu";
|
||||
public static final String UNSORTED_FOLDER_LABEL = "Unsorted Bookmarks";
|
||||
|
||||
// Menu items - some of the items are found only on android 2.3 and lower and some only on android 3.0+
|
||||
public static final String NEW_TAB_LABEL = "New Tab";
|
||||
public static final String NEW_PRIVATE_TAB_LABEL = "New Private Tab";
|
||||
public static final String SHARE_LABEL = "Share";
|
||||
public static final String FIND_IN_PAGE_LABEL = "Find in Page";
|
||||
public static final String DESKTOP_SITE_LABEL = "Request Desktop Site";
|
||||
public static final String PDF_LABEL = "Save as PDF";
|
||||
public static final String DOWNLOADS_LABEL = "Downloads";
|
||||
public static final String ADDONS_LABEL = "Add-ons";
|
||||
public static final String APPS_LABEL = "Apps";
|
||||
public static final String SETTINGS_LABEL = "Settings";
|
||||
public static final String GUEST_MODE_LABEL = "New Guest Session";
|
||||
|
||||
// Android 3.0+
|
||||
public static final String TOOLS_LABEL = "Tools";
|
||||
|
||||
// Android 2.3 and lower only
|
||||
public static final String MORE_LABEL = "More";
|
||||
public static final String RELOAD_LABEL = "Reload";
|
||||
public static final String FORWARD_LABEL = "Forward";
|
||||
public static final String BOOKMARK_LABEL = "Bookmark";
|
||||
}
|
@ -13,24 +13,23 @@ public class testBookmarkKeyword extends AboutHomeTest {
|
||||
public void testBookmarkKeyword() {
|
||||
blockForGeckoReady();
|
||||
|
||||
final String url = getAbsoluteUrl("/robocop/robocop_blank_01.html");
|
||||
final String title = "Browser Blank Page 01";
|
||||
final String url = getAbsoluteUrl(StringHelper.ROBOCOP_BLANK_PAGE_01_URL);
|
||||
final String keyword = "testkeyword";
|
||||
|
||||
// Add a bookmark, and update it to have a keyword.
|
||||
addOrUpdateMobileBookmark(title, url);
|
||||
updateBookmark(url, title, keyword);
|
||||
mDatabaseHelper.addOrUpdateMobileBookmark(StringHelper.ROBOCOP_BLANK_PAGE_01_TITLE, url);
|
||||
mDatabaseHelper.updateBookmark(url, StringHelper.ROBOCOP_BLANK_PAGE_01_TITLE, keyword);
|
||||
|
||||
// Enter the keyword in the urlbar.
|
||||
inputAndLoadUrl(keyword);
|
||||
|
||||
// Wait for the page to load.
|
||||
waitForText(title);
|
||||
waitForText(StringHelper.ROBOCOP_BLANK_PAGE_01_TITLE);
|
||||
|
||||
// Make sure the title of the page appeared.
|
||||
verifyPageTitle(title);
|
||||
verifyPageTitle(StringHelper.ROBOCOP_BLANK_PAGE_01_TITLE);
|
||||
|
||||
// Delete the bookmark to clean up.
|
||||
deleteBookmark(url);
|
||||
mDatabaseHelper.deleteBookmark(url);
|
||||
}
|
||||
}
|
||||
|
@ -14,7 +14,7 @@ public class testBookmarklets extends AboutHomeTest {
|
||||
}
|
||||
|
||||
public void testBookmarklets() {
|
||||
final String url = getAbsoluteUrl("/robocop/robocop_blank_01.html");
|
||||
final String url = getAbsoluteUrl(StringHelper.ROBOCOP_BLANK_PAGE_01_URL);
|
||||
final String title = "alertBookmarklet";
|
||||
final String js = "javascript:alert(12 + .34)";
|
||||
boolean alerted;
|
||||
@ -23,7 +23,7 @@ public class testBookmarklets extends AboutHomeTest {
|
||||
|
||||
// load a standard page so bookmarklets work
|
||||
inputAndLoadUrl(url);
|
||||
verifyPageTitle("Browser Blank Page 01"); // Waiting for page title to ensure the page is loaded
|
||||
verifyPageTitle(StringHelper.ROBOCOP_BLANK_PAGE_01_TITLE); // Waiting for page title to ensure the page is loaded
|
||||
|
||||
// verify that user-entered bookmarklets do *not* work
|
||||
enterUrl(js);
|
||||
@ -38,7 +38,7 @@ public class testBookmarklets extends AboutHomeTest {
|
||||
|
||||
// add the bookmarklet to the database. there's currently no way to
|
||||
// add this using the UI, so we go through the content provider.
|
||||
addOrUpdateMobileBookmark(title, js);
|
||||
mDatabaseHelper.addOrUpdateMobileBookmark(title, js);
|
||||
|
||||
// Open about:home in the Bookmarks page
|
||||
openAboutHomeTab(AboutHomeTabs.BOOKMARKS);
|
||||
@ -77,6 +77,6 @@ public class testBookmarklets extends AboutHomeTest {
|
||||
mAsserter.is(alerted, true, "Alert was shown for clicked bookmarklet");
|
||||
|
||||
// remove the bookmarklet
|
||||
deleteBookmark(js);
|
||||
mDatabaseHelper.deleteBookmark(js);
|
||||
}
|
||||
}
|
||||
|
@ -4,9 +4,7 @@ package @ANDROID_PACKAGE_NAME@.tests;
|
||||
import @ANDROID_PACKAGE_NAME@.*;
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class testClearPrivateData extends AboutHomeTest {
|
||||
private final String BLANK1_TITLE = "Browser Blank Page 01";
|
||||
private final String BLANK2_TITLE = "Browser Blank Page 02";
|
||||
public class testClearPrivateData extends PixelTest {
|
||||
private final int TEST_WAIT_MS = 10000;
|
||||
|
||||
@Override
|
||||
@ -21,13 +19,13 @@ public class testClearPrivateData extends AboutHomeTest {
|
||||
|
||||
private void clearHistory() {
|
||||
// Loading a page and adding a second one as bookmark to have user made bookmarks and history
|
||||
String blank1 = getAbsoluteUrl("/robocop/robocop_blank_01.html");
|
||||
String blank2 = getAbsoluteUrl("/robocop/robocop_blank_02.html");
|
||||
String blank1 = getAbsoluteUrl(StringHelper.ROBOCOP_BLANK_PAGE_01_URL);
|
||||
String blank2 = getAbsoluteUrl(StringHelper.ROBOCOP_BLANK_PAGE_02_URL);
|
||||
|
||||
inputAndLoadUrl(blank1);
|
||||
waitForText(BLANK1_TITLE);
|
||||
loadAndPaint(blank1);
|
||||
waitForText(StringHelper.ROBOCOP_BLANK_PAGE_01_TITLE);
|
||||
|
||||
addOrUpdateMobileBookmark(BLANK2_TITLE, blank2);
|
||||
mDatabaseHelper.addOrUpdateMobileBookmark(StringHelper.ROBOCOP_BLANK_PAGE_02_TITLE, blank2);
|
||||
|
||||
// Checking that the history list is not empty
|
||||
verifyHistoryCount(1);
|
||||
@ -37,13 +35,13 @@ public class testClearPrivateData extends AboutHomeTest {
|
||||
verifyHistoryCount(0);
|
||||
|
||||
// Checking that the user made bookmark is not removed
|
||||
mAsserter.ok(isBookmark(blank2), "Checking that bookmarks have not been removed", "User made bookmarks were not removed with private data");
|
||||
mAsserter.ok(mDatabaseHelper.isBookmark(blank2), "Checking that bookmarks have not been removed", "User made bookmarks were not removed with private data");
|
||||
}
|
||||
|
||||
private void verifyHistoryCount(final int expectedCount) {
|
||||
boolean match = waitForTest( new BooleanTest() {
|
||||
public boolean test() {
|
||||
return (getBrowserDBUrls(BrowserDataType.HISTORY).size() == expectedCount);
|
||||
return (mDatabaseHelper.getBrowserDBUrls(DatabaseHelper.BrowserDataType.HISTORY).size() == expectedCount);
|
||||
}
|
||||
}, TEST_WAIT_MS);
|
||||
mAsserter.ok(match, "Checking that the number of history items is correct", String.valueOf(expectedCount) + " history items present in the database");
|
||||
|
@ -42,15 +42,15 @@ public class testImportFromAndroid extends AboutHomeTest {
|
||||
addData();
|
||||
|
||||
// Get the initial bookmarks and history
|
||||
oldFirefoxBookmarks = getBrowserDBUrls(BrowserDataType.BOOKMARKS);
|
||||
oldFirefoxHistory = getBrowserDBUrls(BrowserDataType.HISTORY);
|
||||
oldFirefoxBookmarks = mDatabaseHelper.getBrowserDBUrls(DatabaseHelper.BrowserDataType.BOOKMARKS);
|
||||
oldFirefoxHistory = mDatabaseHelper.getBrowserDBUrls(DatabaseHelper.BrowserDataType.HISTORY);
|
||||
|
||||
// Import the bookmarks and history
|
||||
importDataFromAndroid();
|
||||
|
||||
// Get the Android history and the Firefox bookmarks and history lists
|
||||
firefoxHistory = getBrowserDBUrls(BrowserDataType.HISTORY);
|
||||
firefoxBookmarks = getBrowserDBUrls(BrowserDataType.BOOKMARKS);
|
||||
firefoxHistory = mDatabaseHelper.getBrowserDBUrls(DatabaseHelper.BrowserDataType.HISTORY);
|
||||
firefoxBookmarks = mDatabaseHelper.getBrowserDBUrls(DatabaseHelper.BrowserDataType.BOOKMARKS);
|
||||
|
||||
/**
|
||||
* Add a delay to make sure the imported items are added to the array lists
|
||||
@ -90,7 +90,7 @@ public class testImportFromAndroid extends AboutHomeTest {
|
||||
|
||||
// Verify bookmarks are not duplicated
|
||||
ArrayList<String> verifiedBookmarks = new ArrayList<String>();
|
||||
firefoxBookmarks = getBrowserDBUrls(BrowserDataType.BOOKMARKS);
|
||||
firefoxBookmarks = mDatabaseHelper.getBrowserDBUrls(DatabaseHelper.BrowserDataType.BOOKMARKS);
|
||||
for (String url:firefoxBookmarks) {
|
||||
if (verifiedBookmarks.contains(url)) {
|
||||
mAsserter.ok(false, "Bookmark " + url + " should not be duplicated", "Bookmark is duplicated");
|
||||
@ -101,7 +101,7 @@ public class testImportFromAndroid extends AboutHomeTest {
|
||||
}
|
||||
|
||||
// Verify history count is not increased after the second import
|
||||
mAsserter.ok(firefoxHistory.size() == getBrowserDBUrls(BrowserDataType.HISTORY).size(), "The number of history entries was not increased", "None of the items were duplicated");
|
||||
mAsserter.ok(firefoxHistory.size() == mDatabaseHelper.getBrowserDBUrls(DatabaseHelper.BrowserDataType.HISTORY).size(), "The number of history entries was not increased", "None of the items were duplicated");
|
||||
}
|
||||
|
||||
private void addData() {
|
||||
@ -111,7 +111,7 @@ public class testImportFromAndroid extends AboutHomeTest {
|
||||
for (String url:androidBookmarks) {
|
||||
// Add every 3rd bookmark to Firefox Mobile
|
||||
if ((androidBookmarks.indexOf(url) % 3) == 0) {
|
||||
addOrUpdateMobileBookmark("Bookmark Number " + String.valueOf(androidBookmarks.indexOf(url)), url);
|
||||
mDatabaseHelper.addOrUpdateMobileBookmark("Bookmark Number" + String.valueOf(androidBookmarks.indexOf(url)), url);
|
||||
}
|
||||
}
|
||||
|
||||
@ -135,7 +135,7 @@ public class testImportFromAndroid extends AboutHomeTest {
|
||||
|
||||
private void importDataFromAndroid() {
|
||||
waitForText("Enter Search or Address");
|
||||
selectSettingsItem("Customize", "Import from Android");
|
||||
selectSettingsItem(StringHelper.CUSTOMIZE_SECTION_LABEL, StringHelper.IMPORT_FROM_ANDROID_LABEL);
|
||||
|
||||
// Wait for the Import form Android pop-up to be opened. It has the same title as the option so waiting for the "Cancel" button
|
||||
waitForText("Cancel");
|
||||
@ -153,7 +153,7 @@ public class testImportFromAndroid extends AboutHomeTest {
|
||||
// Import has finished. Waiting to get back to the Settings Menu and looking for the Import&Export subsection
|
||||
if ("phone".equals(mDevice.type)) {
|
||||
// Phones don't have headers like tablets, so we need to pop up one more level.
|
||||
waitForText("Import from Android");
|
||||
waitForText(StringHelper.IMPORT_FROM_ANDROID_LABEL);
|
||||
mActions.sendSpecialKey(Actions.SpecialKey.BACK);
|
||||
}
|
||||
waitForText("Privacy"); // Settings is a header for the settings menu page. Waiting for Privacy ensures we are back in the top Settings view
|
||||
@ -196,11 +196,11 @@ public class testImportFromAndroid extends AboutHomeTest {
|
||||
// Bookmarks
|
||||
ArrayList<String> androidBookmarks = getAndroidUrls("bookmarks");
|
||||
for (String url:androidBookmarks) {
|
||||
deleteBookmark(url);
|
||||
mDatabaseHelper.deleteBookmark(url);
|
||||
}
|
||||
// History
|
||||
for (String url:androidData) {
|
||||
deleteHistoryItem(url);
|
||||
mDatabaseHelper.deleteHistoryItem(url);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -34,7 +34,7 @@ public class testLinkContextMenu extends ContentContextMenuTest {
|
||||
|
||||
@Override
|
||||
public void tearDown() throws Exception {
|
||||
deleteBookmark(BLANK_PAGE_URL);
|
||||
mDatabaseHelper.deleteBookmark(BLANK_PAGE_URL);
|
||||
super.tearDown();
|
||||
}
|
||||
}
|
||||
|
@ -33,4 +33,10 @@ public class testPictureLinkContextMenu extends ContentContextMenuTest {
|
||||
verifyShareOption(photoMenuItems[7], PICTURE_PAGE_TITLE); // Test the "Share Link" option
|
||||
verifyBookmarkLinkOption(photoMenuItems[8],BLANK_PAGE_URL); // Test the "Bookmark Link" option
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tearDown() throws Exception {
|
||||
mDatabaseHelper.deleteBookmark(BLANK_PAGE_URL);
|
||||
super.tearDown();
|
||||
}
|
||||
}
|
||||
|
@ -154,11 +154,37 @@ public class FaviconView extends ImageView {
|
||||
formatImage();
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the displayed image and apply the scaling logic.
|
||||
* The scaling logic will attempt to resize the image to fit correctly inside the view in a way
|
||||
* that avoids unreasonable levels of loss of quality.
|
||||
* Scaling is necessary only when the icon being provided is not drawn from the Favicon cache
|
||||
* introduced in Bug 914296.
|
||||
*
|
||||
* Due to Bug 913746, icons bundled for search engines are not available to the cache, so must
|
||||
* always have the scaling logic applied here. At the time of writing, this is the only case in
|
||||
* which the scaling logic here is applied.
|
||||
*
|
||||
* @param bitmap The bitmap to display in this favicon view.
|
||||
* @param key The key to use into the dominant colours cache when selecting a background colour.
|
||||
*/
|
||||
public void updateAndScaleImage(Bitmap bitmap, String key) {
|
||||
updateImageInternal(bitmap, key, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the image displayed in the Favicon view without scaling. Images larger than the view
|
||||
* will be centrally cropped. Images smaller than the view will be placed centrally and the
|
||||
* extra space filled with the dominant colour of the provided image.
|
||||
*
|
||||
* @param bitmap The bitmap to display in this favicon view.
|
||||
* @param key The key to use into the dominant colours cache when selecting a background colour.
|
||||
*/
|
||||
public void updateImage(Bitmap bitmap, String key) {
|
||||
updateImageInternal(bitmap, key, false);
|
||||
}
|
||||
|
||||
public Bitmap getBitmap() {
|
||||
return mIconBitmap;
|
||||
}
|
||||
}
|
||||
|
@ -19,6 +19,7 @@ chrome-devtools-frontend.appspot.com: did not receive HSTS header
|
||||
chrome.google.com: did not receive HSTS header
|
||||
code.google.com: did not receive HSTS header
|
||||
codereview.chromium.org: did not receive HSTS header
|
||||
crowdcurity.com: did not receive HSTS header
|
||||
crypto.is: did not receive HSTS header
|
||||
csawctf.poly.edu: did not receive HSTS header
|
||||
dl.google.com: did not receive HSTS header
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user