mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-15 06:15:43 +00:00
Merge last PGO-green changeset of mozilla-inbound to mozilla-central
This commit is contained in:
commit
af790907dd
@ -51,16 +51,7 @@ DeviceRootActor.prototype.disconnect = function DRA_disconnect() {
|
||||
* until at least the next listTabs request.
|
||||
*/
|
||||
DeviceRootActor.prototype.onListTabs = function DRA_onListTabs() {
|
||||
let actor = this._tabActors.get(this.browser);
|
||||
if (!actor) {
|
||||
actor = new DeviceTabActor(this.conn, this.browser);
|
||||
// this.actorID is set by ActorPool when an actor is put into one.
|
||||
actor.parentID = this.actorID;
|
||||
this._tabActors.set(this.browser, actor);
|
||||
}
|
||||
|
||||
let actorPool = new ActorPool(this.conn);
|
||||
actorPool.addActor(actor);
|
||||
|
||||
this._createExtraActors(DebuggerServer.globalActorFactories, actorPool);
|
||||
|
||||
@ -75,7 +66,7 @@ DeviceRootActor.prototype.onListTabs = function DRA_onListTabs() {
|
||||
let response = {
|
||||
'from': 'root',
|
||||
'selected': 0,
|
||||
'tabs': [actor.grip()]
|
||||
'tabs': []
|
||||
};
|
||||
this._appendExtraActors(response);
|
||||
return response;
|
||||
|
@ -457,13 +457,11 @@ function getJSON(element) {
|
||||
|
||||
// Until the input type=date/datetime/time have been implemented
|
||||
// let's return their real type even if the platform returns 'text'
|
||||
// Related to Bug 777279 - Implement <input type=time>
|
||||
let attributeType = element.getAttribute("type") || "";
|
||||
|
||||
if (attributeType) {
|
||||
var typeLowerCase = attributeType.toLowerCase();
|
||||
switch (typeLowerCase) {
|
||||
case "time":
|
||||
case "datetime":
|
||||
case "datetime-local":
|
||||
type = typeLowerCase;
|
||||
|
@ -203,7 +203,7 @@ SettingsListener.observe('devtools.debugger.remote-enabled', false, function(val
|
||||
Services.prefs.setBoolPref('devtools.debugger.remote-enabled', value);
|
||||
// This preference is consulted during startup
|
||||
Services.prefs.savePrefFile(null);
|
||||
value ? startDebugger() : stopDebugger();
|
||||
value ? RemoteDebugger.start() : RemoteDebugger.stop();
|
||||
});
|
||||
|
||||
SettingsListener.observe('debug.log-animations.enabled', false, function(value) {
|
||||
|
@ -269,6 +269,7 @@ var shell = {
|
||||
WebappsHelper.init();
|
||||
AccessFu.attach(window);
|
||||
UserAgentOverrides.init();
|
||||
IndexedDBPromptHelper.init();
|
||||
|
||||
// XXX could factor out into a settings->pref map. Not worth it yet.
|
||||
SettingsListener.observe("debug.fps.enabled", false, function(value) {
|
||||
@ -306,6 +307,7 @@ var shell = {
|
||||
delete Services.audioManager;
|
||||
#endif
|
||||
UserAgentOverrides.uninit();
|
||||
IndexedDBPromptHelper.uninit();
|
||||
},
|
||||
|
||||
// If this key event actually represents a hardware button, filter it here
|
||||
@ -625,6 +627,9 @@ var CustomEventManager = {
|
||||
case 'system-message-listener-ready':
|
||||
Services.obs.notifyObservers(null, 'system-message-listener-ready', null);
|
||||
break;
|
||||
case 'remote-debugger-prompt':
|
||||
RemoteDebugger.handleEvent(detail);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -833,32 +838,87 @@ var WebappsHelper = {
|
||||
}
|
||||
}
|
||||
|
||||
// Start the debugger server.
|
||||
function startDebugger() {
|
||||
if (!DebuggerServer.initialized) {
|
||||
// Allow remote connections.
|
||||
DebuggerServer.init(function () { return true; });
|
||||
DebuggerServer.addBrowserActors();
|
||||
DebuggerServer.addActors('chrome://browser/content/dbg-browser-actors.js');
|
||||
}
|
||||
let IndexedDBPromptHelper = {
|
||||
_quotaPrompt: "indexedDB-quota-prompt",
|
||||
_quotaResponse: "indexedDB-quota-response",
|
||||
|
||||
let port = Services.prefs.getIntPref('devtools.debugger.remote-port') || 6000;
|
||||
try {
|
||||
DebuggerServer.openListener(port);
|
||||
} catch (e) {
|
||||
dump('Unable to start debugger server: ' + e + '\n');
|
||||
init:
|
||||
function IndexedDBPromptHelper_init() {
|
||||
Services.obs.addObserver(this, this._quotaPrompt, false);
|
||||
},
|
||||
|
||||
uninit:
|
||||
function IndexedDBPromptHelper_uninit() {
|
||||
Services.obs.removeObserver(this, this._quotaPrompt, false);
|
||||
},
|
||||
|
||||
observe:
|
||||
function IndexedDBPromptHelper_observe(subject, topic, data) {
|
||||
if (topic != this._quotaPrompt) {
|
||||
throw new Error("Unexpected topic!");
|
||||
}
|
||||
|
||||
let observer = subject.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIObserver);
|
||||
let responseTopic = this._quotaResponse;
|
||||
|
||||
setTimeout(function() {
|
||||
observer.observe(null, responseTopic,
|
||||
Ci.nsIPermissionManager.DENY_ACTION);
|
||||
}, 0);
|
||||
}
|
||||
}
|
||||
|
||||
function stopDebugger() {
|
||||
if (!DebuggerServer.initialized) {
|
||||
return;
|
||||
}
|
||||
let RemoteDebugger = {
|
||||
_promptDone: false,
|
||||
_promptAnswer: false,
|
||||
|
||||
try {
|
||||
DebuggerServer.closeListener();
|
||||
} catch (e) {
|
||||
dump('Unable to stop debugger server: ' + e + '\n');
|
||||
prompt: function debugger_prompt() {
|
||||
this._promptDone = false;
|
||||
|
||||
shell.sendChromeEvent({
|
||||
"type": "remote-debugger-prompt"
|
||||
});
|
||||
|
||||
while(!this._promptDone) {
|
||||
Services.tm.currentThread.processNextEvent(true);
|
||||
}
|
||||
|
||||
return this._promptAnswer;
|
||||
},
|
||||
|
||||
handleEvent: function debugger_handleEvent(detail) {
|
||||
this._promptAnswer = detail.value;
|
||||
this._promptDone = true;
|
||||
},
|
||||
|
||||
// Start the debugger server.
|
||||
start: function debugger_start() {
|
||||
if (!DebuggerServer.initialized) {
|
||||
// Ask for remote connections.
|
||||
DebuggerServer.init(this.prompt.bind(this));
|
||||
DebuggerServer.addBrowserActors();
|
||||
DebuggerServer.addActors('chrome://browser/content/dbg-browser-actors.js');
|
||||
}
|
||||
|
||||
let port = Services.prefs.getIntPref('devtools.debugger.remote-port') || 6000;
|
||||
try {
|
||||
DebuggerServer.openListener(port);
|
||||
} catch (e) {
|
||||
dump('Unable to start debugger server: ' + e + '\n');
|
||||
}
|
||||
},
|
||||
|
||||
stop: function debugger_stop() {
|
||||
if (!DebuggerServer.initialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
DebuggerServer.closeListener();
|
||||
} catch (e) {
|
||||
dump('Unable to stop debugger server: ' + e + '\n');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -148,9 +148,10 @@ ContentPermissionPrompt.prototype = {
|
||||
|
||||
let principal = request.principal;
|
||||
let isApp = principal.appStatus != Ci.nsIPrincipal.APP_STATUS_NOT_INSTALLED;
|
||||
let remember = principal.appStatus == Ci.nsIPrincipal.APP_STATUS_PRIVILEGED
|
||||
? true
|
||||
: request.remember;
|
||||
let remember = (principal.appStatus == Ci.nsIPrincipal.APP_STATUS_PRIVILEGED ||
|
||||
principal.appStatus == Ci.nsIPrincipal.APP_STATUS_CERTIFIED)
|
||||
? true
|
||||
: request.remember;
|
||||
|
||||
let details = {
|
||||
type: "permission-prompt",
|
||||
|
@ -114,20 +114,16 @@ DownloadElementShell.prototype = {
|
||||
this._dataItem = aValue;
|
||||
if (this._dataItem) {
|
||||
this._active = true;
|
||||
this._wasDone = this._dataItem.done;
|
||||
this._wasInProgress = this._dataItem.inProgress;
|
||||
this._targetFileInfoFetched = false;
|
||||
this._fetchTargetFileInfo();
|
||||
}
|
||||
else if (this._placesNode) {
|
||||
this._wasInProgress = false;
|
||||
this._wasDone = this.getDownloadState(true) == nsIDM.DOWNLOAD_FINISHED;
|
||||
this._targetFileInfoFetched = false;
|
||||
if (this.active)
|
||||
this._fetchTargetFileInfo();
|
||||
}
|
||||
|
||||
it (this.active)
|
||||
if (this.active)
|
||||
this._updateStatusUI();
|
||||
return aValue;
|
||||
},
|
||||
@ -146,8 +142,6 @@ DownloadElementShell.prototype = {
|
||||
// We don't need to update the UI if we had a data item, because
|
||||
// the places information isn't used in this case.
|
||||
if (!this._dataItem && this._placesNode) {
|
||||
this._wasInProgress = false;
|
||||
this._wasDone = this.getDownloadState(true) == nsIDM.DOWNLOAD_FINISHED;
|
||||
this._targetFileInfoFetched = false;
|
||||
if (this.active) {
|
||||
this._updateStatusUI();
|
||||
@ -471,8 +465,9 @@ DownloadElementShell.prototype = {
|
||||
},
|
||||
|
||||
/* DownloadView */
|
||||
onStateChange: function DES_onStateChange() {
|
||||
if (!this._wasDone && this._dataItem.done) {
|
||||
onStateChange: function DES_onStateChange(aOldState) {
|
||||
if (aOldState != nsIDM.DOWNLOAD_FINISHED &&
|
||||
aOldState != this.dataItem.state) {
|
||||
// See comment in DVI_onStateChange in downloads.js (the panel-view)
|
||||
this._element.setAttribute("image", this._icon + "&state=normal");
|
||||
|
||||
@ -481,16 +476,6 @@ DownloadElementShell.prototype = {
|
||||
this._fetchTargetFileInfo();
|
||||
}
|
||||
|
||||
this._wasDone = this._dataItem.done;
|
||||
|
||||
// Update the end time using the current time if required.
|
||||
if (this._wasInProgress && !this._dataItem.inProgress) {
|
||||
this._endTime = Date.now();
|
||||
}
|
||||
|
||||
this._wasDone = this._dataItem.done;
|
||||
this._wasInProgress = this._dataItem.inProgress;
|
||||
|
||||
this._updateDownloadStatusUI();
|
||||
if (this._element.selected)
|
||||
goUpdateDownloadCommands();
|
||||
|
@ -856,8 +856,6 @@ function DownloadsViewItem(aDataItem, aElement)
|
||||
this._element = aElement;
|
||||
this.dataItem = aDataItem;
|
||||
|
||||
this.wasDone = this.dataItem.done;
|
||||
this.wasInProgress = this.dataItem.inProgress;
|
||||
this.lastEstimatedSecondsLeft = Infinity;
|
||||
|
||||
// Set the URI that represents the correct icon for the target file. As soon
|
||||
@ -910,7 +908,7 @@ DownloadsViewItem.prototype = {
|
||||
* the download might be the same as before, if the data layer received
|
||||
* multiple events for the same download.
|
||||
*/
|
||||
onStateChange: function DVI_onStateChange()
|
||||
onStateChange: function DVI_onStateChange(aOldState)
|
||||
{
|
||||
// If a download just finished successfully, it means that the target file
|
||||
// now exists and we can extract its specific icon. To ensure that the icon
|
||||
@ -918,18 +916,11 @@ DownloadsViewItem.prototype = {
|
||||
// example by adding a query parameter. Since this URI has a "moz-icon"
|
||||
// scheme, this only works if we add one of the parameters explicitly
|
||||
// supported by the nsIMozIconURI interface.
|
||||
if (!this.wasDone && this.dataItem.openable) {
|
||||
if (aOldState != Ci.nsIDownloadManager.DOWNLOAD_FINISHED &&
|
||||
aOldState != this.dataItem.state) {
|
||||
this._element.setAttribute("image", this.image + "&state=normal");
|
||||
}
|
||||
|
||||
// Update the end time using the current time if required.
|
||||
if (this.wasInProgress && !this.dataItem.inProgress) {
|
||||
this.endTime = Date.now();
|
||||
}
|
||||
|
||||
this.wasDone = this.dataItem.done;
|
||||
this.wasInProgress = this.dataItem.inProgress;
|
||||
|
||||
// Update the user interface after switching states.
|
||||
this._element.setAttribute("state", this.dataItem.state);
|
||||
this._updateProgress();
|
||||
|
@ -941,7 +941,7 @@ DownloadsDataCtor.prototype = {
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//// nsIDownloadProgressListener
|
||||
|
||||
onDownloadStateChange: function DD_onDownloadStateChange(aState, aDownload)
|
||||
onDownloadStateChange: function DD_onDownloadStateChange(aOldState, aDownload)
|
||||
{
|
||||
#ifdef MOZ_PER_WINDOW_PRIVATE_BROWSING
|
||||
if (aDownload.isPrivate != this._isPrivate) {
|
||||
@ -954,14 +954,16 @@ DownloadsDataCtor.prototype = {
|
||||
// When a new download is added, it may have the same identifier of a
|
||||
// download that we previously deleted during this session, and we also
|
||||
// want to provide a visible indication that the download started.
|
||||
let isNew = aState == nsIDM.DOWNLOAD_NOTSTARTED ||
|
||||
aState == nsIDM.DOWNLOAD_QUEUED;
|
||||
let isNew = aOldState == nsIDM.DOWNLOAD_NOTSTARTED ||
|
||||
aOldState == nsIDM.DOWNLOAD_QUEUED;
|
||||
|
||||
let dataItem = this._getOrAddDataItem(aDownload, isNew);
|
||||
if (!dataItem) {
|
||||
return;
|
||||
}
|
||||
|
||||
let wasInProgress = dataItem.inProgress;
|
||||
|
||||
dataItem.state = aDownload.state;
|
||||
dataItem.referrer = aDownload.referrer && aDownload.referrer.spec;
|
||||
dataItem.resumable = aDownload.resumable;
|
||||
@ -969,6 +971,10 @@ DownloadsDataCtor.prototype = {
|
||||
dataItem.currBytes = aDownload.amountTransferred;
|
||||
dataItem.maxBytes = aDownload.size;
|
||||
|
||||
if (wasInProgress && !dataItem.inProgress) {
|
||||
dataItem.endTime = Date.now();
|
||||
}
|
||||
|
||||
// When a download is retried, we create a different download object from
|
||||
// the database with the same ID as before. This means that the nsIDownload
|
||||
// that the dataItem holds might now need updating.
|
||||
@ -981,7 +987,7 @@ DownloadsDataCtor.prototype = {
|
||||
}
|
||||
|
||||
this._views.forEach(
|
||||
function (view) view.getViewItem(dataItem).onStateChange()
|
||||
function (view) view.getViewItem(dataItem).onStateChange(aOldState)
|
||||
);
|
||||
|
||||
if (isNew && !dataItem.newDownloadNotified) {
|
||||
@ -1729,7 +1735,7 @@ DownloadsIndicatorDataCtor.prototype = {
|
||||
let data = this._isPrivate ? PrivateDownloadsIndicatorData
|
||||
: DownloadsIndicatorData;
|
||||
return Object.freeze({
|
||||
onStateChange: function DIVI_onStateChange()
|
||||
onStateChange: function DIVI_onStateChange(aOldState)
|
||||
{
|
||||
if (aDataItem.state == nsIDM.DOWNLOAD_FINISHED ||
|
||||
aDataItem.state == nsIDM.DOWNLOAD_FAILED) {
|
||||
@ -2004,7 +2010,7 @@ DownloadsSummaryData.prototype = {
|
||||
{
|
||||
let self = this;
|
||||
return Object.freeze({
|
||||
onStateChange: function DIVI_onStateChange()
|
||||
onStateChange: function DIVI_onStateChange(aOldState)
|
||||
{
|
||||
// Since the state of a download changed, reset the estimated time left.
|
||||
self._lastRawTimeLeft = -1;
|
||||
|
@ -1896,6 +1896,7 @@ nsEventStateManager::FireContextClick()
|
||||
type == NS_FORM_INPUT_FILE ||
|
||||
type == NS_FORM_INPUT_NUMBER ||
|
||||
type == NS_FORM_INPUT_DATE ||
|
||||
type == NS_FORM_INPUT_TIME ||
|
||||
type == NS_FORM_TEXTAREA);
|
||||
}
|
||||
else if (tag == nsGkAtoms::applet ||
|
||||
|
@ -61,6 +61,7 @@ enum InputElementTypes {
|
||||
NS_FORM_INPUT_SUBMIT,
|
||||
NS_FORM_INPUT_TEL,
|
||||
NS_FORM_INPUT_TEXT,
|
||||
NS_FORM_INPUT_TIME,
|
||||
NS_FORM_INPUT_URL,
|
||||
eInputElementTypesMax
|
||||
};
|
||||
@ -237,8 +238,9 @@ nsIFormControl::IsSingleLineTextControl(bool aExcludePassword, uint32_t aType)
|
||||
aType == NS_FORM_INPUT_URL ||
|
||||
// TODO: this is temporary until bug 635240 is fixed.
|
||||
aType == NS_FORM_INPUT_NUMBER ||
|
||||
// TODO: this is temporary until bug 773205 is fixed.
|
||||
// TODO: those are temporary until bug 773205 is fixed.
|
||||
aType == NS_FORM_INPUT_DATE ||
|
||||
aType == NS_FORM_INPUT_TIME ||
|
||||
(!aExcludePassword && aType == NS_FORM_INPUT_PASSWORD);
|
||||
}
|
||||
|
||||
|
@ -185,6 +185,7 @@ ShouldBeInElements(nsIFormControl* aFormControl)
|
||||
case NS_FORM_INPUT_URL :
|
||||
case NS_FORM_INPUT_NUMBER :
|
||||
case NS_FORM_INPUT_DATE :
|
||||
case NS_FORM_INPUT_TIME :
|
||||
case NS_FORM_SELECT :
|
||||
case NS_FORM_TEXTAREA :
|
||||
case NS_FORM_FIELDSET :
|
||||
|
@ -134,6 +134,7 @@ static const nsAttrValue::EnumTable kInputTypeTable[] = {
|
||||
{ "submit", NS_FORM_INPUT_SUBMIT },
|
||||
{ "tel", NS_FORM_INPUT_TEL },
|
||||
{ "text", NS_FORM_INPUT_TEXT },
|
||||
{ "time", NS_FORM_INPUT_TIME },
|
||||
{ "url", NS_FORM_INPUT_URL },
|
||||
{ 0 }
|
||||
};
|
||||
@ -704,6 +705,7 @@ nsHTMLInputElement::Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const
|
||||
case NS_FORM_INPUT_URL:
|
||||
case NS_FORM_INPUT_NUMBER:
|
||||
case NS_FORM_INPUT_DATE:
|
||||
case NS_FORM_INPUT_TIME:
|
||||
if (mValueChanged) {
|
||||
// We don't have our default value anymore. Set our value on
|
||||
// the clone.
|
||||
@ -1597,7 +1599,8 @@ NS_IMETHODIMP
|
||||
nsHTMLInputElement::MozIsTextField(bool aExcludePassword, bool* aResult)
|
||||
{
|
||||
// TODO: temporary until bug 635240 and 773205 are fixed.
|
||||
if (mType == NS_FORM_INPUT_NUMBER || mType == NS_FORM_INPUT_DATE) {
|
||||
if (mType == NS_FORM_INPUT_NUMBER || mType == NS_FORM_INPUT_DATE ||
|
||||
mType == NS_FORM_INPUT_TIME) {
|
||||
*aResult = false;
|
||||
return NS_OK;
|
||||
}
|
||||
@ -2690,6 +2693,7 @@ nsHTMLInputElement::PostHandleEvent(nsEventChainPostVisitor& aVisitor)
|
||||
keyEvent->keyCode == NS_VK_ENTER) &&
|
||||
(IsSingleLineTextControl(false, mType) ||
|
||||
mType == NS_FORM_INPUT_NUMBER ||
|
||||
mType == NS_FORM_INPUT_TIME ||
|
||||
mType == NS_FORM_INPUT_DATE)) {
|
||||
FireChangeEventIfNeeded();
|
||||
rv = MaybeSubmitForm(aVisitor.mPresContext);
|
||||
@ -3145,6 +3149,7 @@ nsHTMLInputElement::ParseAttribute(int32_t aNamespaceID,
|
||||
if (success) {
|
||||
newType = aResult.GetEnumValue();
|
||||
if ((newType == NS_FORM_INPUT_NUMBER ||
|
||||
newType == NS_FORM_INPUT_TIME ||
|
||||
newType == NS_FORM_INPUT_DATE) &&
|
||||
!Preferences::GetBool("dom.experimental_forms", false)) {
|
||||
newType = kInputDefaultType->value;
|
||||
@ -3772,6 +3777,7 @@ nsHTMLInputElement::SaveState()
|
||||
case NS_FORM_INPUT_HIDDEN:
|
||||
case NS_FORM_INPUT_NUMBER:
|
||||
case NS_FORM_INPUT_DATE:
|
||||
case NS_FORM_INPUT_TIME:
|
||||
{
|
||||
if (mValueChanged) {
|
||||
inputState = new nsHTMLInputElementState();
|
||||
@ -3957,6 +3963,7 @@ nsHTMLInputElement::RestoreState(nsPresState* aState)
|
||||
case NS_FORM_INPUT_HIDDEN:
|
||||
case NS_FORM_INPUT_NUMBER:
|
||||
case NS_FORM_INPUT_DATE:
|
||||
case NS_FORM_INPUT_TIME:
|
||||
{
|
||||
SetValueInternal(inputState->GetValue(), false, true);
|
||||
break;
|
||||
@ -4182,6 +4189,7 @@ nsHTMLInputElement::GetValueMode() const
|
||||
case NS_FORM_INPUT_URL:
|
||||
case NS_FORM_INPUT_NUMBER:
|
||||
case NS_FORM_INPUT_DATE:
|
||||
case NS_FORM_INPUT_TIME:
|
||||
return VALUE_MODE_VALUE;
|
||||
default:
|
||||
NS_NOTYETIMPLEMENTED("Unexpected input type in GetValueMode()");
|
||||
@ -4227,6 +4235,7 @@ nsHTMLInputElement::DoesReadOnlyApply() const
|
||||
case NS_FORM_INPUT_URL:
|
||||
case NS_FORM_INPUT_NUMBER:
|
||||
case NS_FORM_INPUT_DATE:
|
||||
case NS_FORM_INPUT_TIME:
|
||||
return true;
|
||||
default:
|
||||
NS_NOTYETIMPLEMENTED("Unexpected input type in DoesReadOnlyApply()");
|
||||
@ -4264,6 +4273,7 @@ nsHTMLInputElement::DoesRequiredApply() const
|
||||
case NS_FORM_INPUT_URL:
|
||||
case NS_FORM_INPUT_NUMBER:
|
||||
case NS_FORM_INPUT_DATE:
|
||||
case NS_FORM_INPUT_TIME:
|
||||
return true;
|
||||
default:
|
||||
NS_NOTYETIMPLEMENTED("Unexpected input type in DoesRequiredApply()");
|
||||
@ -4278,7 +4288,8 @@ nsHTMLInputElement::DoesRequiredApply() const
|
||||
bool
|
||||
nsHTMLInputElement::PlaceholderApplies() const
|
||||
{
|
||||
if (mType == NS_FORM_INPUT_DATE) {
|
||||
if (mType == NS_FORM_INPUT_DATE ||
|
||||
mType == NS_FORM_INPUT_TIME) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -4288,8 +4299,9 @@ nsHTMLInputElement::PlaceholderApplies() const
|
||||
bool
|
||||
nsHTMLInputElement::DoesPatternApply() const
|
||||
{
|
||||
// TODO: temporary until bug 635240 is fixed.
|
||||
if (mType == NS_FORM_INPUT_NUMBER || mType == NS_FORM_INPUT_DATE) {
|
||||
// TODO: temporary until bug 635240 and bug 773205 are fixed.
|
||||
if (mType == NS_FORM_INPUT_NUMBER || mType == NS_FORM_INPUT_DATE ||
|
||||
mType == NS_FORM_INPUT_TIME) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -4322,6 +4334,8 @@ nsHTMLInputElement::DoesMinMaxApply() const
|
||||
case NS_FORM_INPUT_TEL:
|
||||
case NS_FORM_INPUT_EMAIL:
|
||||
case NS_FORM_INPUT_URL:
|
||||
// TODO: temp until bug 781572 is fixed.
|
||||
case NS_FORM_INPUT_TIME:
|
||||
return false;
|
||||
default:
|
||||
NS_NOTYETIMPLEMENTED("Unexpected input type in DoesRequiredApply()");
|
||||
@ -4497,7 +4511,8 @@ nsHTMLInputElement::HasPatternMismatch() const
|
||||
bool
|
||||
nsHTMLInputElement::IsRangeOverflow() const
|
||||
{
|
||||
if (!DoesMinMaxApply()) {
|
||||
// Ignore type=time until bug 781572 is fixed.
|
||||
if (!DoesMinMaxApply() || mType == NS_FORM_INPUT_TIME) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -201,11 +201,11 @@ reflectLimitedEnumerated({
|
||||
attribute: "type",
|
||||
validValues: [ "hidden", "text", "search", "tel", "url", "email", "password",
|
||||
"checkbox", "radio", "file", "submit", "image", "reset",
|
||||
"button", "date", "number" ],
|
||||
"button", "date", "time", "number" ],
|
||||
invalidValues: [ "this-is-probably-a-wrong-type", "", "tulip" ],
|
||||
defaultValue: "text",
|
||||
unsupportedValues: [ "datetime", "month", "week", "time",
|
||||
"datetime-local", "range", "color" ]
|
||||
unsupportedValues: [ "datetime", "month", "week", "datetime-local",
|
||||
"range", "color" ]
|
||||
});
|
||||
|
||||
// .defaultValue
|
||||
|
@ -26,12 +26,13 @@ var inputTypes =
|
||||
[
|
||||
"text", "password", "search", "tel", "hidden", "checkbox", "radio",
|
||||
"submit", "image", "reset", "button", "email", "url", "number", "date",
|
||||
"time",
|
||||
];
|
||||
|
||||
var todoTypes =
|
||||
[
|
||||
"range", "color",
|
||||
"month", "week", "time", "datetime", "datetime-local",
|
||||
"month", "week", "datetime", "datetime-local",
|
||||
];
|
||||
|
||||
var valueModeValue =
|
||||
@ -121,9 +122,10 @@ function sanitizeValue(aType, aValue)
|
||||
return aValue.replace(/[\n\r]/g, "").replace(/^\s+|\s+$/g, "");
|
||||
case "date":
|
||||
return "";
|
||||
case "time":
|
||||
return "";
|
||||
case "month":
|
||||
case "week":
|
||||
case "time":
|
||||
case "datetime":
|
||||
case "datetime-local":
|
||||
// TODO: write the sanitize algorithm.
|
||||
@ -163,6 +165,11 @@ function checkSanitizing(element)
|
||||
"1.234567898765432",
|
||||
];
|
||||
|
||||
// TODO: temp
|
||||
if (element.type == 'time') {
|
||||
return;
|
||||
}
|
||||
|
||||
for (value of testData) {
|
||||
element.setAttribute('value', value);
|
||||
is(element.value, sanitizeValue(type, value),
|
||||
|
@ -31,7 +31,7 @@ var types = [
|
||||
[ 'date', true ],
|
||||
[ 'month', true, true ],
|
||||
[ 'week', true, true ],
|
||||
[ 'time', true, true ],
|
||||
[ 'time', true ],
|
||||
[ 'datetime-local', true, true ],
|
||||
[ 'number', true ],
|
||||
[ 'range', true, true ],
|
||||
@ -88,6 +88,10 @@ for (var data of types) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (input.type == 'time') {
|
||||
continue;
|
||||
}
|
||||
|
||||
checkValidity(input, true, apply, false);
|
||||
|
||||
if (input.type == 'date') {
|
||||
|
@ -31,7 +31,7 @@ var types = [
|
||||
[ 'date', true ],
|
||||
[ 'month', true, true ],
|
||||
[ 'week', true, true ],
|
||||
[ 'time', true, true ],
|
||||
[ 'time', true ],
|
||||
[ 'datetime-local', true, true ],
|
||||
[ 'number', true ],
|
||||
[ 'range', true, true ],
|
||||
@ -88,6 +88,10 @@ for (var data of types) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (input.type == 'time') {
|
||||
continue;
|
||||
}
|
||||
|
||||
checkValidity(input, true, apply, false);
|
||||
|
||||
if (input.type == 'date') {
|
||||
|
@ -49,6 +49,7 @@ var gInputTestData = [
|
||||
['url', true],
|
||||
['number', false],
|
||||
['date', false],
|
||||
['time', false],
|
||||
];
|
||||
|
||||
/**
|
||||
@ -62,7 +63,6 @@ var gInputTodoData = [
|
||||
['datetime', false],
|
||||
['month', false],
|
||||
['week', false],
|
||||
['time', false],
|
||||
['datetime-local', false],
|
||||
];
|
||||
|
||||
|
@ -261,10 +261,9 @@ var input = document.getElementById('i');
|
||||
// and |invalidTypes| are the ones which do not accept it.
|
||||
var validTypes = Array('text', 'password', 'search', 'tel', 'email', 'url');
|
||||
var barredTypes = Array('hidden', 'reset', 'button', 'submit', 'image');
|
||||
var invalidTypes = Array('checkbox', 'radio', 'file', 'number', 'date');
|
||||
// TODO: 'datetime', 'month', 'week', 'time', 'datetime-local',
|
||||
// 'range', and 'color' do not accept the @pattern too but are not
|
||||
// implemented yet.
|
||||
var invalidTypes = Array('checkbox', 'radio', 'file', 'number', 'date', 'time');
|
||||
// TODO: 'datetime', 'month', 'week', 'datetime-local', 'range' and 'color'
|
||||
// do not accept the @pattern too but are not implemented yet.
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
SpecialPowers.pushPrefEnv({'set': [["dom.experimental_forms", true]]}, function() {
|
||||
|
@ -166,6 +166,8 @@ function checkInputRequiredValidity(type)
|
||||
element.value = '42';
|
||||
} else if (element.type == 'date') {
|
||||
element.value = '2010-10-10';
|
||||
} else if (element.type == 'time') {
|
||||
element.value = '21:21';
|
||||
} else {
|
||||
element.value = 'foo';
|
||||
}
|
||||
@ -375,10 +377,10 @@ for (type of typeRequireNotApply) {
|
||||
}
|
||||
|
||||
// Now, checking for all types which accept the required attribute.
|
||||
// TODO: check 'datetime', 'month', 'week', 'time' and 'datetime-local'
|
||||
// TODO: check 'datetime', 'month', 'week' and 'datetime-local'
|
||||
// when they will be implemented.
|
||||
var typeRequireApply = ["text", "password", "search", "tel", "email", "url",
|
||||
"number", "date"];
|
||||
"number", "date", "time"];
|
||||
|
||||
for (type of typeRequireApply) {
|
||||
checkInputRequiredValidity(type);
|
||||
|
@ -31,7 +31,7 @@ var types = [
|
||||
[ 'date', true ],
|
||||
[ 'month', true, true ],
|
||||
[ 'week', true, true ],
|
||||
[ 'time', true, true ],
|
||||
[ 'time', true ],
|
||||
[ 'datetime-local', true, true ],
|
||||
[ 'number', true ],
|
||||
[ 'range', true, true ],
|
||||
@ -85,6 +85,10 @@ for (var data of types) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (input.type == 'time') {
|
||||
continue;
|
||||
}
|
||||
|
||||
checkValidity(input, true, apply);
|
||||
|
||||
input.step = '0';
|
||||
|
@ -36,11 +36,12 @@ var testData = [
|
||||
[ "password", true ],
|
||||
[ "number", true ],
|
||||
[ "date", true ],
|
||||
[ "time", true ],
|
||||
// 'file' is treated separatly.
|
||||
];
|
||||
|
||||
var todoTypes = [
|
||||
"datetime", "month", "week", "time", "datetime-local", "range", "color"
|
||||
"datetime", "month", "week", "datetime-local", "range", "color"
|
||||
];
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
@ -217,8 +217,8 @@ this.DOMApplicationRegistry = {
|
||||
});
|
||||
},
|
||||
|
||||
// Installs a 3rd party packaged app.
|
||||
installPreinstalledPackage: function installPreinstalledPackage(aId) {
|
||||
// Installs a 3rd party app.
|
||||
installPreinstalledApp: function installPreinstalledApp(aId) {
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
let app = this.webapps[aId];
|
||||
let baseDir;
|
||||
@ -229,30 +229,46 @@ this.DOMApplicationRegistry = {
|
||||
return;
|
||||
}
|
||||
|
||||
let filesToMove;
|
||||
let isPackage;
|
||||
|
||||
let updateFile = baseDir.clone();
|
||||
updateFile.append("update.webapp");
|
||||
if (!updateFile.exists()) {
|
||||
// The update manifest is missing, bail out.
|
||||
return;
|
||||
// The update manifest is missing, this is a hosted app only if there is
|
||||
// no application.zip
|
||||
let appFile = baseDir.clone();
|
||||
appFile.append("application.zip");
|
||||
if (appFile.exists()) {
|
||||
return;
|
||||
}
|
||||
|
||||
isPackage = false;
|
||||
filesToMove = ["manifest.webapp"];
|
||||
} else {
|
||||
isPackage = true;
|
||||
filesToMove = ["application.zip", "update.webapp"];
|
||||
}
|
||||
|
||||
debug("Installing 3rd party packaged app : " + aId +
|
||||
debug("Installing 3rd party app : " + aId +
|
||||
" from " + baseDir.path);
|
||||
|
||||
// We copy this app to DIRECTORY_NAME/$aId, and set the base path as needed.
|
||||
let destDir = FileUtils.getDir(DIRECTORY_NAME, ["webapps", aId], true, true);
|
||||
|
||||
["application.zip", "update.webapp"]
|
||||
.forEach(function(aFile) {
|
||||
filesToMove.forEach(function(aFile) {
|
||||
let file = baseDir.clone();
|
||||
file.append(aFile);
|
||||
file.copyTo(destDir, aFile);
|
||||
let newFile = destDir.clone();
|
||||
newFile.append(aFile);
|
||||
});
|
||||
|
||||
app.basePath = FileUtils.getDir(DIRECTORY_NAME, ["webapps"], true, true)
|
||||
.path;
|
||||
|
||||
if (!isPackage) {
|
||||
return;
|
||||
}
|
||||
|
||||
app.origin = "app://" + aId;
|
||||
app.removable = true;
|
||||
|
||||
@ -311,7 +327,7 @@ this.DOMApplicationRegistry = {
|
||||
let localId = this.webapps[id].localId;
|
||||
let permMgr = Cc["@mozilla.org/permissionmanager;1"]
|
||||
.getService(Ci.nsIPermissionManager);
|
||||
permMgr.RemovePermissionsForApp(localId);
|
||||
permMgr.RemovePermissionsForApp(localId, false);
|
||||
Services.cookies.removeCookiesForApp(localId, false);
|
||||
this._clearPrivateData(localId, false);
|
||||
}
|
||||
@ -384,7 +400,7 @@ this.DOMApplicationRegistry = {
|
||||
if (runUpdate) {
|
||||
// At first run, install preloaded apps and set up their permissions.
|
||||
for (let id in this.webapps) {
|
||||
this.installPreinstalledPackage(id);
|
||||
this.installPreinstalledApp(id);
|
||||
if (!this.webapps[id]) {
|
||||
continue;
|
||||
}
|
||||
@ -392,7 +408,7 @@ this.DOMApplicationRegistry = {
|
||||
this.updatePermissionsForApp(id);
|
||||
}
|
||||
// Need to update the persisted list of apps since
|
||||
// installPreinstalledPackage() removes the ones failing to install.
|
||||
// installPreinstalledApp() removes the ones failing to install.
|
||||
this._saveApps();
|
||||
}
|
||||
this.registerAppsHandlers(runUpdate);
|
||||
@ -1221,8 +1237,15 @@ this.DOMApplicationRegistry = {
|
||||
true);
|
||||
}
|
||||
|
||||
// For non-removable hosted apps, we just check the appcache.
|
||||
if (!app.removable) {
|
||||
// For non-removable hosted apps, we only check the appcache.
|
||||
let onlyCheckAppCache = false;
|
||||
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
let appDir = FileUtils.getDir("coreAppsDir", ["webapps"], false);
|
||||
onlyCheckAppCache = (app.basePath == appDir.path);
|
||||
#endif
|
||||
|
||||
if (onlyCheckAppCache) {
|
||||
// Bail out for packaged apps.
|
||||
if (app.origin.startsWith("app://")) {
|
||||
aData.error = "NOT_UPDATABLE";
|
||||
@ -1259,6 +1282,7 @@ this.DOMApplicationRegistry = {
|
||||
updateSvc.checkForUpdate(Services.io.newURI(aData.manifestURL, null, null),
|
||||
app.localId, false, updateObserver);
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1275,6 +1299,7 @@ this.DOMApplicationRegistry = {
|
||||
this.createLoadContext(app.installerAppId, app.installerIsBrowser);
|
||||
|
||||
xhr.addEventListener("load", (function() {
|
||||
debug("Got http status=" + xhr.status + " for " + aData.manifestURL);
|
||||
if (xhr.status == 200) {
|
||||
let manifest = xhr.response;
|
||||
if (manifest == null) {
|
||||
@ -1313,6 +1338,7 @@ this.DOMApplicationRegistry = {
|
||||
sendError("NETWORK_ERROR");
|
||||
}).bind(this), false);
|
||||
|
||||
debug("Checking manifest at " + aData.manifestURL);
|
||||
xhr.send(null);
|
||||
},
|
||||
|
||||
@ -1873,6 +1899,11 @@ this.DOMApplicationRegistry = {
|
||||
bufferedOutputStream.close();
|
||||
outputStream.close();
|
||||
|
||||
if (!Components.isSuccessCode(aStatusCode)) {
|
||||
cleanup("NETWORK_ERROR");
|
||||
return;
|
||||
}
|
||||
|
||||
if (requestChannel.responseStatus == 304) {
|
||||
// The package's Etag has not changed.
|
||||
// We send a "applied" event right away.
|
||||
@ -1894,11 +1925,6 @@ this.DOMApplicationRegistry = {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Components.isSuccessCode(aStatusCode)) {
|
||||
cleanup("NETWORK_ERROR");
|
||||
return;
|
||||
}
|
||||
|
||||
let certdb;
|
||||
try {
|
||||
certdb = Cc["@mozilla.org/security/x509certdb;1"]
|
||||
|
@ -1285,7 +1285,7 @@ BluetoothOppManager::OnDisconnect()
|
||||
|
||||
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
|
||||
if (obs) {
|
||||
obs->NotifyObservers(mDsFile, "file-watcher-update", data.get());
|
||||
obs->NotifyObservers(mDsFile, "file-watcher-notify", data.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -238,6 +238,25 @@ BluetoothService::~BluetoothService()
|
||||
Cleanup();
|
||||
}
|
||||
|
||||
PLDHashOperator
|
||||
RemoveObserversExceptBluetoothManager
|
||||
(const nsAString& key,
|
||||
nsAutoPtr<BluetoothSignalObserverList>& value,
|
||||
void* arg)
|
||||
{
|
||||
if (!key.EqualsLiteral("/")) {
|
||||
static_cast<BluetoothService*>(arg)->RemoveObserverFromTable(key);
|
||||
}
|
||||
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothService::RemoveObserverFromTable(const nsAString& key)
|
||||
{
|
||||
mBluetoothSignalObserverTable.Remove(key);
|
||||
}
|
||||
|
||||
// static
|
||||
BluetoothService*
|
||||
BluetoothService::Create()
|
||||
@ -306,6 +325,8 @@ BluetoothService::RegisterBluetoothSignalHandler(const nsAString& aNodeName,
|
||||
ol = new BluetoothSignalObserverList();
|
||||
mBluetoothSignalObserverTable.Put(aNodeName, ol);
|
||||
}
|
||||
|
||||
ol->RemoveObserver(aHandler);
|
||||
ol->AddObserver(aHandler);
|
||||
}
|
||||
|
||||
@ -419,10 +440,19 @@ BluetoothService::SetEnabled(bool aEnabled)
|
||||
* cleared after turned off bluetooth
|
||||
*/
|
||||
while (iter.HasMore()) {
|
||||
RegisterBluetoothSignalHandler(managerPath, (BluetoothSignalObserver*)iter.GetNext());
|
||||
RegisterBluetoothSignalHandler(
|
||||
managerPath,
|
||||
(BluetoothSignalObserver*)iter.GetNext());
|
||||
}
|
||||
} else {
|
||||
mBluetoothSignalObserverTable.Clear();
|
||||
/**
|
||||
* Remove all handlers except BluetoothManager when turning off bluetooth
|
||||
* since it is possible that the event 'onAdapterAdded' would be fired after
|
||||
* BluetoothManagers of child process are registered. Please see Bug 827759
|
||||
* for more details.
|
||||
*/
|
||||
mBluetoothSignalObserverTable.Enumerate(
|
||||
RemoveObserversExceptBluetoothManager, this);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -306,6 +306,9 @@ public:
|
||||
bool
|
||||
IsToggling() const;
|
||||
|
||||
void
|
||||
RemoveObserverFromTable(const nsAString& key);
|
||||
|
||||
protected:
|
||||
BluetoothService()
|
||||
: mEnabled(false)
|
||||
|
@ -196,7 +196,7 @@ CameraControlImpl::Get(JSContext* aCx, uint32_t aKey, JS::Value* aValue)
|
||||
nsresult
|
||||
CameraControlImpl::Set(nsICameraShutterCallback* aOnShutter)
|
||||
{
|
||||
mOnShutterCb = new nsMainThreadPtrHolder<nsICameraShutterCallback>(aOnShutter);
|
||||
mOnShutterCb = aOnShutter;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -210,7 +210,7 @@ CameraControlImpl::Get(nsICameraShutterCallback** aOnShutter)
|
||||
nsresult
|
||||
CameraControlImpl::Set(nsICameraClosedCallback* aOnClosed)
|
||||
{
|
||||
mOnClosedCb = new nsMainThreadPtrHolder<nsICameraClosedCallback>(aOnClosed);
|
||||
mOnClosedCb = aOnClosed;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -224,7 +224,7 @@ CameraControlImpl::Get(nsICameraClosedCallback** aOnClosed)
|
||||
nsresult
|
||||
CameraControlImpl::Set(nsICameraRecorderStateChange* aOnRecorderStateChange)
|
||||
{
|
||||
mOnRecorderStateChangeCb = new nsMainThreadPtrHolder<nsICameraRecorderStateChange>(aOnRecorderStateChange);
|
||||
mOnRecorderStateChangeCb = aOnRecorderStateChange;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -258,7 +258,7 @@ void
|
||||
CameraControlImpl::OnShutterInternal()
|
||||
{
|
||||
DOM_CAMERA_LOGI("** SNAP **\n");
|
||||
if (mOnShutterCb.get()) {
|
||||
if (mOnShutterCb) {
|
||||
mOnShutterCb->HandleEvent();
|
||||
}
|
||||
}
|
||||
@ -277,7 +277,7 @@ void
|
||||
CameraControlImpl::OnClosedInternal()
|
||||
{
|
||||
DOM_CAMERA_LOGI("Camera hardware was closed\n");
|
||||
if (mOnClosedCb.get()) {
|
||||
if (mOnClosedCb) {
|
||||
mOnClosedCb->HandleEvent();
|
||||
}
|
||||
}
|
||||
@ -390,10 +390,9 @@ GetPreviewStreamResult::Run()
|
||||
*/
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
nsCOMPtr<nsICameraPreviewStreamCallback> onSuccess = mOnSuccessCb.get();
|
||||
if (onSuccess && nsDOMCameraManager::IsWindowStillActive(mWindowId)) {
|
||||
if (mOnSuccessCb && nsDOMCameraManager::IsWindowStillActive(mWindowId)) {
|
||||
nsCOMPtr<nsIDOMMediaStream> stream = new DOMCameraPreview(mCameraControl, mWidth, mHeight, mFramesPerSecond);
|
||||
onSuccess->HandleEvent(stream);
|
||||
mOnSuccessCb->HandleEvent(stream);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -5,8 +5,8 @@
|
||||
#ifndef DOM_CAMERA_CAMERACONTROLIMPL_H
|
||||
#define DOM_CAMERA_CAMERACONTROLIMPL_H
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsDOMFile.h"
|
||||
#include "nsProxyRelease.h"
|
||||
#include "DictionaryHelpers.h"
|
||||
#include "nsIDOMDeviceStorage.h"
|
||||
#include "DOMCameraManager.h"
|
||||
@ -143,13 +143,13 @@ protected:
|
||||
*/
|
||||
DOMCameraPreview* mDOMPreview;
|
||||
|
||||
nsMainThreadPtrHandle<nsICameraAutoFocusCallback> mAutoFocusOnSuccessCb;
|
||||
nsMainThreadPtrHandle<nsICameraErrorCallback> mAutoFocusOnErrorCb;
|
||||
nsMainThreadPtrHandle<nsICameraTakePictureCallback> mTakePictureOnSuccessCb;
|
||||
nsMainThreadPtrHandle<nsICameraErrorCallback> mTakePictureOnErrorCb;
|
||||
nsMainThreadPtrHandle<nsICameraShutterCallback> mOnShutterCb;
|
||||
nsMainThreadPtrHandle<nsICameraClosedCallback> mOnClosedCb;
|
||||
nsMainThreadPtrHandle<nsICameraRecorderStateChange> mOnRecorderStateChangeCb;
|
||||
nsCOMPtr<nsICameraAutoFocusCallback> mAutoFocusOnSuccessCb;
|
||||
nsCOMPtr<nsICameraErrorCallback> mAutoFocusOnErrorCb;
|
||||
nsCOMPtr<nsICameraTakePictureCallback> mTakePictureOnSuccessCb;
|
||||
nsCOMPtr<nsICameraErrorCallback> mTakePictureOnErrorCb;
|
||||
nsCOMPtr<nsICameraShutterCallback> mOnShutterCb;
|
||||
nsCOMPtr<nsICameraClosedCallback> mOnClosedCb;
|
||||
nsCOMPtr<nsICameraRecorderStateChange> mOnRecorderStateChangeCb;
|
||||
|
||||
private:
|
||||
CameraControlImpl(const CameraControlImpl&) MOZ_DELETE;
|
||||
@ -161,7 +161,7 @@ class CameraErrorResult : public nsRunnable
|
||||
{
|
||||
public:
|
||||
CameraErrorResult(nsICameraErrorCallback* onError, const nsString& aErrorMsg, uint64_t aWindowId)
|
||||
: mOnErrorCb(new nsMainThreadPtrHolder<nsICameraErrorCallback>(onError))
|
||||
: mOnErrorCb(onError)
|
||||
, mErrorMsg(aErrorMsg)
|
||||
, mWindowId(aWindowId)
|
||||
{ }
|
||||
@ -170,14 +170,14 @@ public:
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
if (mOnErrorCb.get() && nsDOMCameraManager::IsWindowStillActive(mWindowId)) {
|
||||
if (mOnErrorCb && nsDOMCameraManager::IsWindowStillActive(mWindowId)) {
|
||||
mOnErrorCb->HandleEvent(mErrorMsg);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
protected:
|
||||
nsMainThreadPtrHandle<nsICameraErrorCallback> mOnErrorCb;
|
||||
nsCOMPtr<nsICameraErrorCallback> mOnErrorCb;
|
||||
const nsString mErrorMsg;
|
||||
uint64_t mWindowId;
|
||||
};
|
||||
@ -186,7 +186,7 @@ protected:
|
||||
class GetPreviewStreamResult : public nsRunnable
|
||||
{
|
||||
public:
|
||||
GetPreviewStreamResult(CameraControlImpl* aCameraControl, uint32_t aWidth, uint32_t aHeight, uint32_t aFramesPerSecond, nsMainThreadPtrHandle<nsICameraPreviewStreamCallback>& onSuccess, uint64_t aWindowId)
|
||||
GetPreviewStreamResult(CameraControlImpl* aCameraControl, uint32_t aWidth, uint32_t aHeight, uint32_t aFramesPerSecond, nsICameraPreviewStreamCallback* onSuccess, uint64_t aWindowId)
|
||||
: mCameraControl(aCameraControl)
|
||||
, mWidth(aWidth)
|
||||
, mHeight(aHeight)
|
||||
@ -210,7 +210,7 @@ protected:
|
||||
uint32_t mWidth;
|
||||
uint32_t mHeight;
|
||||
uint32_t mFramesPerSecond;
|
||||
nsMainThreadPtrHandle<nsICameraPreviewStreamCallback> mOnSuccessCb;
|
||||
nsCOMPtr<nsICameraPreviewStreamCallback> mOnSuccessCb;
|
||||
uint64_t mWindowId;
|
||||
};
|
||||
|
||||
@ -221,8 +221,8 @@ public:
|
||||
GetPreviewStreamTask(CameraControlImpl* aCameraControl, dom::CameraSize aSize, nsICameraPreviewStreamCallback* onSuccess, nsICameraErrorCallback* onError)
|
||||
: mSize(aSize)
|
||||
, mCameraControl(aCameraControl)
|
||||
, mOnSuccessCb(new nsMainThreadPtrHolder<nsICameraPreviewStreamCallback>(onSuccess))
|
||||
, mOnErrorCb(new nsMainThreadPtrHolder<nsICameraErrorCallback>(onError))
|
||||
, mOnSuccessCb(onSuccess)
|
||||
, mOnErrorCb(onError)
|
||||
{
|
||||
DOM_CAMERA_LOGT("%s:%d : this=%p\n", __func__, __LINE__, this);
|
||||
}
|
||||
@ -236,7 +236,7 @@ public:
|
||||
{
|
||||
nsresult rv = mCameraControl->GetPreviewStreamImpl(this);
|
||||
|
||||
if (NS_FAILED(rv) && mOnErrorCb.get()) {
|
||||
if (NS_FAILED(rv) && mOnErrorCb) {
|
||||
rv = NS_DispatchToMainThread(new CameraErrorResult(mOnErrorCb, NS_LITERAL_STRING("FAILURE"), mCameraControl->GetWindowId()));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
@ -245,8 +245,8 @@ public:
|
||||
|
||||
dom::CameraSize mSize;
|
||||
nsRefPtr<CameraControlImpl> mCameraControl;
|
||||
nsMainThreadPtrHandle<nsICameraPreviewStreamCallback> mOnSuccessCb;
|
||||
nsMainThreadPtrHandle<nsICameraErrorCallback> mOnErrorCb;
|
||||
nsCOMPtr<nsICameraPreviewStreamCallback> mOnSuccessCb;
|
||||
nsCOMPtr<nsICameraErrorCallback> mOnErrorCb;
|
||||
};
|
||||
|
||||
// Return the autofocus status to JS. Runs on the main thread.
|
||||
@ -255,7 +255,7 @@ class AutoFocusResult : public nsRunnable
|
||||
public:
|
||||
AutoFocusResult(bool aSuccess, nsICameraAutoFocusCallback* onSuccess, uint64_t aWindowId)
|
||||
: mSuccess(aSuccess)
|
||||
, mOnSuccessCb(new nsMainThreadPtrHolder<nsICameraAutoFocusCallback>(onSuccess))
|
||||
, mOnSuccessCb(onSuccess)
|
||||
, mWindowId(aWindowId)
|
||||
{ }
|
||||
|
||||
@ -265,7 +265,7 @@ public:
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
if (mOnSuccessCb.get() && nsDOMCameraManager::IsWindowStillActive(mWindowId)) {
|
||||
if (mOnSuccessCb && nsDOMCameraManager::IsWindowStillActive(mWindowId)) {
|
||||
mOnSuccessCb->HandleEvent(mSuccess);
|
||||
}
|
||||
return NS_OK;
|
||||
@ -273,7 +273,7 @@ public:
|
||||
|
||||
protected:
|
||||
bool mSuccess;
|
||||
nsMainThreadPtrHandle<nsICameraAutoFocusCallback> mOnSuccessCb;
|
||||
nsCOMPtr<nsICameraAutoFocusCallback> mOnSuccessCb;
|
||||
uint64_t mWindowId;
|
||||
};
|
||||
|
||||
@ -283,8 +283,8 @@ class AutoFocusTask : public nsRunnable
|
||||
public:
|
||||
AutoFocusTask(CameraControlImpl* aCameraControl, nsICameraAutoFocusCallback* onSuccess, nsICameraErrorCallback* onError)
|
||||
: mCameraControl(aCameraControl)
|
||||
, mOnSuccessCb(new nsMainThreadPtrHolder<nsICameraAutoFocusCallback>(onSuccess))
|
||||
, mOnErrorCb(new nsMainThreadPtrHolder<nsICameraErrorCallback>(onError))
|
||||
, mOnSuccessCb(onSuccess)
|
||||
, mOnErrorCb(onError)
|
||||
{
|
||||
DOM_CAMERA_LOGT("%s:%d : this=%p\n", __func__, __LINE__, this);
|
||||
}
|
||||
@ -300,7 +300,7 @@ public:
|
||||
nsresult rv = mCameraControl->AutoFocusImpl(this);
|
||||
DOM_CAMERA_LOGT("%s:%d\n", __func__, __LINE__);
|
||||
|
||||
if (NS_FAILED(rv) && mOnErrorCb.get()) {
|
||||
if (NS_FAILED(rv) && mOnErrorCb) {
|
||||
rv = NS_DispatchToMainThread(new CameraErrorResult(mOnErrorCb, NS_LITERAL_STRING("FAILURE"), mCameraControl->GetWindowId()));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
@ -308,19 +308,17 @@ public:
|
||||
}
|
||||
|
||||
nsRefPtr<CameraControlImpl> mCameraControl;
|
||||
nsMainThreadPtrHandle<nsICameraAutoFocusCallback> mOnSuccessCb;
|
||||
nsMainThreadPtrHandle<nsICameraErrorCallback> mOnErrorCb;
|
||||
nsCOMPtr<nsICameraAutoFocusCallback> mOnSuccessCb;
|
||||
nsCOMPtr<nsICameraErrorCallback> mOnErrorCb;
|
||||
};
|
||||
|
||||
// Return the captured picture to JS. Runs on the main thread.
|
||||
class TakePictureResult : public nsRunnable
|
||||
{
|
||||
public:
|
||||
TakePictureResult(uint8_t* aData, uint64_t aLength, const nsAString& aMimeType, nsICameraTakePictureCallback* onSuccess, uint64_t aWindowId)
|
||||
: mData(aData)
|
||||
, mLength(aLength)
|
||||
, mMimeType(aMimeType)
|
||||
, mOnSuccessCb(new nsMainThreadPtrHolder<nsICameraTakePictureCallback>(onSuccess))
|
||||
TakePictureResult(nsIDOMBlob* aImage, nsICameraTakePictureCallback* onSuccess, uint64_t aWindowId)
|
||||
: mImage(aImage)
|
||||
, mOnSuccessCb(onSuccess)
|
||||
, mWindowId(aWindowId)
|
||||
{
|
||||
DOM_CAMERA_LOGT("%s:%d : this=%p\n", __func__, __LINE__, this);
|
||||
@ -336,21 +334,16 @@ public:
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
DOM_CAMERA_LOGT("%s:%d : this=%p\n", __func__, __LINE__, this);
|
||||
if (mOnSuccessCb.get() && nsDOMCameraManager::IsWindowStillActive(mWindowId)) {
|
||||
nsCOMPtr<nsIDOMBlob> image = new nsDOMMemoryFile(static_cast<void*>(mData), static_cast<uint64_t>(mLength), mMimeType);
|
||||
mOnSuccessCb->HandleEvent(image);
|
||||
} else {
|
||||
delete[] mData;
|
||||
if (mOnSuccessCb && nsDOMCameraManager::IsWindowStillActive(mWindowId)) {
|
||||
mOnSuccessCb->HandleEvent(mImage);
|
||||
}
|
||||
DOM_CAMERA_LOGT("%s:%d : this=%p\n", __func__, __LINE__, this);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
protected:
|
||||
uint8_t* mData;
|
||||
uint64_t mLength;
|
||||
nsString mMimeType;
|
||||
nsMainThreadPtrHandle<nsICameraTakePictureCallback> mOnSuccessCb;
|
||||
nsCOMPtr<nsIDOMBlob> mImage;
|
||||
nsCOMPtr<nsICameraTakePictureCallback> mOnSuccessCb;
|
||||
uint64_t mWindowId;
|
||||
};
|
||||
|
||||
@ -364,8 +357,8 @@ public:
|
||||
, mRotation(aRotation)
|
||||
, mFileFormat(aFileFormat)
|
||||
, mPosition(aPosition)
|
||||
, mOnSuccessCb(new nsMainThreadPtrHolder<nsICameraTakePictureCallback>(onSuccess))
|
||||
, mOnErrorCb(new nsMainThreadPtrHolder<nsICameraErrorCallback>(onError))
|
||||
, mOnSuccessCb(onSuccess)
|
||||
, mOnErrorCb(onError)
|
||||
{
|
||||
DOM_CAMERA_LOGT("%s:%d : this=%p\n", __func__, __LINE__, this);
|
||||
}
|
||||
@ -381,7 +374,7 @@ public:
|
||||
nsresult rv = mCameraControl->TakePictureImpl(this);
|
||||
DOM_CAMERA_LOGT("%s:%d\n", __func__, __LINE__);
|
||||
|
||||
if (NS_FAILED(rv) && mOnErrorCb.get()) {
|
||||
if (NS_FAILED(rv) && mOnErrorCb) {
|
||||
rv = NS_DispatchToMainThread(new CameraErrorResult(mOnErrorCb, NS_LITERAL_STRING("FAILURE"), mCameraControl->GetWindowId()));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
@ -393,8 +386,8 @@ public:
|
||||
int32_t mRotation;
|
||||
nsString mFileFormat;
|
||||
dom::CameraPosition mPosition;
|
||||
nsMainThreadPtrHandle<nsICameraTakePictureCallback> mOnSuccessCb;
|
||||
nsMainThreadPtrHandle<nsICameraErrorCallback> mOnErrorCb;
|
||||
nsCOMPtr<nsICameraTakePictureCallback> mOnSuccessCb;
|
||||
nsCOMPtr<nsICameraErrorCallback> mOnErrorCb;
|
||||
};
|
||||
|
||||
// Return the result of starting recording. Runs on the main thread.
|
||||
@ -402,7 +395,7 @@ class StartRecordingResult : public nsRunnable
|
||||
{
|
||||
public:
|
||||
StartRecordingResult(nsICameraStartRecordingCallback* onSuccess, uint64_t aWindowId)
|
||||
: mOnSuccessCb(new nsMainThreadPtrHolder<nsICameraStartRecordingCallback>(onSuccess))
|
||||
: mOnSuccessCb(onSuccess)
|
||||
, mWindowId(aWindowId)
|
||||
{ }
|
||||
|
||||
@ -412,14 +405,14 @@ public:
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
if (mOnSuccessCb.get() && nsDOMCameraManager::IsWindowStillActive(mWindowId)) {
|
||||
if (mOnSuccessCb && nsDOMCameraManager::IsWindowStillActive(mWindowId)) {
|
||||
mOnSuccessCb->HandleEvent();
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
protected:
|
||||
nsMainThreadPtrHandle<nsICameraStartRecordingCallback> mOnSuccessCb;
|
||||
nsCOMPtr<nsICameraStartRecordingCallback> mOnSuccessCb;
|
||||
uint64_t mWindowId;
|
||||
};
|
||||
|
||||
@ -432,8 +425,8 @@ public:
|
||||
, mOptions(aOptions)
|
||||
, mFolder(aFolder)
|
||||
, mFilename(aFilename)
|
||||
, mOnSuccessCb(new nsMainThreadPtrHolder<nsICameraStartRecordingCallback>(onSuccess))
|
||||
, mOnErrorCb(new nsMainThreadPtrHolder<nsICameraErrorCallback>(onError))
|
||||
, mOnSuccessCb(onSuccess)
|
||||
, mOnErrorCb(onError)
|
||||
, mWindowId(aWindowId)
|
||||
{
|
||||
DOM_CAMERA_LOGT("%s:%d : this=%p\n", __func__, __LINE__, this);
|
||||
@ -468,8 +461,8 @@ public:
|
||||
dom::CameraStartRecordingOptions mOptions;
|
||||
nsCOMPtr<nsIFile> mFolder;
|
||||
nsString mFilename;
|
||||
nsMainThreadPtrHandle<nsICameraStartRecordingCallback> mOnSuccessCb;
|
||||
nsMainThreadPtrHandle<nsICameraErrorCallback> mOnErrorCb;
|
||||
nsCOMPtr<nsICameraStartRecordingCallback> mOnSuccessCb;
|
||||
nsCOMPtr<nsICameraErrorCallback> mOnErrorCb;
|
||||
uint64_t mWindowId;
|
||||
};
|
||||
|
||||
@ -563,8 +556,8 @@ class GetPreviewStreamVideoModeResult : public nsRunnable
|
||||
{
|
||||
public:
|
||||
GetPreviewStreamVideoModeResult(nsIDOMMediaStream* aStream, nsICameraPreviewStreamCallback* onSuccess)
|
||||
: mStream(new nsMainThreadPtrHolder<nsIDOMMediaStream>(aStream))
|
||||
, mOnSuccessCb(new nsMainThreadPtrHolder<nsICameraPreviewStreamCallback>(onSuccess))
|
||||
: mStream(aStream)
|
||||
, mOnSuccessCb(onSuccess)
|
||||
{
|
||||
DOM_CAMERA_LOGT("%s:%d : this=%p\n", __func__, __LINE__, this);
|
||||
}
|
||||
@ -578,15 +571,15 @@ public:
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
if (mOnSuccessCb.get()) {
|
||||
if (mOnSuccessCb) {
|
||||
mOnSuccessCb->HandleEvent(mStream);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
protected:
|
||||
nsMainThreadPtrHandle<nsIDOMMediaStream> mStream;
|
||||
nsMainThreadPtrHandle<nsICameraPreviewStreamCallback> mOnSuccessCb;
|
||||
nsCOMPtr<nsIDOMMediaStream> mStream;
|
||||
nsCOMPtr<nsICameraPreviewStreamCallback> mOnSuccessCb;
|
||||
};
|
||||
|
||||
// Get the video mode preview stream.
|
||||
@ -596,8 +589,8 @@ public:
|
||||
GetPreviewStreamVideoModeTask(CameraControlImpl* aCameraControl, dom::CameraRecorderOptions aOptions, nsICameraPreviewStreamCallback* onSuccess, nsICameraErrorCallback* onError)
|
||||
: mCameraControl(aCameraControl)
|
||||
, mOptions(aOptions)
|
||||
, mOnSuccessCb(new nsMainThreadPtrHolder<nsICameraPreviewStreamCallback>(onSuccess))
|
||||
, mOnErrorCb(new nsMainThreadPtrHolder<nsICameraErrorCallback>(onError))
|
||||
, mOnSuccessCb(onSuccess)
|
||||
, mOnErrorCb(onError)
|
||||
{ }
|
||||
|
||||
NS_IMETHOD Run()
|
||||
@ -606,7 +599,7 @@ public:
|
||||
nsresult rv = mCameraControl->GetPreviewStreamVideoModeImpl(this);
|
||||
DOM_CAMERA_LOGI("%s:%d -- AFTER IMPL : rv = %d\n", __func__, __LINE__, rv);
|
||||
|
||||
if (NS_FAILED(rv) && mOnErrorCb.get()) {
|
||||
if (NS_FAILED(rv) && mOnErrorCb) {
|
||||
rv = NS_DispatchToMainThread(new CameraErrorResult(mOnErrorCb, NS_LITERAL_STRING("FAILURE"), mCameraControl->GetWindowId()));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
@ -615,8 +608,8 @@ public:
|
||||
|
||||
nsRefPtr<CameraControlImpl> mCameraControl;
|
||||
dom::CameraRecorderOptions mOptions;
|
||||
nsMainThreadPtrHandle<nsICameraPreviewStreamCallback> mOnSuccessCb;
|
||||
nsMainThreadPtrHandle<nsICameraErrorCallback> mOnErrorCb;
|
||||
nsCOMPtr<nsICameraPreviewStreamCallback> mOnSuccessCb;
|
||||
nsCOMPtr<nsICameraErrorCallback> mOnErrorCb;
|
||||
};
|
||||
|
||||
// Return the result of releasing the camera hardware. Runs on the main thread.
|
||||
@ -624,7 +617,7 @@ class ReleaseHardwareResult : public nsRunnable
|
||||
{
|
||||
public:
|
||||
ReleaseHardwareResult(nsICameraReleaseCallback* onSuccess, uint64_t aWindowId)
|
||||
: mOnSuccessCb(new nsMainThreadPtrHolder<nsICameraReleaseCallback>(onSuccess))
|
||||
: mOnSuccessCb(onSuccess)
|
||||
, mWindowId(aWindowId)
|
||||
{
|
||||
DOM_CAMERA_LOGT("%s:%d : this=%p\n", __func__, __LINE__, this);
|
||||
@ -639,14 +632,14 @@ public:
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
if (mOnSuccessCb.get() && nsDOMCameraManager::IsWindowStillActive(mWindowId)) {
|
||||
if (mOnSuccessCb && nsDOMCameraManager::IsWindowStillActive(mWindowId)) {
|
||||
mOnSuccessCb->HandleEvent();
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
protected:
|
||||
nsMainThreadPtrHandle<nsICameraReleaseCallback> mOnSuccessCb;
|
||||
nsCOMPtr<nsICameraReleaseCallback> mOnSuccessCb;
|
||||
uint64_t mWindowId;
|
||||
};
|
||||
|
||||
@ -656,8 +649,8 @@ class ReleaseHardwareTask : public nsRunnable
|
||||
public:
|
||||
ReleaseHardwareTask(CameraControlImpl* aCameraControl, nsICameraReleaseCallback* onSuccess, nsICameraErrorCallback* onError)
|
||||
: mCameraControl(aCameraControl)
|
||||
, mOnSuccessCb(new nsMainThreadPtrHolder<nsICameraReleaseCallback>(onSuccess))
|
||||
, mOnErrorCb(new nsMainThreadPtrHolder<nsICameraErrorCallback>(onError))
|
||||
, mOnSuccessCb(onSuccess)
|
||||
, mOnErrorCb(onError)
|
||||
{
|
||||
DOM_CAMERA_LOGT("%s:%d : this=%p\n", __func__, __LINE__, this);
|
||||
}
|
||||
@ -673,7 +666,7 @@ public:
|
||||
nsresult rv = mCameraControl->ReleaseHardwareImpl(this);
|
||||
DOM_CAMERA_LOGT("%s:%d\n", __func__, __LINE__);
|
||||
|
||||
if (NS_FAILED(rv) && mOnErrorCb.get()) {
|
||||
if (NS_FAILED(rv) && mOnErrorCb) {
|
||||
rv = NS_DispatchToMainThread(new CameraErrorResult(mOnErrorCb, NS_LITERAL_STRING("FAILURE"), mCameraControl->GetWindowId()));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
@ -681,8 +674,8 @@ public:
|
||||
}
|
||||
|
||||
nsRefPtr<CameraControlImpl> mCameraControl;
|
||||
nsMainThreadPtrHandle<nsICameraReleaseCallback> mOnSuccessCb;
|
||||
nsMainThreadPtrHandle<nsICameraErrorCallback> mOnErrorCb;
|
||||
nsCOMPtr<nsICameraReleaseCallback> mOnSuccessCb;
|
||||
nsCOMPtr<nsICameraErrorCallback> mOnErrorCb;
|
||||
};
|
||||
|
||||
// Report that the video recorder state has changed.
|
||||
@ -690,7 +683,7 @@ class CameraRecorderStateChange : public nsRunnable
|
||||
{
|
||||
public:
|
||||
CameraRecorderStateChange(nsICameraRecorderStateChange* onStateChange, const nsString& aStateMsg, int32_t aStatus, int32_t aTrackNumber, uint64_t aWindowId)
|
||||
: mOnStateChangeCb(new nsMainThreadPtrHolder<nsICameraRecorderStateChange>(onStateChange))
|
||||
: mOnStateChangeCb(onStateChange)
|
||||
, mStateMsg(aStateMsg)
|
||||
, mStatus(aStatus)
|
||||
, mTrackNumber(aTrackNumber)
|
||||
@ -701,7 +694,7 @@ public:
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
if (mOnStateChangeCb.get() && nsDOMCameraManager::IsWindowStillActive(mWindowId)) {
|
||||
if (mOnStateChangeCb && nsDOMCameraManager::IsWindowStillActive(mWindowId)) {
|
||||
// For now, just pass the state message and swallow mStatus and mTrackNumber
|
||||
mOnStateChangeCb->HandleStateChange(mStateMsg);
|
||||
}
|
||||
@ -709,7 +702,7 @@ public:
|
||||
}
|
||||
|
||||
protected:
|
||||
nsMainThreadPtrHandle<nsICameraRecorderStateChange> mOnStateChangeCb;
|
||||
nsCOMPtr<nsICameraRecorderStateChange> mOnStateChangeCb;
|
||||
const nsString mStateMsg;
|
||||
int32_t mStatus;
|
||||
int32_t mTrackNumber;
|
||||
|
@ -623,8 +623,7 @@ nsGonkCameraControl::GetPreviewStreamImpl(GetPreviewStreamTask* aGetPreviewStrea
|
||||
SetPreviewSize(aGetPreviewStream->mSize.width, aGetPreviewStream->mSize.height);
|
||||
DOM_CAMERA_LOGI("picture preview: wanted %d x %d, got %d x %d (%d fps, format %d)\n", aGetPreviewStream->mSize.width, aGetPreviewStream->mSize.height, mWidth, mHeight, mFps, mFormat);
|
||||
|
||||
nsMainThreadPtrHandle<nsICameraPreviewStreamCallback> onSuccess = aGetPreviewStream->mOnSuccessCb;
|
||||
nsCOMPtr<GetPreviewStreamResult> getPreviewStreamResult = new GetPreviewStreamResult(this, mWidth, mHeight, mFps, onSuccess, mWindowId);
|
||||
nsCOMPtr<GetPreviewStreamResult> getPreviewStreamResult = new GetPreviewStreamResult(this, mWidth, mHeight, mFps, aGetPreviewStream->mOnSuccessCb, mWindowId);
|
||||
return NS_DispatchToMainThread(getPreviewStreamResult);
|
||||
}
|
||||
|
||||
@ -680,16 +679,16 @@ nsGonkCameraControl::StopPreviewImpl(StopPreviewTask* aStopPreview)
|
||||
nsresult
|
||||
nsGonkCameraControl::AutoFocusImpl(AutoFocusTask* aAutoFocus)
|
||||
{
|
||||
nsMainThreadPtrHandle<nsICameraAutoFocusCallback> cb = mAutoFocusOnSuccessCb;
|
||||
if (cb.get()) {
|
||||
nsCOMPtr<nsICameraAutoFocusCallback> cb = mAutoFocusOnSuccessCb;
|
||||
if (cb) {
|
||||
/**
|
||||
* We already have a callback, so someone has already
|
||||
* called autoFocus() -- cancel it.
|
||||
*/
|
||||
mAutoFocusOnSuccessCb = nullptr;
|
||||
nsMainThreadPtrHandle<nsICameraErrorCallback> ecb = mAutoFocusOnErrorCb;
|
||||
nsCOMPtr<nsICameraErrorCallback> ecb = mAutoFocusOnErrorCb;
|
||||
mAutoFocusOnErrorCb = nullptr;
|
||||
if (ecb.get()) {
|
||||
if (ecb) {
|
||||
nsresult rv = NS_DispatchToMainThread(new CameraErrorResult(ecb, NS_LITERAL_STRING("CANCELLED"), mWindowId));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
@ -748,16 +747,16 @@ nsGonkCameraControl::SetupThumbnail(uint32_t aPictureWidth, uint32_t aPictureHei
|
||||
nsresult
|
||||
nsGonkCameraControl::TakePictureImpl(TakePictureTask* aTakePicture)
|
||||
{
|
||||
nsMainThreadPtrHandle<nsICameraTakePictureCallback> cb = mTakePictureOnSuccessCb;
|
||||
if (cb.get()) {
|
||||
nsCOMPtr<nsICameraTakePictureCallback> cb = mTakePictureOnSuccessCb;
|
||||
if (cb) {
|
||||
/**
|
||||
* We already have a callback, so someone has already
|
||||
* called TakePicture() -- cancel it.
|
||||
*/
|
||||
mTakePictureOnSuccessCb = nullptr;
|
||||
nsMainThreadPtrHandle<nsICameraErrorCallback> ecb = mTakePictureOnErrorCb;
|
||||
nsCOMPtr<nsICameraErrorCallback> ecb = mTakePictureOnErrorCb;
|
||||
mTakePictureOnErrorCb = nullptr;
|
||||
if (ecb.get()) {
|
||||
if (ecb) {
|
||||
nsresult rv = NS_DispatchToMainThread(new CameraErrorResult(ecb, NS_LITERAL_STRING("CANCELLED"), mWindowId));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
@ -916,7 +915,7 @@ public:
|
||||
nsString data;
|
||||
CopyASCIItoUTF16(mType, data);
|
||||
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
|
||||
obs->NotifyObservers(mFile, "file-watcher-update", data.get());
|
||||
obs->NotifyObservers(mFile, "file-watcher-notify", data.get());
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -977,7 +976,8 @@ nsGonkCameraControl::TakePictureComplete(uint8_t* aData, uint32_t aLength)
|
||||
memcpy(data, aData, aLength);
|
||||
|
||||
// TODO: see bug 779144.
|
||||
nsCOMPtr<nsIRunnable> takePictureResult = new TakePictureResult(data, aLength, NS_LITERAL_STRING("image/jpeg"), mTakePictureOnSuccessCb, mWindowId);
|
||||
nsIDOMBlob* blob = new nsDOMMemoryFile(static_cast<void*>(data), static_cast<uint64_t>(aLength), NS_LITERAL_STRING("image/jpeg"));
|
||||
nsCOMPtr<nsIRunnable> takePictureResult = new TakePictureResult(blob, mTakePictureOnSuccessCb, mWindowId);
|
||||
/**
|
||||
* Remember to set these to null so that we don't hold any extra
|
||||
* references to our document's window.
|
||||
@ -1335,7 +1335,7 @@ nsGonkCameraControl::ReleaseHardwareImpl(ReleaseHardwareTask* aReleaseHardware)
|
||||
// release the hardware handle
|
||||
GonkCameraHardware::ReleaseHandle(mHwHandle, true /* unregister */);
|
||||
|
||||
if (aReleaseHardware && aReleaseHardware->mOnSuccessCb.get()) {
|
||||
if (aReleaseHardware && aReleaseHardware->mOnSuccessCb) {
|
||||
nsCOMPtr<nsIRunnable> releaseHardwareResult = new ReleaseHardwareResult(aReleaseHardware->mOnSuccessCb, mWindowId);
|
||||
return NS_DispatchToMainThread(releaseHardwareResult);
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ Cu.import("resource://gre/modules/IndexedDBHelper.jsm");
|
||||
Cu.import("resource://gre/modules/PhoneNumberUtils.jsm");
|
||||
|
||||
const DB_NAME = "contacts";
|
||||
const DB_VERSION = 5;
|
||||
const DB_VERSION = 6;
|
||||
const STORE_NAME = "contacts";
|
||||
|
||||
this.ContactDB = function ContactDB(aGlobal) {
|
||||
@ -58,7 +58,6 @@ ContactDB.prototype = {
|
||||
objectStore.createIndex("name", "properties.name", { unique: false, multiEntry: true });
|
||||
objectStore.createIndex("familyName", "properties.familyName", { unique: false, multiEntry: true });
|
||||
objectStore.createIndex("givenName", "properties.givenName", { unique: false, multiEntry: true });
|
||||
objectStore.createIndex("tel", "properties.tel", { unique: false, multiEntry: true });
|
||||
objectStore.createIndex("email", "properties.email", { unique: false, multiEntry: true });
|
||||
objectStore.createIndex("note", "properties.note", { unique: false, multiEntry: true });
|
||||
|
||||
@ -78,7 +77,9 @@ ContactDB.prototype = {
|
||||
objectStore = aTransaction.objectStore(STORE_NAME);
|
||||
}
|
||||
// Delete old tel index.
|
||||
objectStore.deleteIndex("tel");
|
||||
if (objectStore.indexNames.contains("tel")) {
|
||||
objectStore.deleteIndex("tel");
|
||||
}
|
||||
|
||||
// Upgrade existing tel field in the DB.
|
||||
objectStore.openCursor().onsuccess = function(event) {
|
||||
@ -192,6 +193,44 @@ ContactDB.prototype = {
|
||||
cursor.continue();
|
||||
}
|
||||
};
|
||||
} else if (currVersion == 5) {
|
||||
if (DEBUG) debug("Add index for equals tel searches");
|
||||
if (!objectStore) {
|
||||
objectStore = aTransaction.objectStore(STORE_NAME);
|
||||
}
|
||||
|
||||
// Delete old tel index (not on the right field).
|
||||
if (objectStore.indexNames.contains("tel")) {
|
||||
objectStore.deleteIndex("tel");
|
||||
}
|
||||
|
||||
// Create new index for "equals" searches
|
||||
objectStore.createIndex("tel", "search.exactTel", { unique: false, multiEntry: true });
|
||||
|
||||
objectStore.openCursor().onsuccess = function(event) {
|
||||
let cursor = event.target.result;
|
||||
if (cursor) {
|
||||
if (cursor.value.properties.tel) {
|
||||
if (DEBUG) debug("upgrade : " + JSON.stringify(cursor.value));
|
||||
cursor.value.properties.tel.forEach(
|
||||
function(duple) {
|
||||
let number = duple.value.toString();
|
||||
let parsedNumber = PhoneNumberUtils.parse(number);
|
||||
|
||||
cursor.value.search.exactTel = [number];
|
||||
if (parsedNumber &&
|
||||
parsedNumber.internationalNumber &&
|
||||
number !== parsedNumber.internationalNumber) {
|
||||
cursor.value.search.exactTel.push(parsedNumber.internationalNumber);
|
||||
}
|
||||
}
|
||||
)
|
||||
cursor.update(cursor.value);
|
||||
}
|
||||
if (DEBUG) debug("upgrade : " + JSON.stringify(cursor.value));
|
||||
cursor.continue();
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -233,6 +272,7 @@ ContactDB.prototype = {
|
||||
email: [],
|
||||
category: [],
|
||||
tel: [],
|
||||
exactTel: [],
|
||||
org: [],
|
||||
jobTitle: [],
|
||||
note: [],
|
||||
@ -251,6 +291,7 @@ ContactDB.prototype = {
|
||||
|
||||
// Chop off the first characters
|
||||
let number = aContact.properties[field][i].value;
|
||||
contact.search.exactTel.push(number);
|
||||
let search = {};
|
||||
if (number) {
|
||||
for (let i = 0; i < number.length; i++) {
|
||||
@ -273,6 +314,7 @@ ContactDB.prototype = {
|
||||
debug("NationalFormat: " + parsedNumber.nationalFormat);
|
||||
if (parsedNumber.internationalNumber &&
|
||||
number.toString() !== parsedNumber.internationalNumber) {
|
||||
contact.search.exactTel.push(parsedNumber.internationalNumber);
|
||||
let digits = parsedNumber.internationalNumber.match(/\d/g);
|
||||
if (digits) {
|
||||
digits = digits.join('');
|
||||
|
@ -52,6 +52,12 @@ var properties1 = {
|
||||
tel: [{type: ["work"], value: number1.local, carrier: "testCarrier"} , {type: ["home", "fax"], value: number2.local}],
|
||||
};
|
||||
|
||||
var shortNumber = "888";
|
||||
var properties2 = {
|
||||
name: "Testname2",
|
||||
tel: [{type: ["work"], value: shortNumber, carrier: "testCarrier"}]
|
||||
};
|
||||
|
||||
var req;
|
||||
var index = 0;
|
||||
var createResult1;
|
||||
@ -82,6 +88,17 @@ var steps = [
|
||||
};
|
||||
req.onerror = onFailure;
|
||||
},
|
||||
function () {
|
||||
ok(true, "Adding a new contact2");
|
||||
var createResult2 = new mozContact();
|
||||
createResult2.init(properties2);
|
||||
req = navigator.mozContacts.save(createResult2);
|
||||
req.onsuccess = function () {
|
||||
ok(createResult2.id, "The contact now has an ID.");
|
||||
next();
|
||||
};
|
||||
req.onerror = onFailure;
|
||||
},
|
||||
function () {
|
||||
ok(true, "Searching for local number");
|
||||
var options = {filterBy: ["tel"],
|
||||
@ -110,6 +127,44 @@ var steps = [
|
||||
};
|
||||
req.onerror = onFailure;
|
||||
},
|
||||
function () {
|
||||
ok(true, "Searching for a short number matching the prefix");
|
||||
var shortNumber = number1.local.substring(0, 3);
|
||||
var options = {filterBy: ["tel"],
|
||||
filterOp: "equals",
|
||||
filterValue: shortNumber};
|
||||
req = mozContacts.find(options);
|
||||
req.onsuccess = function() {
|
||||
ok(req.result.length == 0, "The prefix short number should not match any contact.");
|
||||
next();
|
||||
};
|
||||
req.onerror = onFailure;
|
||||
},
|
||||
function () {
|
||||
ok(true, "Searching for a short number matching the suffix");
|
||||
var shortNumber = number1.local.substring(number1.local.length - 3);
|
||||
var options = {filterBy: ["tel"],
|
||||
filterOp: "equals",
|
||||
filterValue: shortNumber};
|
||||
req = mozContacts.find(options);
|
||||
req.onsuccess = function() {
|
||||
ok(req.result.length == 0, "The suffix short number should not match any contact.");
|
||||
next();
|
||||
};
|
||||
req.onerror = onFailure;
|
||||
},
|
||||
function () {
|
||||
ok(true, "Searching for a short number matching a contact");
|
||||
var options = {filterBy: ["tel"],
|
||||
filterOp: "equals",
|
||||
filterValue: shortNumber};
|
||||
req = mozContacts.find(options);
|
||||
req.onsuccess = function() {
|
||||
ok(req.result.length == 1, "Found the contact equally matching the shortNumber.");
|
||||
next();
|
||||
};
|
||||
req.onerror = onFailure;
|
||||
},
|
||||
function() {
|
||||
ok(true, "Modifying number");
|
||||
findResult1.tel[0].value = number2.local;
|
||||
@ -207,4 +262,4 @@ ok(true, "test passed");
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "nsIPrincipal.h"
|
||||
#include "nsIObserver.h"
|
||||
#include "nsDOMEventTargetHelper.h"
|
||||
#include "mozilla/StaticPtr.h"
|
||||
|
||||
class DeviceStorageFile MOZ_FINAL
|
||||
: public nsISupports {
|
||||
@ -43,6 +44,18 @@ private:
|
||||
void AppendRelativePath();
|
||||
};
|
||||
|
||||
class FileUpdateDispatcher MOZ_FINAL
|
||||
: public nsIObserver
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIOBSERVER
|
||||
|
||||
static FileUpdateDispatcher* GetSingleton();
|
||||
private:
|
||||
static mozilla::StaticRefPtr<FileUpdateDispatcher> sSingleton;
|
||||
};
|
||||
|
||||
class nsDOMDeviceStorage MOZ_FINAL
|
||||
: public nsIDOMDeviceStorage
|
||||
, public nsDOMEventTargetHelper
|
||||
|
@ -223,6 +223,56 @@ DeviceStorageTypeChecker::GetAccessForRequest(const DeviceStorageRequestType aRe
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
NS_IMPL_ISUPPORTS1(FileUpdateDispatcher, nsIObserver)
|
||||
|
||||
mozilla::StaticRefPtr<FileUpdateDispatcher> FileUpdateDispatcher::sSingleton;
|
||||
|
||||
FileUpdateDispatcher*
|
||||
FileUpdateDispatcher::GetSingleton()
|
||||
{
|
||||
if (sSingleton) {
|
||||
return sSingleton;
|
||||
}
|
||||
|
||||
sSingleton = new FileUpdateDispatcher();
|
||||
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
|
||||
obs->AddObserver(sSingleton, "file-watcher-notify", false);
|
||||
ClearOnShutdown(&sSingleton);
|
||||
|
||||
return sSingleton;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
FileUpdateDispatcher::Observe(nsISupports *aSubject,
|
||||
const char *aTopic,
|
||||
const PRUnichar *aData)
|
||||
{
|
||||
if (XRE_GetProcessType() != GeckoProcessType_Default) {
|
||||
|
||||
DeviceStorageFile* file = static_cast<DeviceStorageFile*>(aSubject);
|
||||
if (!file || !file->mFile) {
|
||||
NS_WARNING("Device storage file looks invalid!");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsString fullpath;
|
||||
nsresult rv = file->mFile->GetPath(fullpath);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("Could not get path from the nsIFile!");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
ContentChild::GetSingleton()->SendFilePathUpdateNotify(file->mStorageType,
|
||||
fullpath,
|
||||
NS_ConvertUTF16toUTF8(aData));
|
||||
} else {
|
||||
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
|
||||
obs->NotifyObservers(aSubject, "file-watcher-update", aData);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
class IOEventComplete : public nsRunnable
|
||||
{
|
||||
public:
|
||||
@ -240,7 +290,8 @@ public:
|
||||
nsString data;
|
||||
CopyASCIItoUTF16(mType, data);
|
||||
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
|
||||
obs->NotifyObservers(mFile, "file-watcher-update", data.get());
|
||||
|
||||
obs->NotifyObservers(mFile, "file-watcher-notify", data.get());
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -1558,6 +1609,18 @@ public:
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
DeviceStorageTypeChecker* typeChecker = DeviceStorageTypeChecker::CreateOrGet();
|
||||
if (!typeChecker) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (!typeChecker->Check(mFile->mStorageType, mFile->mFile) ||
|
||||
!typeChecker->Check(mFile->mStorageType, mBlob)) {
|
||||
r = new PostErrorEvent(mRequest, POST_ERROR_EVENT_ILLEGAL_TYPE);
|
||||
NS_DispatchToMainThread(r);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (XRE_GetProcessType() != GeckoProcessType_Default) {
|
||||
|
||||
BlobChild* actor = ContentChild::GetSingleton()->GetOrCreateActorForBlob(mBlob);
|
||||
@ -1582,6 +1645,17 @@ public:
|
||||
case DEVICE_STORAGE_REQUEST_READ:
|
||||
case DEVICE_STORAGE_REQUEST_WRITE:
|
||||
{
|
||||
DeviceStorageTypeChecker* typeChecker = DeviceStorageTypeChecker::CreateOrGet();
|
||||
if (!typeChecker) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (!typeChecker->Check(mFile->mStorageType, mFile->mFile)) {
|
||||
r = new PostErrorEvent(mRequest, POST_ERROR_EVENT_ILLEGAL_TYPE);
|
||||
NS_DispatchToMainThread(r);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (XRE_GetProcessType() != GeckoProcessType_Default) {
|
||||
PDeviceStorageRequestChild* child = new DeviceStorageRequestChild(mRequest, mFile);
|
||||
DeviceStorageGetParams params(mFile->mStorageType, mFile->mPath, fullpath);
|
||||
@ -1595,6 +1669,17 @@ public:
|
||||
|
||||
case DEVICE_STORAGE_REQUEST_DELETE:
|
||||
{
|
||||
DeviceStorageTypeChecker* typeChecker = DeviceStorageTypeChecker::CreateOrGet();
|
||||
if (!typeChecker) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (!typeChecker->Check(mFile->mStorageType, mFile->mFile)) {
|
||||
r = new PostErrorEvent(mRequest, POST_ERROR_EVENT_ILLEGAL_TYPE);
|
||||
NS_DispatchToMainThread(r);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (XRE_GetProcessType() != GeckoProcessType_Default) {
|
||||
PDeviceStorageRequestChild* child = new DeviceStorageRequestChild(mRequest, mFile);
|
||||
DeviceStorageDeleteParams params(mFile->mStorageType, fullpath);
|
||||
|
@ -30,6 +30,7 @@ MOCHITEST_FILES = \
|
||||
test_stat.html \
|
||||
test_watch.html \
|
||||
test_watchOther.html \
|
||||
test_823965.html \
|
||||
devicestorage_common.js \
|
||||
$(NULL)
|
||||
|
||||
|
94
dom/devicestorage/test/test_823965.html
Normal file
94
dom/devicestorage/test/test_823965.html
Normal file
@ -0,0 +1,94 @@
|
||||
<!--
|
||||
Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/
|
||||
-->
|
||||
<!DOCTYPE HTML>
|
||||
<html> <!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=823965
|
||||
-->
|
||||
<head>
|
||||
<title>Test for the device storage API </title>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="text/javascript" src="devicestorage_common.js"></script>
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=823965">Mozilla Bug 823965</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript">
|
||||
|
||||
devicestorage_setup();
|
||||
|
||||
var gFileName = "devicestorage/hi.png";
|
||||
var gData = "My name is Doug Turner (?!?). My IRC nick is DougT. I like Maple cookies."
|
||||
var gDataBlob = new Blob([gData], {type: 'image/png'});
|
||||
|
||||
function getSuccess(e) {
|
||||
var storage = navigator.getDeviceStorage("pictures");
|
||||
ok(navigator.getDeviceStorage, "Should have getDeviceStorage");
|
||||
|
||||
ok(e.target.result.name == gFileName, "File name should match");
|
||||
ok(e.target.result.size > 0, "File size be greater than zero");
|
||||
ok(e.target.result.type, "File should have a mime type");
|
||||
ok(e.target.result.lastModifiedDate, "File should have a last modified date");
|
||||
|
||||
var mreq = storage.enumerate();
|
||||
mreq.onsuccess = function() {
|
||||
var storage2 = navigator.getDeviceStorage('music');
|
||||
var dreq = storage2.delete(mreq.result.name);
|
||||
dreq.onerror = function () {
|
||||
ok(true, "The bug has been fixed");
|
||||
devicestorage_cleanup();
|
||||
};
|
||||
dreq.onsuccess = function () {
|
||||
ok(false, "The bug has been fixed");
|
||||
devicestorage_cleanup();
|
||||
};
|
||||
};
|
||||
|
||||
mreq.onerror = getError;
|
||||
}
|
||||
|
||||
function getError(e) {
|
||||
ok(false, "getError was called : " + e.target.error.name);
|
||||
devicestorage_cleanup();
|
||||
}
|
||||
|
||||
function addSuccess(e) {
|
||||
|
||||
ok(e.target.result == gFileName, "File name should match");
|
||||
|
||||
var storage = navigator.getDeviceStorage("pictures");
|
||||
request = storage.get(gFileName);
|
||||
request.onsuccess = getSuccess;
|
||||
request.onerror = getError;
|
||||
|
||||
ok(true, "addSuccess was called");
|
||||
}
|
||||
|
||||
function addError(e) {
|
||||
ok(false, "addError was called : " + e.target.error.name);
|
||||
devicestorage_cleanup();
|
||||
}
|
||||
|
||||
ok(navigator.getDeviceStorage, "Should have getDeviceStorage");
|
||||
|
||||
var storage = navigator.getDeviceStorage("pictures");
|
||||
ok(storage, "Should have gotten a storage");
|
||||
|
||||
request = storage.addNamed(gDataBlob, "devicestorage/hi.png");
|
||||
ok(request, "Should have a non-null request");
|
||||
|
||||
request.onsuccess = addSuccess;
|
||||
request.onerror = addError;
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -60,12 +60,12 @@ function TestAdd(iframe, data) {
|
||||
|
||||
function TestGet(iframe, data) {
|
||||
|
||||
createTestFile();
|
||||
createTestFile(data.fileExtension);
|
||||
|
||||
var storage = iframe.contentDocument.defaultView.navigator.getDeviceStorage(data.type);
|
||||
isnot(storage, null, "Should be able to get storage object for " + data.type);
|
||||
|
||||
request = storage.get("testfile");
|
||||
request = storage.get("testfile" + data.fileExtension);
|
||||
isnot(request, null, "Should be able to get request");
|
||||
|
||||
request.onsuccess = function() {
|
||||
@ -81,12 +81,12 @@ function TestGet(iframe, data) {
|
||||
|
||||
function TestDelete(iframe, data) {
|
||||
|
||||
createTestFile();
|
||||
createTestFile(data.fileExtension);
|
||||
|
||||
var storage = iframe.contentDocument.defaultView.navigator.getDeviceStorage(data.type);
|
||||
isnot(storage, null, "Should be able to get storage object for " + data.type);
|
||||
|
||||
request = storage.delete("testfile");
|
||||
request = storage.delete("testfile" + data.fileExtension);
|
||||
isnot(request, null, "Should be able to get request");
|
||||
|
||||
request.onsuccess = function() {
|
||||
@ -103,7 +103,7 @@ function TestDelete(iframe, data) {
|
||||
|
||||
function TestEnumerate(iframe, data) {
|
||||
|
||||
createTestFile();
|
||||
createTestFile(data.fileExtension);
|
||||
|
||||
var storage = iframe.contentDocument.defaultView.navigator.getDeviceStorage(data.type);
|
||||
isnot(storage, null, "Should be able to get storage object for " + data.type);
|
||||
@ -137,21 +137,25 @@ var gData = [
|
||||
{
|
||||
type: 'pictures',
|
||||
shouldPass: false,
|
||||
fileExtension: '.png',
|
||||
test: TestGet
|
||||
},
|
||||
{
|
||||
type: 'videos',
|
||||
shouldPass: false,
|
||||
fileExtension: '.ogv',
|
||||
test: TestGet
|
||||
},
|
||||
{
|
||||
type: 'music',
|
||||
shouldPass: false,
|
||||
fileExtension: '.ogg',
|
||||
test: TestGet
|
||||
},
|
||||
{
|
||||
type: 'sdcard',
|
||||
shouldPass: false,
|
||||
fileExtension: '.txt',
|
||||
test: TestGet
|
||||
},
|
||||
|
||||
@ -159,6 +163,7 @@ var gData = [
|
||||
{
|
||||
type: 'pictures',
|
||||
shouldPass: true,
|
||||
fileExtension: '.png',
|
||||
|
||||
permissions: ["device-storage:pictures"],
|
||||
|
||||
@ -167,6 +172,7 @@ var gData = [
|
||||
{
|
||||
type: 'videos',
|
||||
shouldPass: true,
|
||||
fileExtension: '.ogv',
|
||||
|
||||
permissions: ["device-storage:videos"],
|
||||
|
||||
@ -175,6 +181,7 @@ var gData = [
|
||||
{
|
||||
type: 'music',
|
||||
shouldPass: true,
|
||||
fileExtension: '.ogg',
|
||||
|
||||
permissions: ["device-storage:music"],
|
||||
|
||||
@ -183,6 +190,7 @@ var gData = [
|
||||
{
|
||||
type: 'sdcard',
|
||||
shouldPass: true,
|
||||
fileExtension: '.txt',
|
||||
|
||||
permissions: ["device-storage:sdcard"],
|
||||
|
||||
@ -193,6 +201,7 @@ var gData = [
|
||||
{
|
||||
type: 'pictures',
|
||||
shouldPass: true,
|
||||
fileExtension: '.png',
|
||||
|
||||
app: "https://example.com/manifest_cert.webapp",
|
||||
permissions: ["device-storage:pictures"],
|
||||
@ -202,6 +211,7 @@ var gData = [
|
||||
{
|
||||
type: 'videos',
|
||||
shouldPass: true,
|
||||
fileExtension: '.ogv',
|
||||
|
||||
app: "https://example.com/manifest_cert.webapp",
|
||||
permissions: ["device-storage:videos"],
|
||||
@ -211,6 +221,7 @@ var gData = [
|
||||
{
|
||||
type: 'music',
|
||||
shouldPass: true,
|
||||
fileExtension: '.ogg',
|
||||
|
||||
app: "https://example.com/manifest_cert.webapp",
|
||||
permissions: ["device-storage:music"],
|
||||
@ -220,6 +231,7 @@ var gData = [
|
||||
{
|
||||
type: 'sdcard',
|
||||
shouldPass: true,
|
||||
fileExtension: '.txt',
|
||||
|
||||
app: "https://example.com/manifest_cert.webapp",
|
||||
permissions: ["device-storage:sdcard"],
|
||||
@ -356,21 +368,25 @@ var gData = [
|
||||
{
|
||||
type: 'pictures',
|
||||
shouldPass: false,
|
||||
fileExtension: '.png',
|
||||
test: TestDelete
|
||||
},
|
||||
{
|
||||
type: 'videos',
|
||||
shouldPass: false,
|
||||
fileExtension: '.ogv',
|
||||
test: TestDelete
|
||||
},
|
||||
{
|
||||
type: 'music',
|
||||
shouldPass: false,
|
||||
fileExtension: '.ogg',
|
||||
test: TestDelete
|
||||
},
|
||||
{
|
||||
type: 'sdcard',
|
||||
shouldPass: false,
|
||||
fileExtension: '.txt',
|
||||
test: TestDelete
|
||||
},
|
||||
|
||||
@ -378,6 +394,7 @@ var gData = [
|
||||
{
|
||||
type: 'pictures',
|
||||
shouldPass: true,
|
||||
fileExtension: '.png',
|
||||
|
||||
permissions: ["device-storage:pictures"],
|
||||
|
||||
@ -386,6 +403,7 @@ var gData = [
|
||||
{
|
||||
type: 'videos',
|
||||
shouldPass: true,
|
||||
fileExtension: '.ogv',
|
||||
|
||||
permissions: ["device-storage:videos"],
|
||||
|
||||
@ -394,6 +412,7 @@ var gData = [
|
||||
{
|
||||
type: 'music',
|
||||
shouldPass: true,
|
||||
fileExtension: '.ogg',
|
||||
|
||||
permissions: ["device-storage:music"],
|
||||
|
||||
@ -402,6 +421,7 @@ var gData = [
|
||||
{
|
||||
type: 'sdcard',
|
||||
shouldPass: true,
|
||||
fileExtension: '.txt',
|
||||
|
||||
permissions: ["device-storage:sdcard"],
|
||||
|
||||
@ -412,6 +432,7 @@ var gData = [
|
||||
{
|
||||
type: 'pictures',
|
||||
shouldPass: true,
|
||||
fileExtension: '.png',
|
||||
|
||||
app: "https://example.com/manifest_cert.webapp",
|
||||
permissions: ["device-storage:pictures"],
|
||||
@ -421,6 +442,7 @@ var gData = [
|
||||
{
|
||||
type: 'videos',
|
||||
shouldPass: true,
|
||||
fileExtension: '.ogv',
|
||||
|
||||
app: "https://example.com/manifest_cert.webapp",
|
||||
permissions: ["device-storage:videos"],
|
||||
@ -430,6 +452,7 @@ var gData = [
|
||||
{
|
||||
type: 'music',
|
||||
shouldPass: true,
|
||||
fileExtension: '.ogg',
|
||||
|
||||
app: "https://example.com/manifest_cert.webapp",
|
||||
permissions: ["device-storage:music"],
|
||||
@ -439,6 +462,7 @@ var gData = [
|
||||
{
|
||||
type: 'sdcard',
|
||||
shouldPass: true,
|
||||
fileExtension: '.txt',
|
||||
|
||||
app: "https://example.com/manifest_cert.webapp",
|
||||
permissions: ["device-storage:sdcard"],
|
||||
@ -590,7 +614,7 @@ function runTest() {
|
||||
}
|
||||
}
|
||||
|
||||
function createTestFile() {
|
||||
function createTestFile(extension) {
|
||||
try {
|
||||
const Cc = SpecialPowers.Cc;
|
||||
const Ci = SpecialPowers.Ci;
|
||||
@ -598,12 +622,12 @@ try {
|
||||
var f = directoryService.get("TmpD", Ci.nsIFile);
|
||||
f.appendRelativePath("device-storage-testing");
|
||||
f.remove(true);
|
||||
f.appendRelativePath("testfile");
|
||||
f.appendRelativePath("testfile" + extension);
|
||||
f.create(Ci.nsIFile.NORMAL_FILE_TYPE, 0666);
|
||||
} catch(e) {}
|
||||
}
|
||||
|
||||
createTestFile();
|
||||
createTestFile('.txt');
|
||||
var gTestRunner = runTest();
|
||||
SpecialPowers.addPermission("browser", true, gTestUri);
|
||||
|
||||
|
@ -343,6 +343,9 @@ ContentChild::InitXPCOM()
|
||||
bool isOffline;
|
||||
SendGetXPCOMProcessAttributes(&isOffline);
|
||||
RecvSetOffline(isOffline);
|
||||
|
||||
DebugOnly<FileUpdateDispatcher*> observer = FileUpdateDispatcher::GetSingleton();
|
||||
NS_ASSERTION(observer, "FileUpdateDispatcher is null");
|
||||
}
|
||||
|
||||
PMemoryReportRequestChild*
|
||||
@ -1010,7 +1013,7 @@ ContentChild::RecvFlushMemory(const nsString& reason)
|
||||
mozilla::services::GetObserverService();
|
||||
if (os)
|
||||
os->NotifyObservers(nullptr, "memory-pressure", reason.get());
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -359,7 +359,7 @@ PrivilegesForApp(mozIApplication* aApp)
|
||||
const SpecialPermission specialPermissions[] = {
|
||||
// FIXME/bug 785592: implement a CameraBridge so we don't have
|
||||
// to hack around with OS permissions
|
||||
{ "camera", base::PRIVILEGES_INHERIT },
|
||||
{ "camera", base::PRIVILEGES_CAMERA },
|
||||
// FIXME/bug 793034: change our video architecture so that we
|
||||
// can stream video from remote processes
|
||||
{ "deprecated-hwvideo", base::PRIVILEGES_VIDEO }
|
||||
@ -507,6 +507,9 @@ ContentParent::Init()
|
||||
unused << SendActivateA11y();
|
||||
}
|
||||
#endif
|
||||
|
||||
DebugOnly<FileUpdateDispatcher*> observer = FileUpdateDispatcher::GetSingleton();
|
||||
NS_ASSERTION(observer, "FileUpdateDispatcher is null");
|
||||
}
|
||||
|
||||
void
|
||||
@ -1969,6 +1972,25 @@ ContentParent::RecvAsyncMessage(const nsString& aMsg,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
ContentParent::RecvFilePathUpdateNotify(const nsString& aType, const nsString& aFilePath, const nsCString& aReason)
|
||||
{
|
||||
nsCOMPtr<nsIFile> file;
|
||||
nsresult rv = NS_NewLocalFile(aFilePath, false, getter_AddRefs(file));
|
||||
if (NS_FAILED(rv)) {
|
||||
// ignore
|
||||
return true;
|
||||
}
|
||||
nsRefPtr<DeviceStorageFile> dsf = new DeviceStorageFile(aType, file);
|
||||
|
||||
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
|
||||
if (!obs) {
|
||||
return false;
|
||||
}
|
||||
obs->NotifyObservers(dsf, "file-watcher-update", NS_ConvertASCIItoUTF16(aReason).get());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
ContentParent::RecvAddGeolocationListener(const IPC::Principal& aPrincipal)
|
||||
{
|
||||
|
@ -302,6 +302,10 @@ private:
|
||||
virtual bool RecvAsyncMessage(const nsString& aMsg,
|
||||
const ClonedMessageData& aData);
|
||||
|
||||
virtual bool RecvFilePathUpdateNotify(const nsString& aType,
|
||||
const nsString& aFilePath,
|
||||
const nsCString& aReason);
|
||||
|
||||
virtual bool RecvAddGeolocationListener(const IPC::Principal& aPrincipal);
|
||||
virtual bool RecvRemoveGeolocationListener();
|
||||
virtual bool RecvSetGeolocationHigherAccuracy(const bool& aEnable);
|
||||
|
@ -443,6 +443,9 @@ parent:
|
||||
|
||||
async AudioChannelChangedNotification();
|
||||
|
||||
async FilePathUpdateNotify(nsString aType,
|
||||
nsString aFilepath,
|
||||
nsCString aReason);
|
||||
both:
|
||||
AsyncMessage(nsString aMessage, ClonedMessageData aData);
|
||||
};
|
||||
|
@ -9,7 +9,6 @@ const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
Cu.import("resource://gre/modules/FileUtils.jsm");
|
||||
Cu.import("resource://gre/modules/NetUtil.jsm");
|
||||
|
||||
const RIL_MMSSERVICE_CONTRACTID = "@mozilla.org/mms/rilmmsservice;1";
|
||||
@ -21,14 +20,6 @@ const kNetworkInterfaceStateChangedTopic = "network-interface-state-changed";
|
||||
const kXpcomShutdownObserverTopic = "xpcom-shutdown";
|
||||
const kPrefenceChangedObserverTopic = "nsPref:changed";
|
||||
|
||||
// File modes for saving MMS attachments.
|
||||
const FILE_OPEN_MODE = FileUtils.MODE_CREATE
|
||||
| FileUtils.MODE_WRONLY
|
||||
| FileUtils.MODE_TRUNCATE;
|
||||
|
||||
// Size of each segment in a nsIStorageStream. Must be a power of two.
|
||||
const STORAGE_STREAM_SEGMENT_SIZE = 4096;
|
||||
|
||||
// HTTP status codes:
|
||||
// @see http://tools.ietf.org/html/rfc2616#page-39
|
||||
const HTTP_STATUS_OK = 200;
|
||||
@ -446,79 +437,6 @@ MmsService.prototype = {
|
||||
}).bind(this));
|
||||
},
|
||||
|
||||
/**
|
||||
* @param file
|
||||
* A nsIFile object indicating where to save the data.
|
||||
* @param data
|
||||
* An array of raw octets.
|
||||
* @param callback
|
||||
* Callback function when I/O is done.
|
||||
*
|
||||
* @return An nsIRequest representing the copy operation returned by
|
||||
* NetUtil.asyncCopy().
|
||||
*/
|
||||
saveContentToFile: function saveContentToFile(file, data, callback) {
|
||||
// Write to a StorageStream for NetUtil.asyncCopy()
|
||||
let sstream = Cc["@mozilla.org/storagestream;1"]
|
||||
.createInstance(Ci.nsIStorageStream);
|
||||
sstream.init(STORAGE_STREAM_SEGMENT_SIZE, data.length, null);
|
||||
let bostream = Cc["@mozilla.org/binaryoutputstream;1"]
|
||||
.createInstance(Ci.nsIBinaryOutputStream);
|
||||
bostream.setOutputStream(sstream.getOutputStream(0));
|
||||
bostream.writeByteArray(data, data.length);
|
||||
bostream.close();
|
||||
|
||||
// Write message body to file
|
||||
let ofstream = FileUtils.openSafeFileOutputStream(file, FILE_OPEN_MODE);
|
||||
return NetUtil.asyncCopy(sstream.newInputStream(0), ofstream, callback);
|
||||
},
|
||||
|
||||
/**
|
||||
* @param msg
|
||||
* A MMS message object.
|
||||
* @param callback
|
||||
* A callback function that accepts one argument as retrieved message.
|
||||
*/
|
||||
saveMessageContent: function saveMessageContent(msg, callback) {
|
||||
function saveCallback(obj, counter, status) {
|
||||
obj.saved = Components.isSuccessCode(status);
|
||||
debug("saveMessageContent: " + obj.file.path + ", saved: " + obj.saved);
|
||||
|
||||
// The async copy callback may not be invoked in order, so we only
|
||||
// callback after all of them were done.
|
||||
counter.count++;
|
||||
if (counter.count >= counter.max) {
|
||||
if (callback) {
|
||||
callback(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let tid = msg.headers["x-mms-transaction-id"];
|
||||
if (msg.parts) {
|
||||
let counter = {max: msg.parts.length, count: 0};
|
||||
|
||||
msg.parts.forEach((function (part, index) {
|
||||
part.file = FileUtils.getFile("ProfD", ["mms", tid, index], true);
|
||||
if (!part.content) {
|
||||
saveCallback(part, counter, Cr.NS_ERROR_NOT_AVAILABLE);
|
||||
} else {
|
||||
this.saveContentToFile(part.file, part.content,
|
||||
saveCallback.bind(null, part, counter));
|
||||
}
|
||||
}).bind(this));
|
||||
} else if (msg.content) {
|
||||
msg.file = FileUtils.getFile("ProfD", ["mms", tid, "content"], true);
|
||||
this.saveContentToFile(msg.file, msg.content,
|
||||
saveCallback.bind(null, msg, {max: 1, count: 0}));
|
||||
} else {
|
||||
// Nothing to save here.
|
||||
if (callback) {
|
||||
callback(msg);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* @param data
|
||||
* A wrapped object containing raw PDU data.
|
||||
@ -650,8 +568,9 @@ MmsService.prototype = {
|
||||
callbackIfValid(status, msg);
|
||||
return;
|
||||
}
|
||||
|
||||
this.saveMessageContent(msg, callbackIfValid.bind(null, MMS.MMS_PDU_ERROR_OK));
|
||||
// Todo: Please add code for inserting msg into database
|
||||
// right here.
|
||||
// see bug id: 811252 - B2G MMS: implement MMS database
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -2237,7 +2237,12 @@ this.PduHelper = {
|
||||
|
||||
headers = this.parseHeaders(data, headersEnd, headers);
|
||||
|
||||
let content = Octet.decodeMultiple(data, contentEnd);
|
||||
let octetArray = Octet.decodeMultiple(data, contentEnd);
|
||||
let content = null;
|
||||
if (octetArray) {
|
||||
content = new Blob([octetArray],
|
||||
{"type" : headers["content-type"].media});
|
||||
}
|
||||
|
||||
parts[i] = {
|
||||
index: i,
|
||||
|
@ -383,9 +383,9 @@ function getTxBytes(params, callback) {
|
||||
function setAccessPoint(params, callback) {
|
||||
let command = "softap set " + params.ifname +
|
||||
" " + params.wifictrlinterfacename +
|
||||
" " + params.ssid +
|
||||
" \"" + params.ssid + "\"" +
|
||||
" " + params.security +
|
||||
" " + params.key +
|
||||
" \"" + params.key + "\"" +
|
||||
" " + "6 0 8";
|
||||
return doCommand(command, callback);
|
||||
}
|
||||
|
@ -1470,7 +1470,11 @@ let RIL = {
|
||||
debug("Setting manual network selection: " + options.mcc + options.mnc);
|
||||
}
|
||||
|
||||
let numeric = String(options.mcc) + options.mnc;
|
||||
// TODO: Bug 828307 - B2G RIL: Change to store MNC/MCC values from integer to string
|
||||
let mnc = options.mnc.toString();
|
||||
if (mnc.length == 1)
|
||||
mnc = "0" + mnc;
|
||||
let numeric = options.mcc.toString() + mnc;
|
||||
Buf.newParcel(REQUEST_SET_NETWORK_SELECTION_MANUAL, options);
|
||||
Buf.writeString(numeric);
|
||||
Buf.sendParcel();
|
||||
@ -7693,7 +7697,7 @@ let StkProactiveCmdHelper = {
|
||||
retrieveTextString: function retrieveTextString(length) {
|
||||
if (!length) {
|
||||
// null string.
|
||||
return null;
|
||||
return {textString: null};
|
||||
}
|
||||
|
||||
let text = {
|
||||
@ -9120,7 +9124,10 @@ let ICCRecordHelper = {
|
||||
getPNN: function getPNN() {
|
||||
let pnn = [];
|
||||
function callback(options) {
|
||||
let pnnElement = RIL.iccInfoPrivate.PNN = {};
|
||||
let pnnElement = {
|
||||
fullName: "",
|
||||
shortName: ""
|
||||
};
|
||||
let len = Buf.readUint32();
|
||||
let readLen = 0;
|
||||
while (len > readLen) {
|
||||
|
@ -815,6 +815,74 @@ add_test(function test_stk_proactive_command_event_list() {
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
/**
|
||||
* Verify Proactive Command : Get Input
|
||||
*/
|
||||
add_test(function test_stk_proactive_command_get_input() {
|
||||
let worker = newUint8Worker();
|
||||
let pduHelper = worker.GsmPDUHelper;
|
||||
let berHelper = worker.BerTlvHelper;
|
||||
let stkHelper = worker.StkProactiveCmdHelper;
|
||||
let stkCmdHelper = worker.StkCommandParamsFactory;
|
||||
|
||||
let get_input_1 = [
|
||||
0xD0,
|
||||
0x1E,
|
||||
0x81, 0x03, 0x01, 0x23, 0x8F,
|
||||
0x82, 0x02, 0x81, 0x82,
|
||||
0x8D, 0x05, 0x04, 0x54, 0x65, 0x78, 0x74,
|
||||
0x91, 0x02, 0x01, 0x10,
|
||||
0x17, 0x08, 0x04, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6C, 0x74];
|
||||
|
||||
for (let i = 0; i < get_input_1.length; i++) {
|
||||
pduHelper.writeHexOctet(get_input_1[i]);
|
||||
}
|
||||
|
||||
let berTlv = berHelper.decode(get_input_1.length);
|
||||
let ctlvs = berTlv.value;
|
||||
let tlv = stkHelper.searchForTag(COMPREHENSIONTLV_TAG_COMMAND_DETAILS, ctlvs);
|
||||
do_check_eq(tlv.value.commandNumber, 0x01);
|
||||
do_check_eq(tlv.value.typeOfCommand, STK_CMD_GET_INPUT);
|
||||
|
||||
let input = stkCmdHelper.createParam(tlv.value, ctlvs);
|
||||
do_check_eq(input.text, "Text");
|
||||
do_check_eq(input.isAlphabet, true);
|
||||
do_check_eq(input.isUCS2, true);
|
||||
do_check_eq(input.hideInput, true);
|
||||
do_check_eq(input.isPacked, true);
|
||||
do_check_eq(input.isHelpAvailable, true);
|
||||
do_check_eq(input.minLength, 0x01);
|
||||
do_check_eq(input.maxLength, 0x10);
|
||||
do_check_eq(input.defaultText, "Default");
|
||||
|
||||
let get_input_2 = [
|
||||
0xD0,
|
||||
0x11,
|
||||
0x81, 0x03, 0x01, 0x23, 0x00,
|
||||
0x82, 0x02, 0x81, 0x82,
|
||||
0x8D, 0x00,
|
||||
0x91, 0x02, 0x01, 0x10,
|
||||
0x17, 0x00];
|
||||
|
||||
for (let i = 0; i < get_input_2.length; i++) {
|
||||
pduHelper.writeHexOctet(get_input_2[i]);
|
||||
}
|
||||
|
||||
berTlv = berHelper.decode(get_input_2.length);
|
||||
ctlvs = berTlv.value;
|
||||
tlv = stkHelper.searchForTag(COMPREHENSIONTLV_TAG_COMMAND_DETAILS, ctlvs);
|
||||
do_check_eq(tlv.value.commandNumber, 0x01);
|
||||
do_check_eq(tlv.value.typeOfCommand, STK_CMD_GET_INPUT);
|
||||
|
||||
input = stkCmdHelper.createParam(tlv.value, ctlvs);
|
||||
do_check_eq(input.text, null);
|
||||
do_check_eq(input.minLength, 0x01);
|
||||
do_check_eq(input.maxLength, 0x10);
|
||||
do_check_eq(input.defaultText, null);
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
add_test(function test_spn_display_condition() {
|
||||
let worker = newWorker({
|
||||
postRILMessage: function fakePostRILMessage(data) {
|
||||
|
@ -6,10 +6,12 @@
|
||||
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?>
|
||||
|
||||
<script type="text/javascript">
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
|
||||
|
||||
Components.utils.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
const Ci = Components.interfaces;
|
||||
const CONTENT_PAGE = "http://mochi.test:8888/chrome/dom/tests/mochitest/localstorage/page_blank.html";
|
||||
const slavePath = "/tests/dom/tests/mochitest/localstorage/";
|
||||
@ -19,17 +21,15 @@ var quota;
|
||||
try {
|
||||
quota = Services.prefs.getIntPref("dom.storage.default_quota");
|
||||
} catch (ex) {
|
||||
quota = 5*1024;
|
||||
quota = 5 * 1024;
|
||||
}
|
||||
Services.prefs.setIntPref("browser.startup.page", 0);
|
||||
Services.prefs.setIntPref("dom.storage.default_quota", 1);
|
||||
|
||||
var mainWindow = window.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIWebNavigation)
|
||||
.QueryInterface(Ci.nsIDocShellTreeItem)
|
||||
.rootTreeItem
|
||||
.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIDOMWindow);
|
||||
|
||||
var mainWindow = window.QueryInterface(Ci.nsIInterfaceRequestor).
|
||||
getInterface(Ci.nsIWebNavigation).QueryInterface(Ci.nsIDocShellTreeItem).
|
||||
rootTreeItem.QueryInterface(Ci.nsIInterfaceRequestor).
|
||||
getInterface(Ci.nsIDOMWindow);
|
||||
var slaveLoadsPending = 1;
|
||||
var slaveOrigin = "";
|
||||
var slave = null;
|
||||
@ -37,10 +37,11 @@ var failureRegExp = new RegExp("^FAILURE");
|
||||
|
||||
function startTest() {
|
||||
testOnWindow(true, function(aWindow) {
|
||||
info("Private window loaded");
|
||||
var frame = aWindow.content.document.createElement("iframe");
|
||||
aWindow.content.document.body.appendChild(frame);
|
||||
aWindow.content.addEventListener("message", function(aEvt) {
|
||||
onMessageReceived(aEvt, aWindow)
|
||||
aWindow.content.addEventListener("message", function(aEvent) {
|
||||
onMessageReceived(aEvent, aWindow)
|
||||
}, false);
|
||||
slave = aWindow.content.frames[0];
|
||||
|
||||
@ -51,6 +52,7 @@ function startTest() {
|
||||
function doNextTest(aWindow) {
|
||||
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
|
||||
|
||||
info("Running test: " + currentTest);
|
||||
switch (currentTest) {
|
||||
// Initialy setup the quota to testing value of 1024B and
|
||||
// set a 500 bytes key with name length 1 (allocate 501 bytes)
|
||||
@ -125,6 +127,7 @@ function doNextTest(aWindow) {
|
||||
break;
|
||||
|
||||
default:
|
||||
Services.prefs.clearUserPref("browser.startup.page")
|
||||
Services.prefs.setIntPref("dom.storage.default_quota", quota);
|
||||
aWindow.close();
|
||||
SimpleTest.finish();
|
||||
@ -134,29 +137,23 @@ function doNextTest(aWindow) {
|
||||
}
|
||||
|
||||
function onMessageReceived(event, aWindow) {
|
||||
info("Message received: " + event.data);
|
||||
switch (event.data) {
|
||||
// Indication of the frame onload event
|
||||
case "frame loaded":
|
||||
if (--slaveLoadsPending)
|
||||
break;
|
||||
|
||||
// Just fall through...
|
||||
|
||||
// Indication of successfully finished step of a test
|
||||
case "perf":
|
||||
if (event.data == "perf")
|
||||
doStep();
|
||||
|
||||
slave.postMessage("step", slaveOrigin);
|
||||
break;
|
||||
|
||||
// Indication of all test parts finish (from any of the frames)
|
||||
case "done":
|
||||
aWindow.content.localStorage.clear();
|
||||
slaveLoadsPending = 1;
|
||||
doNextTest(aWindow);
|
||||
break;
|
||||
|
||||
// Any other message indicates error or succes message of a test
|
||||
default:
|
||||
SimpleTest.ok(!event.data.match(failureRegExp), event.data);
|
||||
@ -169,7 +166,7 @@ function testOnWindow(aIsPrivate, aCallback) {
|
||||
win.addEventListener("load", function onLoad() {
|
||||
win.removeEventListener("load", onLoad, false);
|
||||
win.addEventListener("DOMContentLoaded", function onInnerLoad() {
|
||||
if (win.content.location.href == "about:privatebrowsing") {
|
||||
if (win.content.location.href != CONTENT_PAGE) {
|
||||
win.gBrowser.loadURI(CONTENT_PAGE);
|
||||
return;
|
||||
}
|
||||
@ -180,13 +177,8 @@ function testOnWindow(aIsPrivate, aCallback) {
|
||||
}, true);
|
||||
}
|
||||
|
||||
function doStep() {
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
</script>
|
||||
</head>
|
||||
<body onload="startTest();">
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
|
@ -3271,6 +3271,7 @@ nsWebBrowserPersist::CloneNodeWithFixedUpAttributes(
|
||||
case NS_FORM_INPUT_URL:
|
||||
case NS_FORM_INPUT_NUMBER:
|
||||
case NS_FORM_INPUT_DATE:
|
||||
case NS_FORM_INPUT_TIME:
|
||||
nodeAsInput->GetValue(valueStr);
|
||||
// Avoid superfluous value="" serialization
|
||||
if (valueStr.IsEmpty())
|
||||
|
@ -126,7 +126,7 @@ GetHostForPrincipal(nsIPrincipal* aPrincipal, nsACString& aHost)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
class AppUninstallObserver MOZ_FINAL : public nsIObserver {
|
||||
class AppClearDataObserver MOZ_FINAL : public nsIObserver {
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
@ -134,24 +134,29 @@ public:
|
||||
NS_IMETHODIMP
|
||||
Observe(nsISupports *aSubject, const char *aTopic, const PRUnichar *data)
|
||||
{
|
||||
MOZ_ASSERT(!nsCRT::strcmp(aTopic, "webapps-uninstall"));
|
||||
MOZ_ASSERT(!nsCRT::strcmp(aTopic, "webapps-clear-data"));
|
||||
|
||||
nsCOMPtr<nsIAppsService> appsService = do_GetService("@mozilla.org/AppsService;1");
|
||||
nsCOMPtr<mozIApplication> app;
|
||||
|
||||
appsService->GetAppFromObserverMessage(nsAutoString(data), getter_AddRefs(app));
|
||||
NS_ENSURE_TRUE(app, NS_ERROR_UNEXPECTED);
|
||||
nsCOMPtr<mozIApplicationClearPrivateDataParams> params =
|
||||
do_QueryInterface(aSubject);
|
||||
if (!params) {
|
||||
NS_ERROR("'webapps-clear-data' notification's subject should be a mozIApplicationClearPrivateDataParams");
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
uint32_t appId;
|
||||
app->GetLocalId(&appId);
|
||||
MOZ_ASSERT(appId != nsIScriptSecurityManager::NO_APP_ID);
|
||||
nsresult rv = params->GetAppId(&appId);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
bool browserOnly;
|
||||
rv = params->GetBrowserOnly(&browserOnly);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIPermissionManager> permManager = do_GetService("@mozilla.org/permissionmanager;1");
|
||||
return permManager->RemovePermissionsForApp(appId);
|
||||
return permManager->RemovePermissionsForApp(appId, browserOnly);
|
||||
}
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS1(AppUninstallObserver, nsIObserver)
|
||||
NS_IMPL_ISUPPORTS1(AppClearDataObserver, nsIObserver)
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
@ -271,10 +276,10 @@ NS_IMETHODIMP DeleteFromMozHostListener::HandleCompletion(uint16_t aReason)
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
nsPermissionManager::AppUninstallObserverInit()
|
||||
nsPermissionManager::AppClearDataObserverInit()
|
||||
{
|
||||
nsCOMPtr<nsIObserverService> observerService = do_GetService("@mozilla.org/observer-service;1");
|
||||
observerService->AddObserver(new AppUninstallObserver(), "webapps-uninstall", /* holdsWeak= */ false);
|
||||
observerService->AddObserver(new AppClearDataObserver(), "webapps-clear-data", /* holdsWeak= */ false);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@ -1162,7 +1167,7 @@ nsPermissionManager::GetPermissionsForApp(nsPermissionManager::PermissionHashKey
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPermissionManager::RemovePermissionsForApp(uint32_t aAppId)
|
||||
nsPermissionManager::RemovePermissionsForApp(uint32_t aAppId, bool aBrowserOnly)
|
||||
{
|
||||
ENSURE_NOT_CHILD_PROCESS;
|
||||
NS_ENSURE_ARG(aAppId != nsIScriptSecurityManager::NO_APP_ID);
|
||||
@ -1179,6 +1184,10 @@ nsPermissionManager::RemovePermissionsForApp(uint32_t aAppId)
|
||||
sql.AppendLiteral("DELETE FROM moz_hosts WHERE appId=");
|
||||
sql.AppendInt(aAppId);
|
||||
|
||||
if (aBrowserOnly) {
|
||||
sql.AppendLiteral(" AND isInBrowserElement=1");
|
||||
}
|
||||
|
||||
nsCOMPtr<mozIStorageAsyncStatement> removeStmt;
|
||||
nsresult rv = mDBConn->CreateAsyncStatement(sql, getter_AddRefs(removeStmt));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
@ -202,7 +202,7 @@ public:
|
||||
* That way, we can prevent have nsPermissionManager created at startup just
|
||||
* to be able to clear data when an application is uninstalled.
|
||||
*/
|
||||
static void AppUninstallObserverInit();
|
||||
static void AppClearDataObserverInit();
|
||||
|
||||
private:
|
||||
int32_t GetTypeIndex(const char *aTypeString,
|
||||
|
@ -54,8 +54,10 @@ MOCHITEST_FILES = \
|
||||
|
||||
MOCHITEST_CHROME_FILES = \
|
||||
test_permissionmanager_app_isolation.html \
|
||||
test_app_cleardata_permissions.html \
|
||||
test_app_uninstall_permissions.html \
|
||||
test_app_uninstall_cookies.html \
|
||||
frame_clear_browser_data.html \
|
||||
channel_utils.js \
|
||||
$(NULL)
|
||||
|
||||
|
15
extensions/cookie/test/frame_clear_browser_data.html
Normal file
15
extensions/cookie/test/frame_clear_browser_data.html
Normal file
@ -0,0 +1,15 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
</body>
|
||||
<script>
|
||||
addEventListener('message', function(e) {
|
||||
if (e.data == 'clear') {
|
||||
navigator.mozApps.getSelf().onsuccess = function() {
|
||||
this.result.clearBrowserData();
|
||||
document.body.innerHTML = "<done></done>";
|
||||
};
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</html>
|
213
extensions/cookie/test/test_app_cleardata_permissions.html
Normal file
213
extensions/cookie/test/test_app_cleardata_permissions.html
Normal file
@ -0,0 +1,213 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Tests that clearing mozbrowser private data removes the onlyInBrowser permissions</title>
|
||||
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?>
|
||||
</head>
|
||||
<body>
|
||||
<p id="display"></p>
|
||||
<div id="content">
|
||||
<iframe src="http://example.com/tests/error404"></iframe>
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script type="application/javascript;version=1.7">
|
||||
|
||||
const Ci = Components.interfaces;
|
||||
const Cc = Components.classes;
|
||||
const Cu = Components.utils;
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
var permManager = Cc["@mozilla.org/permissionmanager;1"]
|
||||
.getService(Ci.nsIPermissionManager);
|
||||
var appsService = Cc['@mozilla.org/AppsService;1']
|
||||
.getService(Ci.nsIAppsService);
|
||||
var secMan = Cc['@mozilla.org/scriptsecuritymanager;1']
|
||||
.getService(Ci.nsIScriptSecurityManager);
|
||||
var ioService = Cc["@mozilla.org/network/io-service;1"]
|
||||
.getService(Components.interfaces.nsIIOService);
|
||||
|
||||
var Webapps = {};
|
||||
Cu.import("resource://gre/modules/Webapps.jsm", Webapps);
|
||||
|
||||
/**
|
||||
* This function will make sure that the next applications we try to install
|
||||
* will be installed. That means it will behave like if the user allowed the app
|
||||
* to be installed in the door hanger.
|
||||
*/
|
||||
function confirmNextInstall() {
|
||||
var panel = window.top.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIWebNavigation)
|
||||
.QueryInterface(Ci.nsIDocShell)
|
||||
.chromeEventHandler.ownerDocument.defaultView
|
||||
.PopupNotifications.panel
|
||||
|
||||
panel.addEventListener("popupshown", function() {
|
||||
panel.removeEventListener("popupshown", arguments.callee, false);
|
||||
this.childNodes[0].button.doCommand();
|
||||
}, false);
|
||||
}
|
||||
|
||||
// If aAppId = -1, returns permissions count, regardless of app.
|
||||
function getPermissionCountForApp(aAppId) {
|
||||
var nbPermissions = 0;
|
||||
var enumerator = permManager.enumerator;
|
||||
|
||||
while (enumerator.hasMoreElements()) {
|
||||
var permission = enumerator.getNext().QueryInterface(Ci.nsIPermission);
|
||||
|
||||
if (permission.appId == aAppId || aAppId == -1) {
|
||||
nbPermissions++;
|
||||
}
|
||||
}
|
||||
|
||||
return nbPermissions;
|
||||
}
|
||||
|
||||
permManager.addFromPrincipal(window.document.nodePrincipal, "webapps-manage",
|
||||
Ci.nsIPermissionManager.ALLOW_ACTION);
|
||||
permManager.addFromPrincipal(window.document.nodePrincipal, "browser",
|
||||
Ci.nsIPermissionManager.ALLOW_ACTION);
|
||||
|
||||
var previousPrefs = {
|
||||
mozBrowserFramesEnabled: null,
|
||||
installerDryRun: null,
|
||||
};
|
||||
|
||||
// Save the prefs we want to change (so we can re-set them later) and set them
|
||||
// to the needed value.
|
||||
try {
|
||||
previousPrefs.mozBrowserFramesEnabled = SpecialPowers.getBoolPref('dom.mozBrowserFramesEnabled');
|
||||
} catch(e)
|
||||
{
|
||||
}
|
||||
SpecialPowers.setBoolPref('dom.mozBrowserFramesEnabled', true);
|
||||
|
||||
try {
|
||||
previousPrefs.installerDryRun = SpecialPowers.getBoolPref('browser.mozApps.installer.dry_run');
|
||||
} catch(e) {
|
||||
}
|
||||
SpecialPowers.setBoolPref('browser.mozApps.installer.dry_run', true);
|
||||
|
||||
// We want to simulate that all apps are launchable, for testing purpose.
|
||||
var gPreviousLaunchableValue = Webapps.DOMApplicationRegistry.allAppsLaunchable;
|
||||
Webapps.DOMApplicationRegistry.allAppsLaunchable = true;
|
||||
|
||||
// URL of the manifest of the app we want to install.
|
||||
const gManifestURL = "http://www.example.com:80/chrome/dom/tests/mochitest/webapps/apps/basic.webapp";
|
||||
// ID of the installed app.
|
||||
var gTestAppId = 0;
|
||||
|
||||
addLoadEvent(function() {
|
||||
confirmNextInstall();
|
||||
|
||||
navigator.mozApps.install(gManifestURL, null).onsuccess = function() {
|
||||
gTestAppId = appsService.getAppLocalIdByManifestURL(gManifestURL);
|
||||
|
||||
is(getPermissionCountForApp(gTestAppId), 0, "App should have no permission");
|
||||
|
||||
var currentPermissionCount = getPermissionCountForApp(-1);
|
||||
|
||||
var principal = secMan.getAppCodebasePrincipal(ioService.newURI("http://www.example.com", null, null),
|
||||
gTestAppId, true);
|
||||
|
||||
permManager.addFromPrincipal(principal, "foobar", Ci.nsIPermissionManager.ALLOW_ACTION);
|
||||
permManager.addFromPrincipal(principal, "foo", Ci.nsIPermissionManager.DENY_ACTION);
|
||||
permManager.addFromPrincipal(principal, "bar", Ci.nsIPermissionManager.ALLOW_ACTION, Ci.nsIPermissionManager.EXPIRE_SESSION, 0);
|
||||
|
||||
principal = secMan.getAppCodebasePrincipal(ioService.newURI("http://www.example.org", null, null),
|
||||
gTestAppId, true);
|
||||
permManager.addFromPrincipal(principal, "foobar", Ci.nsIPermissionManager.ALLOW_ACTION);
|
||||
|
||||
is(getPermissionCountForApp(gTestAppId), 4, "App should have 4 permissions");
|
||||
|
||||
var frame = document.createElement('iframe');
|
||||
frame.setAttribute('mozbrowser', '');
|
||||
frame.setAttribute('mozapp', gManifestURL);
|
||||
frame.src = 'http://www.example.com/chrome/extensions/cookie/test/frame_clear_browser_data.html';
|
||||
frame.name = 'app';
|
||||
|
||||
frame.addEventListener('load', appFrameLoadEvent);
|
||||
|
||||
document.body.appendChild(frame);
|
||||
};
|
||||
});
|
||||
|
||||
function appFrameLoadEvent() {
|
||||
/*
|
||||
* The app frame has been loaded. We can now add permissions for the app to
|
||||
* create browsers and we will load a page in this browser and wait for the
|
||||
* load event.
|
||||
*/
|
||||
permManager.addFromPrincipal(window.frames[1].document.nodePrincipal, "browser",
|
||||
Ci.nsIPermissionManager.ALLOW_ACTION);
|
||||
|
||||
var frame = document.createElement('iframe');
|
||||
frame.setAttribute('mozbrowser', '');
|
||||
frame.src = 'http://example.com/tests/error404_2';
|
||||
|
||||
frame.addEventListener('load', browserLoadEvent);
|
||||
|
||||
document.getElementsByName('app')[0].contentDocument.body.appendChild(frame);
|
||||
}
|
||||
|
||||
function browserLoadEvent() {
|
||||
/*
|
||||
* The browser inside the app has loaded.
|
||||
*/
|
||||
|
||||
frames[1].postMessage("clear", "http://www.example.com");
|
||||
|
||||
waitForClearBrowserData();
|
||||
};
|
||||
|
||||
function waitForClearBrowserData() {
|
||||
SimpleTest.executeSoon(function() {
|
||||
if (frames[1].document.getElementsByTagName('done').length == 0) {
|
||||
waitForClearBrowserData();
|
||||
} else {
|
||||
checks();
|
||||
}
|
||||
});
|
||||
}
|
||||
function checks() {
|
||||
navigator.mozApps.mgmt.getAll().onsuccess = function() {
|
||||
for (i in this.result) {
|
||||
var app = this.result[i];
|
||||
if (app.manifestURL == gManifestURL) {
|
||||
is(getPermissionCountForApp(gTestAppId), 0, "App should have 0 permissions");
|
||||
|
||||
Webapps.DOMApplicationRegistry.allAppsLaunchable = gPreviousLaunchableValue;
|
||||
|
||||
// Now we uninstall the app and make sure everything is clean.
|
||||
app.uninstall().onsuccess = function() {
|
||||
is(getPermissionCountForApp(gTestAppId), 0, "App should have 0 permissions");
|
||||
finish();
|
||||
};
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will be called when the test will be done. It is going to clear
|
||||
* all storage data, permissions, etc.
|
||||
*/
|
||||
function finish() {
|
||||
permManager.removeFromPrincipal(window.document.nodePrincipal, "webapps-manage",
|
||||
Ci.nsIPermissionManager.ALLOW_ACTION);
|
||||
permManager.removeFromPrincipal(window.document.nodePrincipal, "browser",
|
||||
Ci.nsIPermissionManager.ALLOW_ACTION);
|
||||
|
||||
SpecialPowers.setBoolPref('dom.mozBrowserFramesEnabled', previousPrefs.mozBrowserFramesEnabled);
|
||||
SpecialPowers.setBoolPref('browser.mozApps.installer.dry_run', previousPrefs.installerDryRun);
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
@ -29,10 +29,6 @@
|
||||
# include <private/android_filesystem_config.h>
|
||||
# define CHILD_UNPRIVILEGED_UID AID_APP
|
||||
# define CHILD_UNPRIVILEGED_GID AID_APP
|
||||
# define CHILD_CAMERA_UID AID_SYSTEM
|
||||
# define CHILD_CAMERA_GID AID_SDCARD_RW
|
||||
# define CHILD_VIDEO_UID AID_MEDIA
|
||||
# define CHILD_VIDEO_GID AID_AUDIO
|
||||
#else
|
||||
/*
|
||||
* On platforms that are not gonk based, we fall back to an arbitrary
|
||||
@ -239,7 +235,7 @@ bool LaunchApp(const std::vector<std::string>& argv,
|
||||
gid_t gid = CHILD_UNPRIVILEGED_GID;
|
||||
uid_t uid = CHILD_UNPRIVILEGED_UID;
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
if (privs == PRIVILEGES_UNPRIVILEGED) {
|
||||
{
|
||||
static bool checked_pix_max, pix_max_ok;
|
||||
if (!checked_pix_max) {
|
||||
checked_pix_max = true;
|
||||
@ -266,12 +262,20 @@ bool LaunchApp(const std::vector<std::string>& argv,
|
||||
}
|
||||
gid += getpid();
|
||||
uid += getpid();
|
||||
} else if (privs == PRIVILEGES_CAMERA) {
|
||||
uid = CHILD_CAMERA_UID;
|
||||
gid = CHILD_CAMERA_GID;
|
||||
} else if (privs == PRIVILEGES_VIDEO) {
|
||||
uid = CHILD_VIDEO_UID;
|
||||
gid = CHILD_VIDEO_GID;
|
||||
}
|
||||
if (privs == PRIVILEGES_CAMERA) {
|
||||
gid_t groups[] = { AID_AUDIO, AID_CAMERA, AID_SDCARD_RW };
|
||||
if (setgroups(sizeof(groups) / sizeof(groups[0]), groups) != 0) {
|
||||
DLOG(ERROR) << "FAILED TO setgroups() CHILD PROCESS, path: " << argv_cstr[0];
|
||||
_exit(127);
|
||||
}
|
||||
}
|
||||
else if (privs == PRIVILEGES_VIDEO) {
|
||||
gid_t groups[] = { AID_AUDIO, AID_MEDIA };
|
||||
if (setgroups(sizeof(groups) / sizeof(groups[0]), groups) != 0) {
|
||||
DLOG(ERROR) << "FAILED TO setgroups() CHILD PROCESS, path: " << argv_cstr[0];
|
||||
_exit(127);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (setgid(gid) != 0) {
|
||||
|
@ -2827,7 +2827,7 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor):
|
||||
ret=Type.BOOL))
|
||||
|
||||
openmeth.addstmts([
|
||||
StmtExpr(ExprAssn(p.otherProcessVar(), ExprLiteral.ZERO)),
|
||||
StmtExpr(ExprAssn(p.otherProcessVar(), ExprCall(ExprVar('base::GetCurrentProcessHandle')))),
|
||||
StmtReturn(ExprCall(ExprSelect(p.channelVar(), '.', 'Open'),
|
||||
[ aChannel, aMessageLoop, sidevar ]))
|
||||
])
|
||||
|
@ -3434,6 +3434,8 @@ nsCSSFrameConstructor::FindInputData(Element* aElement,
|
||||
SIMPLE_INT_CREATE(NS_FORM_INPUT_NUMBER, NS_NewTextControlFrame),
|
||||
// TODO: this is temporary until a frame is written: bug 773205.
|
||||
SIMPLE_INT_CREATE(NS_FORM_INPUT_DATE, NS_NewTextControlFrame),
|
||||
// TODO: this is temporary until a frame is written: bug 773205
|
||||
SIMPLE_INT_CREATE(NS_FORM_INPUT_TIME, NS_NewTextControlFrame),
|
||||
{ NS_FORM_INPUT_SUBMIT,
|
||||
FCDATA_WITH_WRAPPING_BLOCK(0, NS_NewGfxButtonControlFrame,
|
||||
nsCSSAnonBoxes::buttonContent) },
|
||||
|
@ -260,7 +260,7 @@ nsLayoutStatics::Initialize()
|
||||
|
||||
InitProcessPriorityManager();
|
||||
|
||||
nsPermissionManager::AppUninstallObserverInit();
|
||||
nsPermissionManager::AppClearDataObserverInit();
|
||||
nsCookieService::AppClearDataObserverInit();
|
||||
nsApplicationCacheService::AppClearDataObserverInit();
|
||||
|
||||
|
@ -314,12 +314,6 @@ nsTransitionManager::UpdateThrottledStyle(dom::Element* aElement,
|
||||
// We also need it for processing of the changes.
|
||||
nsChangeHint styleChange =
|
||||
oldStyle->CalcStyleDifference(newStyle, nsChangeHint(0));
|
||||
// This isn't particularly dangerous, but I want to catch if it happens:
|
||||
NS_ABORT_IF_FALSE(NS_IsHintSubset(styleChange,
|
||||
NS_CombineHint(nsChangeHint_UpdateOpacityLayer,
|
||||
NS_CombineHint(nsChangeHint_UpdateTransformLayer,
|
||||
nsChangeHint_UpdateOverflow))),
|
||||
"unexpected change hint");
|
||||
aChangeList.AppendChange(primaryFrame, primaryFrame->GetContent(),
|
||||
styleChange);
|
||||
|
||||
|
@ -1 +1,15 @@
|
||||
{"addons":[{"id":"fullscreen@mbrubeck.limpet.net","name":"Full Screen","version":"3.2","iconURL":"http://static-cdn.addons.mozilla.net/en-US/firefox/images/addon_icon/252573-32.png?modified=1310547725","homepageURL":"https://addons.mozilla.org/en-US/android/addon/full-screen-252573/?src=api"},{"id":"cloudviewer@starkravingfinkle.org","name":"Cloud Viewer","version":"2.1","iconURL":"https://static-ssl-cdn.addons.mozilla.net/img/uploads/addon_icons/295/295895-32.png?modified=1333044963","homepageURL":"https://addons.mozilla.org/en-US/android/addon/cloud-viewer/?src=api"}]}
|
||||
{
|
||||
"addons": [{
|
||||
"id": "fullscreen@mbrubeck.limpet.net",
|
||||
"name": "Full Screen",
|
||||
"version": "3.4",
|
||||
"iconURL": "https://addons.cdn.mozilla.net/img/uploads/addon_icons/252/252573-32.png?modified=1354183977",
|
||||
"homepageURL": "https://addons.mozilla.org/en-US/android/addon/full-screen-252573/?src=api"
|
||||
}, {
|
||||
"id": "cloudviewer@starkravingfinkle.org",
|
||||
"name": "Cloud Viewer",
|
||||
"version": "2.1",
|
||||
"iconURL": "https://addons.cdn.mozilla.net/img/uploads/addon_icons/295/295895-32.png?modified=1353947644",
|
||||
"homepageURL": "https://addons.mozilla.org/en-US/android/addon/cloud-viewer/?src=api"
|
||||
}]
|
||||
}
|
||||
|
@ -23,6 +23,7 @@ import android.util.Log;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationHandler;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Proxy;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
@ -730,7 +731,30 @@ final class GeckoEditable
|
||||
mActionQueue.syncWithGecko();
|
||||
target = mText;
|
||||
}
|
||||
Object ret = method.invoke(target, args);
|
||||
Object ret;
|
||||
try {
|
||||
ret = method.invoke(target, args);
|
||||
} catch (InvocationTargetException e) {
|
||||
// Bug 817386
|
||||
// Most likely Gecko has changed the text while GeckoInputConnection is
|
||||
// trying to access the text. If we pass through the exception here, Fennec
|
||||
// will crash due to a lack of exception handler. Log the exception and
|
||||
// return an empty value instead.
|
||||
if (!(e.getCause() instanceof IndexOutOfBoundsException)) {
|
||||
// Only handle IndexOutOfBoundsException for now,
|
||||
// as other exceptions might signal other bugs
|
||||
throw e;
|
||||
}
|
||||
Log.w(LOGTAG, "Exception in GeckoEditable." + method.getName(), e.getCause());
|
||||
Class<?> retClass = method.getReturnType();
|
||||
if (retClass != Void.TYPE && retClass.isPrimitive()) {
|
||||
ret = retClass.newInstance();
|
||||
} else if (retClass == String.class) {
|
||||
ret = "";
|
||||
} else {
|
||||
ret = null;
|
||||
}
|
||||
}
|
||||
if (DEBUG) {
|
||||
StringBuilder log = new StringBuilder(method.getName());
|
||||
log.append("(");
|
||||
|
@ -477,9 +477,9 @@ public class GeckoLayerClient implements LayerView.Listener, PanZoomTarget
|
||||
// At this point, we have just switched to displaying a different document than we
|
||||
// we previously displaying. This means we need to abort any panning/zooming animations
|
||||
// that are in progress and send an updated display port request to browser.js as soon
|
||||
// as possible. We accomplish this by passing true to abortPanZoomAnimation, which
|
||||
// sends the request after aborting the animation. The display port request is actually
|
||||
// a full viewport update, which is fine because if browser.js has somehow moved to
|
||||
// as possible. The call to PanZoomController.abortAnimation accomplishes this by calling the
|
||||
// forceRedraw function, which sends the viewport to gecko. The display port request is
|
||||
// actually a full viewport update, which is fine because if browser.js has somehow moved to
|
||||
// be out of sync with this first-paint viewport, then we force them back in sync.
|
||||
abortPanZoomAnimation();
|
||||
|
||||
@ -690,7 +690,7 @@ public class GeckoLayerClient implements LayerView.Listener, PanZoomTarget
|
||||
}
|
||||
|
||||
/** Implementation of PanZoomTarget */
|
||||
public void setForceRedraw() {
|
||||
public void forceRedraw() {
|
||||
mForceRedraw = true;
|
||||
if (mGeckoIsReady) {
|
||||
geometryChanged();
|
||||
|
@ -205,7 +205,7 @@ public class LayerView extends FrameLayout {
|
||||
|
||||
public void setInputConnectionHandler(InputConnectionHandler inputConnectionHandler) {
|
||||
mInputConnectionHandler = inputConnectionHandler;
|
||||
mLayerClient.setForceRedraw();
|
||||
mLayerClient.forceRedraw();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -282,7 +282,7 @@ public class PanZoomController
|
||||
// We just interrupted a double-tap animation, so force a redraw in
|
||||
// case this touchstart is just a tap that doesn't end up triggering
|
||||
// a redraw
|
||||
mTarget.setForceRedraw();
|
||||
mTarget.forceRedraw();
|
||||
// fall through
|
||||
case FLING:
|
||||
case BOUNCE:
|
||||
@ -735,7 +735,7 @@ public class PanZoomController
|
||||
stopAnimationTimer();
|
||||
|
||||
// Force a viewport synchronisation
|
||||
mTarget.setForceRedraw();
|
||||
mTarget.forceRedraw();
|
||||
}
|
||||
|
||||
/* Returns the nearest viewport metrics with no overscroll visible. */
|
||||
@ -926,7 +926,7 @@ public class PanZoomController
|
||||
startTouch(detector.getFocusX(), detector.getFocusY(), detector.getEventTime());
|
||||
|
||||
// Force a viewport synchronisation
|
||||
mTarget.setForceRedraw();
|
||||
mTarget.forceRedraw();
|
||||
|
||||
PointF point = new PointF(detector.getFocusX(), detector.getFocusY());
|
||||
GeckoEvent event = GeckoEvent.createNativeGestureEvent(GeckoEvent.ACTION_MAGNIFY_END, point, getMetrics().zoomFactor);
|
||||
|
@ -17,7 +17,8 @@ public interface PanZoomTarget {
|
||||
|
||||
public void setAnimationTarget(ImmutableViewportMetrics viewport);
|
||||
public void setViewportMetrics(ImmutableViewportMetrics viewport);
|
||||
public void setForceRedraw();
|
||||
/** This triggers an (asynchronous) viewport update/redraw. */
|
||||
public void forceRedraw();
|
||||
|
||||
public boolean post(Runnable action);
|
||||
public Object getLock();
|
||||
|
@ -476,7 +476,7 @@ let WeaveGlue = {
|
||||
// Show the day-of-week and time (HH:MM) of last sync
|
||||
let lastSync = Weave.Svc.Prefs.get("lastSync");
|
||||
if (lastSync != null) {
|
||||
let syncDate = new Date(lastSync).toLocaleFormat("%a %R");
|
||||
let syncDate = new Date(lastSync).toLocaleFormat("%a %H:%M");
|
||||
let dateStr = this._bundle.formatStringFromName("lastSync2.label", [syncDate], 1);
|
||||
sync.setAttribute("title", dateStr);
|
||||
}
|
||||
|
@ -1,8 +1,5 @@
|
||||
. "$topsrcdir/mobile/xul/config/mozconfigs/android/common"
|
||||
|
||||
# Nightlies only since this has a cost in performance
|
||||
ac_add_options --enable-js-diagnostics
|
||||
|
||||
# Build Fennec
|
||||
ac_add_options --enable-application=mobile
|
||||
|
||||
|
@ -36,7 +36,7 @@ interface nsIObserver;
|
||||
interface nsIPrincipal;
|
||||
interface nsIDOMWindow;
|
||||
|
||||
[scriptable, uuid(6c68cd87-4569-4695-8bc8-ad609f624b96)]
|
||||
[scriptable, uuid(9b6ffbb9-5536-4216-afcf-1b7cd7b54005)]
|
||||
interface nsIPermissionManager : nsISupports
|
||||
{
|
||||
/**
|
||||
@ -192,8 +192,12 @@ interface nsIPermissionManager : nsISupports
|
||||
|
||||
/**
|
||||
* Remove all permissions associated with a given app id.
|
||||
* @param aAppId The appId of the app
|
||||
* @param aBrowserOnly Whether we should remove permissions associated with
|
||||
* a browser element (true) or all permissions (false).
|
||||
*/
|
||||
void removePermissionsForApp(in unsigned long appId);
|
||||
void removePermissionsForApp(in unsigned long appId,
|
||||
in boolean browserOnly);
|
||||
};
|
||||
|
||||
%{ C++
|
||||
|
@ -291,6 +291,7 @@ nsHttpChannel::nsHttpChannel()
|
||||
, mCachedContentIsPartial(false)
|
||||
, mTransactionReplaced(false)
|
||||
, mAuthRetryPending(false)
|
||||
, mProxyAuthPending(false)
|
||||
, mResuming(false)
|
||||
, mInitedCacheEntry(false)
|
||||
, mFallbackChannel(false)
|
||||
@ -1277,6 +1278,9 @@ nsHttpChannel::ProcessResponse()
|
||||
// authentication prompt has been invoked and result
|
||||
// is expected asynchronously
|
||||
mAuthRetryPending = true;
|
||||
if (httpStatus == 407 || mTransaction->ProxyConnectFailed())
|
||||
mProxyAuthPending = true;
|
||||
|
||||
// suspend the transaction pump to stop receiving the
|
||||
// unauthenticated content data. We will throw that data
|
||||
// away when user provides credentials or resume the pump
|
||||
@ -3619,8 +3623,16 @@ nsHttpChannel::InitOfflineCacheEntry()
|
||||
}
|
||||
|
||||
if (!mResponseHead || mResponseHead->NoStore()) {
|
||||
if (mResponseHead->NoStore()) {
|
||||
mOfflineCacheEntry->AsyncDoom(nullptr);
|
||||
}
|
||||
|
||||
CloseOfflineCacheEntry();
|
||||
|
||||
if (mResponseHead->NoStore()) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -4134,6 +4146,7 @@ NS_IMETHODIMP nsHttpChannel::OnAuthAvailable()
|
||||
// triggers process of throwing away the unauthenticated data already
|
||||
// coming from the network
|
||||
mAuthRetryPending = true;
|
||||
mProxyAuthPending = false;
|
||||
LOG(("Resuming the transaction, we got credentials from user"));
|
||||
mTransactionPump->Resume();
|
||||
|
||||
@ -4145,12 +4158,23 @@ NS_IMETHODIMP nsHttpChannel::OnAuthCancelled(bool userCancel)
|
||||
LOG(("nsHttpChannel::OnAuthCancelled [this=%p]", this));
|
||||
|
||||
if (mTransactionPump) {
|
||||
// If the channel is trying to authenticate to a proxy and
|
||||
// that was canceled we cannot show the http response body
|
||||
// from the 40x as that might mislead the user into thinking
|
||||
// it was a end host response instead of a proxy reponse.
|
||||
// This must check explicitly whether a proxy auth was being done
|
||||
// because we do want to show the content if this is an error from
|
||||
// the origin server.
|
||||
if (mProxyAuthPending)
|
||||
Cancel(NS_ERROR_PROXY_CONNECTION_REFUSED);
|
||||
|
||||
// ensure call of OnStartRequest of the current listener here,
|
||||
// it would not be called otherwise at all
|
||||
nsresult rv = CallOnStartRequest();
|
||||
|
||||
// drop mAuthRetryPending flag and resume the transaction
|
||||
// this resumes load of the unauthenticated content data
|
||||
// this resumes load of the unauthenticated content data (which
|
||||
// may have been canceled if we don't want to show it)
|
||||
mAuthRetryPending = false;
|
||||
LOG(("Resuming the transaction, user cancelled the auth dialog"));
|
||||
mTransactionPump->Resume();
|
||||
@ -4158,7 +4182,8 @@ NS_IMETHODIMP nsHttpChannel::OnAuthCancelled(bool userCancel)
|
||||
if (NS_FAILED(rv))
|
||||
mTransactionPump->Cancel(rv);
|
||||
}
|
||||
|
||||
|
||||
mProxyAuthPending = false;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -331,6 +331,7 @@ private:
|
||||
uint32_t mCachedContentIsPartial : 1;
|
||||
uint32_t mTransactionReplaced : 1;
|
||||
uint32_t mAuthRetryPending : 1;
|
||||
uint32_t mProxyAuthPending : 1;
|
||||
uint32_t mResuming : 1;
|
||||
uint32_t mInitedCacheEntry : 1;
|
||||
// True if we are loading a fallback cache entry from the
|
||||
|
@ -10,6 +10,9 @@ function createURI(s) {
|
||||
}
|
||||
|
||||
function run_test() {
|
||||
// Set up a profile.
|
||||
do_get_profile();
|
||||
|
||||
var secMan = Cc["@mozilla.org/scriptsecuritymanager;1"].getService(Ci.nsIScriptSecurityManager);
|
||||
const kURI1 = "http://example.com";
|
||||
var app1 = secMan.getAppCodebasePrincipal(createURI(kURI1), 1, false);
|
||||
@ -49,4 +52,4 @@ function run_test() {
|
||||
do_check_eq(domain.value, "example.com");
|
||||
do_check_eq(user.value, "user2");
|
||||
do_check_eq(pass.value, "pass2");
|
||||
}
|
||||
}
|
||||
|
@ -165,7 +165,9 @@ var listener = {
|
||||
|
||||
onStartRequest: function test_onStartR(request, ctx) {
|
||||
try {
|
||||
if (!Components.isSuccessCode(request.status))
|
||||
// Proxy auth cancellation return failures to avoid spoofing
|
||||
if (!Components.isSuccessCode(request.status) &&
|
||||
(this.expectedCode != 407))
|
||||
do_throw("Channel should have a success code!");
|
||||
|
||||
if (!(request instanceof Ci.nsIHttpChannel))
|
||||
|
@ -57,8 +57,8 @@ function asyncCheckCacheEntryExistance(entryName, shouldExist)
|
||||
do_check_eq(status, Cr.NS_OK);
|
||||
do_check_true(!!descriptor);
|
||||
} else {
|
||||
todo_check_eq(status, Cr.NS_ERROR_CACHE_KEY_NOT_FOUND); // bug 761040
|
||||
todo_check_null(descriptor); // bug 761040
|
||||
do_check_eq(status, Cr.NS_ERROR_CACHE_KEY_NOT_FOUND);
|
||||
do_check_null(descriptor);
|
||||
}
|
||||
run_next_test();
|
||||
};
|
||||
@ -101,15 +101,14 @@ function noStoreHandler(metadata, response)
|
||||
}
|
||||
function checkNoStore(request, buffer)
|
||||
{
|
||||
todo_check_eq(buffer, ""); // bug 761040
|
||||
do_check_eq(buffer, "");
|
||||
asyncCheckCacheEntryExistance(noStoreEntry, false);
|
||||
run_next_test();
|
||||
}
|
||||
add_test(function test_noStore() {
|
||||
var chan = make_channel_for_offline_use(baseURI + noStoreEntry);
|
||||
// The no-store should cause the channel to fail to load.
|
||||
chan.asyncOpen(new ChannelListener(checkNoStore, chan
|
||||
/*, TODO(bug 761040): CL_EXPECT_FAILURE*/),
|
||||
chan.asyncOpen(new ChannelListener(checkNoStore, chan, CL_EXPECT_FAILURE),
|
||||
null);
|
||||
});
|
||||
|
||||
|
@ -84,6 +84,7 @@ function run_all_tests() {
|
||||
|
||||
let gTests;
|
||||
function run_test() {
|
||||
do_get_profile();
|
||||
do_test_pending();
|
||||
httpserv = new HttpServer();
|
||||
httpserv.registerPathHandler("/cached", cached_handler);
|
||||
@ -105,4 +106,4 @@ function doneSecondLoad(req, buffer, expected) {
|
||||
} catch (x) {
|
||||
do_test_finished();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -306,6 +306,7 @@
|
||||
"toolkit/components/passwordmgr/test/test_master_password_cleanup.html": "",
|
||||
"toolkit/components/passwordmgr/test/test_notifications.html": "",
|
||||
"toolkit/components/passwordmgr/test/test_notifications_popup.html": "",
|
||||
"toolkit/components/passwordmgr/test/test_privbrowsing_perwindowpb.html": "",
|
||||
"toolkit/components/passwordmgr/test/test_prompt.html": "TIMED_OUT",
|
||||
"toolkit/components/passwordmgr/test/test_prompt_async.html": "TIMED_OUT",
|
||||
"toolkit/components/passwordmgr/test/test_xhr.html": "TIMED_OUT",
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"talos.zip": {
|
||||
"url": "http://build.mozilla.org/talos/zips/talos.766a17c47b0d.zip",
|
||||
"url": "http://build.mozilla.org/talos/zips/talos.6de61e505cf3.zip",
|
||||
"path": ""
|
||||
}
|
||||
}
|
||||
|
@ -738,6 +738,11 @@ function do_register_cleanup(aFunction)
|
||||
* @return nsILocalFile of the profile directory.
|
||||
*/
|
||||
function do_get_profile() {
|
||||
if (!runningInParent) {
|
||||
_dump("TEST-INFO | (xpcshell/head.js) | Ignoring profile creation from child process.\n");
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!_profileInitialized) {
|
||||
// Since we have a profile, we will notify profile shutdown topics at
|
||||
// the end of the current test, to ensure correct cleanup on shutdown.
|
||||
|
@ -92,6 +92,12 @@ MOCHITEST_FILES += \
|
||||
test_prompt.html \
|
||||
$(NULL)
|
||||
endif
|
||||
|
||||
else
|
||||
MOCHITEST_FILES += \
|
||||
privbrowsing_perwindowpb_iframe.html \
|
||||
test_privbrowsing_perwindowpb.html \
|
||||
$(NULL)
|
||||
endif
|
||||
|
||||
# This test doesn't pass because we can't ensure a cross-platform
|
||||
|
@ -0,0 +1,8 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
<iframe id="iframe"></iframe>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,293 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=248970
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 248970</title>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="text/javascript" src="notification_common.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=248970">Mozilla Bug 248970</a>
|
||||
<p id="display"></p>
|
||||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript">
|
||||
|
||||
/** Test for Bug 248970 **/
|
||||
// based on test_notifications.html
|
||||
|
||||
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
|
||||
const Ci = Components.interfaces;
|
||||
const Cc = Components.classes;
|
||||
const Cr = Components.results;
|
||||
|
||||
var testpath = document.location.pathname + "/../";
|
||||
var prefix = "http://test2.example.com" + testpath;
|
||||
var subtests = [
|
||||
"subtst_privbrowsing_1.html", // 1
|
||||
"subtst_privbrowsing_1.html", // 2
|
||||
"subtst_privbrowsing_1.html", // 3
|
||||
"subtst_privbrowsing_2.html", // 4
|
||||
"subtst_privbrowsing_2.html", // 5
|
||||
"subtst_privbrowsing_2.html", // 6
|
||||
"subtst_privbrowsing_3.html", // 7
|
||||
"subtst_privbrowsing_3.html", // 8
|
||||
"subtst_privbrowsing_4.html", // 9
|
||||
"subtst_privbrowsing_3.html" // 10
|
||||
];
|
||||
|
||||
var testNum = 0;
|
||||
function loadNextTest() {
|
||||
// run the initialization code for each test
|
||||
switch (++ testNum) {
|
||||
case 1:
|
||||
popupNotifications = normalWindowPopupNotifications;
|
||||
iframe = normalWindowIframe;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
popupNotifications = privateWindowPopupNotifications;
|
||||
iframe = privateWindowIframe;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
popupNotifications = normalWindowPopupNotifications;
|
||||
iframe = normalWindowIframe;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
pwmgr.addLogin(login);
|
||||
break;
|
||||
|
||||
case 5:
|
||||
popupNotifications = privateWindowPopupNotifications;
|
||||
iframe = privateWindowIframe;
|
||||
break;
|
||||
|
||||
case 6:
|
||||
popupNotifications = normalWindowPopupNotifications;
|
||||
iframe = normalWindowIframe;
|
||||
break;
|
||||
|
||||
case 7:
|
||||
pwmgr.addLogin(login);
|
||||
break;
|
||||
|
||||
case 8:
|
||||
popupNotifications = privateWindowPopupNotifications;
|
||||
iframe = privateWindowIframe;
|
||||
break;
|
||||
|
||||
case 9:
|
||||
break;
|
||||
|
||||
case 10:
|
||||
popupNotifications = normalWindowPopupNotifications;
|
||||
iframe = normalWindowIframe;
|
||||
break;
|
||||
|
||||
default:
|
||||
ok(false, "Unexpected call to loadNextTest for test #" + testNum);
|
||||
}
|
||||
|
||||
ok(true, "Starting test #" + testNum);
|
||||
iframe.src = prefix + subtests[testNum-1];
|
||||
}
|
||||
|
||||
|
||||
function checkTest() {
|
||||
var popup;
|
||||
|
||||
switch (testNum) {
|
||||
case 1:
|
||||
// run outside of private mode, popup notification should appear
|
||||
popup = getPopup(popupNotifications, "password-save");
|
||||
ok(popup, "got popup notification");
|
||||
popup.remove();
|
||||
break;
|
||||
|
||||
case 2:
|
||||
// run inside of private mode, popup notification should not appear
|
||||
popup = getPopup(popupNotifications, "password-save");
|
||||
ok(!popup, "checking for no popup notification");
|
||||
break;
|
||||
|
||||
case 3:
|
||||
// run outside of private mode, popup notification should appear
|
||||
popup = getPopup(popupNotifications, "password-save");
|
||||
ok(popup, "got popup notification");
|
||||
popup.remove();
|
||||
break;
|
||||
|
||||
case 4:
|
||||
// run outside of private mode, popup notification should appear
|
||||
popup = getPopup(popupNotifications, "password-change");
|
||||
ok(popup, "got popup notification");
|
||||
popup.remove();
|
||||
break;
|
||||
|
||||
case 5:
|
||||
// run inside of private mode, popup notification should not appear
|
||||
popup = getPopup(popupNotifications, "password-change");
|
||||
ok(!popup, "checking for no popup notification");
|
||||
break;
|
||||
|
||||
case 6:
|
||||
// run outside of private mode, popup notification should appear
|
||||
popup = getPopup(popupNotifications, "password-change");
|
||||
ok(popup, "got popup notification");
|
||||
popup.remove();
|
||||
pwmgr.removeLogin(login);
|
||||
break;
|
||||
|
||||
case 7:
|
||||
// verify that the user/pass pair was autofilled
|
||||
var gotUser = iframe.contentDocument.getElementById("user").textContent;
|
||||
var gotPass = iframe.contentDocument.getElementById("pass").textContent;
|
||||
is(gotUser, "notifyu1", "Checking submitted username");
|
||||
is(gotPass, "notifyp1", "Checking submitted password");
|
||||
break;
|
||||
|
||||
case 8:
|
||||
// verify that the user/pass pair was not autofilled
|
||||
var gotUser = iframe.contentDocument.getElementById("user").textContent;
|
||||
var gotPass = iframe.contentDocument.getElementById("pass").textContent;
|
||||
is(gotUser, "", "Checking submitted username");
|
||||
is(gotPass, "", "Checking submitted password");
|
||||
break;
|
||||
|
||||
case 9:
|
||||
// verify that the user/pass pair was available for autocomplete
|
||||
var gotUser = iframe.contentDocument.getElementById("user").textContent;
|
||||
var gotPass = iframe.contentDocument.getElementById("pass").textContent;
|
||||
is(gotUser, "notifyu1", "Checking submitted username");
|
||||
is(gotPass, "notifyp1", "Checking submitted password");
|
||||
break;
|
||||
|
||||
case 10:
|
||||
// verify that the user/pass pair was autofilled
|
||||
var gotUser = iframe.contentDocument.getElementById("user").textContent;
|
||||
var gotPass = iframe.contentDocument.getElementById("pass").textContent;
|
||||
is(gotUser, "notifyu1", "Checking submitted username");
|
||||
is(gotPass, "notifyp1", "Checking submitted password");
|
||||
pwmgr.removeLogin(login);
|
||||
break;
|
||||
|
||||
default:
|
||||
ok(false, "Unexpected call to checkTest for test #" + testNum);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
var mainWindow = window.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIWebNavigation)
|
||||
.QueryInterface(Ci.nsIDocShellTreeItem)
|
||||
.rootTreeItem
|
||||
.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIDOMWindow);
|
||||
var contentPage = "http://mochi.test:8888/tests/toolkit/components/passwordmgr/test/privbrowsing_perwindowpb_iframe.html";
|
||||
var testWindows = [];
|
||||
|
||||
function testOnWindow(aIsPrivate, aCallback) {
|
||||
var win = mainWindow.OpenBrowserWindow({private: aIsPrivate});
|
||||
win.addEventListener("load", function onLoad() {
|
||||
win.removeEventListener("load", onLoad, false);
|
||||
win.addEventListener("DOMContentLoaded", function onInnerLoad() {
|
||||
if (win.content.location.href == "about:privatebrowsing") {
|
||||
win.gBrowser.loadURI(contentPage);
|
||||
return;
|
||||
}
|
||||
win.removeEventListener("DOMContentLoaded", onInnerLoad, true);
|
||||
testWindows.push(win);
|
||||
SimpleTest.executeSoon(function() { aCallback(win); });
|
||||
}, true);
|
||||
SimpleTest.executeSoon(function() { win.gBrowser.loadURI(contentPage); });
|
||||
}, true);
|
||||
}
|
||||
|
||||
var ignoreLoad = false;
|
||||
function handleLoad(aEvent) {
|
||||
// ignore every other load event ... We get one for loading the subtest (which
|
||||
// we want to ignore), and another when the subtest's form submits itself
|
||||
// (which we want to handle, to start the next test).
|
||||
ignoreLoad = !ignoreLoad;
|
||||
if (ignoreLoad) {
|
||||
ok(true, "Ignoring load of subtest #" + testNum);
|
||||
return;
|
||||
}
|
||||
ok(true, "Processing submission of subtest #" + testNum);
|
||||
|
||||
checkTest();
|
||||
|
||||
if (testNum < subtests.length) {
|
||||
loadNextTest();
|
||||
} else {
|
||||
ok(true, "private browsing notification tests finished.");
|
||||
|
||||
testWindows.forEach(function(aWin) {
|
||||
aWin.close();
|
||||
});
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
}
|
||||
|
||||
var pwmgr = Cc["@mozilla.org/login-manager;1"].
|
||||
getService(Ci.nsILoginManager);
|
||||
ok(pwmgr != null, "Access pwmgr");
|
||||
|
||||
// We need to make sure no logins have been stored by previous tests
|
||||
// for forms in |url|, otherwise the change password notification
|
||||
// would turn into a prompt, and the test will fail.
|
||||
var url = "http://test2.example.com";
|
||||
is(pwmgr.countLogins(url, "", null), 0, "No logins should be stored for " + url);
|
||||
|
||||
var nsLoginInfo = new Components.Constructor("@mozilla.org/login-manager/loginInfo;1",
|
||||
Ci.nsILoginInfo, "init");
|
||||
var login = new nsLoginInfo(url, url, null, "notifyu1", "notifyp1", "user", "pass");
|
||||
|
||||
var normalWindow;
|
||||
var privateWindow;
|
||||
|
||||
var iframe;
|
||||
var normalWindowIframe;
|
||||
var privateWindowIframe;
|
||||
|
||||
var popupNotifications;
|
||||
var normalWindowPopupNotifications;
|
||||
var privateWindowPopupNotifications;
|
||||
|
||||
testOnWindow(false, function(aWin) {
|
||||
var selectedBrowser = aWin.gBrowser.selectedBrowser;
|
||||
normalWindowIframe = selectedBrowser.contentDocument.getElementById("iframe");
|
||||
normalWindowIframe.onload = handleLoad;
|
||||
selectedBrowser.focus();
|
||||
|
||||
normalWindowPopupNotifications = getPopupNotifications(selectedBrowser.contentWindow.top);
|
||||
ok(normalWindowPopupNotifications, "Got popupNotifications in normal window");
|
||||
// ignore the first load for this window;
|
||||
ignoreLoad = false;
|
||||
|
||||
testOnWindow(true, function(aPrivateWin) {
|
||||
selectedBrowser = aPrivateWin.gBrowser.selectedBrowser;
|
||||
privateWindowIframe = selectedBrowser.contentDocument.getElementById("iframe");
|
||||
privateWindowIframe.onload = handleLoad;
|
||||
selectedBrowser.focus();
|
||||
|
||||
privateWindowPopupNotifications = getPopupNotifications(selectedBrowser.contentWindow.top);
|
||||
ok(privateWindowPopupNotifications, "Got popupNotifications in private window");
|
||||
// ignore the first load for this window;
|
||||
ignoreLoad = false;
|
||||
|
||||
SimpleTest.executeSoon(loadNextTest);
|
||||
});
|
||||
});
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -266,7 +266,15 @@
|
||||
ok(true, "doTest testNum 4");
|
||||
expectedLoads = 1;
|
||||
expectedDialogs = 2;
|
||||
iframe1Doc.location.reload();
|
||||
iframe1.src = exampleCom + "authenticate.sjs?"+
|
||||
"user=user4name&"+
|
||||
"pass=user4pass&"+
|
||||
"realm=mochirealm4&"+
|
||||
"proxy_user=proxy_user3&"+
|
||||
"proxy_pass=proxy_pass3&"+
|
||||
"proxy_realm=proxy_realm3";
|
||||
|
||||
|
||||
break;
|
||||
|
||||
case 5:
|
||||
@ -295,7 +303,14 @@
|
||||
ok(true, "doTest testNum 6");
|
||||
expectedLoads = 1;
|
||||
expectedDialogs = 2;
|
||||
iframe1Doc.location.reload();
|
||||
iframe1.src = exampleCom + "authenticate.sjs?"+
|
||||
"user=user5name&"+
|
||||
"pass=user5pass&"+
|
||||
"realm=mochirealm5&"+
|
||||
"proxy_user=proxy_user4&"+
|
||||
"proxy_pass=proxy_pass4&"+
|
||||
"proxy_realm=proxy_realm4&"+
|
||||
"huge=1";
|
||||
break;
|
||||
|
||||
case 7:
|
||||
@ -346,6 +361,7 @@
|
||||
|
||||
case 3:
|
||||
dialog.cancelDialog();
|
||||
setTimeout(onFrameLoad(), 10); // there are no successful frames for test 3
|
||||
break;
|
||||
|
||||
case 4:
|
||||
@ -357,6 +373,7 @@
|
||||
|
||||
case 5:
|
||||
dialog.cancelDialog();
|
||||
setTimeout(onFrameLoad(), 10); // there are no successful frames for test 5
|
||||
break;
|
||||
|
||||
case 6:
|
||||
@ -435,11 +452,9 @@
|
||||
case 3:
|
||||
ok(true, "doCheck testNum 3");
|
||||
is(monitor.windowsRegistered, 1, "Registered 1 open dialog");
|
||||
var authok1 = iframe1Doc.getElementById("ok").textContent;
|
||||
var proxyok1 = iframe1Doc.getElementById("proxy").textContent;
|
||||
|
||||
is(authok1, "FAIL", "WWW Authorization FAILED, frame1");
|
||||
is(proxyok1, "FAIL", "Proxy Authorization FAILED, frame1");
|
||||
// ensure that the page content is not displayed on failed proxy auth
|
||||
is(iframe1Doc.getElementById("ok"), undefined, "frame did not load");
|
||||
break;
|
||||
|
||||
case 4:
|
||||
@ -455,14 +470,9 @@
|
||||
case 5:
|
||||
ok(true, "doCheck testNum 5");
|
||||
is(monitor.windowsRegistered, 1, "Registered 1 open dialog");
|
||||
var authok1 = iframe1Doc.getElementById("ok").textContent;
|
||||
var proxyok1 = iframe1Doc.getElementById("proxy").textContent;
|
||||
var footnote = iframe1Doc.getElementById("footnote").textContent;
|
||||
|
||||
is(authok1, "FAIL", "WWW Authorization FAILED, frame1");
|
||||
is(proxyok1, "FAIL", "Proxy Authorization FAILED, frame1");
|
||||
is(footnote, "This is a footnote after the huge content fill",
|
||||
"Footnote present and loaded completely");
|
||||
// ensure that the page content is not displayed on failed proxy auth
|
||||
is(iframe1Doc.getElementById("footnote"), undefined, "frame did not load");
|
||||
break;
|
||||
|
||||
case 6:
|
||||
|
@ -98,6 +98,13 @@ Form History test: form field autocomplete
|
||||
<button type="submit">Submit</button>
|
||||
</form>
|
||||
|
||||
<!-- form with input type='time' -->
|
||||
<form id="form15" onsubmit="return false;">
|
||||
<input type="time" name="field12">
|
||||
<button type="submit">Submit</button>
|
||||
</form>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<pre id="test">
|
||||
@ -141,11 +148,11 @@ fh.addEntry("field8", "value");
|
||||
fh.addEntry("field9", "value");
|
||||
fh.addEntry("field10", "42");
|
||||
fh.addEntry("field11", "2010-10-10");
|
||||
fh.addEntry("field12", "21:21");
|
||||
fh.addEntry("searchbar-history", "blacklist test");
|
||||
|
||||
// All these non-implemeted types might need autocomplete tests in the future.
|
||||
var todoTypes = [ "datetime", "month", "week", "time", "datetime-local",
|
||||
"range", "color" ];
|
||||
var todoTypes = [ "datetime", "month", "week", "datetime-local", "range", "color" ];
|
||||
var todoInput = document.createElement("input");
|
||||
for (var type of todoTypes) {
|
||||
todoInput.type = type;
|
||||
@ -748,6 +755,17 @@ function runTest(testNum) {
|
||||
doKey("return");
|
||||
checkForm("2010-10-10");
|
||||
|
||||
input = $_(15, "field12");
|
||||
restoreForm();
|
||||
doKey("down");
|
||||
break;
|
||||
|
||||
case 406:
|
||||
checkMenuEntries(["21:21"]);
|
||||
doKey("down");
|
||||
doKey("return");
|
||||
checkForm("21:21");
|
||||
|
||||
// Go to test 500.
|
||||
fh.addEntry("field1", "value1");
|
||||
input = $_(1, "field1");
|
||||
|
@ -185,9 +185,11 @@ var DebuggerServer = {
|
||||
*/
|
||||
addBrowserActors: function DS_addBrowserActors() {
|
||||
this.addActors("chrome://global/content/devtools/dbg-browser-actors.js");
|
||||
#ifndef MOZ_B2G
|
||||
this.addActors("chrome://global/content/devtools/dbg-webconsole-actors.js");
|
||||
this.addTabActor(this.WebConsoleActor, "consoleActor");
|
||||
this.addGlobalActor(this.WebConsoleActor, "consoleActor");
|
||||
#endif
|
||||
if ("nsIProfiler" in Ci)
|
||||
this.addActors("chrome://global/content/devtools/dbg-profiler-actors.js");
|
||||
},
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
toolkit.jar:
|
||||
content/global/devtools/dbg-transport.js (debugger/dbg-transport.js)
|
||||
content/global/devtools/dbg-server.js (debugger/server/dbg-server.js)
|
||||
* content/global/devtools/dbg-server.js (debugger/server/dbg-server.js)
|
||||
content/global/devtools/dbg-script-actors.js (debugger/server/dbg-script-actors.js)
|
||||
content/global/devtools/dbg-browser-actors.js (debugger/server/dbg-browser-actors.js)
|
||||
content/global/devtools/dbg-webconsole-actors.js (webconsole/dbg-webconsole-actors.js)
|
||||
|
@ -476,6 +476,18 @@ nsOfflineCacheUpdateItem::OnStopRequest(nsIRequest *aRequest,
|
||||
mUpdate->OnByteProgress(mBytesRead);
|
||||
}
|
||||
|
||||
if (NS_FAILED(aStatus)) {
|
||||
nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(mChannel);
|
||||
if (httpChannel) {
|
||||
bool isNoStore;
|
||||
if (NS_SUCCEEDED(httpChannel->IsNoStoreResponse(&isNoStore))
|
||||
&& isNoStore) {
|
||||
LogToConsole("Offline cache manifest item has Cache-control: no-store header",
|
||||
this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// We need to notify the update that the load is complete, but we
|
||||
// want to give the channel a chance to close the cache entries.
|
||||
NS_DispatchToCurrentThread(this);
|
||||
|
@ -162,7 +162,8 @@ nsWindow::nsWindow() :
|
||||
mIMEComposing(false),
|
||||
mIMEMaskSelectionUpdate(false),
|
||||
mIMEMaskTextUpdate(false),
|
||||
mIMEMaskEventsCount(1) // Mask IME events since there's no focus yet
|
||||
mIMEMaskEventsCount(1), // Mask IME events since there's no focus yet
|
||||
mIMESelectionChanged(false)
|
||||
{
|
||||
}
|
||||
|
||||
@ -2064,9 +2065,12 @@ nsWindow::OnIMEFocusChange(bool aFocus)
|
||||
|
||||
if (aFocus) {
|
||||
mIMETextChanges.Clear();
|
||||
mIMESelectionChange = IMEChange();
|
||||
mIMESelectionChanged = false;
|
||||
// OnIMETextChange also notifies selection
|
||||
OnIMETextChange(0, INT32_MAX, INT32_MAX);
|
||||
// Use 'INT32_MAX / 2' here because subsequent text changes might
|
||||
// combine with this text change, and overflow might occur if
|
||||
// we just use INT32_MAX
|
||||
OnIMETextChange(0, INT32_MAX / 2, INT32_MAX / 2);
|
||||
FlushIMEChanges();
|
||||
} else {
|
||||
// Mask events because we lost focus. On the next focus event, Gecko will notify
|
||||
@ -2086,7 +2090,7 @@ nsWindow::OnIMEFocusChange(bool aFocus)
|
||||
void
|
||||
nsWindow::PostFlushIMEChanges()
|
||||
{
|
||||
if (!mIMETextChanges.IsEmpty() || !mIMESelectionChange.IsEmpty()) {
|
||||
if (!mIMETextChanges.IsEmpty() || mIMESelectionChanged) {
|
||||
// Already posted
|
||||
return;
|
||||
}
|
||||
@ -2101,7 +2105,6 @@ nsWindow::FlushIMEChanges()
|
||||
nsRefPtr<nsWindow> kungFuDeathGrip(this);
|
||||
for (uint32_t i = 0; i < mIMETextChanges.Length(); i++) {
|
||||
IMEChange &change = mIMETextChanges[i];
|
||||
MOZ_ASSERT(change.IsTextChange());
|
||||
|
||||
nsQueryContentEvent event(true, NS_QUERY_TEXT_CONTENT, this);
|
||||
InitEvent(event, nullptr);
|
||||
@ -2119,12 +2122,18 @@ nsWindow::FlushIMEChanges()
|
||||
}
|
||||
mIMETextChanges.Clear();
|
||||
|
||||
if (!mIMESelectionChange.IsEmpty()) {
|
||||
MOZ_ASSERT(!mIMESelectionChange.IsTextChange());
|
||||
if (mIMESelectionChanged) {
|
||||
nsQueryContentEvent event(true, NS_QUERY_SELECTED_TEXT, this);
|
||||
InitEvent(event, nullptr);
|
||||
|
||||
DispatchEvent(&event);
|
||||
if (!event.mSucceeded)
|
||||
return;
|
||||
|
||||
AndroidBridge::NotifyIMEChange(nullptr, 0,
|
||||
mIMESelectionChange.mStart,
|
||||
mIMESelectionChange.mOldEnd, -1);
|
||||
mIMESelectionChange = IMEChange();
|
||||
event.GetSelectionStart(),
|
||||
event.GetSelectionEnd(), -1);
|
||||
mIMESelectionChanged = false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2138,7 +2147,7 @@ nsWindow::OnIMETextChange(uint32_t aStart, uint32_t aOldEnd, uint32_t aNewEnd)
|
||||
aStart, aOldEnd, aNewEnd);
|
||||
|
||||
/* Make sure Java's selection is up-to-date */
|
||||
mIMESelectionChange = IMEChange();
|
||||
mIMESelectionChanged = false;
|
||||
OnIMESelectionChange();
|
||||
PostFlushIMEChanges();
|
||||
|
||||
@ -2209,17 +2218,8 @@ nsWindow::OnIMESelectionChange(void)
|
||||
|
||||
ALOGIME("IME: OnIMESelectionChange");
|
||||
|
||||
nsRefPtr<nsWindow> kungFuDeathGrip(this);
|
||||
nsQueryContentEvent event(true, NS_QUERY_SELECTED_TEXT, this);
|
||||
InitEvent(event, nullptr);
|
||||
|
||||
DispatchEvent(&event);
|
||||
if (!event.mSucceeded)
|
||||
return NS_OK;
|
||||
|
||||
PostFlushIMEChanges();
|
||||
mIMESelectionChange = IMEChange((int32_t)event.GetSelectionStart(),
|
||||
(int32_t)event.GetSelectionEnd());
|
||||
mIMESelectionChanged = true;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -201,21 +201,13 @@ protected:
|
||||
mStart(start), mOldEnd(oldEnd), mNewEnd(newEnd)
|
||||
{
|
||||
}
|
||||
IMEChange(int32_t start, int32_t end) :
|
||||
mStart(start), mOldEnd(end), mNewEnd(-1)
|
||||
{
|
||||
}
|
||||
bool IsEmpty()
|
||||
{
|
||||
return mStart < 0;
|
||||
}
|
||||
bool IsTextChange()
|
||||
{
|
||||
return mNewEnd >= 0;
|
||||
}
|
||||
};
|
||||
nsAutoTArray<IMEChange, 4> mIMETextChanges;
|
||||
IMEChange mIMESelectionChange;
|
||||
bool mIMESelectionChanged;
|
||||
|
||||
InputContext mInputContext;
|
||||
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include "nsIScreenManager.h"
|
||||
#include "nsMathUtils.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
#include "cutils/properties.h"
|
||||
|
||||
#define LOG_TAG "HWComposer"
|
||||
|
||||
@ -49,6 +50,14 @@ enum {
|
||||
HWC_USE_COPYBIT
|
||||
};
|
||||
|
||||
// HWC layer flags
|
||||
enum {
|
||||
// Draw a solid color rectangle
|
||||
// The color should be set on the transform member of the hwc_layer_t struct
|
||||
// The expected format is a 32 bit ABGR with 8 bits per component
|
||||
HWC_COLOR_FILL = 0x8
|
||||
};
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
static StaticRefPtr<HwcComposer2D> sInstance;
|
||||
@ -79,6 +88,10 @@ HwcComposer2D::Init(hwc_display_t dpy, hwc_surface_t sur)
|
||||
mScreenWidth = screenSize.width;
|
||||
mScreenHeight = screenSize.height;
|
||||
|
||||
char propValue[PROPERTY_VALUE_MAX];
|
||||
property_get("ro.display.colorfill", propValue, "0");
|
||||
mColorFill = (atoi(propValue) == 1) ? true : false;
|
||||
|
||||
mDpy = dpy;
|
||||
mSur = sur;
|
||||
|
||||
@ -232,7 +245,7 @@ HwcComposer2D::PrepareLayerList(Layer* aLayer,
|
||||
// that require intermediate surfaces. That means all the
|
||||
// GetEffective*() coordinates are relative to the framebuffer.
|
||||
|
||||
const bool TESTING = true;
|
||||
bool fillColor = false;
|
||||
|
||||
const nsIntRegion& visibleRegion = aLayer->GetEffectiveVisibleRegion();
|
||||
if (visibleRegion.IsEmpty()) {
|
||||
@ -249,8 +262,7 @@ HwcComposer2D::PrepareLayerList(Layer* aLayer,
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!TESTING &&
|
||||
visibleRegion.GetNumRects() > 1) {
|
||||
if (visibleRegion.GetNumRects() > 1) {
|
||||
// FIXME/bug 808339
|
||||
LOGD("Layer has nontrivial visible region");
|
||||
return false;
|
||||
@ -279,8 +291,12 @@ HwcComposer2D::PrepareLayerList(Layer* aLayer,
|
||||
|
||||
if (!state.mSurface ||
|
||||
state.mSurface->type() != SurfaceDescriptor::TSurfaceDescriptorGralloc) {
|
||||
LOGD("Layer doesn't have a gralloc buffer");
|
||||
return false;
|
||||
if (aLayer->AsColorLayer() && mColorFill) {
|
||||
fillColor = true;
|
||||
} else {
|
||||
LOGD("Layer doesn't have a gralloc buffer");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (state.BufferRotated()) {
|
||||
LOGD("Layer has a rotated buffer");
|
||||
@ -304,12 +320,18 @@ HwcComposer2D::PrepareLayerList(Layer* aLayer,
|
||||
}
|
||||
}
|
||||
|
||||
sp<GraphicBuffer> buffer = GrallocBufferActor::GetFrom(*state.mSurface);
|
||||
sp<GraphicBuffer> buffer = fillColor ? nullptr : GrallocBufferActor::GetFrom(*state.mSurface);
|
||||
|
||||
nsIntRect visibleRect = visibleRegion.GetBounds();
|
||||
|
||||
nsIntRect bufferRect = nsIntRect(0, 0, int(buffer->getWidth()),
|
||||
int(buffer->getHeight()));
|
||||
nsIntRect bufferRect;
|
||||
if (fillColor) {
|
||||
bufferRect = nsIntRect(0, 0, visibleRect.width,
|
||||
visibleRect.height);
|
||||
} else {
|
||||
bufferRect = nsIntRect(0, 0, int(buffer->getWidth()),
|
||||
int(buffer->getHeight()));
|
||||
}
|
||||
|
||||
hwc_layer_t& hwcLayer = mList->hwLayers[current];
|
||||
|
||||
@ -319,43 +341,42 @@ HwcComposer2D::PrepareLayerList(Layer* aLayer,
|
||||
return true;
|
||||
}
|
||||
|
||||
buffer_handle_t handle = buffer->getNativeBuffer()->handle;
|
||||
buffer_handle_t handle = fillColor ? nullptr : buffer->getNativeBuffer()->handle;
|
||||
hwcLayer.handle = handle;
|
||||
|
||||
hwcLayer.blending = HWC_BLENDING_NONE;
|
||||
hwcLayer.flags = 0;
|
||||
hwcLayer.hints = 0;
|
||||
|
||||
|
||||
hwcLayer.blending = HWC_BLENDING_NONE;
|
||||
hwcLayer.compositionType = HWC_USE_COPYBIT;
|
||||
|
||||
if (transform.xx == 0) {
|
||||
if (transform.xy < 0) {
|
||||
hwcLayer.transform = HWC_TRANSFORM_ROT_90;
|
||||
LOGD("Layer buffer rotated 90 degrees");
|
||||
if (!fillColor) {
|
||||
if (transform.xx == 0) {
|
||||
if (transform.xy < 0) {
|
||||
hwcLayer.transform = HWC_TRANSFORM_ROT_90;
|
||||
LOGD("Layer buffer rotated 90 degrees");
|
||||
} else {
|
||||
hwcLayer.transform = HWC_TRANSFORM_ROT_270;
|
||||
LOGD("Layer buffer rotated 270 degrees");
|
||||
}
|
||||
} else if (transform.xx < 0) {
|
||||
hwcLayer.transform = HWC_TRANSFORM_ROT_180;
|
||||
LOGD("Layer buffer rotated 180 degrees");
|
||||
} else {
|
||||
hwcLayer.transform = 0;
|
||||
}
|
||||
else {
|
||||
hwcLayer.transform = HWC_TRANSFORM_ROT_270;
|
||||
LOGD("Layer buffer rotated 270 degrees");
|
||||
}
|
||||
}
|
||||
else if (transform.xx < 0) {
|
||||
hwcLayer.transform = HWC_TRANSFORM_ROT_180;
|
||||
LOGD("Layer buffer rotated 180 degrees");
|
||||
}
|
||||
else {
|
||||
hwcLayer.transform = 0;
|
||||
}
|
||||
|
||||
hwcLayer.transform |= state.YFlipped() ? HWC_TRANSFORM_FLIP_V : 0;
|
||||
|
||||
hwc_region_t region;
|
||||
region.numRects = 1;
|
||||
region.rects = &(hwcLayer.displayFrame);
|
||||
hwcLayer.visibleRegionScreen = region;
|
||||
hwcLayer.transform |= state.YFlipped() ? HWC_TRANSFORM_FLIP_V : 0;
|
||||
hwc_region_t region;
|
||||
region.numRects = 1;
|
||||
region.rects = &(hwcLayer.displayFrame);
|
||||
hwcLayer.visibleRegionScreen = region;
|
||||
} else {
|
||||
hwcLayer.flags |= HWC_COLOR_FILL;
|
||||
ColorLayer* colorLayer = static_cast<ColorLayer*>(layerGL->GetLayer());
|
||||
hwcLayer.transform = colorLayer->GetColor().Packed();
|
||||
}
|
||||
|
||||
mList->numHwLayers++;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -55,6 +55,7 @@ private:
|
||||
nsCOMPtr<nsIScreen> mScreen;
|
||||
int mScreenWidth, mScreenHeight;
|
||||
int mMaxLayerCount;
|
||||
bool mColorFill;
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
@ -354,7 +354,7 @@ nsTextStore::~nsTextStore()
|
||||
PR_LOG(sTextStoreLog, PR_LOG_ALWAYS,
|
||||
("TSF: 0x%p nsTextStore instance is destroyed, "
|
||||
"mWidget=0x%p, mDocumentMgr=0x%p, mContext=0x%p",
|
||||
this, mWidget, mDocumentMgr, mContext));
|
||||
this, mWidget.get(), mDocumentMgr.get(), mContext.get()));
|
||||
|
||||
if (mCompositionTimer) {
|
||||
mCompositionTimer->Cancel();
|
||||
@ -1978,7 +1978,7 @@ nsTextStore::GetWnd(TsViewCookie vcView,
|
||||
PR_LOG(sTextStoreLog, PR_LOG_ALWAYS,
|
||||
("TSF: 0x%p nsTextStore::GetWnd(vcView=%ld, phwnd=0x%p), "
|
||||
"mWidget=0x%p",
|
||||
this, vcView, phwnd, mWidget));
|
||||
this, vcView, phwnd, mWidget.get()));
|
||||
|
||||
if (vcView != TEXTSTORE_DEFAULT_VIEW) {
|
||||
PR_LOG(sTextStoreLog, PR_LOG_ERROR,
|
||||
@ -2234,7 +2234,8 @@ nsTextStore::InsertTextAtSelectionInternal(const nsAString &aInsertStr,
|
||||
("TSF: 0x%p nsTextStore::InsertTextAtSelectionInternal() succeeded: "
|
||||
"mWidget=0x%p, mWidget->Destroyed()=%s, aTextChange={ acpStart=%ld, "
|
||||
"acpOldEnd=%ld, acpNewEnd=%ld }",
|
||||
this, mWidget, GetBoolName(mWidget ? mWidget->Destroyed() : true),
|
||||
this, mWidget.get(),
|
||||
GetBoolName(mWidget ? mWidget->Destroyed() : true),
|
||||
aTextChange ? aTextChange->acpStart : 0,
|
||||
aTextChange ? aTextChange->acpOldEnd : 0,
|
||||
aTextChange ? aTextChange->acpNewEnd : 0));
|
||||
|
@ -22,7 +22,7 @@
|
||||
|
||||
#ifdef ANDROID
|
||||
#include <stdio.h>
|
||||
#define LOW_MEMORY_THRESHOLD_KB (512 * 1024)
|
||||
#define LOW_MEMORY_THRESHOLD_KB (384 * 1024)
|
||||
#endif
|
||||
|
||||
static nsMemoryImpl sGlobalMemory;
|
||||
|
Loading…
Reference in New Issue
Block a user