Merge m-c to b2g-inbound. a=merge

This commit is contained in:
Ryan VanderMeulen 2014-09-08 19:33:02 -04:00
commit 009f956da2
93 changed files with 949 additions and 703 deletions

View File

@ -596,6 +596,10 @@ this.UtteranceGenerator = { // jshint ignore:line
aOutput.push({string: 'stateUnavailable'});
}
if (aState.contains(States.READONLY)) {
aOutput.push({string: 'stateReadonly'});
}
// Don't utter this in Jelly Bean, we let TalkBack do it for us there.
// This is because we expose the checked information on the node itself.
// XXX: this means the checked state is always appended to the end,

View File

@ -232,6 +232,22 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=753984
{"string": "entry"}]],
expectedBraille: [[{"string": "entryAbbr"}, "I am required"],
["I am required", {"string": "entryAbbr"}]]
}, {
// test unavailable state utterance on inputs
accOrElmOrID: "readonlyInput",
expectedUtterance: [[{"string": "stateReadonly"}, {"string": "entry"},
"No edits"], ["No edits", {"string": "stateReadonly"},
{"string": "entry"}]],
expectedBraille: [[{"string": "entryAbbr"}, "No edits"],
["No edits", {"string": "entryAbbr"}]]
}, {
// test unavailable state utterance on textareas
accOrElmOrID: "readonlyTextarea",
expectedUtterance: [[{"string": "stateReadonly"}, {"string": "textarea"},
"No editing"], ["No editing", {"string": "stateReadonly"},
{"string": "textarea"}]],
expectedBraille: [[{"string": "textareaAbbr"}, "No editing"],
["No editing", {"string": "textareaAbbr"}]]
}, {
// test has popup state utterance
accOrElmOrID: "hasPopupButton",
@ -486,6 +502,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=753984
<button id="expandedButton" aria-expanded="true">I am expanded</button>
<button id="collapsedButton" aria-expanded="false">I am collapsed</button>
<input id="requiredInput" required placeholder="I am required" />
<input id="readonlyInput" readonly value="No edits" />
<textarea id="readonlyTextarea" readonly>No editing</textarea>
<button id="hasPopupButton" aria-haspopup="true">I have a popup</button>
<div role="tablist">
<a id="tab1" href="#" role="tab" aria-selected="true">Account</a>

View File

@ -971,7 +971,7 @@ pref("apz.x_stationary_size_multiplier", "1.5");
pref("apz.y_stationary_size_multiplier", "1.8");
pref("apz.enlarge_displayport_when_clipped", true);
// Use "sticky" axis locking
pref("apz.axis_lock_mode", 2);
pref("apz.axis_lock.mode", 2);
pref("apz.subframe.enabled", true);
// Overscroll-related settings

View File

@ -1131,13 +1131,6 @@ pref("browser.zoom.updateBackgroundTabs", true);
// The breakpad report server to link to in about:crashes
pref("breakpad.reportURL", "https://crash-stats.mozilla.com/report/index/");
#ifndef RELEASE_BUILD
// Override submission of plugin hang reports to a different processing server
// for the smaller-volume nightly/aurora populations.
pref("toolkit.crashreporter.pluginHangSubmitURL",
"https://hang-reports.mozilla.org/submit");
#endif
// URL for "Learn More" for Crash Reporter
pref("toolkit.crashreporter.infoURL",
"https://www.mozilla.org/legal/privacy/firefox.html#crash-reporter");

View File

@ -504,12 +504,21 @@ function HistoryMenu(aPopupShowingEvent) {
}
HistoryMenu.prototype = {
_getClosedTabCount() {
// SessionStore doesn't track the hidden window, so just return zero then.
if (window == Services.appShell.hiddenDOMWindow) {
return 0;
}
return SessionStore.getClosedTabCount(window);
},
toggleRecentlyClosedTabs: function HM_toggleRecentlyClosedTabs() {
// enable/disable the Recently Closed Tabs sub menu
var undoMenu = this._rootElt.getElementsByClassName("recentlyClosedTabsMenu")[0];
// no restorable tabs, so disable menu
if (SessionStore.getClosedTabCount(window) == 0)
if (this._getClosedTabCount() == 0)
undoMenu.setAttribute("disabled", true);
else
undoMenu.removeAttribute("disabled");
@ -527,7 +536,7 @@ HistoryMenu.prototype = {
undoPopup.removeChild(undoPopup.firstChild);
// no restorable tabs, so make sure menu is disabled, and return
if (SessionStore.getClosedTabCount(window) == 0) {
if (this._getClosedTabCount() == 0) {
undoMenu.setAttribute("disabled", true);
return;
}

View File

@ -1520,7 +1520,9 @@ Toolbox.prototype = {
this._telemetry.toolClosed("toolbox");
this._telemetry.destroy();
this._destroyer = promise.all(outstanding).then(() => {
// Finish all outstanding tasks (successfully or not) before destroying the
// target.
this._destroyer = promise.all(outstanding).then(null, console.error).then(() => {
// Targets need to be notified that the toolbox is being torn down.
// This is done after other destruction tasks since it may tear down
// fronts and the debugger transport which earlier destroy methods may
@ -1533,7 +1535,7 @@ Toolbox.prototype = {
this.highlighterUtils.release();
target.off("close", this.destroy);
return target.destroy();
}).then(() => {
}, console.error).then(() => {
this.emit("destroyed");
// We need to grab a reference to win before this._host is destroyed.

View File

@ -57,7 +57,7 @@ pref("apz.x_skate_size_multiplier", "2.5");
pref("apz.y_skate_size_multiplier", "2.5");
pref("apz.min_skate_speed", "10.0");
// 0 = free, 1 = standard, 2 = sticky
pref("apz.axis_lock_mode", 2);
pref("apz.axis_lock.mode", 2);
pref("apz.cross_slide.enabled", true);
pref("apz.subframe.enabled", true);

View File

@ -399,6 +399,10 @@ def do_file(filename, inclname, file_kind, f, all_inclnames, included_h_inclname
# Extract the #include statements as a tree of IBlocks and IIncludes.
for linenum, line in enumerate(f, start=1):
# We're only interested in lines that contain a '#'.
if not '#' in line:
continue
# Look for a |#include "..."| line.
m = re.match(r'\s*#\s*include\s+"([^"]*)"', line)
if m is not None:
@ -482,16 +486,12 @@ def do_file(filename, inclname, file_kind, f, all_inclnames, included_h_inclname
error(filename, str(include1.linenum) + ':' + str(include2.linenum),
include1.quote() + ' should be included after ' + include2.quote())
# The #include statements in the files in assembler/ have all manner of implicit
# ordering requirements. Boo. Ignore them.
skip_order_checking = inclname.startswith('assembler/')
# Check the extracted #include statements, both individually, and the ordering of
# adjacent pairs that live in the same block.
def pair_traverse(prev, this):
if this.isLeaf():
check_include_statement(this)
if prev is not None and prev.isLeaf() and not skip_order_checking:
if prev is not None and prev.isLeaf():
check_includes_order(prev, this)
else:
for prev2, this2 in zip([None] + this.kids[0:-1], this.kids):

View File

@ -5639,7 +5639,7 @@ if test -n "${JAVA_BIN_PATH}" -o \
AC_MSG_ERROR([The program keytool was not found. Set \$JAVA_HOME to your Java SDK directory or use --with-java-bin-path={java-bin-dir}])
fi
AC_MSG_CHECKING([for minimum required javac version = 1.7])
AC_MSG_CHECKING([for minimum required javac version >= 1.7])
dnl Javac spits out something like `javac 1.7.0`. This line cuts off the 'javac'
_javac_version=$($JAVAC -version 2>&1 | cut -d ' ' -f 2)
@ -5653,8 +5653,8 @@ if test -n "${JAVA_BIN_PATH}" -o \
dnl Fail if we have a version other than 1.7.X
if test "$_javac_major_version" -ne "1" -o \
\( "$_javac_minor_version" -ne "7" \); then
AC_MSG_ERROR([javac 1.7 is required.])
\( "$_javac_minor_version" -lt "7" \); then
AC_MSG_ERROR([javac 1.7 or higher is required.])
fi
fi

View File

@ -9,10 +9,6 @@
#include "base/string_util.h"
#include "base/process_util.h"
#ifdef XP_WIN
#include <codecvt>
#endif
#include <string>
using std::vector;
@ -50,9 +46,8 @@ GMPProcessParent::Launch(int32_t aTimeoutMs)
vector<string> args;
args.push_back(mGMPPath);
#ifdef XP_WIN
std::wstring_convert<std::codecvt_utf8<wchar_t>> converter;
std::wstring wGMPPath = converter.from_bytes(mGMPPath.c_str());
#if defined(XP_WIN) && defined(MOZ_SANDBOX)
std::wstring wGMPPath = UTF8ToWide(mGMPPath.c_str());
mAllowedFilesRead.push_back(wGMPPath + L"\\*");
#endif

View File

@ -82,7 +82,7 @@ GetGMPStorageDir(nsIFile** aTempDir, const nsString& aOrigin)
// process (a UUID or somesuch), we can just append it un-hashed here.
// This should reduce the chance of hash collsions exposing data.
nsAutoString nodeIdHash;
nodeIdHash.AppendInt(HashString(aOrigin.get()));
nodeIdHash.AppendInt(HashString(static_cast<const char16_t*>(aOrigin.get())));
rv = tmpFile->Append(nodeIdHash);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;

View File

@ -1227,15 +1227,6 @@ nsDOMClassInfo::HasInstance(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
return NS_ERROR_UNEXPECTED;
}
NS_IMETHODIMP
nsDOMClassInfo::OuterObject(nsIXPConnectWrappedNative *wrapper, JSContext * cx,
JSObject * obj, JSObject * *_retval)
{
NS_WARNING("nsDOMClassInfo::OuterObject Don't call me!");
return NS_ERROR_UNEXPECTED;
}
static nsresult
GetExternalClassInfo(nsScriptNameSpaceManager *aNameSpaceManager,
const nsAString &aName,

View File

@ -1216,6 +1216,7 @@ def UnionTypes(descriptors, dictionaries, callbacks, config):
def addHeadersForType(f):
if f.nullable():
headers.add("mozilla/dom/Nullable.h")
isSequence = f.isSequence()
f = f.unroll()
if f.isInterface():
if f.isSpiderMonkeyInterface():
@ -1227,10 +1228,14 @@ def UnionTypes(descriptors, dictionaries, callbacks, config):
typeDesc = p.getDescriptor(f.inner.identifier.name)
except NoSuchDescriptorError:
continue
if typeDesc.interface.isCallback():
if typeDesc.interface.isCallback() or isSequence:
# Callback interfaces always use strong refs, so
# we need to include the right header to be able
# to Release() in our inlined code.
#
# Similarly, sequences always contain strong
# refs, so we'll need the header to handler
# those.
headers.add(typeDesc.headerFile)
else:
declarations.add((typeDesc.nativeType, False))
@ -4651,7 +4656,7 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
if type.isSpiderMonkeyInterface():
assert not isEnforceRange and not isClamp
name = type.name
name = type.unroll().name # unroll() because it may be nullable
arrayType = CGGeneric(name)
declType = arrayType
if type.nullable():
@ -6202,8 +6207,6 @@ def getUnionMemberName(type):
return type.inner.identifier.name
if type.isEnum():
return type.inner.identifier.name
if type.isArray() or type.isSequence() or type.isMozMap():
return str(type)
return type.name
@ -12448,7 +12451,8 @@ class CGNativeMember(ClassMethod):
if not self.typedArraysAreStructs:
return "JS::Handle<JSObject*>", False, False
return type.name, True, True
# Unroll for the name, in case we're nullable.
return type.unroll().name, True, True
if type.isDOMString() or type.isScalarValueString():
if isMember:

View File

@ -1764,7 +1764,10 @@ class IDLNullableType(IDLType):
assert not innerType.isVoid()
assert not innerType == BuiltinTypes[IDLBuiltinType.Types.any]
IDLType.__init__(self, location, innerType.name)
name = innerType.name
if innerType.isComplete():
name += "OrNull"
IDLType.__init__(self, location, name)
self.inner = innerType
self.builtin = False
@ -1877,7 +1880,7 @@ class IDLNullableType(IDLType):
"be a union type that itself has a nullable "
"type as a member type", [self.location])
self.name = self.inner.name
self.name = self.inner.name + "OrNull"
return self
def unroll(self):
@ -1900,6 +1903,10 @@ class IDLSequenceType(IDLType):
IDLType.__init__(self, location, parameterType.name)
self.inner = parameterType
self.builtin = False
# Need to set self.name up front if our inner type is already complete,
# since in that case our .complete() won't be called.
if self.inner.isComplete():
self.name = self.inner.name + "Sequence"
def __eq__(self, other):
return isinstance(other, IDLSequenceType) and self.inner == other.inner
@ -1961,7 +1968,7 @@ class IDLSequenceType(IDLType):
def complete(self, scope):
self.inner = self.inner.complete(scope)
self.name = self.inner.name
self.name = self.inner.name + "Sequence"
return self
def unroll(self):
@ -1987,6 +1994,10 @@ class IDLMozMapType(IDLType):
IDLType.__init__(self, location, parameterType.name)
self.inner = parameterType
self.builtin = False
# Need to set self.name up front if our inner type is already complete,
# since in that case our .complete() won't be called.
if self.inner.isComplete():
self.name = self.inner.name + "MozMap"
def __eq__(self, other):
return isinstance(other, IDLMozMapType) and self.inner == other.inner
@ -2012,7 +2023,7 @@ class IDLMozMapType(IDLType):
def complete(self, scope):
self.inner = self.inner.complete(scope)
self.name = self.inner.name
self.name = self.inner.name + "MozMap"
return self
def unroll(self):
@ -2077,9 +2088,6 @@ class IDLUnionType(IDLType):
return typeName(type._identifier.object())
if isinstance(type, IDLObjectWithIdentifier):
return typeName(type.identifier)
if (isinstance(type, IDLType) and
(type.isArray() or type.isSequence() or type.isMozMap)):
return str(type)
return type.name
for (i, type) in enumerate(self.memberTypes):

View File

@ -90,7 +90,7 @@ def checkEquivalent(iface, harness):
for attr in dir(type1):
if attr.startswith('_') or \
attr in ['nullable', 'builtin', 'filename', 'location',
'inner', 'QName', 'getDeps'] or \
'inner', 'QName', 'getDeps', 'name'] or \
(hasattr(type(type1), attr) and not callable(getattr(type1, attr))):
continue

View File

@ -12,7 +12,7 @@ def WebIDLTest(parser, harness):
results = parser.finish()
harness.check(results[2].members[1].type.name, "Long",
harness.check(results[2].members[1].type.name, "LongOrNull",
"Should expand typedefs")
parser = parser.reset()

View File

@ -603,6 +603,10 @@ public:
void PassUnion20(JSContext*, const ObjectSequenceOrLong&);
void PassUnion21(const LongMozMapOrLong&);
void PassUnion22(JSContext*, const ObjectMozMapOrLong&);
void PassUnion23(const ImageDataSequenceOrLong&);
void PassUnion24(const ImageDataOrNullSequenceOrLong&);
void PassUnion25(const ImageDataSequenceSequenceOrLong&);
void PassUnion26(const ImageDataOrNullSequenceSequenceOrLong&);
void PassUnionWithCallback(const EventHandlerNonNullOrNullOrLong& arg);
void PassUnionWithByteString(const ByteStringOrLong&);
void PassUnionWithMozMap(const StringMozMapOrString&);

View File

@ -567,6 +567,10 @@ interface TestInterface {
void passUnion20(optional (sequence<object> or long) arg = []);
void passUnion21((MozMap<long> or long) arg);
void passUnion22((MozMap<object> or long) arg);
void passUnion23((sequence<ImageData> or long) arg);
void passUnion24((sequence<ImageData?> or long) arg);
void passUnion25((sequence<sequence<ImageData>> or long) arg);
void passUnion26((sequence<sequence<ImageData?>> or long) arg);
void passUnionWithCallback((EventHandler or long) arg);
void passUnionWithByteString((ByteString or long) arg);
void passUnionWithMozMap((MozMap<DOMString> or DOMString) arg);

View File

@ -431,6 +431,10 @@ interface TestExampleInterface {
void passUnion20(optional (sequence<object> or long) arg = []);
void passUnion21((MozMap<long> or long) arg);
void passUnion22((MozMap<object> or long) arg);
void passUnion23((sequence<ImageData> or long) arg);
void passUnion24((sequence<ImageData?> or long) arg);
void passUnion25((sequence<sequence<ImageData>> or long) arg);
void passUnion26((sequence<sequence<ImageData?>> or long) arg);
void passUnionWithCallback((EventHandler or long) arg);
void passUnionWithByteString((ByteString or long) arg);
void passUnionWithMozMap((MozMap<DOMString> or DOMString) arg);

View File

@ -451,6 +451,10 @@ interface TestJSImplInterface {
void passUnion20(optional (sequence<object> or long) arg = []);
void passUnion21((MozMap<long> or long) arg);
void passUnion22((MozMap<object> or long) arg);
void passUnion23((sequence<ImageData> or long) arg);
void passUnion24((sequence<ImageData?> or long) arg);
void passUnion25((sequence<sequence<ImageData>> or long) arg);
void passUnion26((sequence<sequence<ImageData?>> or long) arg);
void passUnionWithCallback((EventHandler or long) arg);
void passUnionWithByteString((ByteString or long) arg);
void passUnionWithMozMap((MozMap<DOMString> or DOMString) arg);

View File

@ -564,7 +564,7 @@ DrawTarget* CanvasRenderingContext2D::sErrorTarget = nullptr;
CanvasRenderingContext2D::CanvasRenderingContext2D()
: mForceSoftware(false)
: mRenderingMode(RenderingMode::OpenGLBackendMode)
// these are the default values from the Canvas spec
, mWidth(0), mHeight(0)
, mZero(false), mOpaque(false)
@ -577,6 +577,12 @@ CanvasRenderingContext2D::CanvasRenderingContext2D()
{
sNumLivingContexts++;
SetIsDOMBinding();
// The default is to use OpenGL mode
if (!gfxPlatform::GetPlatform()->UseAcceleratedSkiaCanvas()) {
mRenderingMode = RenderingMode::SoftwareBackendMode;
}
}
CanvasRenderingContext2D::~CanvasRenderingContext2D()
@ -773,24 +779,25 @@ CanvasRenderingContext2D::RedrawUser(const gfxRect& r)
Redraw(newr);
}
void CanvasRenderingContext2D::Demote()
bool CanvasRenderingContext2D::SwitchRenderingMode(RenderingMode aRenderingMode)
{
if (!IsTargetValid() || mForceSoftware || !mStream)
return;
RemoveDemotableContext(this);
if (!IsTargetValid() || mRenderingMode == aRenderingMode) {
return false;
}
RefPtr<SourceSurface> snapshot = mTarget->Snapshot();
RefPtr<DrawTarget> oldTarget = mTarget;
mTarget = nullptr;
mStream = nullptr;
mResetLayer = true;
mForceSoftware = true;
// Recreate target, now demoted to software only
EnsureTarget();
// Recreate target using the new rendering mode
RenderingMode attemptedMode = EnsureTarget(aRenderingMode);
if (!IsTargetValid())
return;
return false;
// We succeeded, so update mRenderingMode to reflect reality
mRenderingMode = attemptedMode;
// Restore the content from the old DrawTarget
mgfx::Rect r(0, 0, mWidth, mHeight);
@ -802,6 +809,15 @@ void CanvasRenderingContext2D::Demote()
}
mTarget->SetTransform(oldTarget->GetTransform());
return true;
}
void CanvasRenderingContext2D::Demote()
{
if (SwitchRenderingMode(RenderingMode::SoftwareBackendMode)) {
RemoveDemotableContext(this);
}
}
std::vector<CanvasRenderingContext2D*>&
@ -821,7 +837,9 @@ CanvasRenderingContext2D::DemoteOldestContextIfNecessary()
return;
CanvasRenderingContext2D* oldest = contexts.front();
oldest->Demote();
if (oldest->SwitchRenderingMode(RenderingMode::SoftwareBackendMode)) {
RemoveDemotableContext(oldest);
}
}
void
@ -913,11 +931,16 @@ CanvasRenderingContext2D::CheckSizeForSkiaGL(IntSize size) {
return threshold < 0 || (size.width * size.height) <= threshold;
}
void
CanvasRenderingContext2D::EnsureTarget()
CanvasRenderingContext2D::RenderingMode
CanvasRenderingContext2D::EnsureTarget(RenderingMode aRenderingMode)
{
if (mTarget) {
return;
// This would make no sense, so make sure we don't get ourselves in a mess
MOZ_ASSERT(mRenderingMode != RenderingMode::DefaultBackendMode);
RenderingMode mode = (aRenderingMode == RenderingMode::DefaultBackendMode) ? mRenderingMode : aRenderingMode;
if (mTarget && mode == mRenderingMode) {
return mRenderingMode;
}
// Check that the dimensions are sane
@ -938,9 +961,7 @@ CanvasRenderingContext2D::EnsureTarget()
}
if (layerManager) {
if (gfxPlatform::GetPlatform()->UseAcceleratedSkiaCanvas() &&
!mForceSoftware &&
CheckSizeForSkiaGL(size)) {
if (mode == RenderingMode::OpenGLBackendMode && CheckSizeForSkiaGL(size)) {
DemoteOldestContextIfNecessary();
SkiaGLGlue* glue = gfxPlatform::GetPlatform()->GetSkiaGLGlue();
@ -954,6 +975,7 @@ CanvasRenderingContext2D::EnsureTarget()
AddDemotableContext(this);
} else {
printf_stderr("Failed to create a SkiaGL DrawTarget, falling back to software\n");
mode = RenderingMode::SoftwareBackendMode;
}
}
#endif
@ -962,8 +984,10 @@ CanvasRenderingContext2D::EnsureTarget()
}
} else
mTarget = layerManager->CreateDrawTarget(size, format);
mode = RenderingMode::SoftwareBackendMode;
} else {
mTarget = gfxPlatform::GetPlatform()->CreateOffscreenCanvasDrawTarget(size, format);
mode = RenderingMode::SoftwareBackendMode;
}
}
@ -1002,6 +1026,8 @@ CanvasRenderingContext2D::EnsureTarget()
EnsureErrorTarget();
mTarget = sErrorTarget;
}
return mode;
}
#ifdef DEBUG
@ -1114,12 +1140,17 @@ CanvasRenderingContext2D::SetContextOptions(JSContext* aCx, JS::Handle<JS::Value
return NS_OK;
}
// This shouldn't be called before drawing starts, so there should be no drawtarget yet
MOZ_ASSERT(!mTarget);
ContextAttributes2D attributes;
NS_ENSURE_TRUE(attributes.Init(aCx, aOptions), NS_ERROR_UNEXPECTED);
if (Preferences::GetBool("gfx.canvas.willReadFrequently.enable", false)) {
// Use software when there is going to be a lot of readback
mForceSoftware = attributes.mWillReadFrequently;
if (attributes.mWillReadFrequently) {
mRenderingMode = RenderingMode::SoftwareBackendMode;
}
}
if (!attributes.mAlpha) {

View File

@ -457,6 +457,15 @@ public:
double h, const nsAString& bgColor, uint32_t flags,
mozilla::ErrorResult& error);
enum RenderingMode {
SoftwareBackendMode,
OpenGLBackendMode,
DefaultBackendMode
};
bool SwitchRenderingMode(RenderingMode aRenderingMode);
// Eventually this should be deprecated. Keeping for now to keep the binding functional.
void Demote();
nsresult Redraw();
@ -644,8 +653,10 @@ protected:
* in creating the target then it will put sErrorTarget in place. If there
* is in turn an error in creating the sErrorTarget then they would both
* be null so IsTargetValid() would still return null.
*
* Returns the actual rendering mode being used by the created target.
*/
void EnsureTarget();
RenderingMode EnsureTarget(RenderingMode aRenderMode = RenderingMode::DefaultBackendMode);
/*
* Disposes an old target and prepares to lazily create a new target.
@ -688,8 +699,7 @@ protected:
static void AddDemotableContext(CanvasRenderingContext2D* context);
static void RemoveDemotableContext(CanvasRenderingContext2D* context);
// Do not use GL
bool mForceSoftware;
RenderingMode mRenderingMode;
// Member vars
int32_t mWidth, mHeight;

View File

@ -157,6 +157,7 @@ statePressed = pressed
stateExpanded = expanded
stateCollapsed = collapsed
stateUnavailable = unavailable
stateReadonly = readonly
stateRequired = required
stateTraversed = visited
stateHasPopup = has pop up

View File

@ -30,14 +30,7 @@ const Ci = Components.interfaces;
const crashReporter = Cc["@mozilla.org/toolkit/crash-reporter;1"].getService(Ci.nsICrashReporter);
const SERVER_URL = "http://example.com/browser/toolkit/crashreporter/test/browser/crashreport.sjs";
const serverPrefName = "toolkit.crashreporter.pluginHangSubmitURL";
var oldServerPref;
try {
oldServerPref = Services.prefs.getCharPref(serverPrefName);
}
catch(e) {
}
var oldServerURL = crashReporter.serverURL;
const oldTimeoutPref = Services.prefs.getIntPref("dom.ipc.plugins.timeoutSecs");
@ -90,12 +83,7 @@ var testObserver = {
env.set("MOZ_CRASHREPORTER_NO_REPORT", "1");
// Finally re-set prefs
if (oldServerPref === undefined) {
Services.prefs.clearUserPref(serverPrefName);
}
else {
Services.prefs.setCharPref(serverPrefName, oldServerPref);
}
crashReporter.serverURL = oldServerURL;
Services.prefs.setIntPref("dom.ipc.plugins.timeoutSecs", oldTimeoutPref);
// Check and cleanup CrashManager.
@ -159,7 +147,7 @@ function runTests() {
env.set("MOZ_CRASHREPORTER_NO_REPORT", "");
// Override the crash reporter URL to send to our fake server
Services.prefs.setCharPref("toolkit.crashreporter.pluginHangSubmitURL", SERVER_URL);
crashReporter.serverURL = NetUtil.newURI(SERVER_URL);
// Hook into plugin crash events
Services.obs.addObserver(testObserver, "crash-report-status", true);

View File

@ -151,9 +151,29 @@ typedef mozilla::gfx::Matrix4x4 Matrix4x4;
* The timeout for mAsyncScrollTimeoutTask delay task.
* Units: milliseconds
*
* "apz.axis_lock_mode"
* "apz.axis_lock.mode"
* The preferred axis locking style. See AxisLockMode for possible values.
*
* "apz.axis_lock.lock_angle"
* Angle from axis within which we stay axis-locked.
* Units: radians
*
* "apz.axis_lock.breakout_threshold"
* Distance in inches the user must pan before axis lock can be broken.
* Units: (real-world, i.e. screen) inches
*
* "apz.axis_lock.breakout_angle"
* Angle at which axis lock can be broken.
* Units: radians
*
* "apz.axis_lock.direct_pan_angle"
* If the angle from an axis to the line drawn by a pan move is less than
* this value, we can assume that panning can be done in the allowed direction
* (horizontal or vertical).
* Currently used only for touch-action css property stuff and was addded to
* keep behaviour consistent with IE.
* Units: radians
*
* "apz.content_response_timeout"
* Amount of time before we timeout response from content. For example, if
* content is being unruly/slow and we don't get a response back within this
@ -323,30 +343,6 @@ typedef mozilla::gfx::Matrix4x4 Matrix4x4;
* Units: ms
*/
/**
* Angle from axis within which we stay axis-locked
*/
static const double AXIS_LOCK_ANGLE = M_PI / 6.0; // 30 degrees
/**
* The distance in inches the user must pan before axis lock can be broken
*/
static const float AXIS_BREAKOUT_THRESHOLD = 1.0f/32.0f;
/**
* The angle at which axis lock can be broken
*/
static const double AXIS_BREAKOUT_ANGLE = M_PI / 8.0; // 22.5 degrees
/**
* Angle from axis to the line drawn by pan move.
* If angle is less than this value we can assume that panning
* can be done in allowed direction (horizontal or vertical).
* Currently used only for touch-action css property stuff and was
* added to keep behavior consistent with IE.
*/
static const double ALLOWED_DIRECT_PAN_ANGLE = M_PI / 3.0; // 60 degrees
/**
* Computed time function used for sampling frames of a zoom to animation.
*/
@ -1712,10 +1708,10 @@ void AsyncPanZoomController::HandlePanningWithTouchAction(double aAngle) {
// enabled by default.
if (CurrentTouchBlock()->TouchActionAllowsPanningXY()) {
if (mX.CanScrollNow() && mY.CanScrollNow()) {
if (IsCloseToHorizontal(aAngle, AXIS_LOCK_ANGLE)) {
if (IsCloseToHorizontal(aAngle, gfxPrefs::APZAxisLockAngle())) {
mY.SetAxisLocked(true);
SetState(PANNING_LOCKED_X);
} else if (IsCloseToVertical(aAngle, AXIS_LOCK_ANGLE)) {
} else if (IsCloseToVertical(aAngle, gfxPrefs::APZAxisLockAngle())) {
mX.SetAxisLocked(true);
SetState(PANNING_LOCKED_Y);
} else {
@ -1729,7 +1725,7 @@ void AsyncPanZoomController::HandlePanningWithTouchAction(double aAngle) {
} else if (CurrentTouchBlock()->TouchActionAllowsPanningX()) {
// Using bigger angle for panning to keep behavior consistent
// with IE.
if (IsCloseToHorizontal(aAngle, ALLOWED_DIRECT_PAN_ANGLE)) {
if (IsCloseToHorizontal(aAngle, gfxPrefs::APZAllowedDirectPanAngle())) {
mY.SetAxisLocked(true);
SetState(PANNING_LOCKED_X);
mPanDirRestricted = true;
@ -1739,7 +1735,7 @@ void AsyncPanZoomController::HandlePanningWithTouchAction(double aAngle) {
SetState(NOTHING);
}
} else if (CurrentTouchBlock()->TouchActionAllowsPanningY()) {
if (IsCloseToVertical(aAngle, ALLOWED_DIRECT_PAN_ANGLE)) {
if (IsCloseToVertical(aAngle, gfxPrefs::APZAllowedDirectPanAngle())) {
mX.SetAxisLocked(true);
SetState(PANNING_LOCKED_Y);
mPanDirRestricted = true;
@ -1755,7 +1751,7 @@ void AsyncPanZoomController::HandlePanning(double aAngle) {
ReentrantMonitorAutoEnter lock(mMonitor);
if (!gfxPrefs::APZCrossSlideEnabled() && (!mX.CanScrollNow() || !mY.CanScrollNow())) {
SetState(PANNING);
} else if (IsCloseToHorizontal(aAngle, AXIS_LOCK_ANGLE)) {
} else if (IsCloseToHorizontal(aAngle, gfxPrefs::APZAxisLockAngle())) {
mY.SetAxisLocked(true);
if (mX.CanScrollNow()) {
SetState(PANNING_LOCKED_X);
@ -1763,7 +1759,7 @@ void AsyncPanZoomController::HandlePanning(double aAngle) {
SetState(CROSS_SLIDING_X);
mX.SetAxisLocked(true);
}
} else if (IsCloseToVertical(aAngle, AXIS_LOCK_ANGLE)) {
} else if (IsCloseToVertical(aAngle, gfxPrefs::APZAxisLockAngle())) {
mX.SetAxisLocked(true);
if (mY.CanScrollNow()) {
SetState(PANNING_LOCKED_Y);
@ -1783,16 +1779,16 @@ void AsyncPanZoomController::HandlePanningUpdate(float aDX, float aDY) {
double angle = atan2(aDY, aDX); // range [-pi, pi]
angle = fabs(angle); // range [0, pi]
float breakThreshold = AXIS_BREAKOUT_THRESHOLD * APZCTreeManager::GetDPI();
float breakThreshold = gfxPrefs::APZAxisBreakoutThreshold() * APZCTreeManager::GetDPI();
if (fabs(aDX) > breakThreshold || fabs(aDY) > breakThreshold) {
if (mState == PANNING_LOCKED_X || mState == CROSS_SLIDING_X) {
if (!IsCloseToHorizontal(angle, AXIS_BREAKOUT_ANGLE)) {
if (!IsCloseToHorizontal(angle, gfxPrefs::APZAxisBreakoutAngle())) {
mY.SetAxisLocked(false);
SetState(PANNING);
}
} else if (mState == PANNING_LOCKED_Y || mState == CROSS_SLIDING_Y) {
if (!IsCloseToVertical(angle, AXIS_BREAKOUT_ANGLE)) {
if (!IsCloseToVertical(angle, gfxPrefs::APZAxisLockAngle())) {
mX.SetAxisLocked(false);
SetState(PANNING);
}

View File

@ -721,15 +721,6 @@ CompositorOGL::BeginFrame(const nsIntRegion& aInvalidRegion,
rect = gfx::Rect(0, 0, mSurfaceSize.width, mSurfaceSize.height);
} else {
rect = gfx::Rect(aRenderBounds.x, aRenderBounds.y, aRenderBounds.width, aRenderBounds.height);
// If render bounds is not updated explicitly, try to infer it from widget
if (rect.width == 0 || rect.height == 0) {
// FIXME/bug XXXXXX this races with rotation changes on the main
// thread, and undoes all the care we take with layers txns being
// sent atomically with rotation changes
nsIntRect intRect;
mWidget->GetClientBounds(intRect);
rect = gfx::Rect(0, 0, intRect.width, intRect.height);
}
}
rect = aTransform.TransformBounds(rect);

View File

@ -107,6 +107,10 @@ gfxHarfBuzzShaper::GetGlyph(hb_codepoint_t unicode,
compat);
}
break;
case 10:
gid = gfxFontUtils::MapCharToGlyphFormat10(data + mSubtableOffset,
compat);
break;
case 12:
gid = gfxFontUtils::MapCharToGlyphFormat12(data + mSubtableOffset,
compat);
@ -125,6 +129,10 @@ gfxHarfBuzzShaper::GetGlyph(hb_codepoint_t unicode,
gfxFontUtils::MapCharToGlyphFormat4(data + mSubtableOffset,
unicode) : 0;
break;
case 10:
gid = gfxFontUtils::MapCharToGlyphFormat10(data + mSubtableOffset,
unicode);
break;
case 12:
gid = gfxFontUtils::MapCharToGlyphFormat12(data + mSubtableOffset,
unicode);

View File

@ -8,6 +8,7 @@
#include <stdint.h>
#include "mozilla/Assertions.h"
#include "mozilla/Constants.h" // for M_PI
#include "mozilla/TypedEnum.h"
// First time gfxPrefs::GetSingleton() needs to be called on the main thread,
@ -132,7 +133,11 @@ private:
DECL_GFX_PREF(Live, "apz.allow_checkerboarding", APZAllowCheckerboarding, bool, true);
DECL_GFX_PREF(Live, "apz.asyncscroll.throttle", APZAsyncScrollThrottleTime, int32_t, 100);
DECL_GFX_PREF(Live, "apz.asyncscroll.timeout", APZAsyncScrollTimeout, int32_t, 300);
DECL_GFX_PREF(Live, "apz.axis_lock_mode", APZAxisLockMode, int32_t, 0);
DECL_GFX_PREF(Live, "apz.axis_lock.mode", APZAxisLockMode, int32_t, 0);
DECL_GFX_PREF(Live, "apz.axis_lock.lock_angle", APZAxisLockAngle, float, float(M_PI / 6.0) /* 30 degrees */);
DECL_GFX_PREF(Live, "apz.axis_lock.breakout_threshold", APZAxisBreakoutThreshold, float, 1.0f / 32.0f);
DECL_GFX_PREF(Live, "apz.axis_lock.breakout_angle", APZAxisBreakoutAngle, float, float(M_PI / 8.0) /* 22.5 degrees */);
DECL_GFX_PREF(Live, "apz.axis_lock.direct_pan_angle", APZAllowedDirectPanAngle, float, float(M_PI / 3.0) /* 60 degrees */);
DECL_GFX_PREF(Live, "apz.content_response_timeout", APZContentResponseTimeout, int32_t, 300);
DECL_GFX_PREF(Live, "apz.cross_slide.enabled", APZCrossSlideEnabled, bool, false);
DECL_GFX_PREF(Live, "apz.danger_zone_x", APZDangerZoneX, int32_t, 50);

View File

@ -820,6 +820,7 @@ GeckoChildProcessHost::PerformAsyncLaunchInternal(std::vector<std::string>& aExt
break;
};
#ifdef MOZ_SANDBOX
if (shouldSandboxCurrentProcess) {
for (auto it = mAllowedFilesRead.begin();
it != mAllowedFilesRead.end();
@ -827,6 +828,7 @@ GeckoChildProcessHost::PerformAsyncLaunchInternal(std::vector<std::string>& aExt
mSandboxBroker.AllowReadFile(it->c_str());
}
}
#endif
#endif // XP_WIN

View File

@ -114,8 +114,10 @@ static MOZ_CONSTEXPR_VAR Register FramePointer = InvalidReg;
static MOZ_CONSTEXPR_VAR Register ReturnReg = v0;
static MOZ_CONSTEXPR_VAR FloatRegister ReturnFloat32Reg = { FloatRegisters::f0, FloatRegister::Single };
static MOZ_CONSTEXPR_VAR FloatRegister ReturnDoubleReg = { FloatRegisters::f0, FloatRegister::Double };
static MOZ_CONSTEXPR_VAR FloatRegister ReturnSimdReg = InvalidFloatReg;
static MOZ_CONSTEXPR_VAR FloatRegister ScratchFloat32Reg = { FloatRegisters::f18, FloatRegister::Single };
static MOZ_CONSTEXPR_VAR FloatRegister ScratchDoubleReg = { FloatRegisters::f18, FloatRegister::Double };
static MOZ_CONSTEXPR_VAR FloatRegister ScratchSimdReg = InvalidFloatReg;
static MOZ_CONSTEXPR_VAR FloatRegister SecondScratchFloat32Reg = { FloatRegisters::f16, FloatRegister::Single };
static MOZ_CONSTEXPR_VAR FloatRegister SecondScratchDoubleReg = { FloatRegisters::f16, FloatRegister::Double };
@ -1015,6 +1017,9 @@ class Assembler : public AssemblerShared
return false;
#endif
}
static bool SupportsSimd() {
return js::jit::SupportsSimd;
}
protected:
InstImm invertBranch(InstImm branch, BOffImm16 skipOffset);

View File

@ -265,6 +265,21 @@ class CodeGeneratorMIPS : public CodeGeneratorShared
bool visitEffectiveAddress(LEffectiveAddress *ins);
bool visitUDiv(LUDiv *ins);
bool visitUMod(LUMod *ins);
public:
// Unimplemented SIMD instructions
bool visitSimdValueX4(LSimdValueX4 *lir) { MOZ_CRASH("NYI"); }
bool visitSimdSplatX4(LSimdSplatX4 *lir) { MOZ_CRASH("NYI"); }
bool visitInt32x4(LInt32x4 *ins) { MOZ_CRASH("NYI"); }
bool visitFloat32x4(LFloat32x4 *ins) { MOZ_CRASH("NYI"); }
bool visitSimdExtractElementI(LSimdExtractElementI *ins) { MOZ_CRASH("NYI"); }
bool visitSimdExtractElementF(LSimdExtractElementF *ins) { MOZ_CRASH("NYI"); }
bool visitSimdSignMaskX4(LSimdSignMaskX4 *ins) { MOZ_CRASH("NYI"); }
bool visitSimdBinaryCompIx4(LSimdBinaryCompIx4 *lir) { MOZ_CRASH("NYI"); }
bool visitSimdBinaryCompFx4(LSimdBinaryCompFx4 *lir) { MOZ_CRASH("NYI"); }
bool visitSimdBinaryArithIx4(LSimdBinaryArithIx4 *lir) { MOZ_CRASH("NYI"); }
bool visitSimdBinaryArithFx4(LSimdBinaryArithFx4 *lir) { MOZ_CRASH("NYI"); }
bool visitSimdBinaryBitwiseX4(LSimdBinaryBitwiseX4 *lir) { MOZ_CRASH("NYI"); }
};
typedef CodeGeneratorMIPS CodeGeneratorSpecific;

View File

@ -1560,7 +1560,7 @@ MacroAssemblerMIPSCompat::freeStack(Register amount)
void
MacroAssembler::PushRegsInMask(RegisterSet set, FloatRegisterSet simdSet)
{
JS_ASSERT(!SupportsSimd && simdSet.size() == 0);
JS_ASSERT(!SupportsSimd() && simdSet.size() == 0);
int32_t diffF = set.fpus().getPushSizeInBytes();
int32_t diffG = set.gprs().size() * sizeof(intptr_t);
@ -1588,7 +1588,7 @@ MacroAssembler::PushRegsInMask(RegisterSet set, FloatRegisterSet simdSet)
void
MacroAssembler::PopRegsInMaskIgnore(RegisterSet set, RegisterSet ignore, FloatRegisterSet simdSet)
{
JS_ASSERT(!SupportsSimd && simdSet.size() == 0);
JS_ASSERT(!SupportsSimd() && simdSet.size() == 0);
int32_t diffG = set.gprs().size() * sizeof(intptr_t);
int32_t diffF = set.fpus().getPushSizeInBytes();
const int32_t reservedG = diffG;
@ -3285,7 +3285,7 @@ void
MacroAssembler::alignFrameForICArguments(AfterICSaveLive &aic)
{
if (framePushed() % ABIStackAlignment != 0) {
aic.alignmentPadding = ABIStackAlignment - (framePushed() % StackAlignment);
aic.alignmentPadding = ABIStackAlignment - (framePushed() % ABIStackAlignment);
reserveStack(aic.alignmentPadding);
} else {
aic.alignmentPadding = 0;

View File

@ -1067,6 +1067,16 @@ public:
void loadPrivate(const Address &address, Register dest);
void loadAlignedInt32x4(const Address &addr, FloatRegister dest) { MOZ_CRASH("NYI"); }
void storeAlignedInt32x4(FloatRegister src, Address addr) { MOZ_CRASH("NYI"); }
void loadUnalignedInt32x4(const Address &addr, FloatRegister dest) { MOZ_CRASH("NYI"); }
void storeUnalignedInt32x4(FloatRegister src, Address addr) { MOZ_CRASH("NYI"); }
void loadAlignedFloat32x4(const Address &addr, FloatRegister dest) { MOZ_CRASH("NYI"); }
void storeAlignedFloat32x4(FloatRegister src, Address addr) { MOZ_CRASH("NYI"); }
void loadUnalignedFloat32x4(const Address &addr, FloatRegister dest) { MOZ_CRASH("NYI"); }
void storeUnalignedFloat32x4(FloatRegister src, Address addr) { MOZ_CRASH("NYI"); }
void loadDouble(const Address &addr, FloatRegister dest);
void loadDouble(const BaseIndex &src, FloatRegister dest);

View File

@ -31,7 +31,7 @@ interface nsIXPConnectWrappedNative;
* boolean to PR_TRUE before making the call. Implementations may skip writing
* to *_retval unless they want to return PR_FALSE.
*/
[uuid(9bae4ff5-5618-4ccd-b106-8e21e3fb64d3)]
[uuid(d945a647-a60e-462d-9635-c79d5fa694ce)]
interface nsIXPCScriptable : nsISupports
{
/* bitflags used for 'flags' (only 32 bits available!) */
@ -64,8 +64,6 @@ interface nsIXPCScriptable : nsISupports
const uint32_t ALLOW_PROP_MODS_TO_PROTOTYPE = 1 << 25;
const uint32_t IS_GLOBAL_OBJECT = 1 << 26;
const uint32_t DONT_REFLECT_INTERFACE_NAMES = 1 << 27;
// Unused bit here!
const uint32_t WANT_OUTER_OBJECT = 1 << 29;
// The high order bit is RESERVED for consumers of these flags.
// No implementor of this interface should ever return flags
@ -140,9 +138,6 @@ interface nsIXPCScriptable : nsISupports
in JSContextPtr cx, in JSObjectPtr obj,
in jsval val, out boolean bp);
JSObjectPtr outerObject(in nsIXPConnectWrappedNative wrapper,
in JSContextPtr cx, in JSObjectPtr obj);
void postCreatePrototype(in JSContextPtr cx, in JSObjectPtr proto);
};

View File

@ -76,9 +76,6 @@ XPC_MAP_CLASSNAME::GetScriptableFlags()
#ifdef XPC_MAP_WANT_HASINSTANCE
nsIXPCScriptable::WANT_HASINSTANCE |
#endif
#ifdef XPC_MAP_WANT_OUTER_OBJECT
nsIXPCScriptable::WANT_OUTER_OBJECT |
#endif
#ifdef XPC_MAP_FLAGS
XPC_MAP_FLAGS |
#endif
@ -166,11 +163,6 @@ NS_IMETHODIMP XPC_MAP_CLASSNAME::HasInstance(nsIXPConnectWrappedNative *wrapper,
{NS_ERROR("never called"); return NS_ERROR_NOT_IMPLEMENTED;}
#endif
#ifndef XPC_MAP_WANT_OUTER_OBJECT
NS_IMETHODIMP XPC_MAP_CLASSNAME::OuterObject(nsIXPConnectWrappedNative *wrapper, JSContext * cx, JSObject * obj, JSObject * *_retval)
{NS_ERROR("never called"); return NS_ERROR_NOT_IMPLEMENTED;}
#endif
#ifndef XPC_MAP_WANT_POST_CREATE_PROTOTYPE
NS_IMETHODIMP XPC_MAP_CLASSNAME::PostCreatePrototype(JSContext *cx, JSObject *proto)
{return NS_OK;}
@ -241,10 +233,6 @@ NS_IMETHODIMP XPC_MAP_CLASSNAME::PostCreatePrototype(JSContext *cx, JSObject *pr
#undef XPC_MAP_WANT_HASINSTANCE
#endif
#ifdef XPC_MAP_WANT_OUTER_OBJECT
#undef XPC_MAP_WANT_OUTER_OBJECT
#endif
#ifdef XPC_MAP_WANT_POST_CREATE_PROTOTYPE
#undef XPC_MAP_WANT_POST_CREATE_PROTOTYPE
#endif

View File

@ -629,42 +629,6 @@ XPC_WN_NoHelper_Resolve(JSContext *cx, HandleObject obj, HandleId id)
JSPROP_PERMANENT, nullptr);
}
static JSObject *
XPC_WN_OuterObject(JSContext *cx, HandleObject objArg)
{
JSObject *obj = objArg;
XPCWrappedNative *wrapper = XPCWrappedNative::Get(obj);
if (!wrapper) {
Throw(NS_ERROR_XPC_BAD_OP_ON_WN_PROTO, cx);
return nullptr;
}
if (!wrapper->IsValid()) {
Throw(NS_ERROR_XPC_HAS_BEEN_SHUTDOWN, cx);
return nullptr;
}
XPCNativeScriptableInfo* si = wrapper->GetScriptableInfo();
if (si && si->GetFlags().WantOuterObject()) {
RootedObject newThis(cx);
nsresult rv =
si->GetCallback()->OuterObject(wrapper, cx, obj, newThis.address());
if (NS_FAILED(rv)) {
Throw(rv, cx);
return nullptr;
}
obj = newThis;
}
return obj;
}
const XPCWrappedNativeJSClass XPC_WN_NoHelper_JSClass = {
{ // base
"XPCWrappedNative_NoHelper", // name;
@ -1172,24 +1136,8 @@ XPCNativeScriptableShared::PopulateJSClass()
// We have to figure out resolve strategy at call time
mJSClass.base.resolve = (JSResolveOp) XPC_WN_Helper_NewResolve;
// We need to respect content-defined toString() hooks on Window objects.
// In particular, js::DefaultValue checks for a convert stub, and the one
// we would install below ignores anything implemented in JS.
//
// We've always had this behavior for most XPCWrappedNative-implemented
// objects. However, Window was special, because the outer-window proxy
// had a null convert hook, which means that we'd end up with the default
// JS-engine behavior (which respects toString() overrides). We've fixed
// the convert hook on the outer-window proxy to invoke the defaultValue
// hook on the proxy, which in this case invokes js::DefaultValue on the
// target. So now we need to special-case this for Window to maintain
// consistent behavior. This can go away once Window is on WebIDL bindings.
//
// Note that WantOuterObject() is true if and only if this is a Window object.
if (mFlags.WantConvert())
mJSClass.base.convert = XPC_WN_Helper_Convert;
else if (mFlags.WantOuterObject())
mJSClass.base.convert = JS_ConvertStub;
else
mJSClass.base.convert = XPC_WN_Shared_Convert;
@ -1216,9 +1164,6 @@ XPCNativeScriptableShared::PopulateJSClass()
else
mJSClass.base.trace = XPCWrappedNative::Trace;
if (mFlags.WantOuterObject())
mJSClass.base.ext.outerObject = XPC_WN_OuterObject;
mJSClass.base.ext.isWrappedNative = true;
}

View File

@ -1623,7 +1623,6 @@ public:
bool WantCall() GET_IT(WANT_CALL)
bool WantConstruct() GET_IT(WANT_CONSTRUCT)
bool WantHasInstance() GET_IT(WANT_HASINSTANCE)
bool WantOuterObject() GET_IT(WANT_OUTER_OBJECT)
bool UseJSStubForAddProperty() GET_IT(USE_JSSTUB_FOR_ADDPROPERTY)
bool UseJSStubForDelProperty() GET_IT(USE_JSSTUB_FOR_DELPROPERTY)
bool UseJSStubForSetProperty() GET_IT(USE_JSSTUB_FOR_SETPROPERTY)

View File

@ -470,7 +470,7 @@ public class BrowserApp extends GeckoApp
(new UIAsyncTask.WithoutParams<String>(ThreadUtils.getBackgroundHandler()) {
@Override
public String doInBackground() {
return Favicons.getFaviconURLForPageURL(url);
return Favicons.getFaviconURLForPageURL(getContext(), url);
}
@Override
@ -942,11 +942,13 @@ public class BrowserApp extends GeckoApp
}
final OnFaviconLoadedListener listener = new GeckoAppShell.CreateShortcutFaviconLoadedListener(url, title);
Favicons.getSizedFavicon(url,
tab.getFaviconURL(),
Integer.MAX_VALUE,
LoadFaviconTask.FLAG_PERSIST,
listener);
Favicons.getSizedFavicon(getContext(),
url,
tab.getFaviconURL(),
Integer.MAX_VALUE,
LoadFaviconTask.FLAG_PERSIST,
listener);
return true;
}
@ -1743,7 +1745,7 @@ public class BrowserApp extends GeckoApp
final int tabFaviconSize = getResources().getDimensionPixelSize(R.dimen.browser_toolbar_favicon_size);
int flags = (tab.isPrivate() || tab.getErrorType() != Tab.ErrorType.NONE) ? 0 : LoadFaviconTask.FLAG_PERSIST;
int id = Favicons.getSizedFavicon(tab.getURL(), tab.getFaviconURL(), tabFaviconSize, flags, sFaviconLoadedListener);
int id = Favicons.getSizedFavicon(getContext(), tab.getURL(), tab.getFaviconURL(), tabFaviconSize, flags, sFaviconLoadedListener);
tab.setFaviconLoadId(id);
}

View File

@ -45,6 +45,7 @@ import org.mozilla.gecko.mozglue.GeckoLoader;
import org.mozilla.gecko.preferences.ClearOnShutdownPref;
import org.mozilla.gecko.preferences.GeckoPreferences;
import org.mozilla.gecko.prompts.PromptService;
import org.mozilla.gecko.SmsManager;
import org.mozilla.gecko.updater.UpdateService;
import org.mozilla.gecko.updater.UpdateServiceHelper;
import org.mozilla.gecko.util.ActivityResultHandler;
@ -1190,7 +1191,7 @@ public abstract class GeckoApp
Tabs.getInstance().attachToContext(this);
try {
Favicons.attachToContext(this);
Favicons.initializeWithContext(this);
} catch (Exception e) {
Log.e(LOGTAG, "Exception starting favicon cache. Corrupt resources?", e);
}
@ -1544,9 +1545,8 @@ public abstract class GeckoApp
mWebappEventListener.registerEvents();
}
if (SmsManager.getInstance() != null) {
SmsManager.getInstance().start();
if (SmsManager.isEnabled()) {
SmsManager.getInstance().start();
}
mContactService = new ContactService(EventDispatcher.getInstance(), this);
@ -2079,10 +2079,11 @@ public abstract class GeckoApp
IntentHelper.destroy();
GeckoNetworkManager.destroy();
if (SmsManager.getInstance() != null) {
if (SmsManager.isEnabled()) {
SmsManager.getInstance().stop();
if (isFinishing())
if (isFinishing()) {
SmsManager.getInstance().shutdown();
}
}
final HealthRecorder rec = mHealthRecorder;

View File

@ -48,6 +48,7 @@ import org.mozilla.gecko.mozglue.RobocopTarget;
import org.mozilla.gecko.mozglue.generatorannotations.OptionalGeneratedParameter;
import org.mozilla.gecko.mozglue.generatorannotations.WrapElementForJNI;
import org.mozilla.gecko.prompts.PromptService;
import org.mozilla.gecko.SmsManager;
import org.mozilla.gecko.util.EventCallback;
import org.mozilla.gecko.util.GeckoRequest;
import org.mozilla.gecko.util.HardwareUtils;
@ -2352,7 +2353,7 @@ public class GeckoAppShell
*/
@WrapElementForJNI(stubName = "SendMessageWrapper")
public static void sendMessage(String aNumber, String aMessage, int aRequestId) {
if (SmsManager.getInstance() == null) {
if (!SmsManager.isEnabled()) {
return;
}
@ -2361,7 +2362,7 @@ public class GeckoAppShell
@WrapElementForJNI(stubName = "GetMessageWrapper")
public static void getMessage(int aMessageId, int aRequestId) {
if (SmsManager.getInstance() == null) {
if (!SmsManager.isEnabled()) {
return;
}
@ -2370,7 +2371,7 @@ public class GeckoAppShell
@WrapElementForJNI(stubName = "DeleteMessageWrapper")
public static void deleteMessage(int aMessageId, int aRequestId) {
if (SmsManager.getInstance() == null) {
if (!SmsManager.isEnabled()) {
return;
}
@ -2379,7 +2380,7 @@ public class GeckoAppShell
@WrapElementForJNI(stubName = "CreateMessageListWrapper")
public static void createMessageList(long aStartDate, long aEndDate, String[] aNumbers, int aNumbersCount, String aDelivery, boolean aHasRead, boolean aRead, long aThreadId, boolean aReverse, int aRequestId) {
if (SmsManager.getInstance() == null) {
if (!SmsManager.isEnabled()) {
return;
}
@ -2388,7 +2389,7 @@ public class GeckoAppShell
@WrapElementForJNI(stubName = "GetNextMessageInListWrapper")
public static void getNextMessageInList(int aListId, int aRequestId) {
if (SmsManager.getInstance() == null) {
if (!SmsManager.isEnabled()) {
return;
}
@ -2397,7 +2398,7 @@ public class GeckoAppShell
@WrapElementForJNI
public static void clearMessageList(int aListId) {
if (SmsManager.getInstance() == null) {
if (!SmsManager.isEnabled()) {
return;
}

View File

@ -5,6 +5,7 @@
package org.mozilla.gecko;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
@ -37,39 +38,6 @@ import android.util.Log;
import android.view.KeyCharacterMap;
import android.view.KeyEvent;
// interface for the IC thread
interface GeckoEditableClient {
void sendEvent(GeckoEvent event);
Editable getEditable();
void setUpdateGecko(boolean update);
void setSuppressKeyUp(boolean suppress);
Handler getInputConnectionHandler();
boolean setInputConnectionHandler(Handler handler);
}
/* interface for the Editable to listen to the Gecko thread
and also for the IC thread to listen to the Editable */
interface GeckoEditableListener {
// IME notification type for notifyIME(), corresponding to NotificationToIME enum in Gecko
final int NOTIFY_IME_OPEN_VKB = -2;
final int NOTIFY_IME_REPLY_EVENT = -1;
final int NOTIFY_IME_OF_FOCUS = 1;
final int NOTIFY_IME_OF_BLUR = 2;
final int NOTIFY_IME_TO_COMMIT_COMPOSITION = 8;
final int NOTIFY_IME_TO_CANCEL_COMPOSITION = 9;
// IME enabled state for notifyIMEContext()
final int IME_STATE_DISABLED = 0;
final int IME_STATE_ENABLED = 1;
final int IME_STATE_PASSWORD = 2;
final int IME_STATE_PLUGIN = 3;
void notifyIME(int type);
void notifyIMEContext(int state, String typeHint,
String modeHint, String actionHint);
void onSelectionChange(int start, int end);
void onTextChange(CharSequence text, int start, int oldEnd, int newEnd);
}
/*
GeckoEditable implements only some functions of Editable
The field mText contains the actual underlying
@ -1004,12 +972,12 @@ final class GeckoEditable
} else if (Proxy.isProxyClass(obj.getClass())) {
debugAppend(sb, Proxy.getInvocationHandler(obj));
} else if (obj instanceof CharSequence) {
sb.append("\"").append(obj.toString().replace('\n', '\u21b2')).append("\"");
sb.append('"').append(obj.toString().replace('\n', '\u21b2')).append('"');
} else if (obj.getClass().isArray()) {
sb.append(obj.getClass().getComponentType().getSimpleName()).append("[")
.append(java.lang.reflect.Array.getLength(obj)).append("]");
sb.append(obj.getClass().getComponentType().getSimpleName()).append('[')
.append(Array.getLength(obj)).append(']');
} else {
sb.append(obj.toString());
sb.append(obj);
}
return sb;
}

View File

@ -0,0 +1,21 @@
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: nil; -*-
* 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/. */
package org.mozilla.gecko;
import android.os.Handler;
import android.text.Editable;
/**
* Interface for the IC thread.
*/
interface GeckoEditableClient {
void sendEvent(GeckoEvent event);
Editable getEditable();
void setUpdateGecko(boolean update);
void setSuppressKeyUp(boolean suppress);
Handler getInputConnectionHandler();
boolean setInputConnectionHandler(Handler handler);
}

View File

@ -0,0 +1,30 @@
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: nil; -*-
* 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/. */
package org.mozilla.gecko;
/**
* Interface for the Editable to listen on the Gecko thread, as well as for the IC thread to listen
* to the Editable.
*/
interface GeckoEditableListener {
// IME notification type for notifyIME(), corresponding to NotificationToIME enum in Gecko
int NOTIFY_IME_OPEN_VKB = -2;
int NOTIFY_IME_REPLY_EVENT = -1;
int NOTIFY_IME_OF_FOCUS = 1;
int NOTIFY_IME_OF_BLUR = 2;
int NOTIFY_IME_TO_COMMIT_COMPOSITION = 8;
int NOTIFY_IME_TO_CANCEL_COMPOSITION = 9;
// IME enabled state for notifyIMEContext()
int IME_STATE_DISABLED = 0;
int IME_STATE_ENABLED = 1;
int IME_STATE_PASSWORD = 2;
int IME_STATE_PLUGIN = 3;
void notifyIME(int type);
void notifyIMEContext(int state, String typeHint, String modeHint, String actionHint);
void onSelectionChange(int start, int end);
void onTextChange(CharSequence text, int start, int oldEnd, int newEnd);
}

View File

@ -1007,7 +1007,7 @@ final class DebugGeckoInputConnection
public static GeckoEditableListener create(View targetView,
GeckoEditableClient editable) {
final Class[] PROXY_INTERFACES = { InputConnection.class,
final Class<?>[] PROXY_INTERFACES = { InputConnection.class,
InputConnectionHandler.class,
GeckoEditableListener.class };
DebugGeckoInputConnection dgic =

View File

@ -0,0 +1,22 @@
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: nil; -*-
* 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/. */
package org.mozilla.gecko;
import org.json.JSONObject;
import org.mozilla.gecko.util.EventCallback;
/* Wrapper for MediaRouter types supported by Android, such as Chromecast, Miracast, etc. */
interface GeckoMediaPlayer {
JSONObject toJSON();
void load(String title, String url, String type, EventCallback callback);
void play(EventCallback callback);
void pause(EventCallback callback);
void stop(EventCallback callback);
void start(EventCallback callback);
void end(EventCallback callback);
void mirror(EventCallback callback);
void message(String message, EventCallback callback);
}

View File

@ -24,20 +24,10 @@ import android.telephony.SmsMessage;
import android.util.Log;
import static android.telephony.SmsMessage.MessageClass;
import static org.mozilla.gecko.SmsManager.ISmsManager;
import java.util.ArrayList;
/**
* This class is returning unique ids for PendingIntent requestCode attribute.
* There are only |Integer.MAX_VALUE - Integer.MIN_VALUE| unique IDs available,
* and they wrap around.
*/
class PendingIntentUID
{
static private int sUID = Integer.MIN_VALUE;
static public int generate() { return sUID++; }
}
import java.util.concurrent.atomic.AtomicInteger;
/**
* The envelope class contains all information that are needed to keep track of
@ -76,7 +66,7 @@ class Envelope
mMessageId = -1;
mError = GeckoSmsManager.kNoError;
int size = Envelope.SubParts.values().length;
int size = SubParts.values().length;
mRemainingParts = new int[size];
mFailing = new boolean[size];
@ -86,7 +76,7 @@ class Envelope
}
}
public void decreaseRemainingParts(Envelope.SubParts aType) {
public void decreaseRemainingParts(SubParts aType) {
--mRemainingParts[aType.ordinal()];
if (mRemainingParts[SubParts.SENT_PART.ordinal()] >
@ -95,15 +85,15 @@ class Envelope
}
}
public boolean arePartsRemaining(Envelope.SubParts aType) {
public boolean arePartsRemaining(SubParts aType) {
return mRemainingParts[aType.ordinal()] != 0;
}
public void markAsFailed(Envelope.SubParts aType) {
public void markAsFailed(SubParts aType) {
mFailing[aType.ordinal()] = true;
}
public boolean isFailing(Envelope.SubParts aType) {
public boolean isFailing(SubParts aType) {
return mFailing[aType.ordinal()];
}
@ -141,7 +131,7 @@ class Postman
private static final Postman sInstance = new Postman();
private ArrayList<Envelope> mEnvelopes = new ArrayList<Envelope>(1);
private final ArrayList<Envelope> mEnvelopes = new ArrayList<>(1);
private Postman() {}
@ -224,7 +214,7 @@ class MessagesListManager
return sInstance;
}
private ArrayList<Cursor> mCursors = new ArrayList<Cursor>(0);
private final ArrayList<Cursor> mCursors = new ArrayList<>();
public int add(Cursor aCursor) {
int size = mCursors.size();
@ -355,7 +345,13 @@ public class GeckoSmsManager
private final static int kMessageClassClass2 = 3;
private final static int kMessageClassClass3 = 4;
private final static String[] kRequiredMessageRows = new String[] { "_id", "address", "body", "date", "type", "status" };
private final static String[] kRequiredMessageRows = { "_id", "address", "body", "date", "type", "status" };
// Used to generate monotonically increasing GUIDs.
private static final AtomicInteger pendingIntentGuid = new AtomicInteger(Integer.MIN_VALUE);
// The maximum value of a 32 bit signed integer. Used to enforce a limit on ids.
private static final long UNSIGNED_INTEGER_MAX_VALUE = Integer.MAX_VALUE * 2L + 1L;
public GeckoSmsManager() {
SmsIOThread.getInstance().start();
@ -364,9 +360,9 @@ public class GeckoSmsManager
@Override
public void start() {
IntentFilter smsFilter = new IntentFilter();
smsFilter.addAction(GeckoSmsManager.ACTION_SMS_RECEIVED);
smsFilter.addAction(GeckoSmsManager.ACTION_SMS_SENT);
smsFilter.addAction(GeckoSmsManager.ACTION_SMS_DELIVERED);
smsFilter.addAction(ACTION_SMS_RECEIVED);
smsFilter.addAction(ACTION_SMS_SENT);
smsFilter.addAction(ACTION_SMS_DELIVERED);
GeckoAppShell.getContext().registerReceiver(this, smsFilter);
}
@ -490,8 +486,6 @@ public class GeckoSmsManager
!envelope.arePartsRemaining(Envelope.SubParts.DELIVERED_PART)) {
postman.destroyEnvelope(envelopeId);
}
return;
}
}
@ -530,12 +524,12 @@ public class GeckoSmsManager
*/
PendingIntent sentPendingIntent =
PendingIntent.getBroadcast(GeckoAppShell.getContext(),
PendingIntentUID.generate(), sentIntent,
pendingIntentGuid.incrementAndGet(), sentIntent,
PendingIntent.FLAG_CANCEL_CURRENT);
PendingIntent deliveredPendingIntent =
PendingIntent.getBroadcast(GeckoAppShell.getContext(),
PendingIntentUID.generate(), deliveredIntent,
pendingIntentGuid.incrementAndGet(), deliveredIntent,
PendingIntent.FLAG_CANCEL_CURRENT);
sm.sendTextMessage(aNumber, "", aMessage,
@ -556,13 +550,13 @@ public class GeckoSmsManager
for (int i=0; i<parts.size(); ++i) {
sentPendingIntents.add(
PendingIntent.getBroadcast(GeckoAppShell.getContext(),
PendingIntentUID.generate(), sentIntent,
pendingIntentGuid.incrementAndGet(), sentIntent,
PendingIntent.FLAG_CANCEL_CURRENT)
);
deliveredPendingIntents.add(
PendingIntent.getBroadcast(GeckoAppShell.getContext(),
PendingIntentUID.generate(), deliveredIntent,
pendingIntentGuid.incrementAndGet(), deliveredIntent,
PendingIntent.FLAG_CANCEL_CURRENT)
);
}
@ -597,7 +591,7 @@ public class GeckoSmsManager
// The DOM API takes a 32bits unsigned int for the id. It's unlikely that
// we happen to need more than that but it doesn't cost to check.
if (id > Integer.MAX_VALUE) {
if (id > UNSIGNED_INTEGER_MAX_VALUE) {
throw new IdTooHighException();
}
@ -614,8 +608,8 @@ public class GeckoSmsManager
@Override
public void getMessage(int aMessageId, int aRequestId) {
class GetMessageRunnable implements Runnable {
private int mMessageId;
private int mRequestId;
private final int mMessageId;
private final int mRequestId;
GetMessageRunnable(int aMessageId, int aRequestId) {
mMessageId = aMessageId;
@ -699,8 +693,8 @@ public class GeckoSmsManager
@Override
public void deleteMessage(int aMessageId, int aRequestId) {
class DeleteMessageRunnable implements Runnable {
private int mMessageId;
private int mRequestId;
private final int mMessageId;
private final int mRequestId;
DeleteMessageRunnable(int aMessageId, int aRequestId) {
mMessageId = aMessageId;
@ -739,13 +733,13 @@ public class GeckoSmsManager
@Override
public void createMessageList(long aStartDate, long aEndDate, String[] aNumbers, int aNumbersCount, String aDelivery, boolean aHasRead, boolean aRead, long aThreadId, boolean aReverse, int aRequestId) {
class CreateMessageListRunnable implements Runnable {
private long mStartDate;
private long mEndDate;
private String[] mNumbers;
private int mNumbersCount;
private String mDelivery;
private boolean mReverse;
private int mRequestId;
private final long mStartDate;
private final long mEndDate;
private final String[] mNumbers;
private final int mNumbersCount;
private final String mDelivery;
private final boolean mReverse;
private final int mRequestId;
CreateMessageListRunnable(long aStartDate, long aEndDate, String[] aNumbers, int aNumbersCount, String aDelivery, boolean aHasRead, boolean aRead, long aThreadId, boolean aReverse, int aRequestId) {
mStartDate = aStartDate;
@ -775,34 +769,38 @@ public class GeckoSmsManager
}
if (mNumbersCount > 0) {
String numberRestriction = "address IN ('" + mNumbers[0] + "'";
final StringBuilder numberRestriction = new StringBuilder("address IN ('");
numberRestriction.append(mNumbers[0]).append("'");
for (int i=1; i<mNumbersCount; ++i) {
numberRestriction += ", '" + mNumbers[i] + "'";
numberRestriction.append(", '").append(mNumbers[i]).append("'");
}
numberRestriction += ")";
numberRestriction.append(')');
restrictions.add(numberRestriction);
restrictions.add(numberRestriction.toString());
}
if (mDelivery == null) {
restrictions.add("type IN ('" + kSmsTypeSentbox + "', '" + kSmsTypeInbox + "')");
} else if (mDelivery == "sent") {
} else if (mDelivery.equals("sent")) {
restrictions.add("type = " + kSmsTypeSentbox);
} else if (mDelivery == "received") {
} else if (mDelivery.equals("received")) {
restrictions.add("type = " + kSmsTypeInbox);
} else {
throw new UnexpectedDeliveryStateException();
}
String restrictionText = restrictions.size() > 0 ? restrictions.get(0) : "";
final StringBuilder restrictionText = new StringBuilder();
if (!restrictions.isEmpty()) {
restrictionText.append(restrictions.get(0));
}
for (int i=1; i<restrictions.size(); ++i) {
restrictionText += " AND " + restrictions.get(i);
restrictionText.append(" AND ").append(restrictions.get(i));
}
ContentResolver cr = GeckoAppShell.getContext().getContentResolver();
cursor = cr.query(kSmsContentUri, kRequiredMessageRows, restrictionText, null,
cursor = cr.query(kSmsContentUri, kRequiredMessageRows, restrictionText.toString(), null,
mReverse ? "date DESC" : "date ASC");
if (cursor.getCount() == 0) {
@ -862,8 +860,8 @@ public class GeckoSmsManager
@Override
public void getNextMessageInList(int aListId, int aRequestId) {
class GetNextMessageInListRunnable implements Runnable {
private int mListId;
private int mRequestId;
private final int mListId;
private final int mRequestId;
GetNextMessageInListRunnable(int aListId, int aRequestId) {
mListId = aListId;
@ -963,27 +961,27 @@ public class GeckoSmsManager
}
}
class IdTooHighException extends Exception {
static class IdTooHighException extends Exception {
private static final long serialVersionUID = 29935575131092050L;
}
class InvalidTypeException extends Exception {
static class InvalidTypeException extends Exception {
private static final long serialVersionUID = 47436856832535912L;
}
class NotFoundException extends Exception {
static class NotFoundException extends Exception {
private static final long serialVersionUID = 1940676816633984L;
}
class TooManyResultsException extends Exception {
static class TooManyResultsException extends Exception {
private static final long serialVersionUID = 51883196784325305L;
}
class UnexpectedDeliveryStateException extends Exception {
static class UnexpectedDeliveryStateException extends Exception {
private static final long serialVersionUID = 494122763684005716L;
}
class UnmatchingIdException extends Exception {
static class UnmatchingIdException extends Exception {
private static final long serialVersionUID = 158467542575633280L;
}

View File

@ -27,19 +27,6 @@ import java.util.HashMap;
import java.util.Map;
import java.util.Iterator;
/* Wraper for different MediaRouter types supproted by Android. i.e. Chromecast, Miracast, etc. */
interface GeckoMediaPlayer {
public JSONObject toJSON();
public void load(String title, String url, String type, EventCallback callback);
public void play(EventCallback callback);
public void pause(EventCallback callback);
public void stop(EventCallback callback);
public void start(EventCallback callback);
public void end(EventCallback callback);
public void mirror(EventCallback callback);
public void message(String message, EventCallback callback);
}
/* Manages a list of GeckoMediaPlayers methods (i.e. Chromecast/Miracast). Routes messages
* from Gecko to the correct caster based on the id of the display
*/

View File

@ -9,6 +9,7 @@ import java.util.List;
import org.mozilla.gecko.TabsAccessor.RemoteClient;
import org.mozilla.gecko.TabsAccessor.RemoteTab;
import org.mozilla.gecko.home.TwoLinePageRow;
import android.content.Context;
import android.text.TextUtils;
@ -151,11 +152,18 @@ public class RemoteTabsExpandableListAdapter extends BaseExpandableListAdapter {
final RemoteClient client = clients.get(groupPosition);
final RemoteTab tab = client.tabs.get(childPosition);
final TextView titleView = (TextView) view.findViewById(R.id.title);
titleView.setText(TextUtils.isEmpty(tab.title) ? tab.url : tab.title);
// The view is a TwoLinePageRow only for some of our child views: it's
// present for the home panel children and not for the tabs tray
// children. Therefore, we must handle one case manually.
if (view instanceof TwoLinePageRow) {
((TwoLinePageRow) view).update(tab.title, tab.url);
} else {
final TextView titleView = (TextView) view.findViewById(R.id.title);
titleView.setText(TextUtils.isEmpty(tab.title) ? tab.url : tab.title);
final TextView urlView = (TextView) view.findViewById(R.id.url);
urlView.setText(tab.url);
final TextView urlView = (TextView) view.findViewById(R.id.url);
urlView.setText(tab.url);
}
return view;
}

View File

@ -5,30 +5,35 @@
package org.mozilla.gecko;
class SmsManager
{
static private ISmsManager sInstance;
static public ISmsManager getInstance() {
public class SmsManager {
private static final ISmsManager sInstance;
static {
if (AppConstants.MOZ_WEBSMS_BACKEND) {
if (sInstance == null) {
sInstance = new GeckoSmsManager();
}
sInstance = new GeckoSmsManager();
} else {
sInstance = null;
}
}
public static ISmsManager getInstance() {
return sInstance;
}
public static boolean isEnabled() {
return AppConstants.MOZ_WEBSMS_BACKEND;
}
public interface ISmsManager {
void start();
void stop();
void shutdown();
void send(String aNumber, String aMessage, int aRequestId);
void getMessage(int aMessageId, int aRequestId);
void deleteMessage(int aMessageId, int aRequestId);
void createMessageList(long aStartDate, long aEndDate, String[] aNumbers, int aNumbersCount, String aDelivery, boolean aHasRead, boolean aRead, long aThreadId, boolean aReverse, int aRequestId);
void getNextMessageInList(int aListId, int aRequestId);
void clearMessageList(int aListId);
}
}
interface ISmsManager
{
public void start();
public void stop();
public void shutdown();
public void send(String aNumber, String aMessage, int aRequestId);
public void getMessage(int aMessageId, int aRequestId);
public void deleteMessage(int aMessageId, int aRequestId);
public void createMessageList(long aStartDate, long aEndDate, String[] aNumbers, int aNumbersCount, String aDelivery, boolean aHasRead, boolean aRead, long aThreadId, boolean aReverse, int aRequestId);
public void getNextMessageInList(int aListId, int aRequestId);
public void clearMessageList(int aListId);
}

View File

@ -61,6 +61,11 @@ public class Tab {
return Utils.sameArrays(this.history, other.history);
}
@Override
public int hashCode() {
return super.hashCode();
}
/**
* Extract a <code>Tab</code> from a cursor row.
* <p>

View File

@ -237,14 +237,6 @@ public class BrowserDB {
sDb.registerBookmarkObserver(cr, observer);
}
public static void registerHistoryObserver(ContentResolver cr, ContentObserver observer) {
sDb.registerHistoryObserver(cr, observer);
}
public static void unregisterContentObserver(ContentResolver cr, ContentObserver observer) {
cr.unregisterContentObserver(observer);
}
public static int getCount(ContentResolver cr, String database) {
return sDb.getCount(cr, database);
}
@ -257,23 +249,11 @@ public class BrowserDB {
sDb.unpinSite(cr, position);
}
public static void unpinAllSites(ContentResolver cr) {
sDb.unpinAllSites(cr);
}
public static Cursor getPinnedSites(ContentResolver cr, int limit) {
return sDb.getPinnedSites(cr, limit);
}
@RobocopTarget
public static Cursor getBookmarkForUrl(ContentResolver cr, String url) {
return sDb.getBookmarkForUrl(cr, url);
}
public static boolean areContentProvidersDisabled() {
return sAreContentProvidersEnabled;
}
public static void setEnableContentProviders(boolean enableContentProviders) {
sAreContentProvidersEnabled = enableContentProviders;
}

View File

@ -58,7 +58,7 @@ public class LocalBrowserDB {
// Calculate these once, at initialization. isLoggable is too expensive to
// have in-line in each log call.
private static final String LOGTAG = "GeckoLocalBrowserDB";
private static boolean logDebug = Log.isLoggable(LOGTAG, Log.DEBUG);
private static final boolean logDebug = Log.isLoggable(LOGTAG, Log.DEBUG);
protected static void debug(String message) {
if (logDebug) {
Log.d(LOGTAG, message);
@ -449,11 +449,6 @@ public class LocalBrowserDB {
mDesktopBookmarksExist = null;
}
private Uri historyUriWithLimit(int limit) {
return mHistoryUriWithProfile.buildUpon().appendQueryParameter(BrowserContract.PARAM_LIMIT,
String.valueOf(limit)).build();
}
private Uri bookmarksUriWithLimit(int limit) {
return mBookmarksUriWithProfile.buildUpon().appendQueryParameter(BrowserContract.PARAM_LIMIT,
String.valueOf(limit)).build();
@ -486,11 +481,6 @@ public class LocalBrowserDB {
return uriBuilder.build();
}
private Cursor filterAllSites(ContentResolver cr, String[] projection, CharSequence constraint,
int limit, CharSequence urlFilter) {
return filterAllSites(cr, projection, constraint, limit, urlFilter, "", null);
}
private Cursor filterAllSites(ContentResolver cr, String[] projection, CharSequence constraint,
int limit, CharSequence urlFilter, String selection, String[] selectionArgs) {
// The combined history/bookmarks selection queries for sites with a url or title containing
@ -639,38 +629,6 @@ public class LocalBrowserDB {
new String[] { uri });
}
public void updateHistoryEntry(ContentResolver cr, String uri, String title,
long date, int visits) {
int oldVisits = 0;
Cursor cursor = null;
try {
cursor = cr.query(mHistoryUriWithProfile,
new String[] { History.VISITS },
History.URL + " = ?",
new String[] { uri },
null);
if (cursor.moveToFirst()) {
oldVisits = cursor.getInt(0);
}
} finally {
if (cursor != null)
cursor.close();
}
ContentValues values = new ContentValues();
values.put(History.DATE_LAST_VISITED, date);
values.put(History.VISITS, oldVisits + visits);
if (title != null) {
values.put(History.TITLE, title);
}
cr.update(mHistoryUriWithProfile,
values,
History.URL + " = ?",
new String[] { uri });
}
@RobocopTarget
public Cursor getAllVisitedHistory(ContentResolver cr) {
return cr.query(mHistoryUriWithProfile,
@ -700,12 +658,6 @@ public class LocalBrowserDB {
cr.delete(url, null, null);
}
public void removeHistoryEntry(ContentResolver cr, int id) {
cr.delete(mHistoryUriWithProfile,
History._ID + " = ?",
new String[] { String.valueOf(id) });
}
@RobocopTarget
public void removeHistoryEntry(ContentResolver cr, String url) {
cr.delete(mHistoryUriWithProfile,
@ -807,22 +759,6 @@ public class LocalBrowserDB {
return mDesktopBookmarksExist;
}
public int getReadingListCount(ContentResolver cr) {
Cursor c = null;
try {
c = cr.query(mReadingListUriWithProfile,
new String[] { ReadingListItems._ID },
null,
null,
null);
return c.getCount();
} finally {
if (c != null) {
c.close();
}
}
}
@RobocopTarget
public boolean isBookmark(ContentResolver cr, String uri) {
Cursor c = null;
@ -1008,18 +944,6 @@ public class LocalBrowserDB {
addBookmarkItem(cr, title, uri, folderId);
}
public void removeBookmark(ContentResolver cr, int id) {
Uri contentUri = mBookmarksUriWithProfile;
// Do this now so that the item still exists!
final String idString = String.valueOf(id);
bumpParents(cr, Bookmarks._ID, idString);
final String[] idArgs = new String[] { idString };
final String idEquals = Bookmarks._ID + " = ?";
cr.delete(contentUri, idEquals, idArgs);
}
@RobocopTarget
public void removeBookmarksWithURL(ContentResolver cr, String uri) {
Uri contentUri = mBookmarksUriWithProfile;
@ -1062,18 +986,10 @@ public class LocalBrowserDB {
cr.delete(mReadingListUriWithProfile, ReadingListItems.URL + " = ? ", new String[] { uri });
}
public void removeReadingListItem(ContentResolver cr, int id) {
cr.delete(mReadingListUriWithProfile, ReadingListItems._ID + " = ? ", new String[] { String.valueOf(id) });
}
public void registerBookmarkObserver(ContentResolver cr, ContentObserver observer) {
cr.registerContentObserver(mBookmarksUriWithProfile, false, observer);
}
public void registerHistoryObserver(ContentResolver cr, ContentObserver observer) {
cr.registerContentObserver(mHistoryUriWithProfile, false, observer);
}
@RobocopTarget
public void updateBookmark(ContentResolver cr, int id, String uri, String title, String keyword) {
ContentValues values = new ContentValues();
@ -1415,7 +1331,7 @@ public class LocalBrowserDB {
// This wrapper adds a fake "Desktop Bookmarks" folder entry to the
// beginning of the cursor's data set.
private class SpecialFoldersCursorWrapper extends CursorWrapper {
private static class SpecialFoldersCursorWrapper extends CursorWrapper {
private int mIndexOffset;
private int mDesktopBookmarksIndex = -1;
@ -1431,22 +1347,27 @@ public class LocalBrowserDB {
}
}
@Override
public int getCount() {
return super.getCount() + mIndexOffset;
}
@Override
public boolean moveToPosition(int position) {
mAtDesktopBookmarksPosition = (mDesktopBookmarksIndex == position);
if (mAtDesktopBookmarksPosition)
if (mAtDesktopBookmarksPosition) {
return true;
}
return super.moveToPosition(position - mIndexOffset);
}
@Override
public long getLong(int columnIndex) {
if (!mAtDesktopBookmarksPosition)
if (!mAtDesktopBookmarksPosition) {
return super.getLong(columnIndex);
}
if (columnIndex == getColumnIndex(Bookmarks.PARENT)) {
return Bookmarks.FIXED_ROOT_ID;
@ -1455,25 +1376,32 @@ public class LocalBrowserDB {
return -1;
}
@Override
public int getInt(int columnIndex) {
if (!mAtDesktopBookmarksPosition)
if (!mAtDesktopBookmarksPosition) {
return super.getInt(columnIndex);
}
if (columnIndex == getColumnIndex(Bookmarks._ID) && mAtDesktopBookmarksPosition)
return Bookmarks.FAKE_DESKTOP_FOLDER_ID;
if (columnIndex == getColumnIndex(Bookmarks._ID) && mAtDesktopBookmarksPosition) {
return Bookmarks.FAKE_DESKTOP_FOLDER_ID;
}
if (columnIndex == getColumnIndex(Bookmarks.TYPE))
if (columnIndex == getColumnIndex(Bookmarks.TYPE)) {
return Bookmarks.TYPE_FOLDER;
}
return -1;
}
@Override
public String getString(int columnIndex) {
if (!mAtDesktopBookmarksPosition)
if (!mAtDesktopBookmarksPosition) {
return super.getString(columnIndex);
}
if (columnIndex == getColumnIndex(Bookmarks.GUID) && mAtDesktopBookmarksPosition)
return Bookmarks.FAKE_DESKTOP_FOLDER_GUID;
if (columnIndex == getColumnIndex(Bookmarks.GUID) && mAtDesktopBookmarksPosition) {
return Bookmarks.FAKE_DESKTOP_FOLDER_GUID;
}
return "";
}
@ -1523,35 +1451,6 @@ public class LocalBrowserDB {
});
}
public void unpinAllSites(ContentResolver cr) {
cr.delete(mBookmarksUriWithProfile,
Bookmarks.PARENT + " == ?",
new String[] {
String.valueOf(Bookmarks.FIXED_PINNED_LIST_ID)
});
}
public boolean isVisited(ContentResolver cr, String uri) {
int count = 0;
Cursor c = null;
try {
c = cr.query(historyUriWithLimit(1),
new String[] { History._ID },
History.URL + " = ?",
new String[] { uri },
History.URL);
count = c.getCount();
} catch (NullPointerException e) {
Log.e(LOGTAG, "NullPointerException in isVisited");
} finally {
if (c != null)
c.close();
}
return (count > 0);
}
@RobocopTarget
public Cursor getBookmarkForUrl(ContentResolver cr, String url) {
Cursor c = cr.query(bookmarksUriWithLimit(1),

View File

@ -29,10 +29,12 @@ import java.io.File;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Arrays;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicBoolean;
public class Favicons {
private static final String LOGTAG = "GeckoFavicons";
@ -54,8 +56,6 @@ public class Favicons {
public static final int FLAG_PERSIST = 2;
public static final int FLAG_SCALE = 4;
protected static Context context;
// The default Favicon to show if no other can be found.
public static Bitmap defaultFavicon;
@ -65,14 +65,17 @@ public class Favicons {
// The density-adjusted maximum Favicon dimensions.
public static int largestFaviconSize;
// Used to prevent multiple-initialisation.
public static final AtomicBoolean isInitialized = new AtomicBoolean(false);
// Executor for long-running Favicon Tasks.
public static final ExecutorService longRunningExecutor = Executors.newSingleThreadExecutor();
private static final SparseArray<LoadFaviconTask> loadTasks = new SparseArray<LoadFaviconTask>();
private static final SparseArray<LoadFaviconTask> loadTasks = new SparseArray<>();
// Cache to hold mappings between page URLs and Favicon URLs. Used to avoid going to the DB when
// doing so is not necessary.
private static final NonEvictingLruCache<String, String> pageURLMappings = new NonEvictingLruCache<String, String>(NUM_PAGE_URL_MAPPINGS_TO_STORE);
private static final NonEvictingLruCache<String, String> pageURLMappings = new NonEvictingLruCache<>(NUM_PAGE_URL_MAPPINGS_TO_STORE);
public static String getFaviconURLForPageURLFromCache(String pageURL) {
return pageURLMappings.get(pageURL);
@ -143,7 +146,7 @@ public class Favicons {
* @return The id of the asynchronous task created, NOT_LOADING if none is created, or
* LOADED if the value could be dispatched on the current thread.
*/
public static int getSizedFavicon(String pageURL, String faviconURL, int targetSize, int flags, OnFaviconLoadedListener listener) {
public static int getSizedFavicon(Context context, String pageURL, String faviconURL, int targetSize, int flags, OnFaviconLoadedListener listener) {
// Do we know the favicon URL for this page already?
String cacheURL = faviconURL;
if (cacheURL == null) {
@ -171,7 +174,7 @@ public class Favicons {
}
// Failing that, try and get one from the database or internet.
return loadUncachedFavicon(pageURL, faviconURL, flags, targetSize, listener);
return loadUncachedFavicon(context, pageURL, faviconURL, flags, targetSize, listener);
}
/**
@ -202,7 +205,7 @@ public class Favicons {
* @param callback Callback to fire with the result.
* @return The job ID of the spawned async task, if any.
*/
public static int getSizedFaviconForPageFromLocal(final String pageURL, final int targetSize,
public static int getSizedFaviconForPageFromLocal(Context context, final String pageURL, final int targetSize,
final OnFaviconLoadedListener callback) {
// Firstly, try extremely hard to cheat.
// Have we cached this favicon URL? If we did, we can consult the memcache right away.
@ -223,7 +226,7 @@ public class Favicons {
// No joy using in-memory resources. Go to background thread and ask the database.
final LoadFaviconTask task =
new LoadFaviconTask(pageURL, targetURL, 0, callback, targetSize, true);
new LoadFaviconTask(context, pageURL, targetURL, 0, callback, targetSize, true);
final int taskId = task.getId();
synchronized(loadTasks) {
loadTasks.put(taskId, task);
@ -233,8 +236,8 @@ public class Favicons {
return taskId;
}
public static int getSizedFaviconForPageFromLocal(final String pageURL, final OnFaviconLoadedListener callback) {
return getSizedFaviconForPageFromLocal(pageURL, defaultFaviconSize, callback);
public static int getSizedFaviconForPageFromLocal(Context context, final String pageURL, final OnFaviconLoadedListener callback) {
return getSizedFaviconForPageFromLocal(context, pageURL, defaultFaviconSize, callback);
}
/**
@ -245,7 +248,7 @@ public class Favicons {
* @return The URL of the Favicon used by that webpage, according to either the History database
* or a somewhat educated guess.
*/
public static String getFaviconURLForPageURL(String pageURL) {
public static String getFaviconURLForPageURL(Context context, String pageURL) {
// Attempt to determine the Favicon URL from the Tabs datastructure. Can dodge having to use
// the database sometimes by doing this.
String targetURL;
@ -283,7 +286,7 @@ public class Favicons {
* @param listener The OnFaviconLoadedListener to invoke with the result of this Favicon load.
* @return The id of the LoadFaviconTask handling this job.
*/
private static int loadUncachedFavicon(String pageURL, String faviconURL, int flags,
private static int loadUncachedFavicon(Context context, String pageURL, String faviconURL, int flags,
int targetSize, OnFaviconLoadedListener listener) {
// Handle the case where we have no page url.
if (TextUtils.isEmpty(pageURL)) {
@ -292,7 +295,7 @@ public class Favicons {
}
final LoadFaviconTask task =
new LoadFaviconTask(pageURL, faviconURL, flags, listener, targetSize, false);
new LoadFaviconTask(context, pageURL, faviconURL, flags, listener, targetSize, false);
final int taskId = task.getId();
synchronized(loadTasks) {
loadTasks.put(taskId, task);
@ -382,14 +385,18 @@ public class Favicons {
*
* @param context A reference to the GeckoApp instance.
*/
public static void attachToContext(Context context) throws Exception {
public static void initializeWithContext(Context context) throws IllegalStateException {
// Prevent multiple-initialisation.
if (!isInitialized.compareAndSet(false, true)) {
return;
}
final Resources res = context.getResources();
Favicons.context = context;
// Decode the default Favicon ready for use.
defaultFavicon = BitmapFactory.decodeResource(res, R.drawable.favicon);
if (defaultFavicon == null) {
throw new Exception("Null default favicon was returned from the resources system!");
throw new IllegalStateException("Null default favicon was returned from the resources system!");
}
defaultFaviconSize = res.getDimensionPixelSize(R.dimen.favicon_bg);
@ -412,7 +419,7 @@ public class Favicons {
putFaviconsInMemCache(BUILT_IN_FAVICON_URL, toInsert.iterator(), true);
pageURLMappings.putWithoutEviction(AboutPages.HOME, BUILT_IN_SEARCH_URL);
List<Bitmap> searchIcons = Arrays.asList(BitmapFactory.decodeResource(res, R.drawable.favicon_search));
List<Bitmap> searchIcons = Collections.singletonList(BitmapFactory.decodeResource(res, R.drawable.favicon_search));
putFaviconsInMemCache(BUILT_IN_SEARCH_URL, searchIcons.iterator(), true);
}
@ -491,8 +498,8 @@ public class Favicons {
* @param url page URL to get a large favicon image for.
* @param onFaviconLoadedListener listener to call back with the result.
*/
public static void getPreferredSizeFaviconForPage(String url, OnFaviconLoadedListener onFaviconLoadedListener) {
public static void getPreferredSizeFaviconForPage(Context context, String url, OnFaviconLoadedListener onFaviconLoadedListener) {
int preferredSize = GeckoAppShell.getPreferredIconSize();
loadUncachedFavicon(url, null, 0, preferredSize, onFaviconLoadedListener);
loadUncachedFavicon(context, url, null, 0, preferredSize, onFaviconLoadedListener);
}
}

View File

@ -6,6 +6,7 @@ package org.mozilla.gecko.favicons;
import android.content.ContentResolver;
import android.content.Context;
import android.graphics.Bitmap;
import android.net.http.AndroidHttpClient;
import android.text.TextUtils;
@ -21,8 +22,6 @@ import org.mozilla.gecko.favicons.decoders.LoadFaviconResult;
import org.mozilla.gecko.util.GeckoJarReader;
import org.mozilla.gecko.util.ThreadUtils;
import static org.mozilla.gecko.favicons.Favicons.context;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
@ -44,7 +43,7 @@ public class LoadFaviconTask {
// Access to this map needs to be synchronized prevent multiple jobs loading the same favicon
// from executing concurrently.
private static final HashMap<String, LoadFaviconTask> loadsInFlight = new HashMap<String, LoadFaviconTask>();
private static final HashMap<String, LoadFaviconTask> loadsInFlight = new HashMap<>();
public static final int FLAG_PERSIST = 1;
public static final int FLAG_SCALE = 2;
@ -53,12 +52,13 @@ public class LoadFaviconTask {
// by the server.
private static final int DEFAULT_FAVICON_BUFFER_SIZE = 25000;
private static AtomicInteger nextFaviconLoadId = new AtomicInteger(0);
private int id;
private String pageUrl;
private static final AtomicInteger nextFaviconLoadId = new AtomicInteger(0);
private final Context context;
private final int id;
private final String pageUrl;
private String faviconURL;
private OnFaviconLoadedListener listener;
private int flags;
private final OnFaviconLoadedListener listener;
private final int flags;
private final boolean onlyFromLocal;
/* inner-access */ volatile boolean mCancelled;
@ -70,14 +70,15 @@ public class LoadFaviconTask {
static AndroidHttpClient httpClient = AndroidHttpClient.newInstance(GeckoAppShell.getGeckoInterface().getDefaultUAString());
public LoadFaviconTask(String pageURL, String faviconURL, int flags, OnFaviconLoadedListener listener) {
this(pageURL, faviconURL, flags, listener, -1, false);
public LoadFaviconTask(Context context, String pageURL, String faviconURL, int flags, OnFaviconLoadedListener listener) {
this(context, pageURL, faviconURL, flags, listener, -1, false);
}
public LoadFaviconTask(String pageURL, String faviconURL, int flags, OnFaviconLoadedListener listener,
public LoadFaviconTask(Context context, String pageURL, String faviconURL, int flags, OnFaviconLoadedListener listener,
int targetWidth, boolean onlyFromLocal) {
id = nextFaviconLoadId.incrementAndGet();
this.context = context;
this.pageUrl = pageURL;
this.faviconURL = faviconURL;
this.listener = listener;
@ -112,7 +113,7 @@ public class LoadFaviconTask {
* @return The HttpResponse containing the downloaded Favicon if successful, null otherwise.
*/
private HttpResponse tryDownload(URI faviconURI) throws URISyntaxException, IOException {
HashSet<String> visitedLinkSet = new HashSet<String>();
HashSet<String> visitedLinkSet = new HashSet<>();
visitedLinkSet.add(faviconURI.toString());
return tryDownloadRecurse(faviconURI, visitedLinkSet);
}
@ -183,7 +184,7 @@ public class LoadFaviconTask {
* Retrieve the specified favicon from the JAR, returning null if it's not
* a JAR URI.
*/
private static Bitmap fetchJARFavicon(String uri) {
private Bitmap fetchJARFavicon(String uri) {
if (uri == null) {
return null;
}
@ -370,7 +371,7 @@ public class LoadFaviconTask {
// If that failed, try to get the URL from the database.
if (storedFaviconUrl == null) {
storedFaviconUrl = Favicons.getFaviconURLForPageURL(pageUrl);
storedFaviconUrl = Favicons.getFaviconURLForPageURL(context, pageUrl);
if (storedFaviconUrl != null) {
// If that succeeded, cache the URL loaded from the database in memory.
Favicons.putFaviconURLForPageURLInCache(pageUrl, storedFaviconUrl);
@ -597,7 +598,7 @@ public class LoadFaviconTask {
*/
private void chainTasks(LoadFaviconTask aChainee) {
if (chainees == null) {
chainees = new LinkedList<LoadFaviconTask>();
chainees = new LinkedList<>();
}
chainees.add(aChainee);

View File

@ -370,6 +370,11 @@ public final class HomeConfig {
return mId.equals(other.mId);
}
@Override
public int hashCode() {
return super.hashCode();
}
@Override
public int describeContents() {
return 0;

View File

@ -194,7 +194,7 @@ public abstract class HomeFragment extends Fragment {
}
// Fetch an icon big enough for use as a home screen icon.
Favicons.getPreferredSizeFaviconForPage(info.url, new GeckoAppShell.CreateShortcutFaviconLoadedListener(info.url, info.getDisplayTitle()));
Favicons.getPreferredSizeFaviconForPage(context, info.url, new GeckoAppShell.CreateShortcutFaviconLoadedListener(info.url, info.getDisplayTitle()));
return true;
}

View File

@ -544,7 +544,7 @@ public class TopSitesPanel extends HomeFragment {
// If we have no thumbnail, attempt to show a Favicon instead.
LoadIDAwareFaviconLoadedListener listener = new LoadIDAwareFaviconLoadedListener(view);
final int loadId = Favicons.getSizedFaviconForPageFromLocal(url, listener);
final int loadId = Favicons.getSizedFaviconForPageFromLocal(context, url, listener);
if (loadId == Favicons.LOADED) {
// Great!
return;

View File

@ -50,6 +50,11 @@ public class TwoLinePageRow extends LinearLayout
this.view = new WeakReference<FaviconView>(view);
}
/**
* Update this row's favicon.
* <p>
* This method is always invoked on the UI thread.
*/
@Override
public void onFaviconLoaded(String url, String faviconURL, Bitmap favicon) {
FaviconView v = view.get();
@ -96,24 +101,49 @@ public class TwoLinePageRow extends LinearLayout
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
Tabs.registerOnTabsChangedListener(this);
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
// Tabs' listener array is safe to modify during use: its
// iteration pattern is based on snapshots.
Tabs.unregisterOnTabsChangedListener(this);
}
/**
* Update the row in response to a tab change event.
* <p>
* This method is always invoked on the UI thread.
*/
@Override
public void onTabChanged(final Tab tab, final Tabs.TabEvents msg, final Object data) {
switch(msg) {
// Carefully check if this tab event is relevant to this row.
final String pageUrl = mPageUrl;
if (pageUrl == null) {
return;
}
final String tabUrl;
if (tab == null) {
return;
}
tabUrl = tab.getURL();
if (!pageUrl.equals(tabUrl)) {
return;
}
switch (msg) {
case ADDED:
case CLOSED:
case LOCATION_CHANGE:
updateDisplayedUrl();
break;
default:
break;
}
}
@ -181,32 +211,29 @@ public class TwoLinePageRow extends LinearLayout
mShowIcons = showIcons;
}
public void updateFromCursor(Cursor cursor) {
if (cursor == null) {
return;
}
int titleIndex = cursor.getColumnIndexOrThrow(URLColumns.TITLE);
final String title = cursor.getString(titleIndex);
int urlIndex = cursor.getColumnIndexOrThrow(URLColumns.URL);
final String url = cursor.getString(urlIndex);
/**
* Update the data displayed by this row.
* <p>
* This method must be invoked on the UI thread.
*
* @param title to display.
* @param url to display.
*/
public void update(String title, String url) {
update(title, url, 0);
}
protected void update(String title, String url, long bookmarkId) {
if (mShowIcons) {
final int bookmarkIdIndex = cursor.getColumnIndex(Combined.BOOKMARK_ID);
if (bookmarkIdIndex != -1) {
final long bookmarkId = cursor.getLong(bookmarkIdIndex);
// The bookmark id will be 0 (null in database) when the url
// is not a bookmark.
if (bookmarkId == 0) {
setPageTypeIcon(NO_ICON);
} else {
setPageTypeIcon(R.drawable.ic_url_bar_star);
}
} else {
// The bookmark id will be 0 (null in database) when the url
// is not a bookmark.
if (bookmarkId == 0) {
setPageTypeIcon(NO_ICON);
} else {
setPageTypeIcon(R.drawable.ic_url_bar_star);
}
} else {
setPageTypeIcon(NO_ICON);
}
// Use the URL instead of an empty title for consistency with the normal URL
@ -220,8 +247,38 @@ public class TwoLinePageRow extends LinearLayout
// Blank the Favicon, so we don't show the wrong Favicon if we scroll and miss DB.
mFavicon.clearImage();
mLoadFaviconJobId = Favicons.getSizedFaviconForPageFromLocal(url, mFaviconListener);
Favicons.cancelFaviconLoad(mLoadFaviconJobId);
mLoadFaviconJobId = Favicons.getSizedFaviconForPageFromLocal(getContext(), url, mFaviconListener);
updateDisplayedUrl(url);
}
/**
* Update the data displayed by this row.
* <p>
* This method must be invoked on the UI thread.
*
* @param cursor to extract data from.
*/
public void updateFromCursor(Cursor cursor) {
if (cursor == null) {
return;
}
int titleIndex = cursor.getColumnIndexOrThrow(URLColumns.TITLE);
final String title = cursor.getString(titleIndex);
int urlIndex = cursor.getColumnIndexOrThrow(URLColumns.URL);
final String url = cursor.getString(urlIndex);
final long bookmarkId;
final int bookmarkIdIndex = cursor.getColumnIndex(Combined.BOOKMARK_ID);
if (bookmarkIdIndex != -1) {
bookmarkId = cursor.getLong(bookmarkIdIndex);
} else {
bookmarkId = 0;
}
update(title, url, bookmarkId);
}
}

View File

@ -194,6 +194,8 @@ gbjar.sources += [
'GeckoBatteryManager.java',
'GeckoConnectivityReceiver.java',
'GeckoEditable.java',
'GeckoEditableClient.java',
'GeckoEditableListener.java',
'GeckoEvent.java',
'GeckoHalDefines.java',
'GeckoInputConnection.java',
@ -518,6 +520,7 @@ moz_native_devices_jars = [
]
moz_native_devices_sources = [
'ChromeCast.java',
'GeckoMediaPlayer.java',
'MediaPlayerManager.java',
]
if CONFIG['MOZ_NATIVE_DEVICES']:

View File

@ -192,4 +192,9 @@ public class CollectionKeys {
return false;
}
}
@Override
public int hashCode() {
return super.hashCode();
}
}

View File

@ -112,6 +112,11 @@ public class ClientRecord extends Record {
return this.equalPayloads(o);
}
@Override
public int hashCode() {
return super.hashCode();
}
@Override
public boolean equalPayloads(Object o) {
if (!(o instanceof ClientRecord) || !super.equalPayloads(o)) {

View File

@ -49,6 +49,7 @@ public class SearchEngine {
private String identifier;
private String shortName;
private String iconURL;
// TODO: Make something more robust (like EngineURL in nsSearchService.js)
private Uri resultsUri;
@ -79,8 +80,8 @@ public class SearchEngine {
readShortName(parser);
} else if (tag.equals("Url")) {
readUrl(parser);
// TODO: Support for other tags
//} else if (tag.equals("Image")) {
} else if (tag.equals("Image")) {
readImage(parser);
} else {
skip(parser);
}
@ -129,6 +130,19 @@ public class SearchEngine {
}
}
private void readImage(XmlPullParser parser) throws XmlPullParserException, IOException {
parser.require(XmlPullParser.START_TAG, null, "Image");
// TODO: Use width and height to get a preferred icon URL.
//final int width = Integer.parseInt(parser.getAttributeValue(null, "width"));
//final int height = Integer.parseInt(parser.getAttributeValue(null, "height"));
if (parser.next() == XmlPullParser.TEXT) {
iconURL = parser.getText();
parser.nextTag();
}
}
private void skip(XmlPullParser parser) throws XmlPullParserException, IOException {
if (parser.getEventType() != XmlPullParser.START_TAG) {
throw new IllegalStateException();
@ -176,6 +190,10 @@ public class SearchEngine {
return shortName;
}
public String getIconURL() {
return iconURL;
}
/**
* Determine whether a particular url belongs to this search engine. If not,
* the url will be sent to Fennec.

View File

@ -22,6 +22,6 @@
<instrumentation
android:label="@string/app_name"
android:name="org.mozilla.gecko.browser.harness.BrowserInstrumentationTestRunner"
android:name="org.mozilla.gecko.harness.BrowserInstrumentationTestRunner"
android:targetPackage="@ANDROID_BROWSER_TARGET_PACKAGE_NAME@" />
</manifest>

View File

@ -8,16 +8,16 @@ DEFINES['ANDROID_PACKAGE_NAME'] = CONFIG['ANDROID_PACKAGE_NAME']
jar = add_java_jar('browser-junit3')
jar.sources += [
'src/BrowserTestCase.java',
'src/harness/BrowserInstrumentationTestRunner.java',
'src/harness/BrowserTestListener.java',
'src/tests/BrowserTestCase.java',
'src/tests/TestDistribution.java',
'src/tests/TestGeckoSharedPrefs.java',
'src/tests/TestImageDownloader.java',
'src/tests/TestJarReader.java',
'src/tests/TestRawResource.java',
'src/tests/TestSuggestedSites.java',
'src/tests/TestTopSitesCursorWrapper.java',
'src/TestDistribution.java',
'src/TestGeckoSharedPrefs.java',
'src/TestImageDownloader.java',
'src/TestJarReader.java',
'src/TestRawResource.java',
'src/TestSuggestedSites.java',
'src/TestTopSitesCursorWrapper.java',
]
jar.generated_sources = [] # None yet -- try to keep it this way.
jar.javac_flags += ['-Xlint:all,-unchecked']
@ -36,4 +36,4 @@ main.recursive_make_targets += [OBJDIR + '/generated/' + f for f in jar.generate
main.referenced_projects += ['Fennec']
main.add_classpathentry('src', SRCDIR + '/src',
dstdir='src/org/mozilla/gecko/browser')
dstdir='src/org/mozilla/gecko')

View File

@ -1,7 +1,7 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
package org.mozilla.gecko.browser.tests;
package org.mozilla.gecko;
import org.mozilla.gecko.AppConstants;

View File

@ -2,7 +2,7 @@
* 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/. */
package org.mozilla.gecko.browser.tests;
package org.mozilla.gecko;
import org.mozilla.gecko.distribution.ReferrerDescriptor;

View File

@ -2,7 +2,7 @@
* 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/. */
package org.mozilla.gecko.browser.tests;
package org.mozilla.gecko;
import org.mozilla.gecko.AppConstants;
import org.mozilla.gecko.menu.GeckoMenu;

View File

@ -2,7 +2,7 @@
* 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/. */
package org.mozilla.gecko.browser.tests;
package org.mozilla.gecko;
import java.io.File;
import java.util.HashMap;

View File

@ -1,23 +1,19 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
package org.mozilla.gecko.browser.tests;
package org.mozilla.gecko;
import java.util.Arrays;
import java.util.Collections;
import java.util.EnumSet;
import java.util.Map;
import java.util.HashSet;
import java.util.Set;
import org.mozilla.gecko.GeckoProfile;
import org.mozilla.gecko.GeckoSharedPrefs;
import org.mozilla.gecko.GeckoSharedPrefs.Flags;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.os.Build;
import android.preference.PreferenceManager;
import android.test.RenamingDelegatingContext;

View File

@ -1,7 +1,7 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
package org.mozilla.gecko.browser.tests;
package org.mozilla.gecko;
import android.content.Context;
import android.content.res.Resources;

View File

@ -1,7 +1,7 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
package org.mozilla.gecko.browser.tests;
package org.mozilla.gecko;
import java.io.InputStream;

View File

@ -1,19 +1,18 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
package org.mozilla.gecko.browser.tests;
package org.mozilla.gecko;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import org.mozilla.gecko.util.RawResource;
import android.content.Context;
import android.content.res.Resources;
import android.test.mock.MockContext;
import android.test.mock.MockResources;
import android.util.TypedValue;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.IOException;
import org.mozilla.gecko.util.RawResource;
/**
* Tests whether RawResource.getAsString() produces the right String
@ -64,4 +63,4 @@ public class TestRawResource extends BrowserTestCase {
assertEquals(RAW_CONTENTS, result);
}
}
}

View File

@ -1,48 +1,40 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
package org.mozilla.gecko.browser.tests;
import android.content.Context;
import android.content.ContentResolver;
import android.content.res.Resources;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.database.ContentObserver;
import android.net.Uri;
import android.os.Handler;
import android.os.SystemClock;
import android.test.mock.MockResources;
import android.test.RenamingDelegatingContext;
package org.mozilla.gecko;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URI;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.jar.JarInputStream;
import java.util.Map;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import org.json.JSONArray;
import org.json.JSONObject;
import org.mozilla.gecko.BrowserLocaleManager;
import org.mozilla.gecko.R;
import org.mozilla.gecko.db.BrowserContract;
import org.mozilla.gecko.db.SuggestedSites;
import org.mozilla.gecko.distribution.Distribution;
import org.mozilla.gecko.GeckoSharedPrefs;
import org.mozilla.gecko.preferences.GeckoPreferences;
import android.content.ContentResolver;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.res.Resources;
import android.database.ContentObserver;
import android.database.Cursor;
import android.net.Uri;
import android.os.SystemClock;
import android.test.RenamingDelegatingContext;
import android.test.mock.MockResources;
public class TestSuggestedSites extends BrowserTestCase {
private static class TestContext extends RenamingDelegatingContext {
private static final String PREFIX = "TestSuggestedSites-";
@ -94,12 +86,10 @@ public class TestSuggestedSites extends BrowserTestCase {
}
private static class TestDistribution extends Distribution {
private final Context context;
private final Map<Locale, File> filesPerLocale;
public TestDistribution(Context context) {
super(context);
this.context = context;
this.filesPerLocale = new HashMap<Locale, File>();
}

View File

@ -1,7 +1,7 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
package org.mozilla.gecko.browser.tests;
package org.mozilla.gecko;
import android.database.Cursor;
import android.database.MatrixCursor;
@ -385,4 +385,4 @@ public class TestTopSitesCursorWrapper extends BrowserTestCase {
c.close();
}
}
}

View File

@ -1,7 +1,7 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
package org.mozilla.gecko.browser.harness;
package org.mozilla.gecko.harness;
import android.os.Bundle;
import android.test.AndroidTestRunner;

View File

@ -1,7 +1,7 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
package org.mozilla.gecko.browser.harness;
package org.mozilla.gecko.harness;
import junit.framework.AssertionFailedError;
import junit.framework.Test;

View File

@ -439,8 +439,11 @@ pref("apz.asyncscroll.timeout", 300);
// 0 = FREE (No locking at all)
// 1 = STANDARD (Once locked, remain locked until scrolling ends)
// 2 = STICKY (Allow lock to be broken, with hysteresis)
pref("apz.axis_lock_mode", 0);
pref("apz.axis_lock.mode", 0);
pref("apz.axis_lock.lock_angle", "0.5235987"); // PI / 6 (30 degrees)
pref("apz.axis_lock.breakout_threshold", "0.03125"); // 1/32 inches
pref("apz.axis_lock.breakout_angle", "0.3926991"); // PI / 8 (22.5 degrees)
pref("apz.axis_lock.direct_pan_angle", "1.047197"); // PI / 3 (60 degrees)
pref("apz.content_response_timeout", 300);
pref("apz.cross_slide.enabled", false);
pref("apz.danger_zone_x", 50);

View File

@ -79,6 +79,10 @@ static const char kCybertrust_Global_RootFingerprint[] =
static const char kDigiCert_Assured_ID_Root_CAFingerprint[] =
"I/Lt/z7ekCWanjD0Cvj5EqXls2lOaThEA0H2Bg4BT/o=";
/* DigiCert ECC Secure Server CA */
static const char kDigiCert_ECC_Secure_Server_CAFingerprint[] =
"PZXN3lRAy+8tBKk2Ox6F7jIlnzr2Yzmwqc3JnyfXoCw=";
/* DigiCert Global Root CA */
static const char kDigiCert_Global_Root_CAFingerprint[] =
"r/mIkG3eEpVdm+u/ko/cwxzOMo1bk4TyHIlByibiA5E=";
@ -364,6 +368,7 @@ struct StaticPinset {
/* PreloadedHPKPins.json pinsets */
static const char* kPinset_facebook_sha256_Data[] = {
kDigiCert_ECC_Secure_Server_CAFingerprint,
kVerisign_Class_3_Public_Primary_Certification_Authority___G3Fingerprint,
kDigiCert_High_Assurance_EV_Root_CAFingerprint,
};
@ -1087,4 +1092,4 @@ static const TransportSecurityPreload kPublicKeyPinningPreloadList[] = {
static const int32_t kUnknownId = -1;
static const PRTime kPreloadPKPinsExpirationTime = INT64_C(1418465237331000);
static const PRTime kPreloadPKPinsExpirationTime = INT64_C(1418659817121000);

View File

@ -19,6 +19,10 @@
// name: (string) the DNS name of the host in question
// include_subdomains: (optional bool) whether subdomains of |name| are also covered
// pins: (string) the |name| member of an object in |pinsets|
//
// "extra_certs" is a list of base64-encoded certificates. These are used in
// pinsets that reference certificates not in our root program (for example,
// Facebook).
// equifax -> aus3
// Geotrust Primary -> www.mozilla.org
@ -186,13 +190,12 @@
"XRamp Global CA Root"
]
},
// For pinning tests on pinning.example.com, the certificate must be 'End
// Entity Test Cert'
{
"name": "facebook",
"sha256_hashes": [
"Verisign Class 3 Public Primary Certification Authority - G3",
"DigiCert High Assurance EV Root CA"
"DigiCert High Assurance EV Root CA",
"DigiCert ECC Secure Server CA"
]
}
],
@ -235,5 +238,10 @@
// Facebook (not pinned by Chrome)
{ "name": "facebook.com", "include_subdomains": true,
"pins": "facebook", "test_mode": true }
],
"extra_certificates": [
// DigiCert ECC Secure Server CA (for Facebook)
"MIIDrDCCApSgAwIBAgIQCssoukZe5TkIdnRw883GEjANBgkqhkiG9w0BAQwFADBhMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBDQTAeFw0xMzAzMDgxMjAwMDBaFw0yMzAzMDgxMjAwMDBaMEwxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxJjAkBgNVBAMTHURpZ2lDZXJ0IEVDQyBTZWN1cmUgU2VydmVyIENBMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE4ghC6nfYJN6gLGSkE85AnCNyqQIKDjc/ITa4jVMU9tWRlUvzlgKNcR7E2Munn17voOZ/WpIRllNv68DLP679Wz9HJOeaBy6Wvqgvu1cYr3GkvXg6HuhbPGtkESvMNCuMo4IBITCCAR0wEgYDVR0TAQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAYYwNAYIKwYBBQUHAQEEKDAmMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20wQgYDVR0fBDswOTA3oDWgM4YxaHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0R2xvYmFsUm9vdENBLmNybDA9BgNVHSAENjA0MDIGBFUdIAAwKjAoBggrBgEFBQcCARYcaHR0cHM6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzAdBgNVHQ4EFgQUo53mH/naOU/AbuiRy5Wl2jHiCp8wHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUwDQYJKoZIhvcNAQEMBQADggEBAMeKoENL7HTJxavVHzA1Nm6YVntIrAVjrnuaVyRXzG/63qttnMe2uuzO58pzZNvfBDcKAEmzP58mrZGMIOgfiA4q+2Y3yDDo0sIkp0VILeoBUEoxlBPfjV/aKrtJPGHzecicZpIalir0ezZYoyxBEHQa0+1IttK7igZFcTMQMHp6mCHdJLnsnLWSB62DxsRq+HfmNb4TDydkskO/g+l3VtsIh5RHFPVfKK+jaEyDj2D3loB5hWp2Jp2VDCADjT7ueihlZGak2YPqmXTNbk19HOuNssWvFhtOyPNV6og4ETQdEa8/B6hPatJ0ES8q/HO3X8IVQwVs1n3aAr0im0/T+Xc="
]
}

View File

@ -336,7 +336,7 @@ function downloadAndParseChromePins(filename,
// Returns a pair of maps [certNameToSKD, certSKDToName] between cert
// nicknames and digests of the SPKInfo for the mozilla trust store
function loadNSSCertinfo(derTestFile) {
function loadNSSCertinfo(derTestFile, extraCertificates) {
let allCerts = gCertDB.getCerts();
let enumerator = allCerts.getEnumerator();
let certNameToSKD = {};
@ -351,6 +351,14 @@ function loadNSSCertinfo(derTestFile) {
certNameToSKD[name] = SKD;
certSKDToName[SKD] = name;
}
for (let cert of extraCertificates) {
let name = cert.commonName;
let SKD = cert.sha256SubjectPublicKeyInfoDigest;
certNameToSKD[name] = SKD;
certSKDToName[SKD] = name;
}
{
// A certificate for *.example.com.
let der = readFileToString(derTestFile);
@ -545,7 +553,17 @@ function writeFile(certNameToSKD, certSKDToName,
writeString(genExpirationTime());
}
let [ certNameToSKD, certSKDToName ] = loadNSSCertinfo(gTestCertFile);
function loadExtraCertificates(certStringList) {
let constructedCerts = [];
for (let certString of certStringList) {
constructedCerts.push(gCertDB.constructX509FromBase64(certString));
}
return constructedCerts;
}
let extraCertificates = loadExtraCertificates(gStaticPins.extra_certificates);
let [ certNameToSKD, certSKDToName ] = loadNSSCertinfo(gTestCertFile,
extraCertificates);
let [ chromeNameToHash, chromeNameToMozName ] = downloadAndParseChromeCerts(
gStaticPins.chromium_data.cert_file_url, certSKDToName);
let [ chromeImportedPinsets, chromeImportedEntries ] =

View File

@ -31,6 +31,7 @@ class ErrorCodes(object):
INVALID_RESPONSE = 53
FRAME_SEND_NOT_INITIALIZED_ERROR = 54
FRAME_SEND_FAILURE_ERROR = 55
UNSUPPORTED_OPERATION = 405
MARIONETTE_ERROR = 500
class MarionetteException(Exception):
@ -138,3 +139,6 @@ class FrameSendNotInitializedError(MarionetteException):
class FrameSendFailureError(MarionetteException):
pass
class UnsupportedOperationException(MarionetteException):
pass

View File

@ -708,6 +708,8 @@ class Marionette(object):
raise errors.FrameSendNotInitializedError(message=message, status=status, stacktrace=stacktrace)
elif status == errors.ErrorCodes.FRAME_SEND_FAILURE_ERROR:
raise errors.FrameSendFailureError(message=message, status=status, stacktrace=stacktrace)
elif status == errors.ErrorCodes.UNSUPPORTED_OPERATION:
raise errors.UnsupportedOperationException(message=message, status=status, stacktrace=stacktrace)
else:
raise errors.MarionetteException(message=message, status=status, stacktrace=stacktrace)
raise errors.MarionetteException(message=response, status=500)
@ -883,7 +885,6 @@ class Marionette(object):
:rtype: string
"""
self.window = self._send_message("getWindowHandle", "value")
return self.window
@ -1515,3 +1516,31 @@ class Marionette(object):
self._send_message("setScreenOrientation", "ok", orientation=orientation)
if self.emulator:
self.emulator.screen.orientation = orientation.lower()
@property
def window_size(self):
"""Get the current browser window size.
Will return the current browser window size in pixels. Refers to
window outerWidth and outerHeight values, which include scroll bars,
title bars, etc.
:returns: dictionary representation of current window width and height
"""
return self._send_message("getWindowSize", "value")
def set_window_size(self, width, height):
"""Resize the browser window currently in focus.
The supplied width and height values refer to the window outerWidth
and outerHeight values, which include scroll bars, title bars, etc.
An error will be returned if the requested window size would result
in the window being in the maximised state.
:param width: The width to resize the window to.
:param height: The height to resize the window to.
"""
self._send_message("setWindowSize", "ok", width=width, height=height)

View File

@ -0,0 +1,50 @@
# 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/.
from errors import MarionetteException
from marionette_test import MarionetteTestCase
class TestSetWindowSize(MarionetteTestCase):
def setUp(self):
super(MarionetteTestCase, self).setUp()
self.start_size = self.marionette.window_size
self.max_width = self.marionette.execute_script("return window.screen.availWidth;")
self.max_height = self.marionette.execute_script("return window.screen.availHeight;")
def tearDown(self):
# WebDriver spec says a resize cannot result in window being maximized, an
# error is returned if that is the case; therefore if the window is maximized
# at the start of this test, returning to the original size via set_window_size
# size will result in error; so reset to original size minus 1 pixel width
if self.start_size['width'] == self.max_width and self.start_size['height'] == self.max_height:
self.start_size['width']-=1
self.marionette.set_window_size(self.start_size['width'], self.start_size['height'])
super(MarionetteTestCase, self).tearDown()
def test_set_window_size(self):
# event handler
self.marionette.execute_script("""
window.wrappedJSObject.rcvd_event = false;
window.onresize = function() {
window.wrappedJSObject.rcvd_event = true;
};
""")
# valid size
width = self.max_width - 100
height = self.max_height - 100
self.marionette.set_window_size(width, height)
self.wait_for_condition(lambda m: m.execute_script("return window.wrappedJSObject.rcvd_event;"))
size = self.marionette.window_size
self.assertEqual(size['width'], width,
"Window width is %s but should be %s" % (size['width'], width))
self.assertEqual(size['height'], height,
"Window height is %s but should be %s" % (size['height'], height))
# invalid size (cannot maximize)
with self.assertRaisesRegexp(MarionetteException, "Invalid requested size"):
self.marionette.set_window_size(self.max_width, self.max_height)
size = self.marionette.window_size
self.assertEqual(size['width'], width, "Window width should not have changed")
self.assertEqual(size['height'], height, "Window height should not have changed")

View File

@ -120,5 +120,7 @@ browser = false
[test_click_scrolling.py]
[test_profile_management.py]
b2g = false
[test_set_window_size.py]
b2g = false
[include:oop/manifest.ini]

View File

@ -2353,6 +2353,59 @@ MarionetteServerConnection.prototype = {
this.sendOk(this.command_id);
},
/**
* Get the size of the browser window currently in focus.
*
* Will return the current browser window size in pixels. Refers to
* window outerWidth and outerHeight values, which include scroll bars,
* title bars, etc.
*
*/
getWindowSize: function MDA_getWindowSize(aRequest) {
this.command_id = this.getCommandId();
let curWindow = this.getCurrentWindow();
let curWidth = curWindow.outerWidth;
let curHeight = curWindow.outerHeight;
this.sendResponse({width: curWidth, height: curHeight}, this.command_id);
},
/**
* Set the size of the browser window currently in focus.
*
* Not supported on B2G. The supplied width and height values refer to
* the window outerWidth and outerHeight values, which include scroll
* bars, title bars, etc.
*
* An error will be returned if the requested window size would result
* in the window being in the maximized state.
*/
setWindowSize: function MDA_setWindowSize(aRequest) {
this.command_id = this.getCommandId();
if (appName == "B2G") {
this.sendError("Not supported on B2G", 405, null, this.command_id);
return;
}
try {
var width = parseInt(aRequest.parameters.width);
var height = parseInt(aRequest.parameters.height);
}
catch(e) {
this.sendError(e.message, e.code, e.stack, this.command_id);
return;
}
let curWindow = this.getCurrentWindow();
if (width >= curWindow.screen.availWidth && height >= curWindow.screen.availHeight) {
this.sendError("Invalid requested size, cannot maximize", 405, null, this.command_id);
return;
}
curWindow.resizeTo(width, height);
this.sendOk(this.command_id);
},
/**
* Helper function to convert an outerWindowID into a UID that Marionette
* tracks.
@ -2558,7 +2611,9 @@ MarionetteServerConnection.prototype.requestTypes = {
"deleteCookie": MarionetteServerConnection.prototype.deleteCookie,
"getActiveElement": MarionetteServerConnection.prototype.getActiveElement,
"getScreenOrientation": MarionetteServerConnection.prototype.getScreenOrientation,
"setScreenOrientation": MarionetteServerConnection.prototype.setScreenOrientation
"setScreenOrientation": MarionetteServerConnection.prototype.setScreenOrientation,
"getWindowSize": MarionetteServerConnection.prototype.getWindowSize,
"setWindowSize": MarionetteServerConnection.prototype.setWindowSize
};
/**

View File

@ -254,19 +254,13 @@ Submitter.prototype = {
}
let serverURL = this.extraKeyVals.ServerURL;
// Override the submission URL from the environment or prefs.
// Override the submission URL from the environment
var envOverride = Cc['@mozilla.org/process/environment;1'].
getService(Ci.nsIEnvironment).get("MOZ_CRASHREPORTER_URL");
if (envOverride != '') {
serverURL = envOverride;
}
else if ('PluginHang' in this.extraKeyVals) {
try {
serverURL = Services.prefs.
getCharPref("toolkit.crashreporter.pluginHangSubmitURL");
} catch(e) { }
}
let xhr = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"]
.createInstance(Ci.nsIXMLHttpRequest);

View File

@ -193,8 +193,8 @@ Connection.prototype = {
return;
}
if (!this._client) {
this._transport = transport;
if (this._transport) {
this._customTransport = transport;
if (this._customTransport) {
this.log("connecting (custom transport)");
} else {
this.log("connecting to " + this.host + ":" + this.port);
@ -223,12 +223,15 @@ Connection.prototype = {
},
_clientConnect: function () {
if (!this._transport) {
let transport;
if (this._customTransport) {
transport = this._customTransport;
} else {
if (!this.host) {
this._transport = DebuggerServer.connectPipe();
transport = DebuggerServer.connectPipe();
} else {
try {
this._transport = debuggerSocketConnect(this.host, this.port);
transport = debuggerSocketConnect(this.host, this.port);
} catch (e) {
// In some cases, especially on Mac, the openOutputStream call in
// debuggerSocketConnect may throw NS_ERROR_NOT_INITIALIZED.
@ -240,7 +243,7 @@ Connection.prototype = {
}
}
}
this._client = new DebuggerClient(this._transport);
this._client = new DebuggerClient(transport);
this._client.addOneTimeListener("closed", this._onDisconnected);
this._client.connect(this._onConnected);
},
@ -259,6 +262,7 @@ Connection.prototype = {
_onDisconnected: function() {
this._client = null;
this._customTransport = null;
if (this._status == Connection.Status.CONNECTING && this.keepConnecting) {
setTimeout(() => this._clientConnect(), 100);

View File

@ -37,8 +37,8 @@ public:
protected:
nsresult RegisterForSleepWakeNotifcations();
void RemoveSleepWakeNotifcations();
nsresult RegisterForSleepWakeNotifications();
void RemoveSleepWakeNotifications();
protected:

View File

@ -48,13 +48,13 @@ nsToolkit::nsToolkit()
, mEventTapRLS(nullptr)
{
MOZ_COUNT_CTOR(nsToolkit);
RegisterForSleepWakeNotifcations();
RegisterForSleepWakeNotifications();
}
nsToolkit::~nsToolkit()
{
MOZ_COUNT_DTOR(nsToolkit);
RemoveSleepWakeNotifcations();
RemoveSleepWakeNotifications();
UnregisterAllProcessMouseEventHandlers();
}
@ -98,7 +98,7 @@ static void ToolkitSleepWakeCallback(void *refCon, io_service_t service, natural
}
nsresult
nsToolkit::RegisterForSleepWakeNotifcations()
nsToolkit::RegisterForSleepWakeNotifications()
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
@ -123,7 +123,7 @@ nsToolkit::RegisterForSleepWakeNotifcations()
}
void
nsToolkit::RemoveSleepWakeNotifcations()
nsToolkit::RemoveSleepWakeNotifications()
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;

View File

@ -63,7 +63,7 @@
COMPONENT(VARIANT, nsVariantConstructor)
COMPONENT(INTERFACEINFOMANAGER_SERVICE, nsXPTIInterfaceInfoManagerGetSingleton)
COMPONENT(HASH_PROPERTY_BAG, nsHashPropertyBagConstructor)
COMPONENT(HASH_PROPERTY_BAG, nsHashPropertyBagCCConstructor)
COMPONENT(UUID_GENERATOR, nsUUIDGeneratorConstructor)

View File

@ -215,7 +215,7 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(VisualEventTracer)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsVariant)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsHashPropertyBag)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsHashPropertyBagCC)
NS_GENERIC_AGGREGATED_CONSTRUCTOR(nsProperties)

View File

@ -1,5 +1,5 @@
/* -*- Mode: C++; tab-width: 50; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* vim:set ts=4 sw=4 sts=4: */
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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/. */
@ -12,37 +12,19 @@
#include "nsVariant.h"
#include "mozilla/Attributes.h"
nsresult
NS_NewHashPropertyBag(nsIWritablePropertyBag** aResult)
{
nsRefPtr<nsHashPropertyBag> hpb = new nsHashPropertyBag();
hpb.forget(aResult);
return NS_OK;
}
/*
* nsHashPropertyBag impl
* nsHashPropertyBagBase implementation.
*/
NS_IMPL_ADDREF(nsHashPropertyBag)
NS_IMPL_RELEASE(nsHashPropertyBag)
NS_INTERFACE_MAP_BEGIN(nsHashPropertyBag)
NS_INTERFACE_MAP_ENTRY(nsIWritablePropertyBag)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsIPropertyBag, nsIWritablePropertyBag)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIWritablePropertyBag)
NS_INTERFACE_MAP_ENTRY(nsIPropertyBag2)
NS_INTERFACE_MAP_ENTRY(nsIWritablePropertyBag2)
NS_INTERFACE_MAP_END
NS_IMETHODIMP
nsHashPropertyBag::HasKey(const nsAString& aName, bool* aResult)
nsHashPropertyBagBase::HasKey(const nsAString& aName, bool* aResult)
{
*aResult = mPropertyHash.Get(aName, nullptr);
return NS_OK;
}
NS_IMETHODIMP
nsHashPropertyBag::Get(const nsAString& aName, nsIVariant** aResult)
nsHashPropertyBagBase::Get(const nsAString& aName, nsIVariant** aResult)
{
if (!mPropertyHash.Get(aName, aResult)) {
*aResult = nullptr;
@ -52,7 +34,7 @@ nsHashPropertyBag::Get(const nsAString& aName, nsIVariant** aResult)
}
NS_IMETHODIMP
nsHashPropertyBag::GetProperty(const nsAString& aName, nsIVariant** aResult)
nsHashPropertyBagBase::GetProperty(const nsAString& aName, nsIVariant** aResult)
{
bool isFound = mPropertyHash.Get(aName, aResult);
if (!isFound) {
@ -63,7 +45,7 @@ nsHashPropertyBag::GetProperty(const nsAString& aName, nsIVariant** aResult)
}
NS_IMETHODIMP
nsHashPropertyBag::SetProperty(const nsAString& aName, nsIVariant* aValue)
nsHashPropertyBagBase::SetProperty(const nsAString& aName, nsIVariant* aValue)
{
if (NS_WARN_IF(!aValue)) {
return NS_ERROR_INVALID_ARG;
@ -75,7 +57,7 @@ nsHashPropertyBag::SetProperty(const nsAString& aName, nsIVariant* aValue)
}
NS_IMETHODIMP
nsHashPropertyBag::DeleteProperty(const nsAString& aName)
nsHashPropertyBagBase::DeleteProperty(const nsAString& aName)
{
// is it too much to ask for ns*Hashtable to return
// a boolean indicating whether RemoveEntry succeeded
@ -145,7 +127,7 @@ PropertyHashToArrayFunc(const nsAString& aKey,
NS_IMETHODIMP
nsHashPropertyBag::GetEnumerator(nsISimpleEnumerator** aResult)
nsHashPropertyBagBase::GetEnumerator(nsISimpleEnumerator** aResult)
{
nsCOMPtr<nsIMutableArray> propertyArray = nsArray::Create();
if (!propertyArray) {
@ -159,7 +141,7 @@ nsHashPropertyBag::GetEnumerator(nsISimpleEnumerator** aResult)
#define IMPL_GETSETPROPERTY_AS(Name, Type) \
NS_IMETHODIMP \
nsHashPropertyBag::GetPropertyAs ## Name (const nsAString & prop, Type *_retval) \
nsHashPropertyBagBase::GetPropertyAs ## Name (const nsAString & prop, Type *_retval) \
{ \
nsIVariant* v = mPropertyHash.GetWeak(prop); \
if (!v) \
@ -168,7 +150,7 @@ nsHashPropertyBag::GetPropertyAs ## Name (const nsAString & prop, Type *_retval)
} \
\
NS_IMETHODIMP \
nsHashPropertyBag::SetPropertyAs ## Name (const nsAString & prop, Type value) \
nsHashPropertyBagBase::SetPropertyAs ## Name (const nsAString & prop, Type value) \
{ \
nsCOMPtr<nsIWritableVariant> var = new nsVariant(); \
var->SetAs ## Name(value); \
@ -184,7 +166,7 @@ IMPL_GETSETPROPERTY_AS(Bool, bool)
NS_IMETHODIMP
nsHashPropertyBag::GetPropertyAsAString(const nsAString& aProp,
nsHashPropertyBagBase::GetPropertyAsAString(const nsAString& aProp,
nsAString& aResult)
{
nsIVariant* v = mPropertyHash.GetWeak(aProp);
@ -195,7 +177,7 @@ nsHashPropertyBag::GetPropertyAsAString(const nsAString& aProp,
}
NS_IMETHODIMP
nsHashPropertyBag::GetPropertyAsACString(const nsAString& aProp,
nsHashPropertyBagBase::GetPropertyAsACString(const nsAString& aProp,
nsACString& aResult)
{
nsIVariant* v = mPropertyHash.GetWeak(aProp);
@ -206,7 +188,7 @@ nsHashPropertyBag::GetPropertyAsACString(const nsAString& aProp,
}
NS_IMETHODIMP
nsHashPropertyBag::GetPropertyAsAUTF8String(const nsAString& aProp,
nsHashPropertyBagBase::GetPropertyAsAUTF8String(const nsAString& aProp,
nsACString& aResult)
{
nsIVariant* v = mPropertyHash.GetWeak(aProp);
@ -217,7 +199,7 @@ nsHashPropertyBag::GetPropertyAsAUTF8String(const nsAString& aProp,
}
NS_IMETHODIMP
nsHashPropertyBag::GetPropertyAsInterface(const nsAString& aProp,
nsHashPropertyBagBase::GetPropertyAsInterface(const nsAString& aProp,
const nsIID& aIID,
void** aResult)
{
@ -239,7 +221,7 @@ nsHashPropertyBag::GetPropertyAsInterface(const nsAString& aProp,
}
NS_IMETHODIMP
nsHashPropertyBag::SetPropertyAsAString(const nsAString& aProp,
nsHashPropertyBagBase::SetPropertyAsAString(const nsAString& aProp,
const nsAString& aValue)
{
nsCOMPtr<nsIWritableVariant> var = new nsVariant();
@ -248,7 +230,7 @@ nsHashPropertyBag::SetPropertyAsAString(const nsAString& aProp,
}
NS_IMETHODIMP
nsHashPropertyBag::SetPropertyAsACString(const nsAString& aProp,
nsHashPropertyBagBase::SetPropertyAsACString(const nsAString& aProp,
const nsACString& aValue)
{
nsCOMPtr<nsIWritableVariant> var = new nsVariant();
@ -257,7 +239,7 @@ nsHashPropertyBag::SetPropertyAsACString(const nsAString& aProp,
}
NS_IMETHODIMP
nsHashPropertyBag::SetPropertyAsAUTF8String(const nsAString& aProp,
nsHashPropertyBagBase::SetPropertyAsAUTF8String(const nsAString& aProp,
const nsACString& aValue)
{
nsCOMPtr<nsIWritableVariant> var = new nsVariant();
@ -266,7 +248,7 @@ nsHashPropertyBag::SetPropertyAsAUTF8String(const nsAString& aProp,
}
NS_IMETHODIMP
nsHashPropertyBag::SetPropertyAsInterface(const nsAString& aProp,
nsHashPropertyBagBase::SetPropertyAsInterface(const nsAString& aProp,
nsISupports* aValue)
{
nsCOMPtr<nsIWritableVariant> var = new nsVariant();
@ -274,3 +256,36 @@ nsHashPropertyBag::SetPropertyAsInterface(const nsAString& aProp,
return SetProperty(aProp, var);
}
/*
* nsHashPropertyBag implementation.
*/
NS_IMPL_ADDREF(nsHashPropertyBag)
NS_IMPL_RELEASE(nsHashPropertyBag)
NS_INTERFACE_MAP_BEGIN(nsHashPropertyBag)
NS_INTERFACE_MAP_ENTRY(nsIWritablePropertyBag)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsIPropertyBag, nsIWritablePropertyBag)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIWritablePropertyBag)
NS_INTERFACE_MAP_ENTRY(nsIPropertyBag2)
NS_INTERFACE_MAP_ENTRY(nsIWritablePropertyBag2)
NS_INTERFACE_MAP_END
/*
* nsHashPropertyBagCC implementation.
*/
NS_IMPL_CYCLE_COLLECTION(nsHashPropertyBagCC, mPropertyHash)
NS_IMPL_CYCLE_COLLECTING_ADDREF(nsHashPropertyBagCC)
NS_IMPL_CYCLE_COLLECTING_RELEASE(nsHashPropertyBagCC)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsHashPropertyBagCC)
NS_INTERFACE_MAP_ENTRY(nsIWritablePropertyBag)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsIPropertyBag, nsIWritablePropertyBag)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIWritablePropertyBag)
NS_INTERFACE_MAP_ENTRY(nsIPropertyBag2)
NS_INTERFACE_MAP_ENTRY(nsIWritablePropertyBag2)
NS_INTERFACE_MAP_END

View File

@ -1,4 +1,5 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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/. */
@ -9,16 +10,16 @@
#include "nsIVariant.h"
#include "nsIWritablePropertyBag.h"
#include "nsIWritablePropertyBag2.h"
#include "nsCycleCollectionParticipant.h"
#include "nsInterfaceHashtable.h"
class nsHashPropertyBag
class nsHashPropertyBagBase
: public nsIWritablePropertyBag
, public nsIWritablePropertyBag2
{
public:
nsHashPropertyBag() {}
NS_DECL_THREADSAFE_ISUPPORTS
nsHashPropertyBagBase() {}
NS_DECL_NSIPROPERTYBAG
NS_DECL_NSIPROPERTYBAG2
@ -29,12 +30,28 @@ public:
protected:
// a hash table of string -> nsIVariant
nsInterfaceHashtable<nsStringHashKey, nsIVariant> mPropertyHash;
};
class nsHashPropertyBag : public nsHashPropertyBagBase
{
public:
nsHashPropertyBag() {}
NS_DECL_THREADSAFE_ISUPPORTS
protected:
virtual ~nsHashPropertyBag() {}
};
// Note: NS_NewHashPropertyBag returns a HPB that
// uses a non-thread-safe internal hash
extern "C" nsresult NS_NewHashPropertyBag(nsIWritablePropertyBag** aResult);
/* A cycle collected nsHashPropertyBag for main-thread-only use. */
class nsHashPropertyBagCC MOZ_FINAL : public nsHashPropertyBagBase
{
public:
nsHashPropertyBagCC() {}
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsHashPropertyBagCC,
nsIWritablePropertyBag)
protected:
virtual ~nsHashPropertyBagCC() {}
};
#endif /* nsHashPropertyBag_h___ */