mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-18 15:55:36 +00:00
Merge m-c to b2g-inbound. a=merge
This commit is contained in:
commit
009f956da2
@ -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,
|
||||
|
@ -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>
|
||||
|
@ -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
|
||||
|
@ -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");
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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):
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
|
@ -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:
|
||||
|
@ -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):
|
||||
|
@ -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
|
||||
|
||||
|
@ -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()
|
||||
|
@ -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&);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
@ -157,6 +157,7 @@ statePressed = pressed
|
||||
stateExpanded = expanded
|
||||
stateCollapsed = collapsed
|
||||
stateUnavailable = unavailable
|
||||
stateReadonly = readonly
|
||||
stateRequired = required
|
||||
stateTraversed = visited
|
||||
stateHasPopup = has pop up
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
};
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
21
mobile/android/base/GeckoEditableClient.java
Normal file
21
mobile/android/base/GeckoEditableClient.java
Normal 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);
|
||||
}
|
30
mobile/android/base/GeckoEditableListener.java
Normal file
30
mobile/android/base/GeckoEditableListener.java
Normal 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);
|
||||
}
|
@ -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 =
|
||||
|
22
mobile/android/base/GeckoMediaPlayer.java
Normal file
22
mobile/android/base/GeckoMediaPlayer.java
Normal 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);
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
*/
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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>
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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),
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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']:
|
||||
|
@ -192,4 +192,9 @@ public class CollectionKeys {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return super.hashCode();
|
||||
}
|
||||
}
|
||||
|
@ -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)) {
|
||||
|
@ -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.
|
||||
|
@ -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>
|
||||
|
@ -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')
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
@ -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;
|
@ -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;
|
||||
|
@ -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;
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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>();
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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="
|
||||
]
|
||||
}
|
||||
|
@ -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 ] =
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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")
|
@ -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]
|
||||
|
@ -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
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -37,8 +37,8 @@ public:
|
||||
|
||||
protected:
|
||||
|
||||
nsresult RegisterForSleepWakeNotifcations();
|
||||
void RemoveSleepWakeNotifcations();
|
||||
nsresult RegisterForSleepWakeNotifications();
|
||||
void RemoveSleepWakeNotifications();
|
||||
|
||||
protected:
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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
|
||||
|
@ -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___ */
|
||||
|
Loading…
Reference in New Issue
Block a user