mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-08 19:04:45 +00:00
Bug 1080474 - Part 3 - Presentation UI glue for Firefox OS. r=fabrice.
This commit is contained in:
parent
fbddc387d5
commit
c51a1c2a25
@ -28,6 +28,7 @@ SignInToWebsiteController.init();
|
||||
Cu.import('resource://gre/modules/FxAccountsMgmtService.jsm');
|
||||
Cu.import('resource://gre/modules/DownloadsAPI.jsm');
|
||||
Cu.import('resource://gre/modules/MobileIdentityManager.jsm');
|
||||
Cu.import('resource://gre/modules/PresentationDeviceInfoManager.jsm');
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "SystemAppProxy",
|
||||
"resource://gre/modules/SystemAppProxy.jsm");
|
||||
|
@ -106,3 +106,7 @@ contract @mozilla.org/services/mobileid-ui-glue;1 {83dbe26a-81f3-4a75-9541-3d0b7
|
||||
component {7211ece0-b458-4635-9afc-f8d7f376ee95} B2GAppMigrator.js
|
||||
contract @mozilla.org/app-migrator;1 {7211ece0-b458-4635-9afc-f8d7f376ee95}
|
||||
|
||||
# B2GPresentationDevicePrompt.js
|
||||
component {4a300c26-e99b-4018-ab9b-c48cf9bc4de1} B2GPresentationDevicePrompt.js
|
||||
contract @mozilla.org/presentation-device/prompt;1 {4a300c26-e99b-4018-ab9b-c48cf9bc4de1}
|
||||
|
||||
|
87
b2g/components/B2GPresentationDevicePrompt.js
Normal file
87
b2g/components/B2GPresentationDevicePrompt.js
Normal file
@ -0,0 +1,87 @@
|
||||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
function debug(aMsg) {
|
||||
//dump("-*- B2GPresentationDevicePrompt: " + aMsg + "\n");
|
||||
}
|
||||
|
||||
const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
|
||||
|
||||
const kB2GPRESENTATIONDEVICEPROMPT_CONTRACTID = "@mozilla.org/presentation-device/prompt;1";
|
||||
const kB2GPRESENTATIONDEVICEPROMPT_CID = Components.ID("{4a300c26-e99b-4018-ab9b-c48cf9bc4de1}");
|
||||
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "SystemAppProxy",
|
||||
"resource://gre/modules/SystemAppProxy.jsm");
|
||||
|
||||
function B2GPresentationDevicePrompt() {}
|
||||
|
||||
B2GPresentationDevicePrompt.prototype = {
|
||||
classID: kB2GPRESENTATIONDEVICEPROMPT_CID,
|
||||
contractID: kB2GPRESENTATIONDEVICEPROMPT_CONTRACTID,
|
||||
classDescription: "B2G Presentation Device Prompt",
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIPresentationDevicePrompt]),
|
||||
|
||||
// nsIPresentationDevicePrompt
|
||||
promptDeviceSelection: function(aRequest) {
|
||||
let self = this;
|
||||
let requestId = Cc["@mozilla.org/uuid-generator;1"]
|
||||
.getService(Ci.nsIUUIDGenerator).generateUUID().toString();
|
||||
|
||||
SystemAppProxy.addEventListener("mozContentEvent", function contentEvent(aEvent) {
|
||||
let detail = aEvent.detail;
|
||||
if (detail.id !== requestId) {
|
||||
return;
|
||||
}
|
||||
|
||||
SystemAppProxy.removeEventListener("mozContentEvent", contentEvent);
|
||||
|
||||
switch (detail.type) {
|
||||
case "presentation-select-result":
|
||||
debug("device " + detail.deviceId + " is selected by user");
|
||||
let device = self._getDeviceById(detail.deviceId);
|
||||
if (!device) {
|
||||
debug("cancel request because device is not found");
|
||||
aRequest.cancel();
|
||||
}
|
||||
aRequest.select(device);
|
||||
break;
|
||||
case "presentation-select-deny":
|
||||
debug("request canceled by user");
|
||||
aRequest.cancel();
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
let detail = {
|
||||
type: "presentation-select-device",
|
||||
origin: aRequest.origin,
|
||||
requestURL: aRequest.requestURL,
|
||||
id: requestId,
|
||||
};
|
||||
|
||||
SystemAppProxy.dispatchEvent(detail);
|
||||
},
|
||||
|
||||
_getDeviceById: function(aDeviceId) {
|
||||
let deviceManager = Cc["@mozilla.org/presentation-device/manager;1"]
|
||||
.getService(Ci.nsIPresentationDeviceManager);
|
||||
let devices = deviceManager.getAvailableDevices().QueryInterface(Ci.nsIArray);
|
||||
|
||||
for (let i = 0; i < devices.length; i++) {
|
||||
let device = devices.queryElementAt(i, Ci.nsIPresentationDevice);
|
||||
if (device.id === aDeviceId) {
|
||||
return device;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
},
|
||||
};
|
||||
|
||||
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([B2GPresentationDevicePrompt]);
|
@ -11,6 +11,7 @@ EXTRA_COMPONENTS += [
|
||||
'AlertsService.js',
|
||||
'B2GAboutRedirector.js',
|
||||
'B2GAppMigrator.js',
|
||||
'B2GPresentationDevicePrompt.js',
|
||||
'ContentPermissionPrompt.js',
|
||||
'FilePicker.js',
|
||||
'FxAccountsUIGlue.js',
|
||||
|
@ -5,6 +5,7 @@ support-files =
|
||||
SandboxPromptTest.html
|
||||
filepicker_path_handler_chrome.js
|
||||
systemapp_helper.js
|
||||
presentation_prompt_handler_chrome.js
|
||||
|
||||
[test_filepicker_path.html]
|
||||
[test_permission_deny.html]
|
||||
@ -12,3 +13,4 @@ support-files =
|
||||
skip-if = true # Bug 1019572 - frequent timeouts
|
||||
[test_sandbox_permission.html]
|
||||
[test_systemapp.html]
|
||||
[test_presentation_device_prompt.html]
|
||||
|
@ -0,0 +1,94 @@
|
||||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
'use strict';
|
||||
|
||||
function debug(str) {
|
||||
dump('presentation_prompt_handler_chrome: ' + str + '\n');
|
||||
}
|
||||
|
||||
const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
|
||||
const { XPCOMUtils } = Cu.import('resource://gre/modules/XPCOMUtils.jsm');
|
||||
const { SystemAppProxy } = Cu.import('resource://gre/modules/SystemAppProxy.jsm');
|
||||
|
||||
const manager = Cc["@mozilla.org/presentation-device/manager;1"]
|
||||
.getService(Ci.nsIPresentationDeviceManager);
|
||||
|
||||
const prompt = Cc['@mozilla.org/presentation-device/prompt;1']
|
||||
.getService(Ci.nsIPresentationDevicePrompt);
|
||||
|
||||
function TestPresentationDevice(options) {
|
||||
this.id = options.id;
|
||||
this.name = options.name;
|
||||
this.type = options.type;
|
||||
}
|
||||
|
||||
TestPresentationDevice.prototype = {
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIPresentationDevice]),
|
||||
establishSessionTransport: function() {
|
||||
return null;
|
||||
},
|
||||
};
|
||||
|
||||
function TestPresentationRequest(options) {
|
||||
this.origin = options.origin;
|
||||
this.requestURL = options.requestURL;
|
||||
}
|
||||
|
||||
TestPresentationRequest.prototype = {
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIPresentationDeviceRequest]),
|
||||
select: function(device) {
|
||||
let result = {
|
||||
type: 'select',
|
||||
device: {
|
||||
id: device.id,
|
||||
name: device.name,
|
||||
type: device.type,
|
||||
},
|
||||
};
|
||||
sendAsyncMessage('presentation-select-result', result);
|
||||
},
|
||||
cancel: function() {
|
||||
let result = {
|
||||
type: 'cancel',
|
||||
};
|
||||
sendAsyncMessage('presentation-select-result', result);
|
||||
},
|
||||
};
|
||||
|
||||
var testDevice = null;
|
||||
|
||||
addMessageListener('setup', function(device_options) {
|
||||
testDevice = new TestPresentationDevice(device_options);
|
||||
manager.QueryInterface(Ci.nsIPresentationDeviceListener).addDevice(testDevice);
|
||||
sendAsyncMessage('setup-complete');
|
||||
});
|
||||
|
||||
let eventHandler = function(evt) {
|
||||
if (!evt.detail || evt.detail.type !== 'presentation-select-device') {
|
||||
return;
|
||||
}
|
||||
|
||||
sendAsyncMessage('presentation-select-device', evt.detail);
|
||||
};
|
||||
|
||||
SystemAppProxy.addEventListener('mozChromeEvent', eventHandler);
|
||||
|
||||
// need to remove ChromeEvent listener after test finished.
|
||||
addMessageListener('teardown', function() {
|
||||
if (testDevice) {
|
||||
manager.removeDevice(testDevice);
|
||||
}
|
||||
SystemAppProxy.removeEventListener('mozChromeEvent', eventHandler);
|
||||
});
|
||||
|
||||
addMessageListener('trigger-device-prompt', function(request_options) {
|
||||
let request = new TestPresentationRequest(request_options);
|
||||
prompt.promptDeviceSelection(request);
|
||||
});
|
||||
|
||||
addMessageListener('presentation-select-response', function(detail) {
|
||||
SystemAppProxy._sendCustomEvent('mozContentEvent', detail);
|
||||
});
|
||||
|
@ -0,0 +1,145 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!-- Any copyright is dedicated to the Public Domain.
|
||||
- http://creativecommons.org/publicdomain/zero/1.0/ -->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Test for Presentation Device Selection</title>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=">Test for Presentation Device Selection</a>
|
||||
<script type="application/javascript;version=1.8">
|
||||
|
||||
'use strict';
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
var contentEventHandler = null;
|
||||
|
||||
var gUrl = SimpleTest.getTestFileURL('presentation_prompt_handler_chrome.js');
|
||||
var gScript = SpecialPowers.loadChromeScript(gUrl);
|
||||
|
||||
function testSetup() {
|
||||
info('setup for device selection');
|
||||
return new Promise(function(resolve, reject) {
|
||||
let device = {
|
||||
id: 'test-id',
|
||||
name: 'test-name',
|
||||
type: 'test-type',
|
||||
};
|
||||
gScript.addMessageListener('setup-complete', function() {
|
||||
resolve(device);
|
||||
});
|
||||
gScript.sendAsyncMessage('setup', device);
|
||||
});
|
||||
}
|
||||
|
||||
function testSelected(device) {
|
||||
info('test device selected by user');
|
||||
return new Promise(function(resolve, reject) {
|
||||
let request = {
|
||||
origin: 'test-origin',
|
||||
requestURL: 'test-requestURL',
|
||||
};
|
||||
|
||||
gScript.addMessageListener('presentation-select-device', function contentEventHandler(detail) {
|
||||
gScript.removeMessageListener('presentation-select-device', contentEventHandler);
|
||||
ok(true, 'receive user prompt for device selection');
|
||||
is(detail.origin, request.origin, 'expected origin');
|
||||
is(detail.requestURL, request.requestURL, 'expected requestURL');
|
||||
let response = {
|
||||
id: detail.id,
|
||||
type: 'presentation-select-result',
|
||||
deviceId: device.id,
|
||||
};
|
||||
gScript.sendAsyncMessage('presentation-select-response', response);
|
||||
|
||||
gScript.addMessageListener('presentation-select-result', function resultHandler(result) {
|
||||
gScript.removeMessageListener('presentation-select-result', resultHandler);
|
||||
is(result.type, 'select', 'expect device selected');
|
||||
is(result.device.id, device.id, 'expected device id');
|
||||
is(result.device.name, device.name, 'expected device name');
|
||||
is(result.device.type, device.type, 'expected devcie type');
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
|
||||
gScript.sendAsyncMessage('trigger-device-prompt', request);
|
||||
});
|
||||
}
|
||||
|
||||
function testSelectedNotExisted() {
|
||||
info('test selected device doesn\'t exist');
|
||||
return new Promise(function(resolve, reject) {
|
||||
gScript.addMessageListener('presentation-select-device', function contentEventHandler(detail) {
|
||||
gScript.removeMessageListener('presentation-select-device', contentEventHandler);
|
||||
ok(true, 'receive user prompt for device selection');
|
||||
let response = {
|
||||
id: detail.id,
|
||||
type: 'presentation-select-deny',
|
||||
deviceId: undefined, // simulate device Id that doesn't exist
|
||||
};
|
||||
gScript.sendAsyncMessage('presentation-select-response', response);
|
||||
|
||||
gScript.addMessageListener('presentation-select-result', function resultHandler(result) {
|
||||
gScript.removeMessageListener('presentation-select-result', resultHandler);
|
||||
is(result.type, 'cancel', 'expect user cancel');
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
|
||||
let request = {
|
||||
origin: 'test-origin',
|
||||
requestURL: 'test-requestURL',
|
||||
};
|
||||
gScript.sendAsyncMessage('trigger-device-prompt', request);
|
||||
});
|
||||
}
|
||||
|
||||
function testDenied() {
|
||||
info('test denial of device selection');
|
||||
return new Promise(function(resolve, reject) {
|
||||
gScript.addMessageListener('presentation-select-device', function contentEventHandler(detail) {
|
||||
gScript.removeMessageListener('presentation-select-device', contentEventHandler);
|
||||
ok(true, 'receive user prompt for device selection');
|
||||
let response = {
|
||||
id: detail.id,
|
||||
type: 'presentation-select-deny',
|
||||
};
|
||||
gScript.sendAsyncMessage('presentation-select-response', response);
|
||||
|
||||
gScript.addMessageListener('presentation-select-result', function resultHandler(result) {
|
||||
gScript.removeMessageListener('presentation-select-result', resultHandler);
|
||||
is(result.type, 'cancel', 'expect user cancel');
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
|
||||
let request = {
|
||||
origin: 'test-origin',
|
||||
requestURL: 'test-requestURL',
|
||||
};
|
||||
gScript.sendAsyncMessage('trigger-device-prompt', request);
|
||||
});
|
||||
}
|
||||
|
||||
function runTests() {
|
||||
testSetup()
|
||||
.then(testSelected)
|
||||
.then(testSelectedNotExisted)
|
||||
.then(testDenied)
|
||||
.then(function() {
|
||||
info('test finished, teardown');
|
||||
gScript.sendAsyncMessage('teardown');
|
||||
gScript.destroy();
|
||||
SimpleTest.finish();
|
||||
});
|
||||
}
|
||||
|
||||
window.addEventListener('load', runTests);
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
@ -867,6 +867,7 @@ bin/components/@DLL_PREFIX@nkgnomevfs@DLL_SUFFIX@
|
||||
@BINPATH@/components/InterAppCommUIGlue.js
|
||||
@BINPATH@/components/SystemMessageGlue.js
|
||||
@BINPATH@/components/B2GAppMigrator.js
|
||||
@BINPATH@/components/B2GPresentationDevicePrompt.js
|
||||
|
||||
#ifndef MOZ_WIDGET_GONK
|
||||
@BINPATH@/components/SimulatorScreen.js
|
||||
|
Loading…
Reference in New Issue
Block a user