Merge m-c to inbound on a CLOSED TREE.

This commit is contained in:
Ryan VanderMeulen 2013-10-30 22:42:13 -04:00
Родитель d10640b99b a4511eaf5f
Коммит 1d57260a86
135 изменённых файлов: 2443 добавлений и 2675 удалений

Просмотреть файл

@ -430,7 +430,7 @@ pref("services.push.requestTimeout", 10000);
pref("services.push.udp.wakeupEnabled", true);
// NetworkStats
#ifdef MOZ_B2G_RIL
#ifdef MOZ_WIDGET_GONK
pref("dom.mozNetworkStats.enabled", true);
pref("dom.webapps.firstRunWithSIM", true);
#endif
@ -825,22 +825,9 @@ pref("gfx.canvas.skiagl.dynamic-cache", true);
// enable fence with readpixels for SurfaceStream
pref("gfx.gralloc.fence-with-readpixels", true);
// Enable Telephony API
pref("dom.telephony.enabled", true);
// Cell Broadcast API
pref("dom.cellbroadcast.enabled", true);
pref("ril.cellbroadcast.disabled", false);
// ICC API
pref("dom.icc.enabled", true);
// Mobile Connection API
pref("dom.mobileconnection.enabled", true);
// Voice Mail API
pref("dom.voicemail.enabled", true);
// The url of the page used to display network error details.
pref("b2g.neterror.url", "app://system.gaiamobile.org/net_error.html");

Просмотреть файл

@ -636,7 +636,7 @@ let FormAssistant = {
},
showKeyboard: function fa_showKeyboard(target) {
if (this.isKeyboardOpened)
if (this.focusedElement === target)
return;
if (target instanceof HTMLOptionElement)

Просмотреть файл

@ -138,6 +138,11 @@ SettingsListener.observe('language.current', 'en-US', function(value) {
Services.prefs.setBoolPref('dom.mms.requestStatusReport', value);
});
SettingsListener.observe('ril.mms.requestReadReport.enabled', true,
function(value) {
Services.prefs.setBoolPref('dom.mms.requestReadReport', value);
});
SettingsListener.observe('ril.cellbroadcast.disabled', false,
function(value) {
Services.prefs.setBoolPref('ril.cellbroadcast.disabled', value);

Просмотреть файл

@ -18,7 +18,7 @@ Cu.import("resource://gre/modules/AppsUtils.jsm");
Cu.import('resource://gre/modules/UserAgentOverrides.jsm');
Cu.import('resource://gre/modules/Keyboard.jsm');
Cu.import('resource://gre/modules/ErrorPage.jsm');
#ifdef MOZ_B2G_RIL
#ifdef MOZ_WIDGET_GONK
Cu.import('resource://gre/modules/NetworkStatsService.jsm');
#endif
@ -611,7 +611,7 @@ var shell = {
this.sendEvent(window, 'ContentStart');
#ifdef MOZ_B2G_RIL
#ifdef MOZ_WIDGET_GONK
Cu.import('resource://gre/modules/OperatorApps.jsm');
#endif

Просмотреть файл

@ -1,4 +1,4 @@
{
"revision": "d2dbad943faf566fe36dbe79086127da837af6a3",
"revision": "aa1ebd9c011628a4e1a9802fd552ec853610b2f5",
"repo_path": "/integration/gaia-central"
}

Просмотреть файл

@ -164,10 +164,12 @@
@BINPATH@/components/dom_audiochannel.xpt
@BINPATH@/components/dom_base.xpt
@BINPATH@/components/dom_system.xpt
#ifdef MOZ_B2G_RIL
@BINPATH@/components/dom_voicemail.xpt
#ifdef MOZ_WIDGET_GONK
@BINPATH@/components/dom_wifi.xpt
@BINPATH@/components/dom_system_gonk.xpt
#endif
#ifdef MOZ_B2G_RIL
@BINPATH@/components/dom_voicemail.xpt
@BINPATH@/components/dom_icc.xpt
@BINPATH@/components/dom_cellbroadcast.xpt
@BINPATH@/components/dom_wappush.xpt
@ -399,6 +401,36 @@
@BINPATH@/components/nsDownloadManagerUI.js
@BINPATH@/components/nsSidebar.manifest
@BINPATH@/components/nsSidebar.js
; WiFi, NetworkManager, NetworkStats
#ifdef MOZ_WIDGET_GONK
@BINPATH@/components/DOMWifiManager.js
@BINPATH@/components/DOMWifiManager.manifest
@BINPATH@/components/NetworkInterfaceListService.js
@BINPATH@/components/NetworkInterfaceListService.manifest
@BINPATH@/components/NetworkManager.js
@BINPATH@/components/NetworkManager.manifest
@BINPATH@/components/NetworkStatsManager.js
@BINPATH@/components/NetworkStatsManager.manifest
@BINPATH@/components/NetworkStatsServiceProxy.js
@BINPATH@/components/NetworkStatsServiceProxy.manifest
@BINPATH@/components/WifiWorker.js
@BINPATH@/components/WifiWorker.manifest
#endif // MOZ_WIDGET_GONK
; RIL
#if defined(MOZ_WIDGET_GONK) && defined(MOZ_B2G_RIL)
@BINPATH@/components/MmsService.js
@BINPATH@/components/MmsService.manifest
@BINPATH@/components/MobileMessageDatabaseService.js
@BINPATH@/components/MobileMessageDatabaseService.manifest
@BINPATH@/components/RadioInterfaceLayer.js
@BINPATH@/components/RadioInterfaceLayer.manifest
@BINPATH@/components/RILContentHelper.js
@BINPATH@/components/TelephonyProvider.js
@BINPATH@/components/TelephonyProvider.manifest
#endif // MOZ_WIDGET_GONK && MOZ_B2G_RIL
#ifndef MOZ_WIDGET_GONK
@BINPATH@/components/extensions.manifest
@BINPATH@/components/addonManager.js
@ -464,29 +496,6 @@
@BINPATH@/components/webvtt.xpt
@BINPATH@/components/WebVTT.manifest
@BINPATH@/components/WebVTTParserWrapper.js
#ifdef MOZ_B2G_RIL
@BINPATH@/components/NetworkManager.manifest
@BINPATH@/components/NetworkManager.js
@BINPATH@/components/RadioInterfaceLayer.manifest
@BINPATH@/components/RadioInterfaceLayer.js
@BINPATH@/components/MmsService.manifest
@BINPATH@/components/MmsService.js
@BINPATH@/components/RILContentHelper.js
@BINPATH@/components/MobileMessageDatabaseService.manifest
@BINPATH@/components/MobileMessageDatabaseService.js
@BINPATH@/components/WifiWorker.js
@BINPATH@/components/WifiWorker.manifest
@BINPATH@/components/DOMWifiManager.js
@BINPATH@/components/DOMWifiManager.manifest
@BINPATH@/components/NetworkStatsManager.js
@BINPATH@/components/NetworkStatsManager.manifest
@BINPATH@/components/NetworkInterfaceListService.manifest
@BINPATH@/components/NetworkInterfaceListService.js
@BINPATH@/components/TelephonyProvider.manifest
@BINPATH@/components/TelephonyProvider.js
@BINPATH@/components/NetworkStatsServiceProxy.manifest
@BINPATH@/components/NetworkStatsServiceProxy.js
#endif
#ifdef MOZ_ENABLE_DBUS
@BINPATH@/components/@DLL_PREFIX@dbusservice@DLL_SUFFIX@
#endif

Просмотреть файл

@ -3014,11 +3014,11 @@ const BrowserSearch = {
* allows the search service to provide a different nsISearchSubmission
* depending on e.g. where the search is triggered in the UI.
*
* @return string Name of the search engine used to perform a search or null
* if a search was not performed.
* @return engine The search engine used to perform a search, or null if no
* search was performed.
*/
loadSearch: function BrowserSearch_search(searchText, useNewTab, purpose) {
var engine;
_loadSearch: function (searchText, useNewTab, purpose) {
let engine;
// If the search bar is visible, use the current engine, otherwise, fall
// back to the default engine.
@ -3027,7 +3027,7 @@ const BrowserSearch = {
else
engine = Services.search.defaultEngine;
var submission = engine.getSubmission(searchText, null, purpose); // HTML response
let submission = engine.getSubmission(searchText, null, purpose); // HTML response
// getSubmission can return null if the engine doesn't have a URL
// with a text/html response type. This is unlikely (since
@ -3044,6 +3044,20 @@ const BrowserSearch = {
inBackground: inBackground,
relatedToCurrent: true });
return engine;
},
/**
* Just like _loadSearch, but preserving an old API.
*
* @return string Name of the search engine used to perform a search or null
* if a search was not performed.
*/
loadSearch: function BrowserSearch_search(searchText, useNewTab, purpose) {
let engine = BrowserSearch._loadSearch(searchText, useNewTab, purpose);
if (!engine) {
return null;
}
return engine.name;
},
@ -3054,7 +3068,7 @@ const BrowserSearch = {
* BrowserSearch.loadSearch for the preferred API.
*/
loadSearchFromContext: function (terms) {
let engine = BrowserSearch.loadSearch(terms, true, "contextmenu");
let engine = BrowserSearch._loadSearch(terms, true, "contextmenu");
if (engine) {
BrowserSearch.recordSearchInHealthReport(engine, "contextmenu");
}
@ -3080,8 +3094,7 @@ const BrowserSearch = {
* FHR records only search counts and nothing pertaining to the search itself.
*
* @param engine
* (string) The name of the engine used to perform the search. This
* is typically nsISearchEngine.name.
* (nsISearchEngine) The engine handling the search.
* @param source
* (string) Where the search originated from. See the FHR
* SearchesProvider for allowed values.

Просмотреть файл

@ -486,7 +486,7 @@ function getNumberOfSearches(aEngineName) {
let provider = reporter.getProvider("org.mozilla.searches");
ok(provider, "Searches provider is available.");
let m = provider.getMeasurement("counts", 2);
let m = provider.getMeasurement("counts", 3);
return m.getValues().then(data => {
let now = new Date();
let yday = new Date(now);

Просмотреть файл

@ -47,7 +47,7 @@ function test() {
let provider = reporter.getProvider("org.mozilla.searches");
ok(provider, "Searches provider is available.");
let m = provider.getMeasurement("counts", 2);
let m = provider.getMeasurement("counts", 3);
m.getValues().then(function onValues(data) {
let now = new Date();
ok(data.days.hasDay(now), "Have data for today.");

Просмотреть файл

@ -23,7 +23,7 @@ function test() {
reporter.onInit().then(function onInit() {
let provider = reporter.getProvider("org.mozilla.searches");
ok(provider, "Searches provider is available.");
let m = provider.getMeasurement("counts", 2);
let m = provider.getMeasurement("counts", 3);
m.getValues().then(function onData(data) {
let now = new Date();

Просмотреть файл

@ -320,9 +320,8 @@ BrowserGlue.prototype = {
reporter.onInit().then(function record() {
try {
let name = subject.QueryInterface(Ci.nsISearchEngine).name;
reporter.getProvider("org.mozilla.searches").recordSearch(name,
"urlbar");
let engine = subject.QueryInterface(Ci.nsISearchEngine);
reporter.getProvider("org.mozilla.searches").recordSearch(engine, "urlbar");
} catch (ex) {
Cu.reportError(ex);
}

Просмотреть файл

@ -483,7 +483,7 @@
// null parameter below specifies HTML response for search
var submission = this.currentEngine.getSubmission(aData, null, "searchbar");
BrowserSearch.recordSearchInHealthReport(this.currentEngine.name, "searchbar");
BrowserSearch.recordSearchInHealthReport(this.currentEngine, "searchbar");
openUILinkIn(submission.uri.spec, aWhere, null, submission.postData);
]]></body>
</method>

Просмотреть файл

@ -27,14 +27,15 @@ function test() {
ok(reporter, "Health Reporter available.");
reporter.onInit().then(function onInit() {
let provider = reporter.getProvider("org.mozilla.searches");
let m = provider.getMeasurement("counts", 2);
let m = provider.getMeasurement("counts", 3);
m.getValues().then(function onData(data) {
let now = new Date();
let oldCount = 0;
// Foo engine goes into "other" bucket.
let field = "other.searchbar";
// Find the right bucket for the "Foo" engine.
let engine = Services.search.getEngineByName("Foo");
let field = (engine.identifier || "other-Foo") + ".searchbar";
if (data.days.hasDay(now)) {
let day = data.days.getDay(now);

Просмотреть файл

@ -306,7 +306,20 @@ TabTarget.prototype = {
this._client.connect((aType, aTraits) => {
this._client.listTabs(aResponse => {
this._root = aResponse;
this._form = aResponse.tabs[aResponse.selected];
let windowUtils = this.window
.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils);
let outerWindow = windowUtils.outerWindowID;
aResponse.tabs.some((tab) => {
if (tab.outerWindowID === outerWindow) {
this._form = tab;
return true;
}
});
if (!this._form) {
this._form = aResponse.tabs[aResponse.selected];
}
attachTab();
});
});

Просмотреть файл

@ -165,11 +165,12 @@ let AboutHome = {
Cu.reportError(ex);
break;
}
let engine = Services.search.currentEngine;
#ifdef MOZ_SERVICES_HEALTHREPORT
window.BrowserSearch.recordSearchInHealthReport(data.engineName, "abouthome");
window.BrowserSearch.recordSearchInHealthReport(engine, "abouthome");
#endif
// Trigger a search through nsISearchEngine.getSubmission()
let submission = Services.search.currentEngine.getSubmission(data.searchTerms, null, "homepage");
let submission = engine.getSubmission(data.searchTerms, null, "homepage");
window.loadURI(submission.uri.spec, null, submission.postData);
break;
}

Просмотреть файл

@ -1943,7 +1943,7 @@ ia64*-hpux*)
no_x=yes
if test -n "$gonkdir"; then
_PLATFORM_DEFAULT_TOOLKIT=cairo-gonk
MOZ_B2G_RIL=1
_PLATFORM_HAVE_RIL=1
MOZ_B2G_FM=1
MOZ_SYNTH_PICO=1
else
@ -7276,9 +7276,14 @@ dnl ========================================================
MOZ_ARG_ENABLE_BOOL(b2g-ril,
[ --enable-b2g-ril Set compile flags necessary for testing B2G Radio Interface Layer via network sockets ],
MOZ_B2G_RIL=1,
MOZ_B2G_RIL= )
MOZ_B2G_RIL=,
MOZ_B2G_RIL=$_PLATFORM_HAVE_RIL )
if test -n "$MOZ_B2G_RIL"; then
AC_DEFINE(MOZ_B2G_RIL)
if test -n "$_PLATFORM_HAVE_RIL"; then
AC_DEFINE(MOZ_B2G_RIL)
else
AC_MSG_ERROR([b2g-ril cannot be enabled because target platform doesn't support it.])
fi
fi
AC_SUBST(MOZ_B2G_RIL)

Просмотреть файл

@ -18,7 +18,7 @@ LOCAL_INCLUDES += \
-I$(srcdir)/../../../layout/xul/tree/ \
$(NULL)
ifdef MOZ_B2G_RIL
ifeq (gonk,$(MOZ_WIDGET_TOOLKIT))
LOCAL_INCLUDES += \
-I$(srcdir)/../../../dom/wifi \
$(NULL)

Просмотреть файл

@ -87,7 +87,9 @@ nsresult MediaOmxReader::InitOmxDecoder()
dataSource->initCheck();
sp<MediaExtractor> extractor = MediaExtractor::Create(dataSource);
if (!extractor.get()) {
return NS_ERROR_FAILURE;
}
mOmxDecoder = new OmxDecoder(mDecoder->GetResource(), mDecoder);
if (!mOmxDecoder->Init(extractor)) {
return NS_ERROR_FAILURE;

Просмотреть файл

@ -29,6 +29,7 @@
#include "nsIDOMWakeLock.h"
#include "nsIPowerManagerService.h"
#include "mozilla/dom/MobileMessageManager.h"
#include "mozilla/dom/Telephony.h"
#include "mozilla/Hal.h"
#include "nsISiteSpecificUserAgent.h"
#include "mozilla/ClearOnShutdown.h"
@ -38,9 +39,8 @@
#include "nsGlobalWindow.h"
#ifdef MOZ_B2G_RIL
#include "mozilla/dom/IccManager.h"
#include "MobileConnection.h"
#include "mozilla/dom/CellBroadcast.h"
#include "mozilla/dom/Telephony.h"
#include "mozilla/dom/network/MobileConnection.h"
#include "mozilla/dom/Voicemail.h"
#endif
#include "nsIIdleObserver.h"
@ -138,12 +138,12 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(Navigator)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mBatteryManager)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPowerManager)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mMobileMessageManager)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mTelephony)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mConnection)
#ifdef MOZ_B2G_RIL
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mMobileConnection)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCellBroadcast)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mIccManager)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mTelephony)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mVoicemail)
#endif
#ifdef MOZ_B2G_BT
@ -209,6 +209,10 @@ Navigator::Invalidate()
mMobileMessageManager = nullptr;
}
if (mTelephony) {
mTelephony = nullptr;
}
if (mConnection) {
mConnection->Shutdown();
mConnection = nullptr;
@ -229,10 +233,6 @@ Navigator::Invalidate()
mIccManager = nullptr;
}
if (mTelephony) {
mTelephony = nullptr;
}
if (mVoicemail) {
mVoicemail = nullptr;
}
@ -1165,6 +1165,20 @@ Navigator::GetMozMobileMessage()
return mMobileMessageManager;
}
Telephony*
Navigator::GetMozTelephony(ErrorResult& aRv)
{
if (!mTelephony) {
if (!mWindow) {
aRv.Throw(NS_ERROR_UNEXPECTED);
return nullptr;
}
mTelephony = Telephony::Create(mWindow, aRv);
}
return mTelephony;
}
#ifdef MOZ_B2G_RIL
CellBroadcast*
@ -1181,20 +1195,6 @@ Navigator::GetMozCellBroadcast(ErrorResult& aRv)
return mCellBroadcast;
}
Telephony*
Navigator::GetMozTelephony(ErrorResult& aRv)
{
if (!mTelephony) {
if (!mWindow) {
aRv.Throw(NS_ERROR_UNEXPECTED);
return nullptr;
}
mTelephony = Telephony::Create(mWindow, aRv);
}
return mTelephony;
}
Voicemail*
Navigator::GetMozVoicemail(ErrorResult& aRv)
{
@ -1697,15 +1697,6 @@ Navigator::HasMobileMessageSupport(JSContext* /* unused */, JSObject* aGlobal)
return true;
}
/* static */
bool
Navigator::HasCameraSupport(JSContext* /* unused */, JSObject* aGlobal)
{
nsCOMPtr<nsPIDOMWindow> win = GetWindowFromGlobal(aGlobal);
return win && nsDOMCameraManager::CheckPermission(win);
}
#ifdef MOZ_B2G_RIL
/* static */
bool
Navigator::HasTelephonySupport(JSContext* /* unused */, JSObject* aGlobal)
@ -1719,6 +1710,15 @@ Navigator::HasTelephonySupport(JSContext* /* unused */, JSObject* aGlobal)
return win && CheckPermission(win, "telephony");
}
/* static */
bool
Navigator::HasCameraSupport(JSContext* /* unused */, JSObject* aGlobal)
{
nsCOMPtr<nsPIDOMWindow> win = GetWindowFromGlobal(aGlobal);
return win && nsDOMCameraManager::CheckPermission(win);
}
#ifdef MOZ_B2G_RIL
/* static */
bool
Navigator::HasMobileConnectionSupport(JSContext* /* unused */,

Просмотреть файл

@ -86,11 +86,11 @@ class BluetoothManager;
#ifdef MOZ_B2G_RIL
class CellBroadcast;
class IccManager;
class Telephony;
class Voicemail;
#endif
class PowerManager;
class Telephony;
namespace time {
class TimeManager;
@ -211,6 +211,7 @@ public:
bool MozIsLocallyAvailable(const nsAString& aURI, bool aWhenOffline,
ErrorResult& aRv);
nsIDOMMozMobileMessageManager* GetMozMobileMessage();
Telephony* GetMozTelephony(ErrorResult& aRv);
nsIDOMMozConnection* GetMozConnection();
nsDOMCameraManager* GetMozCameras(ErrorResult& aRv);
void MozSetMessageHandler(const nsAString& aType,
@ -218,7 +219,6 @@ public:
ErrorResult& aRv);
bool MozHasPendingMessage(const nsAString& aType, ErrorResult& aRv);
#ifdef MOZ_B2G_RIL
Telephony* GetMozTelephony(ErrorResult& aRv);
nsIDOMMozMobileConnection* GetMozMobileConnection(ErrorResult& aRv);
CellBroadcast* GetMozCellBroadcast(ErrorResult& aRv);
Voicemail* GetMozVoicemail(ErrorResult& aRv);
@ -268,11 +268,11 @@ public:
}
static bool HasMobileMessageSupport(JSContext* /* unused */,
JSObject* aGlobal);
static bool HasTelephonySupport(JSContext* /* unused */,
JSObject* aGlobal);
static bool HasCameraSupport(JSContext* /* unused */,
JSObject* aGlobal);
#ifdef MOZ_B2G_RIL
static bool HasTelephonySupport(JSContext* /* unused */,
JSObject* aGlobal);
static bool HasMobileConnectionSupport(JSContext* /* unused */,
JSObject* aGlobal);
static bool HasCellBroadcastSupport(JSContext* /* unused */,
@ -326,12 +326,12 @@ private:
#endif
nsRefPtr<PowerManager> mPowerManager;
nsRefPtr<MobileMessageManager> mMobileMessageManager;
nsRefPtr<Telephony> mTelephony;
nsRefPtr<network::Connection> mConnection;
#ifdef MOZ_B2G_RIL
nsRefPtr<network::MobileConnection> mMobileConnection;
nsRefPtr<CellBroadcast> mCellBroadcast;
nsRefPtr<IccManager> mIccManager;
nsRefPtr<Telephony> mTelephony;
nsRefPtr<Voicemail> mVoicemail;
#endif
#ifdef MOZ_B2G_BT

Просмотреть файл

@ -128,7 +128,6 @@ LIBRARY_NAME = 'jsdombase_s'
LOCAL_INCLUDES += [
'../battery',
'../bluetooth',
'../icc/src',
'../media',
'../network/src',
'../src/geolocation',
@ -144,7 +143,7 @@ LOCAL_INCLUDES += [
'/layout/xul/base/src',
]
if CONFIG['MOZ_B2G_RIL']:
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk':
LOCAL_INCLUDES += [
'../fmradio',
'../system/gonk',

Просмотреть файл

@ -881,6 +881,7 @@ BluetoothAdapter::IsScoConnected(ErrorResult& aRv)
already_AddRefed<DOMRequest>
BluetoothAdapter::AnswerWaitingCall(ErrorResult& aRv)
{
#ifdef MOZ_B2G_RIL
nsCOMPtr<nsPIDOMWindow> win = GetOwner();
if (!win) {
aRv.Throw(NS_ERROR_FAILURE);
@ -899,11 +900,16 @@ BluetoothAdapter::AnswerWaitingCall(ErrorResult& aRv)
bs->AnswerWaitingCall(results);
return request.forget();
#else
aRv.Throw(NS_ERROR_NOT_IMPLEMENTED);
return nullptr;
#endif // MOZ_B2G_RIL
}
already_AddRefed<DOMRequest>
BluetoothAdapter::IgnoreWaitingCall(ErrorResult& aRv)
{
#ifdef MOZ_B2G_RIL
nsCOMPtr<nsPIDOMWindow> win = GetOwner();
if (!win) {
aRv.Throw(NS_ERROR_FAILURE);
@ -922,11 +928,16 @@ BluetoothAdapter::IgnoreWaitingCall(ErrorResult& aRv)
bs->IgnoreWaitingCall(results);
return request.forget();
#else
aRv.Throw(NS_ERROR_NOT_IMPLEMENTED);
return nullptr;
#endif // MOZ_B2G_RIL
}
already_AddRefed<DOMRequest>
BluetoothAdapter::ToggleCalls(ErrorResult& aRv)
{
#ifdef MOZ_B2G_RIL
nsCOMPtr<nsPIDOMWindow> win = GetOwner();
if (!win) {
aRv.Throw(NS_ERROR_FAILURE);
@ -945,6 +956,10 @@ BluetoothAdapter::ToggleCalls(ErrorResult& aRv)
bs->ToggleCalls(results);
return request.forget();
#else
aRv.Throw(NS_ERROR_NOT_IMPLEMENTED);
return nullptr;
#endif // MOZ_B2G_RIL
}
already_AddRefed<DOMRequest>

Просмотреть файл

@ -15,19 +15,24 @@
#include "BluetoothUtils.h"
#include "BluetoothUuid.h"
#include "MobileConnection.h"
#include "jsapi.h"
#include "mozilla/dom/bluetooth/BluetoothTypes.h"
#include "mozilla/Services.h"
#include "mozilla/StaticPtr.h"
#include "nsContentUtils.h"
#include "nsIAudioManager.h"
#include "nsIDOMIccInfo.h"
#include "nsIIccProvider.h"
#include "nsIObserverService.h"
#include "nsISettingsService.h"
#include "nsServiceManagerUtils.h"
#ifdef MOZ_B2G_RIL
#include "nsIDOMIccInfo.h"
#include "nsIDOMMobileConnection.h"
#include "nsIIccProvider.h"
#include "nsIMobileConnectionProvider.h"
#include "nsITelephonyProvider.h"
#include "nsRadioInterfaceLayer.h"
#include "nsServiceManagerUtils.h"
#endif
/**
* BRSF bitmask of AG supported features. See 4.34.1 "Bluetooth Defined AT
@ -44,6 +49,7 @@
#define BRSF_BIT_EXTENDED_ERR_RESULT_CODES (1 << 8)
#define BRSF_BIT_CODEC_NEGOTIATION (1 << 9)
#ifdef MOZ_B2G_RIL
/**
* These constants are used in result code such as +CLIP and +CCWA. The value
* of these constants is the same as TOA_INTERNATIONAL/TOA_UNKNOWN defined in
@ -51,6 +57,7 @@
*/
#define TOA_UNKNOWN 0x81
#define TOA_INTERNATIONAL 0x91
#endif
#define CR_LF "\xd\xa";
@ -66,6 +73,7 @@ namespace {
bool sInShutdown = false;
static const char kHfpCrlf[] = "\xd\xa";
#ifdef MOZ_B2G_RIL
// Sending ringtone related
static bool sStopSendingRingFlag = true;
static int sRingInterval = 3000; //unit: ms
@ -79,8 +87,10 @@ namespace {
// The mechanism should be revised once we know the exact time at which
// Dialer stops playing.
static int sBusyToneInterval = 3700; //unit: ms
#endif // MOZ_B2G_RIL
} // anonymous namespace
#ifdef MOZ_B2G_RIL
/* CallState for sCINDItems[CINDType::CALL].value
* - NO_CALL: there are no calls in progress
* - IN_PROGRESS: at least one call is in progress
@ -113,6 +123,7 @@ enum CallHeldState {
ONHOLD_ACTIVE,
ONHOLD_NOACTIVE
};
#endif // MOZ_B2G_RIL
typedef struct {
const char* name;
@ -123,23 +134,27 @@ typedef struct {
enum CINDType {
BATTCHG = 1,
#ifdef MOZ_B2G_RIL
CALL,
CALLHELD,
CALLSETUP,
SERVICE,
SIGNAL,
ROAM
#endif
};
static CINDItem sCINDItems[] = {
{},
{"battchg", "0-5", 5, true},
#ifdef MOZ_B2G_RIL
{"call", "0,1", CallState::NO_CALL, true},
{"callheld", "0-2", CallHeldState::NO_CALLHELD, true},
{"callsetup", "0-3", CallSetupState::NO_CALLSETUP, true},
{"service", "0,1", 0, true},
{"signal", "0-5", 0, true},
{"roam", "0,1", 0, true}
#endif
};
class BluetoothHfpManager::GetVolumeTask : public nsISettingsServiceCallback
@ -206,6 +221,7 @@ BluetoothHfpManager::Notify(const hal::BatteryInformation& aBatteryInfo)
}
}
#ifdef MOZ_B2G_RIL
class BluetoothHfpManager::RespondToBLDNTask : public Task
{
private:
@ -265,6 +281,7 @@ private:
nsString mNumber;
int mType;
};
#endif // MOZ_B2G_RIL
class BluetoothHfpManager::CloseScoTask : public Task
{
@ -277,6 +294,7 @@ private:
}
};
#ifdef MOZ_B2G_RIL
static bool
IsValidDtmf(const char aChar) {
// Valid DTMF: [*#0-9ABCD]
@ -319,6 +337,7 @@ Call::IsActive()
{
return (mState == nsITelephonyProvider::CALL_STATE_CONNECTED);
}
#endif // MOZ_B2G_RIL
/**
* BluetoothHfpManager
@ -328,6 +347,7 @@ BluetoothHfpManager::BluetoothHfpManager() : mController(nullptr)
Reset();
}
#ifdef MOZ_B2G_RIL
void
BluetoothHfpManager::ResetCallArray()
{
@ -341,25 +361,31 @@ BluetoothHfpManager::ResetCallArray()
mCdmaSecondCall.Reset();
}
}
#endif // MOZ_B2G_RIL
void
BluetoothHfpManager::Reset()
{
#ifdef MOZ_B2G_RIL
sStopSendingRingFlag = true;
sCINDItems[CINDType::CALL].value = CallState::NO_CALL;
sCINDItems[CINDType::CALLSETUP].value = CallSetupState::NO_CALLSETUP;
sCINDItems[CINDType::CALLHELD].value = CallHeldState::NO_CALLHELD;
#endif
for (uint8_t i = 1; i < ArrayLength(sCINDItems); i++) {
sCINDItems[i].activated = true;
}
#ifdef MOZ_B2G_RIL
mCCWA = false;
mCLIP = false;
mDialingRequestProcessed = true;
#endif
mCMEE = false;
mCMER = false;
mReceiveVgsFlag = false;
mDialingRequestProcessed = true;
#ifdef MOZ_B2G_RIL
// We disable BSIR by default as it requires OEM implement BT SCO + SPEAKER
// output audio path in audio driver. OEM can enable BSIR by setting
// mBSIR=true here.
@ -368,6 +394,7 @@ BluetoothHfpManager::Reset()
mBSIR = false;
ResetCallArray();
#endif
}
bool
@ -386,11 +413,13 @@ BluetoothHfpManager::Init()
hal::RegisterBatteryObserver(this);
#ifdef MOZ_B2G_RIL
mListener = new BluetoothRilListener();
if (!mListener->StartListening()) {
BT_WARNING("Failed to start listening RIL");
return false;
}
#endif
nsCOMPtr<nsISettingsService> settings =
do_GetService("@mozilla.org/settingsService;1");
@ -417,10 +446,12 @@ BluetoothHfpManager::Init()
BluetoothHfpManager::~BluetoothHfpManager()
{
#ifdef MOZ_B2G_RIL
if (!mListener->StopListening()) {
BT_WARNING("Failed to stop listening RIL");
}
mListener = nullptr;
#endif
nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
NS_ENSURE_TRUE_VOID(obs);
@ -486,6 +517,7 @@ BluetoothHfpManager::NotifyConnectionStatusChanged(const nsAString& aType)
DispatchStatusChangedEvent(eventName, mDeviceAddress, status);
}
#ifdef MOZ_B2G_RIL
void
BluetoothHfpManager::NotifyDialer(const nsAString& aCommand)
{
@ -502,6 +534,7 @@ BluetoothHfpManager::NotifyDialer(const nsAString& aCommand)
BT_WARNING("Failed to broadcast system message to dialer");
}
}
#endif // MOZ_B2G_RIL
void
BluetoothHfpManager::HandleVolumeChanged(const nsAString& aData)
@ -551,6 +584,7 @@ BluetoothHfpManager::HandleVolumeChanged(const nsAString& aData)
}
}
#ifdef MOZ_B2G_RIL
void
BluetoothHfpManager::HandleVoiceConnectionChanged()
{
@ -559,7 +593,8 @@ BluetoothHfpManager::HandleVoiceConnectionChanged()
NS_ENSURE_TRUE_VOID(connection);
nsCOMPtr<nsIDOMMozMobileConnectionInfo> voiceInfo;
connection->GetVoiceConnectionInfo(getter_AddRefs(voiceInfo));
// TODO: Bug 921991 - B2G BT: support multiple sim cards
connection->GetVoiceConnectionInfo(0, getter_AddRefs(voiceInfo));
NS_ENSURE_TRUE_VOID(voiceInfo);
nsString type;
@ -595,7 +630,8 @@ BluetoothHfpManager::HandleVoiceConnectionChanged()
* - manual: set mNetworkSelectionMode to 1 (manual)
*/
nsString mode;
connection->GetNetworkSelectionMode(mode);
// TODO: Bug 921991 - B2G BT: support multiple sim cards
connection->GetNetworkSelectionMode(0, mode);
if (mode.EqualsLiteral("manual")) {
mNetworkSelectionMode = 1;
} else {
@ -636,6 +672,7 @@ BluetoothHfpManager::HandleIccInfoChanged()
NS_ENSURE_TRUE_VOID(gsmIccInfo);
gsmIccInfo->GetMsisdn(mMsisdn);
}
#endif // MOZ_B2G_RIL
void
BluetoothHfpManager::HandleShutdown()
@ -663,6 +700,7 @@ BluetoothHfpManager::ReceiveSocketData(BluetoothSocket* aSocket,
// For more information, please refer to 4.34.1 "Bluetooth Defined AT
// Capabilities" in Bluetooth hands-free profile 1.6
if (msg.Find("AT+BRSF=") != -1) {
#ifdef MOZ_B2G_RIL
uint32_t brsf = BRSF_BIT_ABILITY_TO_REJECT_CALL |
BRSF_BIT_ENHANCED_CALL_STATUS;
@ -675,6 +713,9 @@ BluetoothHfpManager::ReceiveSocketData(BluetoothSocket* aSocket,
if (mBSIR) {
brsf |= BRSF_BIT_IN_BAND_RING_TONE;
}
#else
uint32_t brsf = 0;
#endif // MOZ_B2G_RIL
SendCommand("+BRSF: ", brsf);
} else if (msg.Find("AT+CIND=?") != -1) {
@ -715,6 +756,7 @@ BluetoothHfpManager::ReceiveSocketData(BluetoothSocket* aSocket,
// AT+CMEE = 1: use numeric <err>
// AT+CMEE = 2: use verbose <err>
mCMEE = !atCommandValues[0].EqualsLiteral("0");
#ifdef MOZ_B2G_RIL
} else if (msg.Find("AT+COPS=") != -1) {
ParseAtCommand(msg, 8, atCommandValues);
@ -753,6 +795,7 @@ BluetoothHfpManager::ReceiveSocketData(BluetoothSocket* aSocket,
message += atCommandValues[0].get()[0];
NotifyDialer(NS_ConvertUTF8toUTF16(message));
}
#endif // MOZ_B2G_RIL
} else if (msg.Find("AT+VGM=") != -1) {
ParseAtCommand(msg, 7, atCommandValues);
@ -770,6 +813,7 @@ BluetoothHfpManager::ReceiveSocketData(BluetoothSocket* aSocket,
NS_ASSERTION(vgm >= 0 && vgm <= 15, "Received invalid VGM value");
mCurrentVgm = vgm;
#ifdef MOZ_B2G_RIL
} else if (msg.Find("AT+CHLD=?") != -1) {
SendLine("+CHLD: (0,1,2)");
} else if (msg.Find("AT+CHLD=") != -1) {
@ -820,6 +864,7 @@ BluetoothHfpManager::ReceiveSocketData(BluetoothSocket* aSocket,
SendLine("ERROR");
return;
}
#endif // MOZ_B2G_RIL
} else if (msg.Find("AT+VGS=") != -1) {
// Adjust volume by headset
mReceiveVgsFlag = true;
@ -847,6 +892,7 @@ BluetoothHfpManager::ReceiveSocketData(BluetoothSocket* aSocket,
nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
data.AppendInt(newVgs);
os->NotifyObservers(nullptr, "bluetooth-volume-change", data.get());
#ifdef MOZ_B2G_RIL
} else if ((msg.Find("AT+BLDN") != -1) || (msg.Find("ATD>") != -1)) {
// Dialer app of FFOS v1 does not have plan to support Memory Dailing.
// However, in order to pass Bluetooth HFP certification, we still have to
@ -972,6 +1018,7 @@ BluetoothHfpManager::ReceiveSocketData(BluetoothSocket* aSocket,
// Ignore requests to activate/deactivate mandatory indicators
}
}
#endif // MOZ_B2G_RIL
} else {
nsCString warningMsg;
warningMsg.Append(NS_LITERAL_CSTRING("Unsupported AT command: "));
@ -1096,6 +1143,7 @@ BluetoothHfpManager::Disconnect(BluetoothProfileController* aController)
mSocket->Disconnect();
}
#ifdef MOZ_B2G_RIL
void
BluetoothHfpManager::SendCCWA(const nsAString& aNumber, int aType)
{
@ -1157,6 +1205,7 @@ BluetoothHfpManager::SendCLCC(const Call& aCall, int aIndex)
return SendLine(message.get());
}
#endif // MOZ_B2G_RIL
bool
BluetoothHfpManager::SendLine(const char* aMessage)
@ -1222,6 +1271,7 @@ BluetoothHfpManager::SendCommand(const char* aCommand, uint32_t aValue)
message.AppendLiteral(",");
}
}
#ifdef MOZ_B2G_RIL
} else if (!strcmp(aCommand, "+CLCC: ")) {
bool rv = true;
uint32_t callNumbers = mCurrentCallArray.Length();
@ -1238,6 +1288,7 @@ BluetoothHfpManager::SendCommand(const char* aCommand, uint32_t aValue)
}
return rv;
#endif // MOZ_B2G_RIL
} else {
message.AppendInt(aValue);
}
@ -1245,6 +1296,7 @@ BluetoothHfpManager::SendCommand(const char* aCommand, uint32_t aValue)
return SendLine(message.get());
}
#ifdef MOZ_B2G_RIL
void
BluetoothHfpManager::UpdateCIND(uint8_t aType, uint8_t aValue, bool aSend)
{
@ -1525,12 +1577,15 @@ BluetoothHfpManager::ToggleCalls()
nsITelephonyProvider::CALL_STATE_HELD :
nsITelephonyProvider::CALL_STATE_CONNECTED;
}
#endif // MOZ_B2G_RIL
void
BluetoothHfpManager::OnSocketConnectSuccess(BluetoothSocket* aSocket)
{
MOZ_ASSERT(aSocket);
#ifdef MOZ_B2G_RIL
MOZ_ASSERT(mListener);
#endif
// Success to create a SCO socket
if (aSocket == mScoSocket) {
@ -1559,10 +1614,12 @@ BluetoothHfpManager::OnSocketConnectSuccess(BluetoothSocket* aSocket)
mHandsfreeSocket = nullptr;
}
#ifdef MOZ_B2G_RIL
// Enumerate current calls
mListener->EnumerateCalls();
mFirstCKPD = true;
#endif
// Cache device path for NotifySettings() since we can't get socket address
// when a headset disconnect with us

Просмотреть файл

@ -9,7 +9,9 @@
#include "BluetoothCommon.h"
#include "BluetoothProfileManagerBase.h"
#ifdef MOZ_B2G_RIL
#include "BluetoothRilListener.h"
#endif
#include "BluetoothSocketObserver.h"
#include "mozilla/ipc/UnixSocket.h"
#include "mozilla/Hal.h"
@ -18,6 +20,8 @@ BEGIN_BLUETOOTH_NAMESPACE
class BluetoothReplyRunnable;
class BluetoothSocket;
#ifdef MOZ_B2G_RIL
class Call;
/**
@ -67,6 +71,7 @@ public:
nsString mNumber;
int mType;
};
#endif // MOZ_B2G_RIL
class BluetoothHfpManager : public BluetoothSocketObserver
, public BluetoothProfileManagerBase
@ -109,6 +114,7 @@ public:
bool DisconnectSco();
bool ListenSco();
#ifdef MOZ_B2G_RIL
/**
* @param aSend A boolean indicates whether we need to notify headset or not
*/
@ -117,26 +123,33 @@ public:
const bool aIsOutgoing, bool aSend);
void HandleIccInfoChanged();
void HandleVoiceConnectionChanged();
#endif
bool IsConnected();
bool IsScoConnected();
#ifdef MOZ_B2G_RIL
// CDMA-specific functions
void UpdateSecondNumber(const nsAString& aNumber);
void AnswerWaitingCall();
void IgnoreWaitingCall();
void ToggleCalls();
#endif
private:
class CloseScoTask;
class GetVolumeTask;
#ifdef MOZ_B2G_RIL
class RespondToBLDNTask;
class SendRingIndicatorTask;
#endif
friend class CloseScoTask;
friend class GetVolumeTask;
#ifdef MOZ_B2G_RIL
friend class RespondToBLDNTask;
friend class SendRingIndicatorTask;
#endif
friend class BluetoothHfpManagerObserver;
BluetoothHfpManager();
@ -146,41 +159,55 @@ private:
bool Init();
void Notify(const hal::BatteryInformation& aBatteryInfo);
void Reset();
#ifdef MOZ_B2G_RIL
void ResetCallArray();
uint32_t FindFirstCall(uint16_t aState);
uint32_t GetNumberOfCalls(uint16_t aState);
PhoneType GetPhoneType(const nsAString& aType);
#endif
void NotifyConnectionStatusChanged(const nsAString& aType);
void NotifyDialer(const nsAString& aCommand);
#ifdef MOZ_B2G_RIL
void SendCCWA(const nsAString& aNumber, int aType);
bool SendCLCC(const Call& aCall, int aIndex);
#endif
bool SendCommand(const char* aCommand, uint32_t aValue = 0);
bool SendLine(const char* aMessage);
#ifdef MOZ_B2G_RIL
void UpdateCIND(uint8_t aType, uint8_t aValue, bool aSend = true);
#endif
void OnScoConnectSuccess();
void OnScoConnectError();
void OnScoDisconnect();
int mCurrentVgs;
int mCurrentVgm;
#ifdef MOZ_B2G_RIL
bool mBSIR;
bool mCCWA;
bool mCLIP;
#endif
bool mCMEE;
bool mCMER;
#ifdef MOZ_B2G_RIL
bool mFirstCKPD;
int mNetworkSelectionMode;
PhoneType mPhoneType;
#endif
bool mReceiveVgsFlag;
#ifdef MOZ_B2G_RIL
bool mDialingRequestProcessed;
#endif
nsString mDeviceAddress;
#ifdef MOZ_B2G_RIL
nsString mMsisdn;
nsString mOperatorName;
nsTArray<Call> mCurrentCallArray;
nsAutoPtr<BluetoothRilListener> mListener;
#endif
nsRefPtr<BluetoothProfileController> mController;
nsRefPtr<BluetoothReplyRunnable> mScoRunnable;
@ -198,8 +225,10 @@ private:
nsRefPtr<BluetoothSocket> mScoSocket;
SocketConnectionStatus mScoSocketStatus;
#ifdef MOZ_B2G_RIL
// CDMA-specific variable
Call mCdmaSecondCall;
#endif
};
END_BLUETOOTH_NAMESPACE

Просмотреть файл

@ -125,6 +125,12 @@ MobileConnectionListener::NotifyOtaStatusChanged(const nsAString & status)
return NS_OK;
}
NS_IMETHODIMP
MobileConnectionListener::NotifyIccChanged()
{
return NS_OK;
}
/**
* TelephonyListener Implementation
*/
@ -292,8 +298,9 @@ BluetoothRilListener::StartMobileConnectionListening()
do_GetService(NS_RILCONTENTHELPER_CONTRACTID);
NS_ENSURE_TRUE(provider, false);
// TODO: Bug 921991 - B2G BT: support multiple sim cards
nsresult rv = provider->
RegisterMobileConnectionMsg(mMobileConnectionListener);
RegisterMobileConnectionMsg(0, mMobileConnectionListener);
return NS_SUCCEEDED(rv);
}
@ -304,8 +311,9 @@ BluetoothRilListener::StopMobileConnectionListening()
do_GetService(NS_RILCONTENTHELPER_CONTRACTID);
NS_ENSURE_TRUE(provider, false);
// TODO: Bug 921991 - B2G BT: support multiple sim cards
nsresult rv = provider->
UnregisterMobileConnectionMsg(mMobileConnectionListener);
UnregisterMobileConnectionMsg(0, mMobileConnectionListener);
return NS_SUCCEEDED(rv);
}

Просмотреть файл

@ -266,6 +266,7 @@ public:
virtual void
IsScoConnected(BluetoothReplyRunnable* aRunnable) = 0;
#ifdef MOZ_B2G_RIL
virtual void
AnswerWaitingCall(BluetoothReplyRunnable* aRunnable) = 0;
@ -274,6 +275,7 @@ public:
virtual void
ToggleCalls(BluetoothReplyRunnable* aRunnable) = 0;
#endif
virtual void
SendMetaData(const nsAString& aTitle,

Просмотреть файл

@ -1,4 +1,4 @@
/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*-
/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/*
** Copyright 2006, The Android Open Source Project
@ -31,6 +31,8 @@ using namespace mozilla;
using namespace mozilla::ipc;
USING_BLUETOOTH_NAMESPACE
typedef char bdstr_t[18];
/**
* Classes only used in this file
*/
@ -63,6 +65,11 @@ private:
static bluetooth_device_t* sBtDevice;
static const bt_interface_t* sBtInterface;
static bool sIsBtEnabled = false;
static bool sAdapterDiscoverable = false;
static nsString sAdapterBdAddress;
static nsString sAdapterBdName;
static uint32_t sAdapterDiscoverableTimeout;
static nsTArray<nsRefPtr<BluetoothReplyRunnable> > sSetPropertyRunnableArray;
/**
* Static callback functions
@ -72,7 +79,7 @@ AdapterStateChangeCallback(bt_state_t aStatus)
{
MOZ_ASSERT(!NS_IsMainThread());
BT_LOGD("Enter: %s, BT_STATE:%d", __FUNCTION__, aStatus);
BT_LOGD("%s, BT_STATE:%d", __FUNCTION__, aStatus);
nsAutoString signalName;
if (aStatus == BT_STATE_ON) {
sIsBtEnabled = true;
@ -90,9 +97,85 @@ AdapterStateChangeCallback(bt_state_t aStatus)
}
}
static void
BdAddressTypeToString(bt_bdaddr_t* aBdAddressType, nsAString& aRetBdAddress)
{
uint8_t* addr = aBdAddressType->address;
bdstr_t bdstr;
sprintf((char*)bdstr, "%02x:%02x:%02x:%02x:%02x:%02x",
(int)addr[0],(int)addr[1],(int)addr[2],
(int)addr[3],(int)addr[4],(int)addr[5]);
aRetBdAddress = NS_ConvertUTF8toUTF16((char*)bdstr);
}
static void
AdapterPropertiesChangeCallback(bt_status_t aStatus, int aNumProperties,
bt_property_t *aProperties)
{
MOZ_ASSERT(!NS_IsMainThread());
BluetoothValue propertyValue;
InfallibleTArray<BluetoothNamedValue> propertiesArray;
for (int i = 0; i < aNumProperties; i++) {
bt_property_t p = aProperties[i];
if (p.type == BT_PROPERTY_BDADDR) {
BdAddressTypeToString((bt_bdaddr_t*)p.val, sAdapterBdAddress);
propertyValue = sAdapterBdAddress;
propertiesArray.AppendElement(
BluetoothNamedValue(NS_LITERAL_STRING("Address"), propertyValue));
} else if (p.type == BT_PROPERTY_BDNAME) {
// Construct nsCString here because Bd name returned from bluedroid
// is missing a null terminated character after SetProperty.
propertyValue = sAdapterBdName = NS_ConvertUTF8toUTF16(
nsCString((char*)p.val, p.len));
propertiesArray.AppendElement(
BluetoothNamedValue(NS_LITERAL_STRING("Name"), propertyValue));
} else if (p.type == BT_PROPERTY_ADAPTER_SCAN_MODE) {
propertyValue = sAdapterDiscoverable = *(uint32_t*)p.val;
propertiesArray.AppendElement(
BluetoothNamedValue(NS_LITERAL_STRING("Discoverable"), propertyValue));
} else if (p.type == BT_PROPERTY_ADAPTER_DISCOVERY_TIMEOUT) {
propertyValue = sAdapterDiscoverableTimeout = *(uint32_t*)p.val;
propertiesArray.AppendElement(
BluetoothNamedValue(NS_LITERAL_STRING("DiscoverableTimeout"),
propertyValue));
} else if (p.type == BT_PROPERTY_ADAPTER_BONDED_DEVICES) {
//FIXME: This will be implemented in the later patchset
return;
} else if (p.type == BT_PROPERTY_UUIDS) {
//FIXME: This will be implemented in the later patchset
return;
} else {
BT_LOGR("Unhandled adapter property type: %d", p.type);
return;
}
BluetoothValue value(propertiesArray);
BluetoothSignal signal(NS_LITERAL_STRING("PropertyChanged"),
NS_LITERAL_STRING(KEY_ADAPTER), value);
nsRefPtr<DistributeBluetoothSignalTask>
t = new DistributeBluetoothSignalTask(signal);
if (NS_FAILED(NS_DispatchToMainThread(t))) {
NS_WARNING("Failed to dispatch to main thread!");
}
// bluedroid BTU task was stored in the task queue, see GKI_send_msg
if (!sSetPropertyRunnableArray.IsEmpty()) {
DispatchBluetoothReply(sSetPropertyRunnableArray[0], BluetoothValue(true),
EmptyString());
sSetPropertyRunnableArray.RemoveElementAt(0);
}
}
}
bt_callbacks_t sBluetoothCallbacks = {
sizeof(sBluetoothCallbacks),
AdapterStateChangeCallback
AdapterStateChangeCallback,
AdapterPropertiesChangeCallback
};
/**
@ -145,6 +228,32 @@ StartStopGonkBluetooth(bool aShouldEnable)
return (ret == BT_STATUS_SUCCESS) ? NS_OK : NS_ERROR_FAILURE;
}
static void
ReplyStatusError(BluetoothReplyRunnable* aBluetoothReplyRunnable,
int aStatusCode, const nsAString& aCustomMsg)
{
MOZ_ASSERT(aBluetoothReplyRunnable, "Reply runnable is nullptr");
nsAutoString replyError;
replyError.Assign(aCustomMsg);
if (aStatusCode == BT_STATUS_BUSY) {
replyError.AppendLiteral(":BT_STATUS_BUSY");
} else if (aStatusCode == BT_STATUS_NOT_READY) {
replyError.AppendLiteral(":BT_STATUS_NOT_READY");
} else if (aStatusCode == BT_STATUS_DONE) {
replyError.AppendLiteral(":BT_STATUS_DONE");
} else if (aStatusCode == BT_STATUS_AUTH_FAILURE) {
replyError.AppendLiteral(":BT_STATUS_AUTH_FAILURE");
} else if (aStatusCode == BT_STATUS_RMT_DEV_DOWN) {
replyError.AppendLiteral(":BT_STATUS_RMT_DEV_DOWN");
} else if (aStatusCode == BT_STATUS_FAIL) {
replyError.AppendLiteral(":BT_STATUS_FAIL");
}
DispatchBluetoothReply(aBluetoothReplyRunnable, BluetoothValue(true),
replyError);
}
/**
* Member functions
*/
@ -191,6 +300,19 @@ nsresult
BluetoothServiceBluedroid::GetDefaultAdapterPathInternal(
BluetoothReplyRunnable* aRunnable)
{
MOZ_ASSERT(NS_IsMainThread());
nsRefPtr<BluetoothReplyRunnable> runnable(aRunnable);
BluetoothValue v = InfallibleTArray<BluetoothNamedValue>();
v.get_ArrayOfBluetoothNamedValue().AppendElement(
BluetoothNamedValue(NS_LITERAL_STRING("Name"), sAdapterBdName));
nsAutoString replyError;
DispatchBluetoothReply(runnable.get(), v, replyError);
runnable.forget();
return NS_OK;
}
@ -235,6 +357,50 @@ BluetoothServiceBluedroid::SetProperty(BluetoothObjectType aType,
const BluetoothNamedValue& aValue,
BluetoothReplyRunnable* aRunnable)
{
MOZ_ASSERT(NS_IsMainThread());
const nsString propName = aValue.name();
bt_property_t prop;
nsString str;
// For Bluedroid, it's necessary to check property name for SetProperty
if (propName.EqualsLiteral("Name")) {
prop.type = BT_PROPERTY_BDNAME;
} else if (propName.EqualsLiteral("Discoverable")) {
prop.type = BT_PROPERTY_ADAPTER_SCAN_MODE;
} else if (propName.EqualsLiteral("DiscoverableTimeout")) {
prop.type = BT_PROPERTY_ADAPTER_DISCOVERY_TIMEOUT;
} else {
BT_LOGR("Warning: Property type is not supported yet, type: %d", prop.type);
}
if (aValue.value().type() == BluetoothValue::Tuint32_t) {
// Set discoverable timeout
prop.val = (void*)aValue.value().get_uint32_t();
} else if (aValue.value().type() == BluetoothValue::TnsString) {
// Set name
str = aValue.value().get_nsString();
const char* name = NS_ConvertUTF16toUTF8(str).get();
prop.val = (void*)name;
prop.len = strlen(name);
} else if (aValue.value().type() == BluetoothValue::Tbool) {
bt_scan_mode_t mode = aValue.value().get_bool() ?
BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE :
BT_SCAN_MODE_CONNECTABLE;
bt_scan_mode_t* sss = &mode;
prop.val = (void*)sss;
prop.len = sizeof(sss);
} else {
BT_LOGR("SetProperty but the property cannot be recognized correctly.");
return NS_OK;
}
sSetPropertyRunnableArray.AppendElement(aRunnable);
int ret = sBtInterface->set_adapter_property(&prop);
if (ret != BT_STATUS_SUCCESS)
ReplyStatusError(aRunnable, ret, NS_LITERAL_STRING("SetProperty"));
return NS_OK;
}

Просмотреть файл

@ -226,12 +226,14 @@ BluetoothParent::RecvPBluetoothRequestConstructor(
return actor->DoRequest(aRequest.get_DisconnectScoRequest());
case Request::TIsScoConnectedRequest:
return actor->DoRequest(aRequest.get_IsScoConnectedRequest());
#ifdef MOZ_B2G_RIL
case Request::TAnswerWaitingCallRequest:
return actor->DoRequest(aRequest.get_AnswerWaitingCallRequest());
case Request::TIgnoreWaitingCallRequest:
return actor->DoRequest(aRequest.get_IgnoreWaitingCallRequest());
case Request::TToggleCallsRequest:
return actor->DoRequest(aRequest.get_ToggleCallsRequest());
#endif
case Request::TSendMetaDataRequest:
return actor->DoRequest(aRequest.get_SendMetaDataRequest());
case Request::TSendPlayStatusRequest:
@ -581,6 +583,7 @@ BluetoothRequestParent::DoRequest(const IsScoConnectedRequest& aRequest)
return true;
}
#ifdef MOZ_B2G_RIL
bool
BluetoothRequestParent::DoRequest(const AnswerWaitingCallRequest& aRequest)
{
@ -613,6 +616,7 @@ BluetoothRequestParent::DoRequest(const ToggleCallsRequest& aRequest)
return true;
}
#endif // MOZ_B2G_RIL
bool
BluetoothRequestParent::DoRequest(const SendMetaDataRequest& aRequest)

Просмотреть файл

@ -190,6 +190,7 @@ protected:
bool
DoRequest(const IsScoConnectedRequest& aRequest);
#ifdef MOZ_B2G_RIL
bool
DoRequest(const AnswerWaitingCallRequest& aRequest);
@ -198,6 +199,7 @@ protected:
bool
DoRequest(const ToggleCallsRequest& aRequest);
#endif
bool
DoRequest(const SendMetaDataRequest& aRequest);

Просмотреть файл

@ -328,6 +328,7 @@ BluetoothServiceChildProcess::IsScoConnected(BluetoothReplyRunnable* aRunnable)
SendRequest(aRunnable, IsScoConnectedRequest());
}
#ifdef MOZ_B2G_RIL
void
BluetoothServiceChildProcess::AnswerWaitingCall(
BluetoothReplyRunnable* aRunnable)
@ -348,6 +349,7 @@ BluetoothServiceChildProcess::ToggleCalls(
{
SendRequest(aRunnable, ToggleCallsRequest());
}
#endif // MOZ_B2G_RIL
void
BluetoothServiceChildProcess::SendMetaData(const nsAString& aTitle,

Просмотреть файл

@ -149,6 +149,7 @@ public:
virtual void
IsScoConnected(BluetoothReplyRunnable* aRunnable) MOZ_OVERRIDE;
#ifdef MOZ_B2G_RIL
virtual void
AnswerWaitingCall(BluetoothReplyRunnable* aRunnable) MOZ_OVERRIDE;
@ -157,6 +158,7 @@ public:
virtual void
ToggleCalls(BluetoothReplyRunnable* aRunnable) MOZ_OVERRIDE;
#endif
virtual void
SendMetaData(const nsAString& aTitle,

Просмотреть файл

@ -2627,6 +2627,7 @@ BluetoothDBusService::IsConnected(const uint16_t aServiceUuid)
return profile->IsConnected();
}
#ifdef MOZ_B2G_RIL
void
BluetoothDBusService::AnswerWaitingCall(BluetoothReplyRunnable* aRunnable)
{
@ -2659,6 +2660,7 @@ BluetoothDBusService::ToggleCalls(BluetoothReplyRunnable* aRunnable)
DispatchBluetoothReply(aRunnable, BluetoothValue(true), EmptyString());
}
#endif // MOZ_B2G_RIL
class OnUpdateSdpRecordsRunnable : public nsRunnable
{

Просмотреть файл

@ -135,6 +135,7 @@ public:
virtual void
IsScoConnected(BluetoothReplyRunnable* aRunnable) MOZ_OVERRIDE;
#ifdef MOZ_B2G_RIL
virtual void
AnswerWaitingCall(BluetoothReplyRunnable* aRunnable);
@ -143,6 +144,7 @@ public:
virtual void
ToggleCalls(BluetoothReplyRunnable* aRunnable);
#endif
virtual void
SendMetaData(const nsAString& aTitle,

Просмотреть файл

@ -48,7 +48,7 @@ const ContentPanning = {
// If we are using an AsyncPanZoomController for the parent frame,
// it will handle subframe scrolling too. We don't need to listen for
// these events.
if (!this._asyncPanZoomForViewportFrame) {
if (!docShell.asyncPanZoomEnabled) {
let els = Cc["@mozilla.org/eventlistenerservice;1"]
.getService(Ci.nsIEventListenerService);
@ -155,23 +155,11 @@ const ContentPanning = {
let oldTarget = this.target;
[this.target, this.scrollCallback] = this.getPannable(this.pointerDownTarget);
// If we found a target, that means we have found a scrollable subframe. In
// this case, and if we are using async panning and zooming on the parent
// frame, inform the pan/zoom controller that it should not attempt to
// handle any touch events it gets until the next batch (meaning the next
// time we get a touch end).
if (this.target != null && this._asyncPanZoomForViewportFrame) {
this.detectingScrolling = true;
var os = Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService);
os.notifyObservers(docShell, 'detect-scrollable-subframe', null);
}
// If we have a pointer down target and we're not async
// pan/zooming, we may need to fill in for EventStateManager in
// setting the active state on the target element. Set a timer to
// If we have a pointer down target, we may need to fill in for EventStateManager
// in setting the active state on the target element. Set a timer to
// ensure the pointer-down target is active. (If it's already
// active, the timer is a no-op.)
if (this.pointerDownTarget !== null && !this.detectingScrolling) {
if (this.pointerDownTarget !== null) {
// If there's no possibility this is a drag/pan, activate now.
// Otherwise wait a little bit to see if the gesture isn't a
// tap.
@ -262,12 +250,6 @@ const ContentPanning = {
this.pointerDownTarget = null;
},
// True when there's an async pan-zoom controll watching the
// outermost scrollable frame, and we're waiting to see whether
// we're going to take over from it and synchronously scroll an
// inner scrollable frame.
detectingScrolling: false,
onTouchMove: function cp_onTouchMove(evt) {
if (!this.dragging)
return;
@ -296,27 +278,7 @@ const ContentPanning = {
}
let isPan = KineticPanning.isPan();
if (!isPan && this.detectingScrolling) {
// If panning distance is not large enough and we're waiting to
// see whether we should use the sync scroll fallback or not,
// don't attempt scrolling.
return;
}
let isScroll = this.scrollCallback(delta.scale(-1));
if (this.detectingScrolling) {
this.detectingScrolling = false;
// Stop async-pan-zooming if the user is panning the subframe.
if (isScroll) {
// We're going to drive synchronously scrolling an inner frame.
Services.obs.notifyObservers(docShell, 'cancel-default-pan-zoom', null);
} else {
// Let AsyncPanZoomController handle the scrolling gesture.
this.scrollCallback = null;
return;
}
}
this.scrollCallback(delta.scale(-1));
// If we've detected a pan gesture, cancel the active state of the
// current target.
@ -392,13 +354,6 @@ const ContentPanning = {
node = node.parentNode;
}
if (ContentPanning._asyncPanZoomForViewportFrame &&
nodeContent === content) {
// The parent context is asynchronously panning and zooming our
// root scrollable frame, so don't use our synchronous fallback.
return null;
}
if (nodeContent.scrollMaxX || nodeContent.scrollMaxY) {
return nodeContent;
}
@ -515,10 +470,6 @@ const ContentPanning = {
this._domUtils.setContentState(elt, kStateActive);
},
get _asyncPanZoomForViewportFrame() {
return docShell.asyncPanZoomEnabled;
},
_recvViewportChange: function(data) {
let metrics = data.json;
this._viewport = new Rect(metrics.x, metrics.y,
@ -637,7 +588,6 @@ const ContentPanning = {
_finishPanning: function() {
this._resetActive();
this.dragging = false;
this.detectingScrolling = false;
delete this.primaryPointerId;
this._activationTimer.cancel();

Просмотреть файл

@ -76,8 +76,8 @@ enum {
CAMERA_PARAM_FOCUSDISTANCEOPTIMUM,
CAMERA_PARAM_FOCUSDISTANCEFAR,
CAMERA_PARAM_EXPOSURECOMPENSATION,
CAMERA_PARAM_THUMBNAILWIDTH,
CAMERA_PARAM_THUMBNAILHEIGHT,
CAMERA_PARAM_PICTURESIZE,
CAMERA_PARAM_THUMBNAILSIZE,
CAMERA_PARAM_THUMBNAILQUALITY,
CAMERA_PARAM_SUPPORTED_PREVIEWSIZES,

Просмотреть файл

@ -254,6 +254,20 @@ CameraControlImpl::Get(nsICameraPreviewStateChange** aOnPreviewStateChange)
return NS_OK;
}
nsresult
CameraControlImpl::Set(uint32_t aKey, const idl::CameraSize& aSize)
{
SetParameter(aKey, aSize);
return NS_OK;
}
nsresult
CameraControlImpl::Get(uint32_t aKey, idl::CameraSize& aSize)
{
GetParameter(aKey, aSize);
return NS_OK;
}
already_AddRefed<RecorderProfileManager>
CameraControlImpl::GetRecorderProfileManager()
{
@ -407,7 +421,7 @@ CameraControlImpl::AutoFocus(nsICameraAutoFocusCallback* onSuccess, nsICameraErr
}
nsresult
CameraControlImpl::TakePicture(CameraSize aSize, int32_t aRotation, const nsAString& aFileFormat, CameraPosition aPosition, uint64_t aDateTime, nsICameraTakePictureCallback* onSuccess, nsICameraErrorCallback* onError)
CameraControlImpl::TakePicture(const CameraSize& aSize, int32_t aRotation, const nsAString& aFileFormat, CameraPosition aPosition, uint64_t aDateTime, nsICameraTakePictureCallback* onSuccess, nsICameraErrorCallback* onError)
{
MOZ_ASSERT(NS_IsMainThread());
bool cancel = false;

Просмотреть файл

@ -53,7 +53,7 @@ public:
nsresult StartPreview(DOMCameraPreview* aDOMPreview);
void StopPreview();
nsresult AutoFocus(nsICameraAutoFocusCallback* onSuccess, nsICameraErrorCallback* onError);
nsresult TakePicture(idl::CameraSize aSize, int32_t aRotation, const nsAString& aFileFormat, idl::CameraPosition aPosition, uint64_t aDateTime, nsICameraTakePictureCallback* onSuccess, nsICameraErrorCallback* onError);
nsresult TakePicture(const idl::CameraSize& aSize, int32_t aRotation, const nsAString& aFileFormat, idl::CameraPosition aPosition, uint64_t aDateTime, nsICameraTakePictureCallback* onSuccess, nsICameraErrorCallback* onError);
nsresult StartRecording(idl::CameraStartRecordingOptions* aOptions, nsIFile* aFolder, const nsAString& aFilename, nsICameraStartRecordingCallback* onSuccess, nsICameraErrorCallback* onError);
nsresult StopRecording();
nsresult GetPreviewStreamVideoMode(idl::CameraRecorderOptions* aOptions, nsICameraPreviewStreamCallback* onSuccess, nsICameraErrorCallback* onError);
@ -73,6 +73,8 @@ public:
nsresult Get(nsICameraRecorderStateChange** aOnRecorderStateChange);
nsresult Set(nsICameraPreviewStateChange* aOnPreviewStateChange);
nsresult Get(nsICameraPreviewStateChange** aOnPreviewStateChange);
nsresult Set(uint32_t aKey, const idl::CameraSize& aSize);
nsresult Get(uint32_t aKey, idl::CameraSize& aSize);
nsresult SetFocusAreas(JSContext* aCx, const JS::Value& aValue)
{
@ -91,10 +93,12 @@ public:
virtual const char* GetParameterConstChar(uint32_t aKey) = 0;
virtual double GetParameterDouble(uint32_t aKey) = 0;
virtual void GetParameter(uint32_t aKey, nsTArray<idl::CameraRegion>& aRegions) = 0;
virtual void GetParameter(uint32_t aKey, idl::CameraSize& aSize) = 0;
virtual void SetParameter(const char* aKey, const char* aValue) = 0;
virtual void SetParameter(uint32_t aKey, const char* aValue) = 0;
virtual void SetParameter(uint32_t aKey, double aValue) = 0;
virtual void SetParameter(uint32_t aKey, const nsTArray<idl::CameraRegion>& aRegions) = 0;
virtual void SetParameter(uint32_t aKey, const idl::CameraSize& aSize) = 0;
virtual nsresult GetVideoSizes(nsTArray<idl::CameraSize>& aVideoSizes) = 0;
virtual nsresult PushParameters() = 0;
virtual void Shutdown();
@ -372,7 +376,7 @@ protected:
class TakePictureTask : public nsRunnable
{
public:
TakePictureTask(CameraControlImpl* aCameraControl, bool aCancel, idl::CameraSize aSize, int32_t aRotation, const nsAString& aFileFormat, idl::CameraPosition aPosition, uint64_t aDateTime, nsICameraTakePictureCallback* onSuccess, nsICameraErrorCallback* onError)
TakePictureTask(CameraControlImpl* aCameraControl, bool aCancel, const idl::CameraSize& aSize, int32_t aRotation, const nsAString& aFileFormat, idl::CameraPosition aPosition, uint64_t aDateTime, nsICameraTakePictureCallback* onSuccess, nsICameraErrorCallback* onError)
: mCameraControl(aCameraControl)
, mCancel(aCancel)
, mSize(aSize)

Просмотреть файл

@ -199,6 +199,13 @@ DOMCameraCapabilities::GetPictureSizes(JSContext* cx, JS::Value* aPictureSizes)
return DimensionListToNewObject(cx, aPictureSizes, CAMERA_PARAM_SUPPORTED_PICTURESIZES);
}
/* readonly attribute jsval thumbnailSizes; */
NS_IMETHODIMP
DOMCameraCapabilities::GetThumbnailSizes(JSContext* cx, JS::Value* aThumbnailSizes)
{
return DimensionListToNewObject(cx, aThumbnailSizes, CAMERA_PARAM_SUPPORTED_JPEG_THUMBNAIL_SIZES);
}
/* readonly attribute jsval fileFormats; */
NS_IMETHODIMP
DOMCameraCapabilities::GetFileFormats(JSContext* cx, JS::Value* aFileFormats)

Просмотреть файл

@ -26,6 +26,7 @@
using namespace mozilla;
using namespace mozilla::dom;
using namespace mozilla::idl;
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_2(nsDOMCameraControl, mDOMCapabilities, mWindow)
@ -155,6 +156,83 @@ nsDOMCameraControl::SetFocusAreas(JSContext* cx, JS::Handle<JS::Value> aFocusAre
aRv = mCameraControl->SetFocusAreas(cx, aFocusAreas);
}
static nsresult
GetSize(JSContext* aCx, JS::Value* aValue, const CameraSize& aSize)
{
JS::Rooted<JSObject*> o(aCx, JS_NewObject(aCx, nullptr, nullptr, nullptr));
if (!o) {
return NS_ERROR_OUT_OF_MEMORY;
}
JS::Rooted<JS::Value> v(aCx);
v = INT_TO_JSVAL(aSize.width);
if (!JS_SetProperty(aCx, o, "width", v)) {
return NS_ERROR_FAILURE;
}
v = INT_TO_JSVAL(aSize.height);
if (!JS_SetProperty(aCx, o, "height", v)) {
return NS_ERROR_FAILURE;
}
*aValue = JS::ObjectValue(*o);
return NS_OK;
}
/* attribute any pictureSize */
JS::Value
nsDOMCameraControl::GetPictureSize(JSContext* cx, ErrorResult& aRv)
{
JS::Rooted<JS::Value> value(cx);
CameraSize size;
aRv = mCameraControl->Get(CAMERA_PARAM_PICTURESIZE, size);
if (aRv.Failed()) {
return value;
}
aRv = GetSize(cx, value.address(), size);
return value;
}
void
nsDOMCameraControl::SetPictureSize(JSContext* cx, JS::Handle<JS::Value> aSize, ErrorResult& aRv)
{
CameraSize size;
aRv = size.Init(cx, aSize.address());
if (aRv.Failed()) {
return;
}
aRv = mCameraControl->Set(CAMERA_PARAM_PICTURESIZE, size);
}
/* attribute any thumbnailSize */
JS::Value
nsDOMCameraControl::GetThumbnailSize(JSContext* cx, ErrorResult& aRv)
{
JS::Rooted<JS::Value> value(cx);
CameraSize size;
aRv = mCameraControl->Get(CAMERA_PARAM_THUMBNAILSIZE, size);
if (aRv.Failed()) {
return value;
}
aRv = GetSize(cx, value.address(), size);
return value;
}
void
nsDOMCameraControl::SetThumbnailSize(JSContext* cx, JS::Handle<JS::Value> aSize, ErrorResult& aRv)
{
CameraSize size;
aRv = size.Init(cx, aSize.address());
if (aRv.Failed()) {
return;
}
aRv = mCameraControl->Set(CAMERA_PARAM_THUMBNAILSIZE, size);
}
double
nsDOMCameraControl::GetFocalLength(ErrorResult& aRv)
{

Просмотреть файл

@ -66,6 +66,10 @@ public:
void SetMeteringAreas(JSContext* aCx, JS::Handle<JS::Value> aAreas, ErrorResult& aRv);
JS::Value GetFocusAreas(JSContext* aCx, ErrorResult& aRv);
void SetFocusAreas(JSContext* aCx, JS::Handle<JS::Value> aAreas, ErrorResult& aRv);
JS::Value GetPictureSize(JSContext* aCx, ErrorResult& aRv);
void SetPictureSize(JSContext* aCx, JS::Handle<JS::Value> aSize, ErrorResult& aRv);
JS::Value GetThumbnailSize(JSContext* aCx, ErrorResult& aRv);
void SetThumbnailSize(JSContext* aCx, JS::Handle<JS::Value> aSize, ErrorResult& aRv);
double GetFocalLength(ErrorResult& aRv);
double GetFocusDistanceNear(ErrorResult& aRv);
double GetFocusDistanceOptimum(ErrorResult& aRv);

Просмотреть файл

@ -25,10 +25,12 @@ public:
const char* GetParameterConstChar(uint32_t aKey);
double GetParameterDouble(uint32_t aKey);
void GetParameter(uint32_t aKey, nsTArray<idl::CameraRegion>& aRegions);
void GetParameter(uint32_t aKey, idl::CameraSize& aSize);
void SetParameter(const char* aKey, const char* aValue);
void SetParameter(uint32_t aKey, const char* aValue);
void SetParameter(uint32_t aKey, double aValue);
void SetParameter(uint32_t aKey, const nsTArray<idl::CameraRegion>& aRegions);
void SetParameter(uint32_t aKey, const idl::CameraSize& aSize);
nsresult GetVideoSizes(nsTArray<idl::CameraSize>& aVideoSizes);
nsresult PushParameters();
@ -104,6 +106,11 @@ nsFallbackCameraControl::GetParameter(uint32_t aKey, nsTArray<idl::CameraRegion>
{
}
void
nsFallbackCameraControl::GetParameter(uint32_t aKey, idl::CameraSize& aSize)
{
}
void
nsFallbackCameraControl::SetParameter(const char* aKey, const char* aValue)
{
@ -124,6 +131,11 @@ nsFallbackCameraControl::SetParameter(uint32_t aKey, const nsTArray<idl::CameraR
{
}
void
nsFallbackCameraControl::SetParameter(uint32_t aKey, const idl::CameraSize& aSize)
{
}
nsresult
nsFallbackCameraControl::PushParameters()
{

Просмотреть файл

@ -95,10 +95,8 @@ static const char* getKeyText(uint32_t aKey)
return CameraParameters::KEY_FOCUS_DISTANCES;
case CAMERA_PARAM_EXPOSURECOMPENSATION:
return CameraParameters::KEY_EXPOSURE_COMPENSATION;
case CAMERA_PARAM_THUMBNAILWIDTH:
return CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH;
case CAMERA_PARAM_THUMBNAILHEIGHT:
return CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT;
case CAMERA_PARAM_PICTURESIZE:
return CameraParameters::KEY_PICTURE_SIZE;
case CAMERA_PARAM_THUMBNAILQUALITY:
return CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY;
@ -211,6 +209,8 @@ nsGonkCameraControl::nsGonkCameraControl(uint32_t aCameraId, nsIThread* aCameraT
, mHeight(0)
, mLastPictureWidth(0)
, mLastPictureHeight(0)
, mLastThumbnailWidth(0)
, mLastThumbnailHeight(0)
#if !FORCE_PREVIEW_FORMAT_YUV420SP
, mFormat(PREVIEW_FORMAT_UNKNOWN)
#else
@ -290,11 +290,22 @@ nsGonkCameraControl::Init()
mExposureCompensationStep = mParams.getFloat(mParams.KEY_EXPOSURE_COMPENSATION_STEP);
mMaxMeteringAreas = mParams.getInt(mParams.KEY_MAX_NUM_METERING_AREAS);
mMaxFocusAreas = mParams.getInt(mParams.KEY_MAX_NUM_FOCUS_AREAS);
mLastThumbnailWidth = mParams.getInt(mParams.KEY_JPEG_THUMBNAIL_WIDTH);
mLastThumbnailHeight = mParams.getInt(mParams.KEY_JPEG_THUMBNAIL_HEIGHT);
int w;
int h;
mParams.getPictureSize(&w, &h);
MOZ_ASSERT(w > 0 && h > 0); // make sure the driver returns sane values
mLastPictureWidth = static_cast<uint32_t>(w);
mLastPictureHeight = static_cast<uint32_t>(h);
DOM_CAMERA_LOGI(" - minimum exposure compensation: %f\n", mExposureCompensationMin);
DOM_CAMERA_LOGI(" - exposure compensation step: %f\n", mExposureCompensationStep);
DOM_CAMERA_LOGI(" - maximum metering areas: %d\n", mMaxMeteringAreas);
DOM_CAMERA_LOGI(" - maximum focus areas: %d\n", mMaxFocusAreas);
DOM_CAMERA_LOGI(" - default picture size: %u x %u\n", mLastPictureWidth, mLastPictureHeight);
DOM_CAMERA_LOGI(" - default thumbnail size: %u x %u\n", mLastThumbnailWidth, mLastThumbnailHeight);
return NS_OK;
}
@ -507,6 +518,40 @@ nsGonkCameraControl::GetParameter(uint32_t aKey,
return;
}
void
nsGonkCameraControl::GetParameter(uint32_t aKey, idl::CameraSize& aSize)
{
if (aKey == CAMERA_PARAM_THUMBNAILSIZE) {
// This is a special case--for some reason the thumbnail size
// is accessed as two separate values instead of a tuple.
RwAutoLockRead lock(mRwLock);
aSize.width = mParams.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH);
aSize.height = mParams.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT);
DOM_CAMERA_LOGI("thumbnail size --> value='%ux%u'\n", aSize.width, aSize.height);
return;
}
const char* key = getKeyText(aKey);
if (!key) {
return;
}
RwAutoLockRead lock(mRwLock);
const char* value = mParams.get(key);
DOM_CAMERA_LOGI("key='%s' --> value='%s'\n", key, value);
if (!value) {
return;
}
if (sscanf(value, "%ux%u", &aSize.width, &aSize.height) != 2) {
DOM_CAMERA_LOGE("%s:%d : size tuple has bad format: '%s'\n", __func__, __LINE__, value);
aSize.width = 0;
aSize.height = 0;
}
}
nsresult
nsGonkCameraControl::PushParameters()
{
@ -522,7 +567,7 @@ nsGonkCameraControl::PushParameters()
* we can proceed.
*/
if (NS_IsMainThread()) {
DOM_CAMERA_LOGT("%s:%d - dispatching to main thread\n", __func__, __LINE__);
DOM_CAMERA_LOGT("%s:%d - dispatching to camera thread\n", __func__, __LINE__);
nsCOMPtr<nsIRunnable> pushParametersTask = NS_NewRunnableMethod(this, &nsGonkCameraControl::PushParametersImpl);
return mCameraThread->Dispatch(pushParametersTask, NS_DISPATCH_NORMAL);
}
@ -634,6 +679,39 @@ nsGonkCameraControl::SetParameter(uint32_t aKey, int aValue)
PushParameters();
}
void
nsGonkCameraControl::SetParameter(uint32_t aKey, const idl::CameraSize& aSize)
{
switch (aKey) {
case CAMERA_PARAM_PICTURESIZE:
DOM_CAMERA_LOGI("setting picture size to %ux%u\n", aSize.width, aSize.height);
SetPictureSize(aSize.width, aSize.height);
break;
case CAMERA_PARAM_THUMBNAILSIZE:
DOM_CAMERA_LOGI("setting thumbnail size to %ux%u\n", aSize.width, aSize.height);
SetThumbnailSize(aSize.width, aSize.height);
break;
default:
{
const char* key = getKeyText(aKey);
if (!key) {
return;
}
nsCString s;
s.AppendPrintf("%ux%u", aSize.width, aSize.height);
DOM_CAMERA_LOGI("setting '%s' to %s\n", key, s.get());
RwAutoLockWrite lock(mRwLock);
mParams.set(key, s.get());
}
break;
}
PushParameters();
}
nsresult
nsGonkCameraControl::GetPreviewStreamImpl(GetPreviewStreamTask* aGetPreviewStream)
{
@ -727,42 +805,143 @@ nsGonkCameraControl::AutoFocusImpl(AutoFocusTask* aAutoFocus)
}
void
nsGonkCameraControl::SetupThumbnail(uint32_t aPictureWidth, uint32_t aPictureHeight, uint32_t aPercentQuality)
nsGonkCameraControl::SetThumbnailSize(uint32_t aWidth, uint32_t aHeight)
{
/**
* Use the smallest non-0x0 thumbnail size that matches
* the aspect ratio of our parameters...
* We keep a copy of the specified size so that if the picture size
* changes, we can choose a new thumbnail size close to what was asked for
* last time.
*/
uint32_t smallestArea = UINT_MAX;
uint32_t smallestIndex = UINT_MAX;
nsAutoTArray<idl::CameraSize, 8> thumbnailSizes;
GetParameter(CAMERA_PARAM_SUPPORTED_JPEG_THUMBNAIL_SIZES, thumbnailSizes);
mLastThumbnailWidth = aWidth;
mLastThumbnailHeight = aHeight;
/**
* If either of width or height is zero, set the other to zero as well.
* This should disable inclusion of a thumbnail in the final picture.
*/
if (!aWidth || !aHeight) {
DOM_CAMERA_LOGW("Requested thumbnail size %ux%u, disabling thumbnail\n", aWidth, aHeight);
RwAutoLockWrite write(mRwLock);
mParams.set(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH, 0);
mParams.set(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT, 0);
return;
}
/**
* Choose the supported thumbnail size that is closest to the specified size.
* Some drivers will fail to take a picture if the thumbnail does not have
* the same aspect ratio as the set picture size, so we need to enforce that
* too.
*/
int smallestDelta = INT_MAX;
uint32_t smallestDeltaIndex = UINT32_MAX;
int targetArea = aWidth * aHeight;
nsAutoTArray<idl::CameraSize, 8> supportedSizes;
GetParameter(CAMERA_PARAM_SUPPORTED_JPEG_THUMBNAIL_SIZES, supportedSizes);
for (uint32_t i = 0; i < supportedSizes.Length(); ++i) {
int area = supportedSizes[i].width * supportedSizes[i].height;
int delta = abs(area - targetArea);
for (uint32_t i = 0; i < thumbnailSizes.Length(); ++i) {
uint32_t area = thumbnailSizes[i].width * thumbnailSizes[i].height;
if (area != 0
&& area < smallestArea
&& thumbnailSizes[i].width * aPictureHeight / thumbnailSizes[i].height == aPictureWidth
&& delta < smallestDelta
&& supportedSizes[i].width * mLastPictureHeight / supportedSizes[i].height == mLastPictureWidth
) {
smallestArea = area;
smallestIndex = i;
smallestDelta = delta;
smallestDeltaIndex = i;
}
}
aPercentQuality = clamped<uint32_t>(aPercentQuality, 1, 100);
SetParameter(CAMERA_PARAM_THUMBNAILQUALITY, static_cast<int>(aPercentQuality));
if (smallestIndex != UINT_MAX) {
uint32_t w = thumbnailSizes[smallestIndex].width;
uint32_t h = thumbnailSizes[smallestIndex].height;
DOM_CAMERA_LOGI("Using thumbnail size: %ux%u, quality: %u %%\n", w, h, aPercentQuality);
if (w > INT_MAX || h > INT_MAX) {
DOM_CAMERA_LOGE("Thumbnail dimension is too big, will use defaults\n");
return;
}
SetParameter(CAMERA_PARAM_THUMBNAILWIDTH, static_cast<int>(w));
SetParameter(CAMERA_PARAM_THUMBNAILHEIGHT, static_cast<int>(h));
if (smallestDeltaIndex == UINT32_MAX) {
DOM_CAMERA_LOGW("Unable to find a thumbnail size close to %ux%u\n", aWidth, aHeight);
return;
}
uint32_t w = supportedSizes[smallestDeltaIndex].width;
uint32_t h = supportedSizes[smallestDeltaIndex].height;
DOM_CAMERA_LOGI("Requested thumbnail size %ux%u --> using supported size %ux%u\n", aWidth, aHeight, w, h);
if (w > INT32_MAX || h > INT32_MAX) {
DOM_CAMERA_LOGE("Supported thumbnail size is too big, no change\n");
return;
}
RwAutoLockWrite write(mRwLock);
mParams.set(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH, static_cast<int>(w));
mParams.set(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT, static_cast<int>(h));
}
void
nsGonkCameraControl::UpdateThumbnailSize()
{
SetThumbnailSize(mLastThumbnailWidth, mLastThumbnailHeight);
}
void
nsGonkCameraControl::SetPictureSize(uint32_t aWidth, uint32_t aHeight)
{
/**
* Some drivers are less friendly about getting one of these set to zero,
* so if either is not specified, ignore both and go with current or
* default settings.
*/
if (!aWidth || !aHeight) {
DOM_CAMERA_LOGW("Ignoring requested picture size of %ux%u\n", aWidth, aHeight);
return;
}
if (aWidth == mLastPictureWidth && aHeight == mLastPictureHeight) {
DOM_CAMERA_LOGI("Requested picture size %ux%u unchanged\n", aWidth, aHeight);
return;
}
/**
* Choose the supported picture size that is closest in area to the
* specified size. Some drivers will fail to take a picture if the
* thumbnail size is not the same aspect ratio, so we update that
* as well to a size closest to the last user-requested one.
*/
int smallestDelta = INT_MAX;
uint32_t smallestDeltaIndex = UINT32_MAX;
int targetArea = aWidth * aHeight;
nsAutoTArray<idl::CameraSize, 8> supportedSizes;
GetParameter(CAMERA_PARAM_SUPPORTED_PICTURESIZES, supportedSizes);
for (uint32_t i = 0; i < supportedSizes.Length(); ++i) {
int area = supportedSizes[i].width * supportedSizes[i].height;
int delta = abs(area - targetArea);
if (area != 0 && delta < smallestDelta) {
smallestDelta = delta;
smallestDeltaIndex = i;
}
}
if (smallestDeltaIndex == UINT32_MAX) {
DOM_CAMERA_LOGW("Unable to find a picture size close to %ux%u\n", aWidth, aHeight);
return;
}
uint32_t w = supportedSizes[smallestDeltaIndex].width;
uint32_t h = supportedSizes[smallestDeltaIndex].height;
DOM_CAMERA_LOGI("Requested picture size %ux%u --> using supported size %ux%u\n", aWidth, aHeight, w, h);
if (w > INT32_MAX || h > INT32_MAX) {
DOM_CAMERA_LOGE("Supported picture size is too big, no change\n");
return;
}
mLastPictureWidth = w;
mLastPictureHeight = h;
{
// We must release the write-lock before updating the thumbnail size
RwAutoLockWrite write(mRwLock);
mParams.setPictureSize(static_cast<int>(w), static_cast<int>(h));
}
// Finally, update the thumbnail size
UpdateThumbnailSize();
}
nsresult
@ -782,25 +961,7 @@ nsGonkCameraControl::TakePictureImpl(TakePictureTask* aTakePicture)
// batch-update camera configuration
mDeferConfigUpdate = true;
if (aTakePicture->mSize.width != mLastPictureWidth || aTakePicture->mSize.height != mLastPictureHeight) {
/**
* height and width: some drivers are less friendly about getting one of
* these set to zero, so if either is not specified, ignore both and go
* with current or default settings.
*/
if (aTakePicture->mSize.width && aTakePicture->mSize.height) {
nsCString s;
s.AppendPrintf("%ux%u", aTakePicture->mSize.width, aTakePicture->mSize.height);
DOM_CAMERA_LOGI("setting picture size to '%s'\n", s.get());
SetParameter(CameraParameters::KEY_PICTURE_SIZE, s.get());
// Choose an appropriate thumbnail size and quality (from 1..100)
SetupThumbnail(aTakePicture->mSize.width, aTakePicture->mSize.height, 60);
}
mLastPictureWidth = aTakePicture->mSize.width;
mLastPictureHeight = aTakePicture->mSize.height;
}
SetPictureSize(aTakePicture->mSize.width, aTakePicture->mSize.height);
// Picture format -- need to keep it for the callback.
mFileFormat = aTakePicture->mFileFormat;

Просмотреть файл

@ -55,11 +55,13 @@ public:
double GetParameterDouble(uint32_t aKey);
void GetParameter(uint32_t aKey, nsTArray<idl::CameraRegion>& aRegions);
void GetParameter(uint32_t aKey, nsTArray<idl::CameraSize>& aSizes);
void GetParameter(uint32_t aKey, idl::CameraSize& aSize);
void SetParameter(const char* aKey, const char* aValue);
void SetParameter(uint32_t aKey, const char* aValue);
void SetParameter(uint32_t aKey, double aValue);
void SetParameter(uint32_t aKey, const nsTArray<idl::CameraRegion>& aRegions);
void SetParameter(uint32_t aKey, int aValue);
void SetParameter(uint32_t aKey, const idl::CameraSize& aSize);
nsresult GetVideoSizes(nsTArray<idl::CameraSize>& aVideoSizes);
nsresult PushParameters();
@ -89,7 +91,9 @@ protected:
nsresult SetupRecording(int aFd, int aRotation, int64_t aMaxFileSizeBytes, int64_t aMaxVideoLengthMs);
nsresult SetupVideoMode(const nsAString& aProfile);
void SetPreviewSize(uint32_t aWidth, uint32_t aHeight);
void SetupThumbnail(uint32_t aPictureWidth, uint32_t aPictureHeight, uint32_t aPercentQuality);
void SetThumbnailSize(uint32_t aWidth, uint32_t aHeight);
void UpdateThumbnailSize();
void SetPictureSize(uint32_t aWidth, uint32_t aHeight);
android::sp<android::GonkCameraHardware> mCameraHw;
double mExposureCompensationMin;
@ -101,6 +105,8 @@ protected:
uint32_t mHeight;
uint32_t mLastPictureWidth;
uint32_t mLastPictureHeight;
uint32_t mLastThumbnailWidth;
uint32_t mLastThumbnailHeight;
enum {
PREVIEW_FORMAT_UNKNOWN,

Просмотреть файл

@ -12,7 +12,6 @@
namespace mozilla {
class DOMCameraPreview;
class RecorderProfileManager;
@ -25,7 +24,7 @@ public:
virtual nsresult StartPreview(DOMCameraPreview* aDOMPreview) = 0;
virtual void StopPreview() = 0;
virtual nsresult AutoFocus(nsICameraAutoFocusCallback* onSuccess, nsICameraErrorCallback* onError) = 0;
virtual nsresult TakePicture(idl::CameraSize aSize, int32_t aRotation, const nsAString& aFileFormat, idl::CameraPosition aPosition, uint64_t aDateTime, nsICameraTakePictureCallback* onSuccess, nsICameraErrorCallback* onError) = 0;
virtual nsresult TakePicture(const idl::CameraSize& aSize, int32_t aRotation, const nsAString& aFileFormat, idl::CameraPosition aPosition, uint64_t aDateTime, nsICameraTakePictureCallback* onSuccess, nsICameraErrorCallback* onError) = 0;
virtual nsresult StartRecording(idl::CameraStartRecordingOptions* aOptions, nsIFile* aFolder, const nsAString& aFilename, nsICameraStartRecordingCallback* onSuccess, nsICameraErrorCallback* onError) = 0;
virtual nsresult StopRecording() = 0;
virtual nsresult GetPreviewStreamVideoMode(idl::CameraRecorderOptions* aOptions, nsICameraPreviewStreamCallback* onSuccess, nsICameraErrorCallback* onError) = 0;
@ -45,6 +44,8 @@ public:
virtual nsresult Get(nsICameraRecorderStateChange** aOnRecorderStateChange) = 0;
virtual nsresult Set(nsICameraPreviewStateChange* aOnPreviewStateChange) = 0;
virtual nsresult Get(nsICameraPreviewStateChange** aOnPreviewStateChange) = 0;
virtual nsresult Set(uint32_t aKey, const idl::CameraSize& aSize) = 0;
virtual nsresult Get(uint32_t aKey, idl::CameraSize& aSize) = 0;
virtual nsresult SetFocusAreas(JSContext* aCx, const JS::Value& aValue) = 0;
virtual nsresult SetMeteringAreas(JSContext* aCx, const JS::Value& aValue) = 0;
virtual nsresult GetVideoSizes(nsTArray<idl::CameraSize>& aVideoSizes) = 0;

Просмотреть файл

@ -36,7 +36,7 @@ dictionary CameraPosition {
double timestamp;
};
[scriptable, uuid(177472c9-f83d-48b5-8782-03b43b27f25d)]
[scriptable, uuid(0711a4af-73c2-481d-85bc-0ba3ec36c004)]
interface nsICameraCapabilities : nsISupports
{
/* an array of objects with 'height' and 'width' properties
@ -49,6 +49,11 @@ interface nsICameraCapabilities : nsISupports
[implicit_jscontext]
readonly attribute jsval pictureSizes;
/* an array of objects with 'height' and 'width' properties
supported for thumbnail sizes in taken pictures */
[implicit_jscontext]
readonly attribute jsval thumbnailSizes;
/* an array of strings, e.g. [ "jpeg", "rgb565" ] */
[implicit_jscontext]
readonly attribute jsval fileFormats;

Просмотреть файл

@ -176,18 +176,18 @@ function validateArrayField(data, createCb) {
}
};
if (data) {
data = Array.isArray(data) ? data : [data];
let filtered = [];
for (let i = 0, n = data.length; i < n; ++i) {
if (data === null || data === undefined) {
return undefined;
}
data = Array.isArray(data) ? data : [data];
let filtered = [];
for (let i = 0, n = data.length; i < n; ++i) {
if (data[i]) {
filtered.push(createCb(data[i]));
}
if (filtered.length === 0) {
return undefined;
}
return new Proxy(filtered, ArrayPropertyHandler);
}
return undefined;
return new Proxy(filtered, ArrayPropertyHandler);
}
// We need this to create a copy of the mozContact object in ContactManager.save

Просмотреть файл

@ -264,7 +264,7 @@ function removeAndroidDefaultCategory(category) {
function checkArrayField(array1, array2, func, msg) {
if (!!array1 ^ !!array2) {
ok(false, "Expected both arrays to be either present or absent");
ok(false, "Expected both arrays to be either present or absent: " + JSON.stringify(array1) + " vs. " + JSON.stringify(array2) + ". (" + msg + ")");
return;
}
if (!array1 && !array2) {
@ -1523,17 +1523,11 @@ var steps = [
},
function () {
ok(true, "Adding contact with invalid data");
var input = document.createElement("input");
var obj = {
honorificPrefix: [],
honorificSuffix: [{foo: "bar"}],
sex: 17,
genderIdentity: 18,
email: input,
adr: input,
tel: input,
impp: input,
url: input
genderIdentity: 18
};
obj.honorificPrefix.__defineGetter__('0',(function() {
var c = 0;
@ -1668,6 +1662,38 @@ var steps = [
}
next();
},
function() {
ok(true, "Undefined strings should be treated as null");
var c = new mozContact({
adr: [{value: undefined}],
email: [{value: undefined}],
url: [{value: undefined}],
impp: [{value: undefined}],
tel: [{value: undefined}],
});
is(c.adr[0].type, null, "adr is null");
is(c.email[0].type, null, "email is null");
is(c.url[0].type, null, "url is null");
is(c.impp[0].type, null, "impp is null");
is(c.tel[0].type, null, "tel is null");
next();
},
function() {
ok(true, "Setting array properties to an empty array should work");
var c = new mozContact();
function testArrayProp(prop) {
is(c[prop], null, "property is initially null");
c[prop] = [];
ok(Array.isArray(c[prop]), "property is an array after setting");
is(c[prop].length, 0, "property has length 0 after setting");
}
testArrayProp("email");
testArrayProp("adr");
testArrayProp("tel");
testArrayProp("impp");
testArrayProp("url");
next();
},
function () {
ok(true, "all done!\n");
clearTemps();

Просмотреть файл

@ -1233,7 +1233,6 @@ Blob<ActorFlavor>::SetMysteryBlobInfo(const nsString& aName,
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(mBlob);
MOZ_ASSERT(mRemoteBlob);
MOZ_ASSERT(aLength);
MOZ_ASSERT(aLastModifiedDate != UINT64_MAX);
ToConcreteBlob(mBlob)->SetLazyData(aName, aContentType,
@ -1252,7 +1251,6 @@ Blob<ActorFlavor>::SetMysteryBlobInfo(const nsString& aContentType,
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(mBlob);
MOZ_ASSERT(mRemoteBlob);
MOZ_ASSERT(aLength);
nsString voidString;
voidString.SetIsVoid(true);

Просмотреть файл

@ -88,10 +88,8 @@ NS_IMPL_ISUPPORTS1(ContentListener, nsIDOMEventListener)
static const CSSSize kDefaultViewportSize(980, 480);
static const char CANCEL_DEFAULT_PAN_ZOOM[] = "cancel-default-pan-zoom";
static const char BROWSER_ZOOM_TO_RECT[] = "browser-zoom-to-rect";
static const char BEFORE_FIRST_PAINT[] = "before-first-paint";
static const char DETECT_SCROLLABLE_SUBFRAME[] = "detect-scrollable-subframe";
static bool sCpowsEnabled = false;
@ -354,13 +352,7 @@ TabChild::Observe(nsISupports *aSubject,
const char *aTopic,
const PRUnichar *aData)
{
if (!strcmp(aTopic, CANCEL_DEFAULT_PAN_ZOOM)) {
nsCOMPtr<nsIDocShell> docShell(do_QueryInterface(aSubject));
nsCOMPtr<nsITabChild> tabChild(TabChild::GetFrom(docShell));
if (tabChild == this) {
mRemoteFrame->CancelDefaultPanZoom();
}
} else if (!strcmp(aTopic, BROWSER_ZOOM_TO_RECT)) {
if (!strcmp(aTopic, BROWSER_ZOOM_TO_RECT)) {
nsCOMPtr<nsIDocShell> docShell(do_QueryInterface(aSubject));
nsCOMPtr<nsITabChild> tabChild(TabChild::GetFrom(docShell));
if (tabChild == this) {
@ -409,12 +401,6 @@ TabChild::Observe(nsISupports *aSubject,
HandlePossibleViewportChange();
}
}
} else if (!strcmp(aTopic, DETECT_SCROLLABLE_SUBFRAME)) {
nsCOMPtr<nsIDocShell> docShell(do_QueryInterface(aSubject));
nsCOMPtr<nsITabChild> tabChild(TabChild::GetFrom(docShell));
if (tabChild == this) {
mRemoteFrame->DetectScrollableSubframe();
}
}
return NS_OK;
@ -2120,10 +2106,8 @@ TabChild::RecvDestroy()
nsCOMPtr<nsIObserverService> observerService =
mozilla::services::GetObserverService();
observerService->RemoveObserver(this, CANCEL_DEFAULT_PAN_ZOOM);
observerService->RemoveObserver(this, BROWSER_ZOOM_TO_RECT);
observerService->RemoveObserver(this, BEFORE_FIRST_PAINT);
observerService->RemoveObserver(this, DETECT_SCROLLABLE_SUBFRAME);
const InfallibleTArray<PIndexedDBChild*>& idbActors =
ManagedPIndexedDBChild();
@ -2258,18 +2242,12 @@ TabChild::InitRenderingState()
mozilla::services::GetObserverService();
if (observerService) {
observerService->AddObserver(this,
CANCEL_DEFAULT_PAN_ZOOM,
false);
observerService->AddObserver(this,
BROWSER_ZOOM_TO_RECT,
false);
observerService->AddObserver(this,
BEFORE_FIRST_PAINT,
false);
observerService->AddObserver(this,
DETECT_SCROLLABLE_SUBFRAME,
false);
}
// This state can't really change during the lifetime of the child.

Просмотреть файл

@ -22,7 +22,7 @@ XPIDL_SOURCES += [
'nsIWapPushApplication.idl',
]
if CONFIG['MOZ_B2G_RIL']:
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk' and CONFIG['MOZ_B2G_RIL']:
XPIDL_SOURCES += [
'nsIRilMobileMessageDatabaseService.idl',
]

Просмотреть файл

@ -10,7 +10,7 @@
#include "android/MobileMessageDatabaseService.h"
#include "android/SmsService.h"
#include "android/MmsService.h"
#elif defined(MOZ_B2G_RIL)
#elif defined(MOZ_WIDGET_GONK) && defined(MOZ_B2G_RIL)
#include "gonk/SmsService.h"
#else
#include "fallback/MmsService.h"
@ -47,7 +47,7 @@ SmsServicesFactory::CreateMobileMessageDatabaseService()
if (XRE_GetProcessType() == GeckoProcessType_Content) {
mobileMessageDBService = new SmsIPCService();
} else {
#ifdef MOZ_B2G_RIL
#if defined(MOZ_WIDGET_GONK) && defined(MOZ_B2G_RIL)
mobileMessageDBService = do_GetService(RIL_MOBILE_MESSAGE_DATABASE_SERVICE_CONTRACTID);
#else
mobileMessageDBService = new MobileMessageDatabaseService();
@ -65,7 +65,7 @@ SmsServicesFactory::CreateMmsService()
if (XRE_GetProcessType() == GeckoProcessType_Content) {
mmsService = new SmsIPCService();
} else {
#ifdef MOZ_B2G_RIL
#if defined(MOZ_WIDGET_GONK) && defined(MOZ_B2G_RIL)
mmsService = do_CreateInstance(RIL_MMSSERVICE_CONTRACTID);
#else
mmsService = new MmsService();

Просмотреть файл

@ -37,21 +37,28 @@ const NS_XPCOM_SHUTDOWN_OBSERVER_ID = "xpcom-shutdown";
const kNetworkInterfaceStateChangedTopic = "network-interface-state-changed";
const kMobileMessageDeletedObserverTopic = "mobile-message-deleted";
const kPrefRilMmsc = "ril.mms.mmsc";
const kPrefRilMmsProxy = "ril.mms.mmsproxy";
const kPrefRilMmsPort = "ril.mms.mmsport";
const kPrefRilRadioDisabled = "ril.radio.disabled";
// HTTP status codes:
// @see http://tools.ietf.org/html/rfc2616#page-39
const HTTP_STATUS_OK = 200;
// Non-standard HTTP status for internal use.
const _HTTP_STATUS_ACQUIRE_CONNECTION_SUCCESS = 0;
const _HTTP_STATUS_USER_CANCELLED = -1;
const _HTTP_STATUS_RADIO_DISABLED = -2;
const _HTTP_STATUS_NO_SIM_CARD = -3;
const _HTTP_STATUS_ACQUIRE_TIMEOUT = 4;
const _HTTP_STATUS_ACQUIRE_CONNECTION_SUCCESS = 0;
const _HTTP_STATUS_USER_CANCELLED = -1;
const _HTTP_STATUS_RADIO_DISABLED = -2;
const _HTTP_STATUS_NO_SIM_CARD = -3;
const _HTTP_STATUS_ACQUIRE_TIMEOUT = -4;
// Non-standard MMS status for internal use.
const _MMS_ERROR_MESSAGE_DELETED = -1;
const _MMS_ERROR_RADIO_DISABLED = -2;
const _MMS_ERROR_NO_SIM_CARD = -3;
const _MMS_ERROR_MESSAGE_DELETED = -1;
const _MMS_ERROR_RADIO_DISABLED = -2;
const _MMS_ERROR_NO_SIM_CARD = -3;
const _MMS_ERROR_SHUTDOWN = -4;
const _MMS_ERROR_USER_CANCELLED_NO_REASON = -5;
const CONFIG_SEND_REPORT_NEVER = 0;
const CONFIG_SEND_REPORT_DEFAULT_NO = 1;
@ -156,10 +163,10 @@ XPCOMUtils.defineLazyGetter(this, "gMmsConnection", function () {
radioDisabled: false,
proxyInfo: null,
settings: ["ril.mms.mmsc",
"ril.mms.mmsproxy",
"ril.mms.mmsport",
"ril.radio.disabled"],
settings: [kPrefRilMmsc,
kPrefRilMmsProxy,
kPrefRilMmsPort,
kPrefRilRadioDisabled],
connected: false,
//A queue to buffer the MMS HTTP requests when the MMS network
@ -206,9 +213,9 @@ XPCOMUtils.defineLazyGetter(this, "gMmsConnection", function () {
}, this);
try {
this.mmsc = Services.prefs.getCharPref("ril.mms.mmsc");
this.proxy = Services.prefs.getCharPref("ril.mms.mmsproxy");
this.port = Services.prefs.getIntPref("ril.mms.mmsport");
this.mmsc = Services.prefs.getCharPref(kPrefRilMmsc);
this.proxy = Services.prefs.getCharPref(kPrefRilMmsProxy);
this.port = Services.prefs.getIntPref(kPrefRilMmsPort);
this.updateProxyInfo();
} catch (e) {
if (DEBUG) debug("Unable to initialize the MMS proxy settings from " +
@ -218,7 +225,7 @@ XPCOMUtils.defineLazyGetter(this, "gMmsConnection", function () {
}
try {
this.radioDisabled = Services.prefs.getBoolPref("ril.radio.disabled");
this.radioDisabled = Services.prefs.getBoolPref(kPrefRilRadioDisabled);
} catch (e) {
if (DEBUG) debug("Getting preference 'ril.radio.disabled' fails.");
this.radioDisabled = false;
@ -373,9 +380,9 @@ XPCOMUtils.defineLazyGetter(this, "gMmsConnection", function () {
break;
}
case NS_PREFBRANCH_PREFCHANGE_TOPIC_ID: {
if (data == "ril.radio.disabled") {
if (data == kPrefRilRadioDisabled) {
try {
this.radioDisabled = Services.prefs.getBoolPref("ril.radio.disabled");
this.radioDisabled = Services.prefs.getBoolPref(kPrefRilRadioDisabled);
} catch (e) {
if (DEBUG) debug("Updating preference 'ril.radio.disabled' fails.");
this.radioDisabled = false;
@ -385,15 +392,15 @@ XPCOMUtils.defineLazyGetter(this, "gMmsConnection", function () {
try {
switch (data) {
case "ril.mms.mmsc":
this.mmsc = Services.prefs.getCharPref("ril.mms.mmsc");
case kPrefRilMmsc:
this.mmsc = Services.prefs.getCharPref(kPrefRilMmsc);
break;
case "ril.mms.mmsproxy":
this.proxy = Services.prefs.getCharPref("ril.mms.mmsproxy");
case kPrefRilMmsProxy:
this.proxy = Services.prefs.getCharPref(kPrefRilMmsProxy);
this.updateProxyInfo();
break;
case "ril.mms.mmsport":
this.port = Services.prefs.getIntPref("ril.mms.mmsport");
case kPrefRilMmsPort:
this.port = Services.prefs.getIntPref(kPrefRilMmsPort);
this.updateProxyInfo();
break;
default:
@ -671,10 +678,12 @@ XPCOMUtils.defineLazyGetter(this, "gMmsTransactionHelper", function () {
return true;
},
translateHttpStatusToMmsStatus: function translateHttpStatusToMmsStatus(httpStatus, defaultStatus) {
translateHttpStatusToMmsStatus: function translateHttpStatusToMmsStatus(httpStatus,
cancelledReason,
defaultStatus) {
switch(httpStatus) {
case _HTTP_STATUS_USER_CANCELLED:
return _MMS_ERROR_MESSAGE_DELETED;
return cancelledReason;
case _HTTP_STATUS_RADIO_DISABLED:
return _MMS_ERROR_RADIO_DISABLED;
case _HTTP_STATUS_NO_SIM_CARD:
@ -756,10 +765,13 @@ CancellableTransaction.prototype = {
isObserversAdded: false,
cancelledReason: _MMS_ERROR_USER_CANCELLED_NO_REASON,
registerRunCallback: function registerRunCallback(callback) {
if (!this.isObserversAdded) {
Services.obs.addObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, false);
Services.obs.addObserver(this, kMobileMessageDeletedObserverTopic, false);
Services.prefs.addObserver(kPrefRilRadioDisabled, this, false);
this.isObserversAdded = true;
}
@ -771,6 +783,7 @@ CancellableTransaction.prototype = {
if (this.isObserversAdded) {
Services.obs.removeObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID);
Services.obs.removeObserver(this, kMobileMessageDeletedObserverTopic);
Services.prefs.removeObserver(kPrefRilRadioDisabled, this);
this.isObserversAdded = false;
}
},
@ -788,15 +801,16 @@ CancellableTransaction.prototype = {
// |gMmsTransactionHelper.sendRequest(...)|.
cancellable: null,
cancelRunning: function cancelRunning() {
cancelRunning: function cancelRunning(reason) {
this.isCancelled = true;
this.cancelledReason = reason;
if (this.timer) {
// The sending or retrieving process is waiting for the next retry.
// What we only need to do is to cancel the timer.
this.timer.cancel();
this.timer = null;
this.runCallbackIfValid(_MMS_ERROR_MESSAGE_DELETED, null);
this.runCallbackIfValid(reason, null);
return;
}
@ -813,7 +827,7 @@ CancellableTransaction.prototype = {
observe: function observe(subject, topic, data) {
switch (topic) {
case NS_XPCOM_SHUTDOWN_OBSERVER_ID: {
this.cancelRunning();
this.cancelRunning(_MMS_ERROR_SHUTDOWN);
break;
}
case kMobileMessageDeletedObserverTopic: {
@ -822,7 +836,20 @@ CancellableTransaction.prototype = {
return;
}
this.cancelRunning();
this.cancelRunning(_MMS_ERROR_MESSAGE_DELETED);
break;
}
case NS_PREFBRANCH_PREFCHANGE_TOPIC_ID: {
if (data == kPrefRilRadioDisabled) {
try {
let radioDisabled = Services.prefs.getBoolPref(kPrefRilRadioDisabled);
if (radioDisabled) {
this.cancelRunning(_MMS_ERROR_RADIO_DISABLED);
}
} catch (e) {
if (DEBUG) debug("Failed to get preference of 'ril.radio.disabled'.");
}
}
break;
}
}
@ -891,6 +918,7 @@ RetrieveTransaction.prototype = Object.create(CancellableTransaction.prototype,
(function (httpStatus, data) {
let mmsStatus = gMmsTransactionHelper
.translateHttpStatusToMmsStatus(httpStatus,
this.cancelledReason,
MMS.MMS_PDU_STATUS_DEFERRED);
if (mmsStatus != MMS.MMS_PDU_ERROR_OK) {
callback(mmsStatus, null);
@ -952,7 +980,12 @@ function SendTransaction(cancellableId, msg, requestDeliveryReport) {
msg.headers["x-mms-message-class"] = "personal";
msg.headers["x-mms-expiry"] = 7 * 24 * 60 * 60;
msg.headers["x-mms-priority"] = 129;
msg.headers["x-mms-read-report"] = true;
try {
msg.headers["x-mms-read-report"] =
Services.prefs.getBoolPref("dom.mms.requestReadReport");
} catch (e) {
msg.headers["x-mms-read-report"] = true;
}
msg.headers["x-mms-delivery-report"] = requestDeliveryReport;
if (!gMmsTransactionHelper.checkMaxValuesParameters(msg)) {
@ -1120,9 +1153,10 @@ SendTransaction.prototype = Object.create(CancellableTransaction.prototype, {
this.cancellable =
gMmsTransactionHelper.sendRequest("POST", gMmsConnection.mmsc,
this.istream,
function (httpStatus, data) {
(function (httpStatus, data) {
let mmsStatus = gMmsTransactionHelper.
translateHttpStatusToMmsStatus(httpStatus,
this.cancelledReason,
MMS.MMS_PDU_ERROR_TRANSIENT_FAILURE);
if (httpStatus != HTTP_STATUS_OK) {
callback(mmsStatus, null);
@ -1142,7 +1176,7 @@ SendTransaction.prototype = Object.create(CancellableTransaction.prototype, {
let responseStatus = response.headers["x-mms-response-status"];
callback(responseStatus, response);
});
}).bind(this));
},
enumerable: true,
configurable: true,

Просмотреть файл

@ -19,7 +19,7 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'android':
'android/MobileMessageDatabaseService.cpp',
'android/SmsService.cpp',
]
elif CONFIG['MOZ_B2G_RIL']:
elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk' and CONFIG['MOZ_B2G_RIL']:
EXTRA_JS_MODULES = [
'gonk/mms_consts.js',
'gonk/MmsPduHelper.jsm',

Просмотреть файл

@ -1,9 +1,3 @@
# 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/.
ifdef MOZ_B2G_RIL
MOCHITEST_CHROME_FILES = \
test_smsdatabaseservice.xul \
$(NULL)
endif

Просмотреть файл

@ -1,876 +0,0 @@
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
type="text/css"?>
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
title="Test MobileMessageDatabaseService by SMS"
onload="run_test();">
<title>Test MobileMessageDatabaseService by SMS</title>
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
<script type="application/javascript"><![CDATA[
function run_test() {
SimpleTest.waitForExplicitFinish();
run_next_test();
}
let gTests = [];
function add_test(func) {
gTests.push(func);
}
function run_next_test() {
let func = gTests.shift();
if (!func) {
SimpleTest.finish();
return;
}
SimpleTest.executeSoon(func);
}
const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
let gMobileMessageDatabaseService = Cc["@mozilla.org/mobilemessage/rilmobilemessagedatabaseservice;1"]
.getService(Ci.nsIMobileMessageDatabaseService);
let gRegistrar = Components.manager.QueryInterface(Ci.nsIComponentRegistrar);
let SmsRequestManagerImpl = {
notifySmsSent: function notifySmsSent(requestId, message) {
ok(false, "Unexpected notifySmsSent.");
},
notifySmsSendFailed: function notifySmsSendFailed(requestId, error) {
ok(false, "Unexpected notifySmsSendFailed.");
},
notifyGotSms: function notifyGotSms(requestId, message) {
ok(false, "Unexpected notifyGotSms.");
},
notifyGetSmsFailed: function notifyGetSmsFailed(requestId, error) {
ok(false, "Unexpected notifyGetSmsFailed." + k);
},
notifySmsDeleted: function notifySmsDeleted(requestId, message) {
ok(false, "Unexpected notifySmsSent.");
},
notifySmsDeleteFailed: function notifySmsDeleteFailed(requestId, error) {
ok(false, "Unexpected notifySmsDeleteFailed.");
},
notifyNoMessageInList: function notifyNoMessageInList(requestId) {
ok(false, "Unexpected notifyNoMessageInList.");
},
noitfyCreateMessageList: function notifyCreateMessageList(requestId,
listId,
message) {
ok(false, "Unexpected notifyCreateMessageList.");
},
notifyGotNextMessage: function notifyGotNextMessage(requestId, message) {
ok(false, "Unexpected notifyGotNextMessage.");
},
notifyReadMessageListFailed: function notifyReadMessageListFailed(requestId, error) {
ok(false, "Unexpected notifyReadMessageListFailed.");
}
};
let FakeSmsRequestManagerService = {
contractID: "@mozilla.org/sms/smsrequestmanager;1",
//get CID() { return gRegistrar.contractIDToCID(this.contractID); },
CID: Components.ID("{a97a3129-1e0b-45da-a385-cfe5b0b1c48f}"),
QueryInterface: XPCOMUtils.generateQI([Ci.nsISmsRequestManager,
Ci.nsIFactory]),
createInstance: function createInstance(outer, iid) {
if (outer != null) {
throw Cr.NS_ERROR_NO_AGGREGATION;
}
return this;
},
__proto__: SmsRequestManagerImpl
};
/**
* Create and register a new fake nsISmsRequestManager service.
*
* Example:
*
* fakeSmsRequestManager({
* notifySmsSent: function notifySmsSent() {
* ...
* }
* });
*/
function fakeSmsRequestManager(obj) {
let service = FakeSmsRequestManagerService;
// Clean previous methods from the service, then copy new ones onto it.
for (let name in SmsRequestManagerImpl) {
delete service[name];
}
for (let name in obj) {
service[name] = obj[name];
}
// Register service
let oldFactory = Components.manager.getClassObject(Cc[service.contractID],
Ci.nsIFactory);
gRegistrar.unregisterFactory(service.CID, oldFactory);
gRegistrar.registerFactory(service.CID,
"Fake SmsRequestManager",
service.contractID,
service);
}
const DB_NAME = "sms";
const DB_VERSION = 2;
const STORE_NAME = "sms";
const MAX_SMS = 3;
const LONG_MAX = 2147483647;
let _db;
function ensureDB(callback) {
if (_db) {
callback(_db);
return;
}
let request;
try {
request = indexedDB.open(DB_NAME, DB_VERSION);
} catch (ex) {
ok(false, ex);
}
request.onsuccess = function onsuccess(event) {
_db = request.result;
callback(_db);
};
request.onerror =
request.onupgradeneeded =
request.onblocked = function onerror(event) {
ok(false, "Opening DB failed: " + request.errorCode);
};
};
function checkDB(callback) {
ensureDB(function (db) {
let txn = db.transaction([STORE_NAME], "readwrite");
let store = txn.objectStore(STORE_NAME);
txn.oncomplete = run_next_test;
txn.onerror = function onerror(event) {
ok(false, "Transaction failed: " + event.target.errorCode);
};
callback(store);
});
}
function newRandomId() {
return Math.floor(Math.random() * LONG_MAX);
};
let sms = [
{
type: "sms",
sender: "+34666000000",
receiver: "+34666111000",
body: "message 0",
messageClass: "normal",
timestamp: 1329999861762
},
{
type: "sms",
sender: "+34666000111",
receiver: "+34666111111",
body: "message 1",
messageClass: "normal",
timestamp: 1329999861763
},
{
type: "sms",
sender: "+34666000222",
receiver: "+34666111222",
body: "message 2",
messageClass: "normal",
timestamp: 1329999861764
},
];
/**
* nsIMobileMessageDatabaseService.saveReceivedMessage
*/
add_test(function test_saveReceivedMessage() {
info("test_saveReceivedMessage");
let messageId = gMobileMessageDatabaseService.saveReceivedMessage(sms[0]);
checkDB(function (store) {
let request = store.get(messageId);
request.onsuccess = function onsuccess() {
let data = request.result;
isnot(data, null);
is(data.id, messageId);
is(data.sender, sms[0].sender);
is(data.receiver, null);
is(data.body, sms[0].body);
is(data.timestamp, sms[0].timestamp);
is(data.read, false);
};
});
});
/**
* nsIMobileMessageDatabaseService.saveSentMessage
*/
add_test(function test_saveSentMessage() {
info("test_saveSentMessage");
let messageId = gMobileMessageDatabaseService.saveSentMessage(sms[1].receiver,
sms[1].body,
sms[1].timestamp);
checkDB(function (store) {
let request = store.get(messageId);
request.onsuccess = function onsuccess() {
let data = request.result;
isnot(data, null);
is(data.id, messageId);
is(data.sender, null);
is(data.receiver, sms[1].receiver);
is(data.body, sms[1].body);
is(data.timestamp, sms[1].timestamp);
is(data.read, true);
};
});
});
/**
* nsIMobileMessageDatabaseService.getMessage
*/
add_test(function test_getMessage_success() {
info("test_getMessage_success");
let fakeRequestId = newRandomId();
fakeSmsRequestManager({
notifyGotSms: function notifyGotSms(requestId, message) {
is(requestId, fakeRequestId);
ok(message instanceof Ci.nsIDOMMozSmsMessage);
is(message.id, messageId);
is(message.delivery, "received");
is(message.sender, sms[2].sender);
is(message.receiver, null);
is(message.body, sms[2].body);
is(message.read, false);
run_next_test();
}
});
let messageId = gMobileMessageDatabaseService.saveReceivedMessage(sms[2]);
SimpleTest.executeSoon(function () {
gMobileMessageDatabaseService.getMessage(messageId, fakeRequestId);
});
});
add_test(function test_getMessage_failed() {
info("test_getMessage_failed");
let fakeRequestId = newRandomId();
fakeSmsRequestManager({
notifyGetSmsFailed: function notifyGetSmsFailed(requestId, error) {
is(requestId, fakeRequestId);
is(error, Ci.nsISmsRequestManager.NOT_FOUND_ERROR);
run_next_test();
}
});
gMobileMessageDatabaseService.getMessage(-1, fakeRequestId);
});
/**
* nsIMobileMessageDatabaseService.createMessageList
*/
function checkReceivedSms(message, i) {
ok(message instanceof Ci.nsIDOMMozSmsMessage);
is(message.sender, sms[i].sender);
is(message.receiver, null);
is(message.body, sms[i].body);
is(message.timestamp.getTime(), sms[i].timestamp);
is(message.read, false);
}
function checkSentSms(message, i) {
ok(message instanceof Ci.nsIDOMMozSmsMessage);
is(message.sender, null);
is(message.receiver, sms[i].receiver);
is(message.body, sms[i].body);
is(message.timestamp.getTime(), sms[i].timestamp);
is(message.read, true);
}
add_test(function test_createMessageList_empty_filter() {
info("test_createMessageList_empty_filter");
let fakeRequestId = newRandomId();
let auxListId;
let i = 0;
fakeSmsRequestManager({
notifyCreateMessageList: function notifyCreateMessageList(requestId,
listId,
message) {
is(requestId, fakeRequestId);
checkReceivedSms(message, i);
auxListId = listId;
i += 1;
gMobileMessageDatabaseService.getNextMessageInList(listId, requestId);
},
notifyGotNextMessage: function notifyGotNextMessage(requestId,
message) {
is(requestId, fakeRequestId);
ok(message instanceof Ci.nsIDOMMozSmsMessage);
i % 2 ? checkSentSms(message, i) : checkReceivedSms(message, i);
i += 1;
gMobileMessageDatabaseService.getNextMessageInList(auxListId, requestId);
},
notifyNoMessageInList: function notifyNoMessageInList(requestId) {
is(requestId, fakeRequestId);
is(i, MAX_SMS);
run_next_test();
}
});
let filter = new MozSmsFilter();
gMobileMessageDatabaseService.createMessageList(filter, false, fakeRequestId);
});
add_test(function test_createMessageList_empty_filter_reverse() {
info("test_createMessageList_empty_filter_reverse");
let fakeRequestId = newRandomId();
let auxListId;
let i = 2;
fakeSmsRequestManager({
notifyCreateMessageList: function notifyCreateMessageList(requestId,
listId,
message) {
is(requestId, fakeRequestId);
checkReceivedSms(message, i);
auxListId = listId;
i -= 1;
gMobileMessageDatabaseService.getNextMessageInList(listId, requestId);
},
notifyGotNextMessage: function notifyGotNextMessage(requestId,
message) {
is(requestId, fakeRequestId);
ok(message instanceof Ci.nsIDOMMozSmsMessage);
i % 2 ? checkSentSms(message, i) : checkReceivedSms(message, i);
i -= 1;
gMobileMessageDatabaseService.getNextMessageInList(auxListId, requestId);
},
notifyNoMessageInList: function notifyNoMessageInList(requestId) {
is(requestId, fakeRequestId);
is(i, -1);
run_next_test();
}
});
let filter = new MozSmsFilter();
gMobileMessageDatabaseService.createMessageList(filter, true, fakeRequestId);
});
add_test(function test_createMessageList_complete_filter_one_result() {
info("test_createMessageList_complete_filter_one_result");
let fakeRequestId = newRandomId();
fakeSmsRequestManager({
notifyCreateMessageList: function notifyCreateMessageList(requestId,
listId,
message) {
is(requestId, fakeRequestId);
checkReceivedSms(message, 0);
gMobileMessageDatabaseService.getNextMessageInList(listId, requestId);
},
notifyGotNextMessage: function notifyGotNextMessage(requestId,
message) {
is(requestId, fakeRequestId);
ok(false, "No more messages expected");
},
notifyNoMessageInList: function notifyNoMessageInList(requestId) {
is(requestId, fakeRequestId);
run_next_test();
}
});
let filter = new MozSmsFilter();
filter.startDate = new Date(sms[0].timestamp);
filter.endDate = new Date(sms[0].timestamp);
filter.numbers = [sms[0].sender];
filter.delivery = "received";
gMobileMessageDatabaseService.createMessageList(filter, false, fakeRequestId);
});
add_test(function test_createMessageList_complete_filter_multi_result() {
info("test_createMessageList_complete_filter_multi_result");
let fakeRequestId = newRandomId();
let auxListId;
let secondMessage = false;
fakeSmsRequestManager({
notifyCreateMessageList: function notifyCreateMessageList(requestId,
listId,
message) {
is(requestId, fakeRequestId);
checkReceivedSms(message, 0);
auxListId = listId;
gMobileMessageDatabaseService.getNextMessageInList(listId, requestId);
},
notifyGotNextMessage: function notifyGotNextMessage(requestId, message) {
ok(!secondMessage);
is(requestId, fakeRequestId);
checkReceivedSms(message, 2);
secondMessage = true;
gMobileMessageDatabaseService.getNextMessageInList(auxListId, requestId);
},
notifyNoMessageInList: function notifyNoMessageInList(requestId) {
ok(secondMessage);
is(requestId, fakeRequestId);
run_next_test();
}
});
let filter = new MozSmsFilter();
filter.startDate = new Date(sms[0].timestamp);
filter.endDate = new Date(sms[2].timestamp);
filter.numbers = [sms[0].sender, sms[2].sender];
filter.delivery = "received";
gMobileMessageDatabaseService.createMessageList(filter, false, fakeRequestId);
});
add_test(function test_createMessageList_complete_filter_no_result() {
info("test_createMessageList_complete_filter_no_result");
let fakeRequestId = newRandomId();
fakeSmsRequestManager({
notifyNoMessageInList: function notifyNoMessageInList(requestId) {
is(requestId, fakeRequestId);
run_next_test();
},
});
let filter = new MozSmsFilter();
filter.startDate = new Date(sms[0].timestamp);
filter.endDate = new Date(sms[0].timestamp);
filter.numbers = [sms[0].sender];
filter.delivery = "sent";
gMobileMessageDatabaseService.createMessageList(filter, false, fakeRequestId);
});
add_test(function test_createMessageList_delivery_sent_filter_success() {
info("test_createMessageList_delivery_sent_filter_success");
let fakeRequestId = newRandomId();
fakeSmsRequestManager({
notifyCreateMessageList: function notifyCreateMessageList(requestId,
listId,
message) {
is(requestId, fakeRequestId);
checkSentSms(message, 1);
gMobileMessageDatabaseService.getNextMessageInList(listId, requestId);
},
notifyNoMessageInList: function notifyNoMessageInList(requestId) {
is(requestId, fakeRequestId);
run_next_test();
}
});
let filter = new MozSmsFilter();
filter.delivery = "sent";
gMobileMessageDatabaseService.createMessageList(filter, false, fakeRequestId);
});
add_test(function test_createMessageList_delivery_received_filter_success() {
info("test_createMessageList_delivery_received_filter_success");
let fakeRequestId = newRandomId();
let auxListId;
let secondMessage = false;
fakeSmsRequestManager({
notifyCreateMessageList: function notifyCreateMessageList(requestId,
listId,
message) {
is(requestId, fakeRequestId);
checkReceivedSms(message, 0);
auxListId = listId;
gMobileMessageDatabaseService.getNextMessageInList(listId, requestId);
},
notifyGotNextMessage: function notifyGotNextMessage(requestId, message) {
ok(!secondMessage);
is(requestId, fakeRequestId);
checkReceivedSms(message, 2);
secondMessage = true;
gMobileMessageDatabaseService.getNextMessageInList(auxListId, requestId);
},
notifyNoMessageInList: function notifyNoMessageInList(requestId) {
ok(secondMessage);
is(requestId, fakeRequestId);
run_next_test();
}
});
let filter = new MozSmsFilter();
filter.delivery = "received";
gMobileMessageDatabaseService.createMessageList(filter, false, fakeRequestId);
});
add_test(function test_createMessageList_startDate_filter_success() {
info("test_createMessageList_startDate_filter_success");
let fakeRequestId = newRandomId();
let auxListId;
let i = 0;
fakeSmsRequestManager({
notifyCreateMessageList: function notifyCreateMessageList(requestId,
listId,
message) {
is(requestId, fakeRequestId);
checkReceivedSms(message, i);
auxListId = listId;
i += 1;
gMobileMessageDatabaseService.getNextMessageInList(listId, requestId);
},
notifyGotNextMessage: function notifyGotNextMessage(requestId,
message) {
is(requestId, fakeRequestId);
i % 2 ? checkSentSms(message, i) : checkReceivedSms(message, i);
i += 1;
gMobileMessageDatabaseService.getNextMessageInList(auxListId, requestId);
},
notifyNoMessageInList: function notifyNoMessageInList(requestId) {
is(requestId, fakeRequestId);
is(i, MAX_SMS);
run_next_test();
}
});
let filter = new MozSmsFilter();
filter.startDate = new Date(sms[0].timestamp);
gMobileMessageDatabaseService.createMessageList(filter, false, fakeRequestId);
});
add_test(function test_createMessageList_startDate_filter_failed() {
info("test_createMessageList_startDate_filter_failed");
let fakeRequestId = newRandomId();
fakeSmsRequestManager({
notifyNoMessageInList: function notifyNoMessageInList(requestId) {
is(requestId, fakeRequestId);
run_next_test();
},
});
let filter = new MozSmsFilter();
filter.startDate = new Date(sms[2].timestamp + 1);
gMobileMessageDatabaseService.createMessageList(filter, false, fakeRequestId);
});
add_test(function test_createMessageList_endDate_filter_success() {
info("test_createMessageList_endDate_filter_success");
let fakeRequestId = newRandomId();
let auxListId;
let i = 0;
fakeSmsRequestManager({
notifyCreateMessageList: function notifyCreateMessageList(requestId,
listId,
message) {
is(requestId, fakeRequestId);
checkReceivedSms(message, i);
auxListId = listId;
i += 1;
gMobileMessageDatabaseService.getNextMessageInList(listId, requestId);
},
notifyGotNextMessage: function notifyGotNextMessage(requestId,
message) {
is(requestId, fakeRequestId);
i % 2 ? checkSentSms(message, i) : checkReceivedSms(message, i);
i += 1;
gMobileMessageDatabaseService.getNextMessageInList(auxListId, requestId);
},
notifyNoMessageInList: function notifyNoMessageInList(requestId) {
is(requestId, fakeRequestId);
is(i, MAX_SMS);
run_next_test();
}
});
let filter = new MozSmsFilter();
filter.endDate = new Date(sms[2].timestamp);
gMobileMessageDatabaseService.createMessageList(filter, false, fakeRequestId);
});
add_test(function test_createMessageList_endDate_filter_failed() {
info("test_createMessageList_endDate_filter_failed");
let fakeRequestId = newRandomId();
fakeSmsRequestManager({
notifyNoMessageInList: function notifyNoMessageInList(requestId) {
is(requestId, fakeRequestId);
run_next_test();
}
});
let filter = new MozSmsFilter();
filter.endDate = new Date(sms[0].timestamp - 1);
gMobileMessageDatabaseService.createMessageList(filter, false, fakeRequestId);
});
add_test(function test_createMessageList_fullDate_filter_success() {
info("test_createMessageList_fullDate_filter_success");
let fakeRequestId = newRandomId();
let auxListId;
let i = 0;
fakeSmsRequestManager({
notifyCreateMessageList: function notifyCreateMessageList(requestId,
listId,
message) {
is(requestId, fakeRequestId);
checkReceivedSms(message, i);
auxListId = listId;
i += 1;
gMobileMessageDatabaseService.getNextMessageInList(listId, requestId);
},
notifyGotNextMessage: function notifyGotNextMessage(requestId,
message) {
is(requestId, fakeRequestId);
i % 2 ? checkSentSms(message, i) : checkReceivedSms(message, i);
i += 1;
gMobileMessageDatabaseService.getNextMessageInList(auxListId, requestId);
},
notifyNoMessageInList: function notifyNoMessageInList(requestId) {
is(requestId, fakeRequestId);
is(i, MAX_SMS);
run_next_test();
}
});
let filter = new MozSmsFilter();
filter.startDate = new Date(sms[0].timestamp);
filter.endDate = new Date(sms[MAX_SMS - 1].timestamp);
gMobileMessageDatabaseService.createMessageList(filter, false, fakeRequestId);
});
add_test(function test_createMessageList_fullDate_filter_failed() {
info("test_createMessageList_fullDate_filter_failed");
let fakeRequestId = newRandomId();
fakeSmsRequestManager({
notifyNoMessageInList: function notifyNoMessageInList(requestId) {
is(requestId, fakeRequestId);
run_next_test();
}
});
let filter = new MozSmsFilter();
filter.startDate = new Date(sms[MAX_SMS - 1] + 1);
filter.endDate = new Date(sms[MAX_SMS - 1] + 1);
gMobileMessageDatabaseService.createMessageList(filter, false, fakeRequestId);
});
add_test(function test_createMessageList_single_number_success() {
info("test_createMessageList_single_number_success");
let fakeRequestId = newRandomId();
let firstMessage = false;
fakeSmsRequestManager({
notifyCreateMessageList: function notifyCreateMessageList(requestId,
listId,
message) {
is(firstMessage, false);
is(requestId, fakeRequestId);
checkReceivedSms(message, 0);
firstMessage = true;
gMobileMessageDatabaseService.getNextMessageInList(listId, requestId);
},
notifyNoMessageInList: function notifyNoMessageInList(requestId) {
ok(firstMessage);
is(requestId, fakeRequestId);
run_next_test();
}
});
let filter = new MozSmsFilter();
filter.numbers = [sms[0].sender];
gMobileMessageDatabaseService.createMessageList(filter, false, fakeRequestId);
});
add_test(function test_createMessageList_single_number_failed() {
info("test_createMessageList_single_number_failed");
let fakeRequestId = newRandomId();
fakeSmsRequestManager({
notifyNoMessageInList: function notifyNoMessageInList(requestId) {
is(requestId, fakeRequestId);
run_next_test();
}
});
let filter = new MozSmsFilter();
filter.numbers = ["00000000000"];
gMobileMessageDatabaseService.createMessageList(filter, false, fakeRequestId);
});
add_test(function test_createMessageList_multi_number_success() {
info("test_createMessageList_multi_number_success");
let fakeRequestId = newRandomId();
let auxListId;
let secondMessage = false;
fakeSmsRequestManager({
notifyCreateMessageList: function notifyCreateMessageList(requestId,
listId,
message) {
is(requestId, fakeRequestId);
checkReceivedSms(message, 0);
auxListId = listId;
gMobileMessageDatabaseService.getNextMessageInList(listId, requestId);
},
notifyGotNextMessage: function notifyGotNextMessage(requestId, message) {
ok(!secondMessage);
is(requestId, fakeRequestId);
checkSentSms(message, 1);
secondMessage = true;
gMobileMessageDatabaseService.getNextMessageInList(auxListId, requestId);
},
notifyNoMessageInList: function notifyNoMessageInList(requestId) {
ok(secondMessage);
is(requestId, fakeRequestId);
run_next_test();
}
});
let filter = new MozSmsFilter();
filter.numbers = [sms[0].sender, sms[1].receiver];
gMobileMessageDatabaseService.createMessageList(filter, false, fakeRequestId);
});
add_test(function test_createMessageList_multi_number_wrong_number_success() {
info("test_createMessageList_multi_number_wrong_number_success");
let fakeRequestId = newRandomId();
let firstMessage = false;
fakeSmsRequestManager({
notifyCreateMessageList: function notifyCreateMessageList(requestId,
listId,
message) {
is(firstMessage, false);
is(requestId, fakeRequestId);
checkReceivedSms(message, 0);
firstMessage = true;
gMobileMessageDatabaseService.getNextMessageInList(listId, requestId);
},
notifyNoMessageInList: function notifyNoMessageInList(requestId) {
ok(firstMessage);
is(requestId, fakeRequestId);
run_next_test();
}
});
let filter = new MozSmsFilter();
filter.numbers = ["00000000000", sms[0].sender];
gMobileMessageDatabaseService.createMessageList(filter, false, fakeRequestId);
});
add_test(function test_createMessageList_multi_number_failed() {
info("test_createMessageList_multi_number_failed");
let fakeRequestId = newRandomId();
fakeSmsRequestManager({
notifyNoMessageInList: function notifyNoMessageInList(requestId) {
is(requestId, fakeRequestId);
run_next_test();
}
});
let filter = new MozSmsFilter();
filter.numbers = ["00000000000", "11111111111"];
gMobileMessageDatabaseService.createMessageList(filter, false, fakeRequestId);
});
add_test(function test_createMessageList_read_filter_success() {
info("test_createMessageList_read_filter_success");
let fakeRequestId = newRandomId();
let lId;
let secondMessage = false;
fakeSmsRequestManager({
notifyCreateMessageList: function notifyCreateMessageList(requestId,
listId,
message) {
is(requestId, fakeRequestId);
checkReceivedSms(message, 0);
lId = listId;
gMobileMessageDatabaseService.getNextMessageInList(listId, requestId);
},
notifyGotNextMessage: function notifyGotNextMessage(requestId, message) {
ok(!secondMessage);
is(requestId, fakeRequestId);
checkReceivedSms(message, 2);
secondMessage = true;
gMobileMessageDatabaseService.getNextMessageInList(lId, requestId);
},
notifyNoMessageInList: function notifyNoMessageInList(requestId) {
ok(secondMessage);
is(requestId, fakeRequestId);
run_next_test();
}
});
SimpleTest.executeSoon(function () {
let filter = new MozSmsFilter();
filter.read = false;
gMobileMessageDatabaseService.createMessageList(filter, false, fakeRequestId);
});
});
/**
* nsIMobileMessageDatabaseService.getNextMessageInList
*/
add_test(function test_getNextMessageInList_unknown_list() {
info("test_getNextMessageInList_unknown_list");
let fakeRequestId = newRandomId();
fakeSmsRequestManager({
notifyReadMessageListFailed:
function notifyReadMessageListFailed(requestId) {
is(requestId, fakeRequestId);
run_next_test();
}
});
gMobileMessageDatabaseService.getNextMessageInList(-1, fakeRequestId);
});
/**
* nsIMobileMessageDatabaseService.deleteMessage
*/
add_test(function test_deleteMessage_success() {
info("test_deleteMessage_success");
let fakeRequestId = newRandomId();
fakeSmsRequestManager({
notifySmsDeleted: function notifySmsDeleted(requestId, deleted) {
is(requestId, fakeRequestId);
ok(deleted);
run_next_test();
}
});
let messageId = gMobileMessageDatabaseService.saveReceivedMessage(sms[0]);
SimpleTest.executeSoon(function () {
gMobileMessageDatabaseService.deleteMessage(messageId, fakeRequestId);
});
});
add_test(function test_deleteMessage_failed() {
info("test_deleteMessage_failed");
let fakeRequestId = newRandomId();
fakeSmsRequestManager({
notifySmsDeleted: function notifySmsDeleted(requestId, deleted) {
is(requestId, fakeRequestId);
is(deleted, false);
run_next_test();
}
});
gMobileMessageDatabaseService.deleteMessage(-1, fakeRequestId);
});
add_test(function test_markMessageRead_success() {
info("test_markMessageRead_success");
let fakeRequestId = newRandomId();
fakeSmsRequestManager({
notifyMarkedMessageRead: function notifyMarkedMessageRead(requestId, read) {
is(requestId, fakeRequestId);
is(read, true);
run_next_test();
}
});
let messageId = gMobileMessageDatabaseService.saveReceivedMessage(sms[2]);
SimpleTest.executeSoon(function () {
gMobileMessageDatabaseService.markMessageRead(messageId, true, fakeRequestId);
});
});
add_test(function test_markMessageRead_failed() {
info("test_markMessageRead_failed");
let fakeRequestId = newRandomId();
fakeSmsRequestManager({
notifyMarkMessageReadFailed: function notifyMarkMessageReadFailed(requestId, error) {
is(requestId, fakeRequestId);
run_next_test();
}
});
SimpleTest.executeSoon(function () {
gMobileMessageDatabaseService.markMessageRead(-1, true, fakeRequestId);
});
});
]]></script>
<body xmlns="http://www.w3.org/1999/xhtml">
<p id="display"></p>
<div id="content" style="display: none"></div>
<pre id="test"></pre>
</body>
</window>

Просмотреть файл

@ -3,7 +3,6 @@ head = header_helpers.js
tail =
support-files =
test_sms_basics.html
test_smsdatabaseservice.xul
test_smsfilter.html
[test_smsservice_createsmsmessage.js]

Просмотреть файл

@ -72,7 +72,6 @@ PARALLEL_DIRS += [
'camera',
'audiochannel',
'promise',
'wappush',
'telephony',
'inputmethod',
'webidl',
@ -81,12 +80,15 @@ PARALLEL_DIRS += [
if CONFIG['OS_ARCH'] == 'WINNT':
PARALLEL_DIRS += ['plugins/ipc/hangui']
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk':
PARALLEL_DIRS += ['wifi']
if CONFIG['MOZ_B2G_RIL']:
PARALLEL_DIRS += [
'wifi',
'icc',
'cellbroadcast',
'voicemail',
'wappush',
]
if CONFIG['MOZ_PAY']:

Просмотреть файл

@ -6,10 +6,8 @@
XPIDL_SOURCES += [
'nsIDOMConnection.idl',
'nsIDOMDataErrorEvent.idl',
'nsIDOMTCPServerSocket.idl',
'nsIDOMTCPSocket.idl',
'nsIDOMUSSDReceivedEvent.idl',
'nsIMozNavigatorNetwork.idl',
'nsITCPServerSocketChild.idl',
'nsITCPServerSocketParent.idl',
@ -20,12 +18,18 @@ XPIDL_SOURCES += [
if CONFIG['MOZ_B2G_RIL']:
XPIDL_SOURCES += [
'nsIDOMCFStateChangeEvent.idl',
'nsIDOMDataErrorEvent.idl',
'nsIDOMMobileConnection.idl',
'nsIDOMMozEmergencyCbModeEvent.idl',
'nsIDOMMozOtaStatusEvent.idl',
'nsIDOMUSSDReceivedEvent.idl',
'nsIMobileConnectionProvider.idl',
]
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk':
XPIDL_SOURCES += [
'nsIDOMNetworkStats.idl',
'nsIDOMNetworkStatsManager.idl',
'nsIMobileConnectionProvider.idl',
'nsINetworkStatsServiceProxy.idl',
]

Просмотреть файл

@ -10,7 +10,7 @@ interface nsIDOMMozMobileConnectionInfo;
interface nsIDOMMozMobileNetworkInfo;
interface nsIDOMWindow;
[scriptable, uuid(f1878629-4151-4e02-a22a-8cec3d7eddee)]
[scriptable, uuid(f02c50d5-9d34-4f24-80eb-527a280e31fa)]
interface nsIMobileConnectionListener : nsISupports
{
void notifyVoiceChanged();
@ -27,13 +27,14 @@ interface nsIMobileConnectionListener : nsISupports
void notifyEmergencyCbModeChanged(in boolean active,
in unsigned long timeoutMs);
void notifyOtaStatusChanged(in DOMString status);
void notifyIccChanged();
};
/**
* XPCOM component (in the content process) that provides the mobile
* network information.
*/
[scriptable, uuid(c66652e0-0628-11e3-8ffd-0800200c9a66)]
[scriptable, uuid(84278a49-0f05-4585-b3f4-c74882ae5719)]
interface nsIMobileConnectionProvider : nsISupports
{
/**
@ -41,47 +42,71 @@ interface nsIMobileConnectionProvider : nsISupports
* RadioInterfaceLayer in the chrome process. Only a content process that has
* the 'mobileconnection' permission is allowed to register.
*/
void registerMobileConnectionMsg(in nsIMobileConnectionListener listener);
void unregisterMobileConnectionMsg(in nsIMobileConnectionListener listener);
void registerMobileConnectionMsg(in unsigned long clientId,
in nsIMobileConnectionListener listener);
void unregisterMobileConnectionMsg(in unsigned long clientId,
in nsIMobileConnectionListener listener);
readonly attribute nsIDOMMozMobileConnectionInfo voiceConnectionInfo;
readonly attribute nsIDOMMozMobileConnectionInfo dataConnectionInfo;
readonly attribute DOMString networkSelectionMode;
nsIDOMMozMobileConnectionInfo getVoiceConnectionInfo(in unsigned long clientId);
nsIDOMMozMobileConnectionInfo getDataConnectionInfo(in unsigned long clientId);
DOMString getIccId(in unsigned long clientId);
DOMString getNetworkSelectionMode(in unsigned long clientId);
nsIDOMDOMRequest getNetworks(in nsIDOMWindow window);
nsIDOMDOMRequest selectNetwork(in nsIDOMWindow window, in nsIDOMMozMobileNetworkInfo network);
nsIDOMDOMRequest selectNetworkAutomatically(in nsIDOMWindow window);
nsIDOMDOMRequest getNetworks(in unsigned long clientId,
in nsIDOMWindow window);
nsIDOMDOMRequest selectNetwork(in unsigned long clientId,
in nsIDOMWindow window,
in nsIDOMMozMobileNetworkInfo network);
nsIDOMDOMRequest selectNetworkAutomatically(in unsigned long clientId,
in nsIDOMWindow window);
nsIDOMDOMRequest setRoamingPreference(in nsIDOMWindow window,
nsIDOMDOMRequest setRoamingPreference(in unsigned long clientId,
in nsIDOMWindow window,
in DOMString mode);
nsIDOMDOMRequest getRoamingPreference(in nsIDOMWindow window);
nsIDOMDOMRequest getRoamingPreference(in unsigned long clientId,
in nsIDOMWindow window);
nsIDOMDOMRequest setVoicePrivacyMode(in nsIDOMWindow window,
nsIDOMDOMRequest setVoicePrivacyMode(in unsigned long clientId,
in nsIDOMWindow window,
in bool enabled);
nsIDOMDOMRequest getVoicePrivacyMode(in nsIDOMWindow window);
nsIDOMDOMRequest getVoicePrivacyMode(in unsigned long clientId,
in nsIDOMWindow window);
nsIDOMDOMRequest sendMMI(in nsIDOMWindow window, in DOMString mmi);
nsIDOMDOMRequest cancelMMI(in nsIDOMWindow window);
nsIDOMDOMRequest sendMMI(in unsigned long clientId,
in nsIDOMWindow window,
in DOMString mmi);
nsIDOMDOMRequest cancelMMI(in unsigned long clientId,
in nsIDOMWindow window);
nsIDOMDOMRequest getCallForwardingOption(in nsIDOMWindow window,
nsIDOMDOMRequest getCallForwardingOption(in unsigned long clientId,
in nsIDOMWindow window,
in unsigned short reason);
nsIDOMDOMRequest setCallForwardingOption(in nsIDOMWindow window,
nsIDOMDOMRequest setCallForwardingOption(in unsigned long clientId,
in nsIDOMWindow window,
in nsIDOMMozMobileCFInfo CFInfo);
nsIDOMDOMRequest getCallBarringOption(in nsIDOMWindow window,
in jsval option);
nsIDOMDOMRequest setCallBarringOption(in nsIDOMWindow window,
in jsval option);
nsIDOMDOMRequest changeCallBarringPassword(in nsIDOMWindow window,
nsIDOMDOMRequest getCallBarringOption(in unsigned long clientId,
in nsIDOMWindow window,
in jsval option);
nsIDOMDOMRequest setCallBarringOption(in unsigned long clientId,
in nsIDOMWindow window,
in jsval option);
nsIDOMDOMRequest changeCallBarringPassword(in unsigned long clientId,
in nsIDOMWindow window,
in jsval info);
nsIDOMDOMRequest setCallWaitingOption(in nsIDOMWindow window,
nsIDOMDOMRequest setCallWaitingOption(in unsigned long clientId,
in nsIDOMWindow window,
in bool enabled);
nsIDOMDOMRequest getCallWaitingOption(in nsIDOMWindow window);
nsIDOMDOMRequest getCallWaitingOption(in unsigned long clientId,
in nsIDOMWindow window);
nsIDOMDOMRequest setCallingLineIdRestriction(in nsIDOMWindow window,
nsIDOMDOMRequest setCallingLineIdRestriction(in unsigned long clientId,
in nsIDOMWindow window,
in unsigned short clirMode);
nsIDOMDOMRequest getCallingLineIdRestriction(in nsIDOMWindow window);
nsIDOMDOMRequest getCallingLineIdRestriction(in unsigned long clientId,
in nsIDOMWindow window);
nsIDOMDOMRequest exitEmergencyCbMode(in nsIDOMWindow window);
nsIDOMDOMRequest exitEmergencyCbMode(in unsigned long clientId,
in nsIDOMWindow window);
};

Просмотреть файл

@ -2,7 +2,8 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "MobileConnection.h"
#include "mozilla/dom/network/MobileConnection.h"
#include "GeneratedEvents.h"
#include "mozilla/Preferences.h"
#include "nsDOMEvent.h"
@ -82,6 +83,9 @@ MobileConnection::MobileConnection()
mProvider = do_GetService(NS_RILCONTENTHELPER_CONTRACTID);
mWindow = nullptr;
// TODO: Bug 814629 - WebMobileConnection API: support multiple sim cards
mClientId = 0;
// Not being able to acquire the provider isn't fatal since we check
// for it explicitly below.
if (!mProvider) {
@ -100,7 +104,7 @@ MobileConnection::Init(nsPIDOMWindow* aWindow)
if (!CheckPermission("mobilenetwork") &&
CheckPermission("mobileconnection")) {
DebugOnly<nsresult> rv = mProvider->RegisterMobileConnectionMsg(mListener);
DebugOnly<nsresult> rv = mProvider->RegisterMobileConnectionMsg(mClientId, mListener);
NS_WARN_IF_FALSE(NS_SUCCEEDED(rv),
"Failed registering mobile connection messages with provider");
@ -113,7 +117,7 @@ MobileConnection::Shutdown()
{
if (mProvider && mListener) {
mListener->Disconnect();
mProvider->UnregisterMobileConnectionMsg(mListener);
mProvider->UnregisterMobileConnectionMsg(mClientId, mListener);
mProvider = nullptr;
mListener = nullptr;
}
@ -172,7 +176,7 @@ MobileConnection::GetVoice(nsIDOMMozMobileConnectionInfo** voice)
if (!mProvider || !CheckPermission("mobileconnection")) {
return NS_OK;
}
return mProvider->GetVoiceConnectionInfo(voice);
return mProvider->GetVoiceConnectionInfo(mClientId, voice);
}
NS_IMETHODIMP
@ -183,7 +187,7 @@ MobileConnection::GetData(nsIDOMMozMobileConnectionInfo** data)
if (!mProvider || !CheckPermission("mobileconnection")) {
return NS_OK;
}
return mProvider->GetDataConnectionInfo(data);
return mProvider->GetDataConnectionInfo(mClientId, data);
}
NS_IMETHODIMP
@ -194,7 +198,7 @@ MobileConnection::GetNetworkSelectionMode(nsAString& networkSelectionMode)
if (!mProvider || !CheckPermission("mobileconnection")) {
return NS_OK;
}
return mProvider->GetNetworkSelectionMode(networkSelectionMode);
return mProvider->GetNetworkSelectionMode(mClientId, networkSelectionMode);
}
NS_IMETHODIMP
@ -210,7 +214,7 @@ MobileConnection::GetNetworks(nsIDOMDOMRequest** request)
return NS_ERROR_FAILURE;
}
return mProvider->GetNetworks(GetOwner(), request);
return mProvider->GetNetworks(mClientId, GetOwner(), request);
}
NS_IMETHODIMP
@ -226,7 +230,7 @@ MobileConnection::SelectNetwork(nsIDOMMozMobileNetworkInfo* network, nsIDOMDOMRe
return NS_ERROR_FAILURE;
}
return mProvider->SelectNetwork(GetOwner(), network, request);
return mProvider->SelectNetwork(mClientId, GetOwner(), network, request);
}
NS_IMETHODIMP
@ -242,7 +246,7 @@ MobileConnection::SelectNetworkAutomatically(nsIDOMDOMRequest** request)
return NS_ERROR_FAILURE;
}
return mProvider->SelectNetworkAutomatically(GetOwner(), request);
return mProvider->SelectNetworkAutomatically(mClientId, GetOwner(), request);
}
NS_IMETHODIMP
@ -258,7 +262,7 @@ MobileConnection::SetRoamingPreference(const nsAString& aMode, nsIDOMDOMRequest*
return NS_ERROR_FAILURE;
}
return mProvider->SetRoamingPreference(GetOwner(), aMode, aDomRequest);
return mProvider->SetRoamingPreference(mClientId, GetOwner(), aMode, aDomRequest);
}
NS_IMETHODIMP
@ -274,7 +278,7 @@ MobileConnection::GetRoamingPreference(nsIDOMDOMRequest** aDomRequest)
return NS_ERROR_FAILURE;
}
return mProvider->GetRoamingPreference(GetOwner(), aDomRequest);
return mProvider->GetRoamingPreference(mClientId, GetOwner(), aDomRequest);
}
NS_IMETHODIMP
@ -290,7 +294,7 @@ MobileConnection::SetVoicePrivacyMode(bool aEnabled, nsIDOMDOMRequest** aDomRequ
return NS_ERROR_FAILURE;
}
return mProvider->SetVoicePrivacyMode(GetOwner(), aEnabled, aDomRequest);
return mProvider->SetVoicePrivacyMode(mClientId, GetOwner(), aEnabled, aDomRequest);
}
NS_IMETHODIMP
@ -306,7 +310,7 @@ MobileConnection::GetVoicePrivacyMode(nsIDOMDOMRequest** aDomRequest)
return NS_ERROR_FAILURE;
}
return mProvider->GetVoicePrivacyMode(GetOwner(), aDomRequest);
return mProvider->GetVoicePrivacyMode(mClientId, GetOwner(), aDomRequest);
}
NS_IMETHODIMP
@ -321,7 +325,7 @@ MobileConnection::SendMMI(const nsAString& aMMIString,
return NS_ERROR_FAILURE;
}
return mProvider->SendMMI(GetOwner(), aMMIString, aRequest);
return mProvider->SendMMI(mClientId, GetOwner(), aMMIString, aRequest);
}
NS_IMETHODIMP
@ -335,7 +339,7 @@ MobileConnection::CancelMMI(nsIDOMDOMRequest** aRequest)
return NS_ERROR_FAILURE;
}
return mProvider->CancelMMI(GetOwner(), aRequest);
return mProvider->CancelMMI(mClientId, GetOwner(),aRequest);
}
NS_IMETHODIMP
@ -352,7 +356,7 @@ MobileConnection::GetCallForwardingOption(uint16_t aReason,
return NS_ERROR_FAILURE;
}
return mProvider->GetCallForwardingOption(GetOwner(), aReason, aRequest);
return mProvider->GetCallForwardingOption(mClientId, GetOwner(), aReason, aRequest);
}
NS_IMETHODIMP
@ -369,7 +373,7 @@ MobileConnection::SetCallForwardingOption(nsIDOMMozMobileCFInfo* aCFInfo,
return NS_ERROR_FAILURE;
}
return mProvider->SetCallForwardingOption(GetOwner(), aCFInfo, aRequest);
return mProvider->SetCallForwardingOption(mClientId, GetOwner(), aCFInfo, aRequest);
}
NS_IMETHODIMP
@ -386,7 +390,7 @@ MobileConnection::GetCallBarringOption(const JS::Value& aOption,
return NS_ERROR_FAILURE;
}
return mProvider->GetCallBarringOption(GetOwner(), aOption, aRequest);
return mProvider->GetCallBarringOption(mClientId, GetOwner(), aOption, aRequest);
}
NS_IMETHODIMP
@ -403,7 +407,7 @@ MobileConnection::SetCallBarringOption(const JS::Value& aOption,
return NS_ERROR_FAILURE;
}
return mProvider->SetCallBarringOption(GetOwner(), aOption, aRequest);
return mProvider->SetCallBarringOption(mClientId, GetOwner(), aOption, aRequest);
}
NS_IMETHODIMP
@ -420,7 +424,7 @@ MobileConnection::ChangeCallBarringPassword(const JS::Value& aInfo,
return NS_ERROR_FAILURE;
}
return mProvider->ChangeCallBarringPassword(GetOwner(), aInfo, aRequest);
return mProvider->ChangeCallBarringPassword(mClientId, GetOwner(), aInfo, aRequest);
}
NS_IMETHODIMP
@ -436,7 +440,7 @@ MobileConnection::GetCallWaitingOption(nsIDOMDOMRequest** aRequest)
return NS_ERROR_FAILURE;
}
return mProvider->GetCallWaitingOption(GetOwner(), aRequest);
return mProvider->GetCallWaitingOption(mClientId, GetOwner(), aRequest);
}
NS_IMETHODIMP
@ -453,7 +457,7 @@ MobileConnection::SetCallWaitingOption(bool aEnabled,
return NS_ERROR_FAILURE;
}
return mProvider->SetCallWaitingOption(GetOwner(), aEnabled, aRequest);
return mProvider->SetCallWaitingOption(mClientId, GetOwner(), aEnabled, aRequest);
}
NS_IMETHODIMP
@ -469,7 +473,7 @@ MobileConnection::GetCallingLineIdRestriction(nsIDOMDOMRequest** aRequest)
return NS_ERROR_FAILURE;
}
return mProvider->GetCallingLineIdRestriction(GetOwner(), aRequest);
return mProvider->GetCallingLineIdRestriction(mClientId, GetOwner(), aRequest);
}
NS_IMETHODIMP
@ -486,7 +490,7 @@ MobileConnection::SetCallingLineIdRestriction(unsigned short aClirMode,
return NS_ERROR_FAILURE;
}
return mProvider->SetCallingLineIdRestriction(GetOwner(), aClirMode, aRequest);
return mProvider->SetCallingLineIdRestriction(mClientId, GetOwner(), aClirMode, aRequest);
}
NS_IMETHODIMP
@ -502,7 +506,7 @@ MobileConnection::ExitEmergencyCbMode(nsIDOMDOMRequest** aRequest)
return NS_ERROR_FAILURE;
}
return mProvider->ExitEmergencyCbMode(GetOwner(), aRequest);
return mProvider->ExitEmergencyCbMode(mClientId, GetOwner(), aRequest);
}
// nsIMobileConnectionListener
@ -630,3 +634,11 @@ MobileConnection::NotifyOtaStatusChanged(const nsAString& aStatus)
return DispatchTrustedEvent(ce);
}
NS_IMETHODIMP
MobileConnection::NotifyIccChanged()
{
// TODO: Bug 814629 - WebMobileConnection API: support multiple sim cards
// Return NS_OK for now, will be implemented in Bug 814629.
return NS_OK;
}

Просмотреть файл

@ -48,6 +48,8 @@ private:
nsRefPtr<Listener> mListener;
nsWeakPtr mWindow;
uint32_t mClientId;
bool CheckPermission(const char* type);
};

Просмотреть файл

@ -46,12 +46,6 @@ XPCOMUtils.defineLazyServiceGetter(this, "gSettingsService",
"@mozilla.org/settingsService;1",
"nsISettingsService");
XPCOMUtils.defineLazyGetter(this, "gRadioInterface", function () {
let ril = Cc["@mozilla.org/ril;1"].getService(Ci["nsIRadioInterfaceLayer"]);
// TODO: Bug 923382 - B2G Multi-SIM: support multiple SIM cards for network metering.
return ril.getRadioInterface(0);
});
this.NetworkStatsService = {
init: function() {
debug("Service started");
@ -202,10 +196,13 @@ this.NetworkStatsService = {
let id = '0';
if (aNetwork.type == NET_TYPE_MOBILE) {
// Bug 904542 will provide the serviceId to map the iccId with the
// nsINetworkInterface of the NetworkManager. Now, lets assume that
// network is mapped with the current iccId of the single SIM.
id = gRadioInterface.rilContext.iccInfo.iccid;
if (!(aNetwork instanceof Ci.nsIRilNetworkInterface)) {
debug("Error! Mobile network should be an nsIRilNetworkInterface!");
return null;
}
let rilNetwork = aNetwork.QueryInterface(Ci.nsIRilNetworkInterface);
id = rilNetwork.iccId;
}
let netId = this.getNetworkId(id, aNetwork.type);
@ -271,12 +268,13 @@ this.NetworkStatsService = {
debug("getstats for network " + network.id + " of type " + network.type);
debug("appId: " + appId + " from manifestURL: " + manifestURL);
self._db.find(function onStatsFound(aError, aResult) {
mm.sendAsyncMessage("NetworkStats:Get:Return",
{ id: msg.id, error: aError, result: aResult });
}, network, start, end, appId, manifestURL);
});
this.updateCachedAppStats(function onAppStatsUpdated(aResult, aMessage) {
self._db.find(function onStatsFound(aError, aResult) {
mm.sendAsyncMessage("NetworkStats:Get:Return",
{ id: msg.id, error: aError, result: aResult });
}, network, start, end, appId, manifestURL);
});
}.bind(this));
},
clearInterfaceStats: function clearInterfaceStats(mm, msg) {
@ -564,6 +562,10 @@ this.NetworkStatsService = {
let stats = Object.keys(this.cachedAppStats);
if (stats.length == 0) {
// |cachedAppStats| is empty, no need to update.
if (aCallback) {
aCallback(true, "no need to update");
}
return;
}

Просмотреть файл

@ -22,9 +22,14 @@ SOURCES += [
]
if CONFIG['MOZ_B2G_RIL']:
EXPORTS.mozilla.dom.network += [
'MobileConnection.h',
]
SOURCES += [
'MobileConnection.cpp',
]
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk':
EXTRA_JS_MODULES = [
'NetworkStatsDB.jsm',
'NetworkStatsService.jsm',
@ -40,7 +45,7 @@ EXTRA_PP_COMPONENTS += [
'TCPSocket.js',
]
if CONFIG['MOZ_B2G_RIL']:
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk':
EXTRA_COMPONENTS += [
'NetworkStatsManager.js',
'NetworkStatsManager.manifest',

Просмотреть файл

@ -9,7 +9,7 @@ MOCHITEST_FILES = \
test_tcpsocket_enabled_with_perm.html \
$(NULL)
ifdef MOZ_B2G_RIL
ifeq (gonk,$(MOZ_WIDGET_TOOLKIT))
MOCHITEST_FILES = \
test_networkstats_basics.html \
test_networkstats_disabled.html \

Просмотреть файл

@ -44,7 +44,8 @@ this.PhoneNumberUtils = {
#ifdef MOZ_B2G_RIL
// Get network mcc
let voice = mobileConnection.voiceConnectionInfo;
// TODO: Bug 926740 - PhoneNumberUtils for multisim
let voice = mobileConnection.getVoiceConnectionInfo(0);
if (voice && voice.network && voice.network.mcc) {
mcc = voice.network.mcc;
}

Просмотреть файл

@ -61,7 +61,6 @@ public:
JSContext* aCx)
{
MOZ_ASSERT(!aID.IsEmpty());
MOZ_ASSERT(!aTitle.IsEmpty());
NotificationOptions options;
options.mDir = Notification::StringToDirection(nsString(aDir));

Просмотреть файл

@ -18,19 +18,21 @@
#include <hardware/gps.h>
#include "GonkGPSGeolocationProvider.h"
#include "SystemWorkerManager.h"
#include "mozilla/Preferences.h"
#include "nsGeoPosition.h"
#include "nsIInterfaceRequestorUtils.h"
#include "nsINetworkManager.h"
#include "nsIRadioInterfaceLayer.h"
#include "nsIDOMIccInfo.h"
#include "nsIDOMMobileConnection.h"
#include "nsJSUtils.h"
#include "nsServiceManagerUtils.h"
#include "nsThreadUtils.h"
#include "nsContentUtils.h"
#ifdef MOZ_B2G_RIL
#include "nsIDOMIccInfo.h"
#include "nsIDOMMobileConnection.h"
#include "nsIRadioInterfaceLayer.h"
#endif
#ifdef AGPS_TYPE_INVALID
#define AGPS_HAVE_DUAL_APN
#endif
@ -44,10 +46,15 @@ static const int kDefaultPeriod = 1000; // ms
// While most methods of GonkGPSGeolocationProvider should only be
// called from main thread, we deliberately put the Init and ShutdownGPS
// methods off main thread to avoid blocking.
#ifdef MOZ_B2G_RIL
NS_IMPL_ISUPPORTS3(GonkGPSGeolocationProvider,
nsIGeolocationProvider,
nsIRILDataCallback,
nsISettingsServiceCallback)
#else
NS_IMPL_ISUPPORTS1(GonkGPSGeolocationProvider,
nsIGeolocationProvider)
#endif
/* static */ GonkGPSGeolocationProvider* GonkGPSGeolocationProvider::sSingleton = nullptr;
GpsCallbacks GonkGPSGeolocationProvider::mCallbacks = {
@ -65,6 +72,7 @@ GpsCallbacks GonkGPSGeolocationProvider::mCallbacks = {
#endif
};
#ifdef MOZ_B2G_RIL
AGpsCallbacks
GonkGPSGeolocationProvider::mAGPSCallbacks = {
AGPSStatusCallback,
@ -77,6 +85,7 @@ GonkGPSGeolocationProvider::mAGPSRILCallbacks = {
AGPSRILRefLocCallback,
CreateThreadCallback,
};
#endif // MOZ_B2G_RIL
void
GonkGPSGeolocationProvider::LocationCallback(GpsLocation* location)
@ -146,8 +155,10 @@ GonkGPSGeolocationProvider::SetCapabilitiesCallback(uint32_t capabilities)
GonkGPSGeolocationProvider::GetSingleton();
provider->mSupportsScheduling = mCapabilities & GPS_CAPABILITY_SCHEDULING;
#ifdef MOZ_B2G_RIL
provider->mSupportsMSB = mCapabilities & GPS_CAPABILITY_MSB;
provider->mSupportsMSA = mCapabilities & GPS_CAPABILITY_MSA;
#endif
provider->mSupportsSingleShot = mCapabilities & GPS_CAPABILITY_SINGLE_SHOT;
#ifdef GPS_CAPABILITY_ON_DEMAND_TIME
provider->mSupportsTimeInjection = mCapabilities & GPS_CAPABILITY_ON_DEMAND_TIME;
@ -196,6 +207,7 @@ GonkGPSGeolocationProvider::RequestUtcTimeCallback()
{
}
#ifdef MOZ_B2G_RIL
void
GonkGPSGeolocationProvider::AGPSStatusCallback(AGpsStatus* status)
{
@ -267,12 +279,15 @@ GonkGPSGeolocationProvider::AGPSRILRefLocCallback(uint32_t flags)
NS_DispatchToMainThread(new RequestRefLocEvent());
}
}
#endif // MOZ_B2G_RIL
GonkGPSGeolocationProvider::GonkGPSGeolocationProvider()
: mStarted(false)
, mSupportsScheduling(false)
#ifdef MOZ_B2G_RIL
, mSupportsMSB(false)
, mSupportsMSA(false)
#endif
, mSupportsSingleShot(false)
, mSupportsTimeInjection(false)
, mGpsInterface(nullptr)
@ -320,6 +335,7 @@ GonkGPSGeolocationProvider::GetGPSInterface()
return result;
}
#ifdef MOZ_B2G_RIL
int32_t
GonkGPSGeolocationProvider::GetDataConnectionState()
{
@ -507,6 +523,7 @@ GonkGPSGeolocationProvider::SetReferenceLocation()
}
}
}
#endif // MOZ_B2G_RIL
void
GonkGPSGeolocationProvider::Init()
@ -523,6 +540,7 @@ GonkGPSGeolocationProvider::Init()
return;
}
#ifdef MOZ_B2G_RIL
mAGpsInterface =
static_cast<const AGpsInterface*>(mGpsInterface->get_extension(AGPS_INTERFACE));
if (mAGpsInterface) {
@ -534,6 +552,7 @@ GonkGPSGeolocationProvider::Init()
if (mAGpsRilInterface) {
mAGpsRilInterface->init(&mAGPSRILCallbacks);
}
#endif
NS_DispatchToMainThread(NS_NewRunnableMethod(this, &GonkGPSGeolocationProvider::StartGPS));
}
@ -546,19 +565,23 @@ GonkGPSGeolocationProvider::StartGPS()
int32_t update = Preferences::GetInt("geo.default.update", kDefaultPeriod);
#ifdef MOZ_B2G_RIL
if (mSupportsMSA || mSupportsMSB) {
SetupAGPS();
}
#endif
int positionMode = GPS_POSITION_MODE_STANDALONE;
bool singleShot = false;
#ifdef MOZ_B2G_RIL
// XXX: If we know this is a single shot request, use MSA can be faster.
if (singleShot && mSupportsMSA) {
positionMode = GPS_POSITION_MODE_MS_ASSISTED;
} else if (mSupportsMSB) {
positionMode = GPS_POSITION_MODE_MS_BASED;
}
#endif
if (!mSupportsScheduling) {
update = kDefaultPeriod;
}
@ -574,6 +597,7 @@ GonkGPSGeolocationProvider::StartGPS()
mGpsInterface->start();
}
#ifdef MOZ_B2G_RIL
void
GonkGPSGeolocationProvider::SetupAGPS()
{
@ -599,9 +623,8 @@ GonkGPSGeolocationProvider::SetupAGPS()
mRadioInterface->RegisterDataCallCallback(this);
}
}
return;
}
#endif // MOZ_B2G_RIL
NS_IMETHODIMP
GonkGPSGeolocationProvider::Startup()
@ -643,9 +666,11 @@ GonkGPSGeolocationProvider::Shutdown()
}
mStarted = false;
#ifdef MOZ_B2G_RIL
if (mRadioInterface) {
mRadioInterface->UnregisterDataCallCallback(this);
}
#endif
mInitThread->Dispatch(NS_NewRunnableMethod(this, &GonkGPSGeolocationProvider::ShutdownGPS),
NS_DISPATCH_NORMAL);
@ -670,6 +695,7 @@ GonkGPSGeolocationProvider::SetHighAccuracy(bool)
return NS_OK;
}
#ifdef MOZ_B2G_RIL
/** nsIRILDataCallback interface **/
NS_IMETHODIMP
@ -721,3 +747,4 @@ GonkGPSGeolocationProvider::HandleError(const nsAString& aErrorMessage)
{
return NS_OK;
}
#endif // MOZ_B2G_RIL

Просмотреть файл

@ -20,9 +20,10 @@
#include <hardware/gps.h> // for GpsInterface
#include "nsCOMPtr.h"
#include "nsIGeolocationProvider.h"
#ifdef MOZ_B2G_RIL
#include "nsIRadioInterfaceLayer.h"
#include "nsString.h"
#include "nsISettingsService.h"
#endif
class nsIThread;
@ -33,14 +34,18 @@ class nsIThread;
"@mozilla.org/gonk-gps-geolocation-provider;1"
class GonkGPSGeolocationProvider : public nsIGeolocationProvider
#ifdef MOZ_B2G_RIL
, public nsIRILDataCallback
, public nsISettingsServiceCallback
#endif
{
public:
NS_DECL_THREADSAFE_ISUPPORTS
NS_DECL_NSIGEOLOCATIONPROVIDER
#ifdef MOZ_B2G_RIL
NS_DECL_NSIRILDATACALLBACK
NS_DECL_NSISETTINGSSERVICECALLBACK
#endif
static already_AddRefed<GonkGPSGeolocationProvider> GetSingleton();
@ -61,25 +66,31 @@ private:
static void ReleaseWakelockCallback();
static pthread_t CreateThreadCallback(const char* name, void (*start)(void*), void* arg);
static void RequestUtcTimeCallback();
#ifdef MOZ_B2G_RIL
static void AGPSStatusCallback(AGpsStatus* status);
static void AGPSRILSetIDCallback(uint32_t flags);
static void AGPSRILRefLocCallback(uint32_t flags);
#endif
static GpsCallbacks mCallbacks;
#ifdef MOZ_B2G_RIL
static AGpsCallbacks mAGPSCallbacks;
static AGpsRilCallbacks mAGPSRILCallbacks;
#endif
int32_t GetDataConnectionState();
void SetAGpsDataConn(nsAString& aApn);
void RequestSettingValue(char* aKey);
void Init();
void SetupAGPS();
void StartGPS();
void ShutdownGPS();
#ifdef MOZ_B2G_RIL
void SetupAGPS();
int32_t GetDataConnectionState();
void SetAGpsDataConn(nsAString& aApn);
void RequestDataConnection();
void ReleaseDataConnection();
void RequestSettingValue(char* aKey);
void RequestSetID(uint32_t flags);
void SetReferenceLocation();
#endif
const GpsInterface* GetGPSInterface();
@ -88,17 +99,21 @@ private:
bool mStarted;
bool mSupportsScheduling;
#ifdef MOZ_B2G_RIL
bool mSupportsMSB;
bool mSupportsMSA;
#endif
bool mSupportsSingleShot;
bool mSupportsTimeInjection;
const GpsInterface* mGpsInterface;
#ifdef MOZ_B2G_RIL
const AGpsInterface* mAGpsInterface;
const AGpsRilInterface* mAGpsRilInterface;
nsCOMPtr<nsIRadioInterface> mRadioInterface;
#endif
nsCOMPtr<nsIGeolocationUpdate> mLocationCallback;
nsCOMPtr<nsIThread> mInitThread;
nsCOMPtr<nsIRadioInterface> mRadioInterface;
};
#endif /* GonkGPSGeolocationProvider_h */

Просмотреть файл

@ -133,8 +133,10 @@ function defineLazyRegExp(obj, name, pattern) {
function NetworkManager() {
this.networkInterfaces = {};
Services.obs.addObserver(this, TOPIC_INTERFACE_STATE_CHANGED, true);
#ifdef MOZ_B2G_RIL
Services.obs.addObserver(this, TOPIC_INTERFACE_REGISTERED, true);
Services.obs.addObserver(this, TOPIC_INTERFACE_UNREGISTERED, true);
#endif
Services.obs.addObserver(this, TOPIC_XPCOM_SHUTDOWN, false);
Services.obs.addObserver(this, TOPIC_MOZSETTINGS_CHANGED, false);
@ -229,6 +231,7 @@ NetworkManager.prototype = {
debug("Network " + network.name + " changed state to " + network.state);
switch (network.state) {
case Ci.nsINetworkInterface.NETWORK_STATE_CONNECTED:
#ifdef MOZ_B2G_RIL
// Add host route for data calls
if (network.type == Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE ||
network.type == Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE_MMS ||
@ -238,16 +241,19 @@ NetworkManager.prototype = {
}
// Add extra host route. For example, mms proxy or mmsc.
this.setExtraHostRoute(network);
#endif
// Remove pre-created default route and let setAndConfigureActive()
// to set default route only on preferred network
this.removeDefaultRoute(network.name);
this.setAndConfigureActive();
#ifdef MOZ_B2G_RIL
// Update data connection when Wifi connected/disconnected
if (network.type == Ci.nsINetworkInterface.NETWORK_TYPE_WIFI) {
for (let i = 0; i < this.mRIL.numRadioInterfaces; i++) {
this.mRIL.getRadioInterface(i).updateRILNetworkInterface();
}
}
#endif
this.onConnectionChanged(network);
@ -255,6 +261,7 @@ NetworkManager.prototype = {
CaptivePortalDetectionHelper.notify(CaptivePortalDetectionHelper.EVENT_CONNECT, this.active);
break;
case Ci.nsINetworkInterface.NETWORK_STATE_DISCONNECTED:
#ifdef MOZ_B2G_RIL
// Remove host route for data calls
if (network.type == Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE ||
network.type == Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE_MMS ||
@ -263,24 +270,30 @@ NetworkManager.prototype = {
}
// Remove extra host route. For example, mms proxy or mmsc.
this.removeExtraHostRoute(network);
#endif
// Remove routing table in /proc/net/route
if (network.type == Ci.nsINetworkInterface.NETWORK_TYPE_WIFI) {
this.resetRoutingTable(network);
#ifdef MOZ_B2G_RIL
} else if (network.type == Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE) {
this.removeDefaultRoute(network.name);
#endif
}
// Abort ongoing captive portal detection on the wifi interface
CaptivePortalDetectionHelper.notify(CaptivePortalDetectionHelper.EVENT_DISCONNECT, network);
this.setAndConfigureActive();
#ifdef MOZ_B2G_RIL
// Update data connection when Wifi connected/disconnected
if (network.type == Ci.nsINetworkInterface.NETWORK_TYPE_WIFI) {
for (let i = 0; i < this.mRIL.numRadioInterfaces; i++) {
this.mRIL.getRadioInterface(i).updateRILNetworkInterface();
}
}
#endif
break;
}
break;
#ifdef MOZ_B2G_RIL
case TOPIC_INTERFACE_REGISTERED:
let regNetwork = subject.QueryInterface(Ci.nsINetworkInterface);
// Add extra host route. For example, mms proxy or mmsc.
@ -291,6 +304,7 @@ NetworkManager.prototype = {
// Remove extra host route. For example, mms proxy or mmsc.
this.removeExtraHostRoute(unregNetwork);
break;
#endif
case TOPIC_MOZSETTINGS_CHANGED:
let setting = JSON.parse(data);
this.handle(setting.key, setting.value);
@ -303,8 +317,10 @@ NetworkManager.prototype = {
case TOPIC_XPCOM_SHUTDOWN:
Services.obs.removeObserver(this, TOPIC_XPCOM_SHUTDOWN);
Services.obs.removeObserver(this, TOPIC_MOZSETTINGS_CHANGED);
#ifdef MOZ_B2G_RIL
Services.obs.removeObserver(this, TOPIC_INTERFACE_REGISTERED);
Services.obs.removeObserver(this, TOPIC_INTERFACE_UNREGISTERED);
#endif
Services.obs.removeObserver(this, TOPIC_INTERFACE_STATE_CHANGED);
break;
}
@ -313,15 +329,19 @@ NetworkManager.prototype = {
receiveMessage: function receiveMessage(aMsg) {
switch (aMsg.name) {
case "NetworkInterfaceList:ListInterface": {
#ifdef MOZ_B2G_RIL
let excludeMms = aMsg.json.exculdeMms;
let excludeSupl = aMsg.json.exculdeSupl;
#endif
let interfaces = [];
for each (let i in this.networkInterfaces) {
#ifdef MOZ_B2G_RIL
if ((i.type == Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE_MMS && excludeMms) ||
(i.type == Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE_SUPL && excludeSupl)) {
continue;
}
#endif
interfaces.push({
state: i.state,
type: i.type,
@ -353,12 +373,14 @@ NetworkManager.prototype = {
Cr.NS_ERROR_INVALID_ARG);
}
this.networkInterfaces[network.name] = network;
#ifdef MOZ_B2G_RIL
// Add host route for data calls
if (network.type == Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE ||
network.type == Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE_MMS ||
network.type == Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE_SUPL) {
this.addHostRoute(network);
}
#endif
// Remove pre-created default route and let setAndConfigureActive()
// to set default route only on preferred network
this.removeDefaultRoute(network.name);
@ -377,12 +399,14 @@ NetworkManager.prototype = {
Cr.NS_ERROR_INVALID_ARG);
}
delete this.networkInterfaces[network.name];
#ifdef MOZ_B2G_RIL
// Remove host route for data calls
if (network.type == Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE ||
network.type == Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE_MMS ||
network.type == Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE_SUPL) {
this.removeHostRoute(network);
}
#endif
this.setAndConfigureActive();
Services.obs.notifyObservers(network, TOPIC_INTERFACE_UNREGISTERED, null);
debug("Network '" + network.name + "' unregistered.");
@ -397,8 +421,12 @@ NetworkManager.prototype = {
return this._preferredNetworkType;
},
set preferredNetworkType(val) {
#ifdef MOZ_B2G_RIL
if ([Ci.nsINetworkInterface.NETWORK_TYPE_WIFI,
Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE].indexOf(val) == -1) {
#else
if (val != Ci.nsINetworkInterface.NETWORK_TYPE_WIFI) {
#endif
throw "Invalid network type";
}
this._preferredNetworkType = val;
@ -411,10 +439,12 @@ NetworkManager.prototype = {
_activeInfo: null,
overrideActive: function overrideActive(network) {
#ifdef MOZ_B2G_RIL
if (network.type == Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE_MMS ||
network.type == Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE_SUPL) {
throw "Invalid network type";
}
#endif
this._overriddenActive = network;
this.setAndConfigureActive();
},
@ -486,6 +516,7 @@ NetworkManager.prototype = {
}
},
#ifdef MOZ_B2G_RIL
setExtraHostRoute: function setExtraHostRoute(network) {
if (network.type == Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE_MMS) {
debug("Network '" + network.name + "' registered, adding mmsproxy and/or mmsc route");
@ -505,6 +536,7 @@ NetworkManager.prototype = {
this.removeHostRouteWithResolve(network, mmsHosts);
}
},
#endif // MOZ_B2G_RIL
/**
* Determine the active interface and configure it.
@ -512,7 +544,6 @@ NetworkManager.prototype = {
setAndConfigureActive: function setAndConfigureActive() {
debug("Evaluating whether active network needs to be changed.");
let oldActive = this.active;
let defaultDataNetwork;
if (this._overriddenActive) {
debug("We have an override for the active network: " +
@ -538,13 +569,18 @@ NetworkManager.prototype = {
// Find a suitable network interface to activate.
this.active = null;
this._activeInfo = Object.create(null);
#ifdef MOZ_B2G_RIL
let defaultDataNetwork;
#endif
for each (let network in this.networkInterfaces) {
if (network.state != Ci.nsINetworkInterface.NETWORK_STATE_CONNECTED) {
continue;
}
#ifdef MOZ_B2G_RIL
if (network.type == Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE) {
defaultDataNetwork = network;
}
#endif
this.active = network;
this._activeInfo = {name:network.name, ip:network.ip, netmask:network.netmask};
if (network.type == this.preferredNetworkType) {
@ -553,6 +589,7 @@ NetworkManager.prototype = {
}
}
if (this.active) {
#ifdef MOZ_B2G_RIL
// Give higher priority to default data APN than seconary APN.
// If default data APN is not connected, we still set default route
// and DNS on seconary APN.
@ -567,8 +604,11 @@ NetworkManager.prototype = {
this.active.type == Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE_SUPL) {
this.setDNS(this.active);
} else {
#endif // MOZ_B2G_RIL
this.setDefaultRouteAndDNS(oldActive);
#ifdef MOZ_B2G_RIL
}
#endif
if (this.active != oldActive) {
Services.obs.notifyObservers(this.active, TOPIC_ACTIVE_CHANGED, null);
}
@ -593,6 +633,7 @@ NetworkManager.prototype = {
this.worker.postMessage(options);
},
#ifdef MOZ_B2G_RIL
setDNS: function setDNS(networkInterface) {
debug("Going DNS to " + networkInterface.name);
let options = {
@ -603,6 +644,7 @@ NetworkManager.prototype = {
};
this.worker.postMessage(options);
},
#endif
setDefaultRouteAndDNS: function setDefaultRouteAndDNS(oldInterface) {
debug("Going to change route and DNS to " + this.active.name);
@ -627,6 +669,7 @@ NetworkManager.prototype = {
this.worker.postMessage(options);
},
#ifdef MOZ_B2G_RIL
addHostRoute: function addHostRoute(network) {
debug("Going to add host route on " + network.name);
let options = {
@ -706,6 +749,7 @@ NetworkManager.prototype = {
};
this.worker.postMessage(options);
},
#endif // MOZ_B2G_RIL
setNetworkProxy: function setNetworkProxy(network) {
try {
@ -1224,9 +1268,11 @@ let CaptivePortalDetectionHelper = (function() {
};
}());
#ifdef MOZ_B2G_RIL
XPCOMUtils.defineLazyServiceGetter(NetworkManager.prototype, "mRIL",
"@mozilla.org/ril;1",
"nsIRadioInterfaceLayer");
#endif
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([NetworkManager]);

Просмотреть файл

@ -82,13 +82,13 @@ const RIL_IPC_MSG_NAMES = [
"RIL:StkCommand",
"RIL:StkSessionEnd",
"RIL:DataError",
"RIL:SetCallForwardingOption",
"RIL:GetCallForwardingOption",
"RIL:SetCallBarringOption",
"RIL:GetCallBarringOption",
"RIL:SetCallForwardingOptions",
"RIL:GetCallForwardingOptions",
"RIL:SetCallBarringOptions",
"RIL:GetCallBarringOptions",
"RIL:ChangeCallBarringPassword",
"RIL:SetCallWaitingOption",
"RIL:GetCallWaitingOption",
"RIL:SetCallWaitingOptions",
"RIL:GetCallWaitingOptions",
"RIL:SetCallingLineIdRestriction",
"RIL:GetCallingLineIdRestriction",
"RIL:CellBroadcastReceived",
@ -380,13 +380,13 @@ CellBroadcastEtwsInfo.prototype = {
popup: null
};
function CallBarringOption(option) {
this.program = option.program;
this.enabled = option.enabled;
this.password = option.password;
this.serviceClass = option.serviceClass;
function CallBarringOptions(options) {
this.program = options.program;
this.enabled = options.enabled;
this.password = options.password;
this.serviceClass = options.serviceClass;
}
CallBarringOption.prototype = {
CallBarringOptions.prototype = {
__exposedProps__ : {program: 'r',
enabled: 'r',
password: 'r',
@ -447,18 +447,30 @@ IccCardLockError.prototype = {
function RILContentHelper() {
this.updateDebugFlag();
this.rilContext = {
cardState: RIL.GECKO_CARDSTATE_UNKNOWN,
networkSelectionMode: RIL.GECKO_NETWORK_SELECTION_UNKNOWN,
iccInfo: null,
voiceConnectionInfo: new MobileConnectionInfo(),
dataConnectionInfo: new MobileConnectionInfo()
};
this.numClients = gNumRadioInterfaces;
debug("Number of clients: " + this.numClients);
this.rilContexts = [];
for (let clientId = 0; clientId < this.numClients; clientId++) {
this.rilContexts[clientId] = {
cardState: RIL.GECKO_CARDSTATE_UNKNOWN,
networkSelectionMode: RIL.GECKO_NETWORK_SELECTION_UNKNOWN,
iccInfo: null,
voiceConnectionInfo: new MobileConnectionInfo(),
dataConnectionInfo: new MobileConnectionInfo()
};
}
this.voicemailInfo = new VoicemailInfo();
this.voicemailDefaultServiceId = this.getVoicemailDefaultServiceId();
this.initDOMRequestHelper(/* aWindow */ null, RIL_IPC_MSG_NAMES);
this._windowsMap = [];
this._selectingNetworks = [];
this._mobileConnectionListeners = [];
this._cellBroadcastListeners = [];
this._voicemailListeners = [];
this._iccListeners = [];
Services.obs.addObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, false);
@ -535,88 +547,119 @@ RILContentHelper.prototype = {
* 1. Should clear iccInfo to null if there is no card detected.
* 2. Need to create corresponding object based on iccType.
*/
updateIccInfo: function updateIccInfo(newInfo) {
updateIccInfo: function updateIccInfo(clientId, newInfo) {
let rilContext = this.rilContexts[clientId];
// Card is not detected, clear iccInfo to null.
if (!newInfo || !newInfo.iccType) {
this.rilContext.iccInfo = null;
if (rilContext.iccInfo) {
rilContext.iccInfo = null;
this._deliverEvent(clientId,
"_mobileConnectionListeners",
"notifyIccChanged",
null);
}
return;
}
// If iccInfo is null, new corresponding object based on iccType.
if (!this.rilContext.iccInfo) {
if (!rilContext.iccInfo) {
if (newInfo.iccType === "ruim" || newInfo.iccType === "csim") {
this.rilContext.iccInfo = new CdmaIccInfo();
rilContext.iccInfo = new CdmaIccInfo();
} else {
this.rilContext.iccInfo = new GsmIccInfo();
rilContext.iccInfo = new GsmIccInfo();
}
}
let changed = (rilContext.iccInfo.iccid != newInfo.iccid) ?
true : false;
this.updateInfo(newInfo, this.rilContext.iccInfo);
this.updateInfo(newInfo, rilContext.iccInfo);
// Deliver event after info is updated.
if (changed) {
this._deliverEvent(clientId,
"_mobileConnectionListeners",
"notifyIccChanged",
null);
}
},
_windowsMap: null,
rilContext: null,
rilContexts: null,
getRilContext: function getRilContext() {
// Update ril context by sending IPC message to chrome only when the first
getRilContext: function getRilContext(clientId) {
// Update ril contexts by sending IPC message to chrome only when the first
// time we require it. The information will be updated by following info
// changed messages.
this.getRilContext = function getRilContext() {
return this.rilContext;
this.getRilContext = function getRilContext(clientId) {
return this.rilContexts[clientId];
};
let rilContext =
cpmm.sendSyncMessage("RIL:GetRilContext", {clientId: 0})[0];
if (!rilContext) {
debug("Received null rilContext from chrome process.");
return;
for (let cId = 0; cId < this.numClients; cId++) {
let rilContext =
cpmm.sendSyncMessage("RIL:GetRilContext", {clientId: cId})[0];
if (!rilContext) {
debug("Received null rilContext from chrome process.");
continue;
}
this.rilContexts[cId].cardState = rilContext.cardState;
this.rilContexts[cId].networkSelectionMode = rilContext.networkSelectionMode;
this.updateIccInfo(cId, rilContext.iccInfo);
this.updateConnectionInfo(rilContext.voice, this.rilContexts[cId].voiceConnectionInfo);
this.updateConnectionInfo(rilContext.data, this.rilContexts[cId].dataConnectionInfo);
}
this.rilContext.cardState = rilContext.cardState;
this.rilContext.networkSelectionMode = rilContext.networkSelectionMode;
this.updateIccInfo(rilContext.iccInfo);
this.updateConnectionInfo(rilContext.voice, this.rilContext.voiceConnectionInfo);
this.updateConnectionInfo(rilContext.data, this.rilContext.dataConnectionInfo);
return this.rilContext;
return this.rilContexts[clientId];
},
/**
* nsIIccProvider
*/
get iccInfo() {
//TODO: Bug 814637 - WebIccManager API: support multiple sim cards.
let context = this.getRilContext(0);
return context && context.iccInfo;
},
get cardState() {
//TODO: Bug 814637 - WebIccManager API: support multiple sim cards.
let context = this.getRilContext(0);
return context && context.cardState;
},
/**
* nsIMobileConnectionProvider
*/
get iccInfo() {
let context = this.getRilContext();
return context && context.iccInfo;
},
get voiceConnectionInfo() {
let context = this.getRilContext();
getVoiceConnectionInfo: function getVoiceConnectionInfo(clientId) {
let context = this.getRilContext(clientId);
return context && context.voiceConnectionInfo;
},
get dataConnectionInfo() {
let context = this.getRilContext();
getDataConnectionInfo: function getDataConnectionInfo(clientId) {
let context = this.getRilContext(clientId);
return context && context.dataConnectionInfo;
},
get cardState() {
let context = this.getRilContext();
return context && context.cardState;
getIccId: function getIccId(clientId) {
let context = this.getRilContext(clientId);
return context && context.iccInfo && context.iccInfo.iccid;
},
get networkSelectionMode() {
let context = this.getRilContext();
getNetworkSelectionMode: function getNetworkSelectionMode(clientId) {
let context = this.getRilContext(clientId);
return context && context.networkSelectionMode;
},
/**
* The network that is currently trying to be selected (or "automatic").
* This helps ensure that only one network is selected at a time.
* The networks that are currently trying to be selected (or "automatic").
* This helps ensure that only one network per client is selected at a time.
*/
_selectingNetwork: null,
_selectingNetworks: null,
getNetworks: function getNetworks(window) {
getNetworks: function getNetworks(clientId, window) {
if (window == null) {
throw Components.Exception("Can't get window object",
Cr.NS_ERROR_UNEXPECTED);
@ -626,7 +669,7 @@ RILContentHelper.prototype = {
let requestId = this.getRequestId(request);
cpmm.sendAsyncMessage("RIL:GetAvailableNetworks", {
clientId: 0,
clientId: clientId,
data: {
requestId: requestId
}
@ -634,14 +677,14 @@ RILContentHelper.prototype = {
return request;
},
selectNetwork: function selectNetwork(window, network) {
selectNetwork: function selectNetwork(clientId, window, network) {
if (window == null) {
throw Components.Exception("Can't get window object",
Cr.NS_ERROR_UNEXPECTED);
}
if (this._selectingNetwork) {
throw new Error("Already selecting a network: " + this._selectingNetwork);
if (this._selectingNetworks[clientId]) {
throw new Error("Already selecting a network: " + this._selectingNetworks[clientId]);
}
if (!network) {
@ -659,8 +702,8 @@ RILContentHelper.prototype = {
let request = Services.DOMRequest.createRequest(window);
let requestId = this.getRequestId(request);
if (this.rilContext.networkSelectionMode == RIL.GECKO_NETWORK_SELECTION_MANUAL &&
this.rilContext.voiceConnectionInfo.network === network) {
if (this.rilContexts[clientId].networkSelectionMode == RIL.GECKO_NETWORK_SELECTION_MANUAL &&
this.rilContexts[clientId].voiceConnectionInfo.network === network) {
// Already manually selected this network, so schedule
// onsuccess to be fired on the next tick
@ -668,10 +711,10 @@ RILContentHelper.prototype = {
return request;
}
this._selectingNetwork = network;
this._selectingNetworks[clientId] = network;
cpmm.sendAsyncMessage("RIL:SelectNetwork", {
clientId: 0,
clientId: clientId,
data: {
requestId: requestId,
mnc: network.mnc,
@ -682,30 +725,30 @@ RILContentHelper.prototype = {
return request;
},
selectNetworkAutomatically: function selectNetworkAutomatically(window) {
selectNetworkAutomatically: function selectNetworkAutomatically(clientId, window) {
if (window == null) {
throw Components.Exception("Can't get window object",
Cr.NS_ERROR_UNEXPECTED);
}
if (this._selectingNetwork) {
throw new Error("Already selecting a network: " + this._selectingNetwork);
if (this._selectingNetworks[clientId]) {
throw new Error("Already selecting a network: " + this._selectingNetworks[clientId]);
}
let request = Services.DOMRequest.createRequest(window);
let requestId = this.getRequestId(request);
if (this.rilContext.networkSelectionMode == RIL.GECKO_NETWORK_SELECTION_AUTOMATIC) {
if (this.rilContexts[clientId].networkSelectionMode == RIL.GECKO_NETWORK_SELECTION_AUTOMATIC) {
// Already using automatic selection mode, so schedule
// onsuccess to be be fired on the next tick
this.dispatchFireRequestSuccess(requestId, null);
return request;
}
this._selectingNetwork = "automatic";
this._selectingNetworks[clientId] = "automatic";
cpmm.sendAsyncMessage("RIL:SelectNetworkAuto", {
clientId: 0,
clientId: clientId,
data: {
requestId: requestId
}
@ -713,7 +756,7 @@ RILContentHelper.prototype = {
return request;
},
setRoamingPreference: function setRoamingPreference(window, mode) {
setRoamingPreference: function setRoamingPreference(clientId, window, mode) {
if (window == null) {
throw Components.Exception("Can't get window object",
Cr.NS_ERROR_UNEXPECTED);
@ -729,7 +772,7 @@ RILContentHelper.prototype = {
}
cpmm.sendAsyncMessage("RIL:SetRoamingPreference", {
clientId: 0,
clientId: clientId,
data: {
requestId: requestId,
mode: mode
@ -738,7 +781,7 @@ RILContentHelper.prototype = {
return request;
},
getRoamingPreference: function getRoamingPreference(window) {
getRoamingPreference: function getRoamingPreference(clientId, window) {
if (window == null) {
throw Components.Exception("Can't get window object",
Cr.NS_ERROR_UNEXPECTED);
@ -748,7 +791,7 @@ RILContentHelper.prototype = {
let requestId = this.getRequestId(request);
cpmm.sendAsyncMessage("RIL:GetRoamingPreference", {
clientId: 0,
clientId: clientId,
data: {
requestId: requestId
}
@ -756,7 +799,7 @@ RILContentHelper.prototype = {
return request;
},
setVoicePrivacyMode: function setVoicePrivacyMode(window, enabled) {
setVoicePrivacyMode: function setVoicePrivacyMode(clientId, window, enabled) {
if (window == null) {
throw Components.Exception("Can't get window object",
Cr.NS_ERROR_UNEXPECTED);
@ -766,7 +809,7 @@ RILContentHelper.prototype = {
let requestId = this.getRequestId(request);
cpmm.sendAsyncMessage("RIL:SetVoicePrivacyMode", {
clientId: 0,
clientId: clientId,
data: {
requestId: requestId,
enabled: enabled
@ -775,7 +818,7 @@ RILContentHelper.prototype = {
return request;
},
getVoicePrivacyMode: function getVoicePrivacyMode(window) {
getVoicePrivacyMode: function getVoicePrivacyMode(clientId, window) {
if (window == null) {
throw Components.Exception("Can't get window object",
Cr.NS_ERROR_UNEXPECTED);
@ -785,7 +828,7 @@ RILContentHelper.prototype = {
let requestId = this.getRequestId(request);
cpmm.sendAsyncMessage("RIL:GetVoicePrivacyMode", {
clientId: 0,
clientId: clientId,
data: {
requestId: requestId
}
@ -861,7 +904,7 @@ RILContentHelper.prototype = {
return request;
},
sendMMI: function sendMMI(window, mmi) {
sendMMI: function sendMMI(clientId, window, mmi) {
debug("Sending MMI " + mmi);
if (!window) {
throw Components.Exception("Can't get window object",
@ -874,7 +917,7 @@ RILContentHelper.prototype = {
this._windowsMap[requestId] = window;
cpmm.sendAsyncMessage("RIL:SendMMI", {
clientId: 0,
clientId: clientId,
data: {
mmi: mmi,
requestId: requestId
@ -883,7 +926,7 @@ RILContentHelper.prototype = {
return request;
},
cancelMMI: function cancelMMI(window) {
cancelMMI: function cancelMMI(clientId, window) {
debug("Cancel MMI");
if (!window) {
throw Components.Exception("Can't get window object",
@ -892,7 +935,7 @@ RILContentHelper.prototype = {
let request = Services.DOMRequest.createRequest(window);
let requestId = this.getRequestId(request);
cpmm.sendAsyncMessage("RIL:CancelMMI", {
clientId: 0,
clientId: clientId,
data: {
requestId: requestId
}
@ -1086,7 +1129,7 @@ RILContentHelper.prototype = {
return request;
},
getCallForwardingOption: function getCallForwardingOption(window, reason) {
getCallForwardingOption: function getCallForwardingOption(clientId, window, reason) {
if (window == null) {
throw Components.Exception("Can't get window object",
Cr.NS_ERROR_UNEXPECTED);
@ -1100,8 +1143,8 @@ RILContentHelper.prototype = {
return request;
}
cpmm.sendAsyncMessage("RIL:GetCallForwardingOption", {
clientId: 0,
cpmm.sendAsyncMessage("RIL:GetCallForwardingOptions", {
clientId: clientId,
data: {
requestId: requestId,
reason: reason
@ -1111,7 +1154,7 @@ RILContentHelper.prototype = {
return request;
},
setCallForwardingOption: function setCallForwardingOption(window, cfInfo) {
setCallForwardingOption: function setCallForwardingOption(clientId, window, cfInfo) {
if (window == null) {
throw Components.Exception("Can't get window object",
Cr.NS_ERROR_UNEXPECTED);
@ -1127,8 +1170,8 @@ RILContentHelper.prototype = {
return request;
}
cpmm.sendAsyncMessage("RIL:SetCallForwardingOption", {
clientId: 0,
cpmm.sendAsyncMessage("RIL:SetCallForwardingOptions", {
clientId: clientId,
data: {
requestId: requestId,
active: cfInfo.active,
@ -1142,7 +1185,7 @@ RILContentHelper.prototype = {
return request;
},
getCallBarringOption: function getCallBarringOption(window, option) {
getCallBarringOption: function getCallBarringOption(clientId, window, option) {
if (window == null) {
throw Components.Exception("Can't get window object",
Cr.NS_ERROR_UNEXPECTED);
@ -1151,14 +1194,14 @@ RILContentHelper.prototype = {
let requestId = this.getRequestId(request);
if (DEBUG) debug("getCallBarringOption: " + JSON.stringify(option));
if (!this._isValidCallBarringOption(option)) {
if (!this._isValidCallBarringOptions(option)) {
this.dispatchFireRequestError(requestId,
RIL.GECKO_ERROR_INVALID_PARAMETER);
return request;
}
cpmm.sendAsyncMessage("RIL:GetCallBarringOption", {
clientId: 0,
cpmm.sendAsyncMessage("RIL:GetCallBarringOptions", {
clientId: clientId,
data: {
requestId: requestId,
program: option.program,
@ -1169,7 +1212,7 @@ RILContentHelper.prototype = {
return request;
},
setCallBarringOption: function setCallBarringOption(window, option) {
setCallBarringOption: function setCallBarringOption(clientId, window, option) {
if (window == null) {
throw Components.Exception("Can't get window object",
Cr.NS_ERROR_UNEXPECTED);
@ -1178,14 +1221,14 @@ RILContentHelper.prototype = {
let requestId = this.getRequestId(request);
if (DEBUG) debug("setCallBarringOption: " + JSON.stringify(option));
if (!this._isValidCallBarringOption(option, true)) {
if (!this._isValidCallBarringOptions(option, true)) {
this.dispatchFireRequestError(requestId,
RIL.GECKO_ERROR_INVALID_PARAMETER);
return request;
}
cpmm.sendAsyncMessage("RIL:SetCallBarringOption", {
clientId: 0,
cpmm.sendAsyncMessage("RIL:SetCallBarringOptions", {
clientId: clientId,
data: {
requestId: requestId,
program: option.program,
@ -1197,7 +1240,7 @@ RILContentHelper.prototype = {
return request;
},
changeCallBarringPassword: function changeCallBarringPassword(window, info) {
changeCallBarringPassword: function changeCallBarringPassword(clientId, window, info) {
if (window == null) {
throw Components.Exception("Can't get window object",
Cr.NS_ERROR_UNEXPECTED);
@ -1215,14 +1258,14 @@ RILContentHelper.prototype = {
if (DEBUG) debug("changeCallBarringPassword: " + JSON.stringify(info));
info.requestId = requestId;
cpmm.sendAsyncMessage("RIL:ChangeCallBarringPassword", {
clientId: 0,
clientId: clientId,
data: info
});
return request;
},
getCallWaitingOption: function getCallWaitingOption(window) {
getCallWaitingOption: function getCallWaitingOption(clientId, window) {
if (window == null) {
throw Components.Exception("Can't get window object",
Cr.NS_ERROR_UNEXPECTED);
@ -1230,8 +1273,8 @@ RILContentHelper.prototype = {
let request = Services.DOMRequest.createRequest(window);
let requestId = this.getRequestId(request);
cpmm.sendAsyncMessage("RIL:GetCallWaitingOption", {
clientId: 0,
cpmm.sendAsyncMessage("RIL:GetCallWaitingOptions", {
clientId: clientId,
data: {
requestId: requestId
}
@ -1240,7 +1283,7 @@ RILContentHelper.prototype = {
return request;
},
setCallWaitingOption: function setCallWaitingOption(window, enabled) {
setCallWaitingOption: function setCallWaitingOption(clientId, window, enabled) {
if (window == null) {
throw Components.Exception("Can't get window object",
Cr.NS_ERROR_UNEXPECTED);
@ -1248,8 +1291,8 @@ RILContentHelper.prototype = {
let request = Services.DOMRequest.createRequest(window);
let requestId = this.getRequestId(request);
cpmm.sendAsyncMessage("RIL:SetCallWaitingOption", {
clientId: 0,
cpmm.sendAsyncMessage("RIL:SetCallWaitingOptions", {
clientId: clientId,
data: {
requestId: requestId,
enabled: enabled
@ -1259,7 +1302,7 @@ RILContentHelper.prototype = {
return request;
},
getCallingLineIdRestriction: function getCallingLineIdRestriction(window) {
getCallingLineIdRestriction: function getCallingLineIdRestriction(clientId, window) {
if (window == null) {
throw Components.Exception("Can't get window object",
Cr.NS_ERROR_UNEXPECTED);
@ -1268,7 +1311,7 @@ RILContentHelper.prototype = {
let requestId = this.getRequestId(request);
cpmm.sendAsyncMessage("RIL:GetCallingLineIdRestriction", {
clientId: 0,
clientId: clientId,
data: {
requestId: requestId
}
@ -1278,7 +1321,7 @@ RILContentHelper.prototype = {
},
setCallingLineIdRestriction:
function setCallingLineIdRestriction(window, clirMode) {
function setCallingLineIdRestriction(clientId, window, clirMode) {
if (window == null) {
throw Components.Exception("Can't get window object",
@ -1288,7 +1331,7 @@ RILContentHelper.prototype = {
let requestId = this.getRequestId(request);
cpmm.sendAsyncMessage("RIL:SetCallingLineIdRestriction", {
clientId: 0,
clientId: clientId,
data: {
requestId: requestId,
clirMode: clirMode
@ -1298,7 +1341,7 @@ RILContentHelper.prototype = {
return request;
},
exitEmergencyCbMode: function exitEmergencyCbMode(window) {
exitEmergencyCbMode: function exitEmergencyCbMode(clientId, window) {
if (window == null) {
throw Components.Exception("Can't get window object",
Cr.NS_ERROR_UNEXPECTED);
@ -1307,7 +1350,7 @@ RILContentHelper.prototype = {
let requestId = this.getRequestId(request);
cpmm.sendAsyncMessage("RIL:ExitEmergencyCbMode", {
clientId: 0,
clientId: clientId,
data: {
requestId: requestId,
}
@ -1357,10 +1400,13 @@ RILContentHelper.prototype = {
return this.getVoicemailInfo().displayName;
},
registerListener: function registerListener(listenerType, listener) {
let listeners = this[listenerType];
registerListener: function registerListener(listenerType, clientId, listener) {
if (!this[listenerType]) {
return;
}
let listeners = this[listenerType][clientId];
if (!listeners) {
listeners = this[listenerType] = [];
listeners = this[listenerType][clientId] = [];
}
if (listeners.indexOf(listener) != -1) {
@ -1371,8 +1417,11 @@ RILContentHelper.prototype = {
if (DEBUG) debug("Registered " + listenerType + " listener: " + listener);
},
unregisterListener: function unregisterListener(listenerType, listener) {
let listeners = this[listenerType];
unregisterListener: function unregisterListener(listenerType, clientId, listener) {
if (!this[listenerType]) {
return;
}
let listeners = this[listenerType][clientId];
if (!listeners) {
return;
}
@ -1384,44 +1433,50 @@ RILContentHelper.prototype = {
}
},
registerMobileConnectionMsg: function registerMobileConnectionMsg(listener) {
registerMobileConnectionMsg: function registerMobileConnectionMsg(clientId, listener) {
debug("Registering for mobile connection related messages");
this.registerListener("_mobileConnectionListeners", listener);
this.registerListener("_mobileConnectionListeners", clientId, listener);
cpmm.sendAsyncMessage("RIL:RegisterMobileConnectionMsg");
},
unregisterMobileConnectionMsg: function unregisteMobileConnectionMsg(listener) {
this.unregisterListener("_mobileConnectionListeners", listener);
unregisterMobileConnectionMsg: function unregisteMobileConnectionMsg(clientId, listener) {
this.unregisterListener("_mobileConnectionListeners", clientId, listener);
},
registerVoicemailMsg: function registerVoicemailMsg(listener) {
debug("Registering for voicemail-related messages");
this.registerListener("_voicemailListeners", listener);
//TODO: Bug 814634 - WebVoicemail API: support multiple sim cards.
this.registerListener("_voicemailListeners", 0, listener);
cpmm.sendAsyncMessage("RIL:RegisterVoicemailMsg");
},
unregisterVoicemailMsg: function unregisteVoicemailMsg(listener) {
this.unregisterListener("_voicemailListeners", listener);
//TODO: Bug 814634 - WebVoicemail API: support multiple sim cards.
this.unregisterListener("_voicemailListeners", 0, listener);
},
registerCellBroadcastMsg: function registerCellBroadcastMsg(listener) {
debug("Registering for Cell Broadcast related messages");
this.registerListener("_cellBroadcastListeners", listener);
//TODO: Bug 921326 - Cellbroadcast API: support multiple sim cards
this.registerListener("_cellBroadcastListeners", 0, listener);
cpmm.sendAsyncMessage("RIL:RegisterCellBroadcastMsg");
},
unregisterCellBroadcastMsg: function unregisterCellBroadcastMsg(listener) {
this.unregisterListener("_cellBroadcastListeners", listener);
//TODO: Bug 921326 - Cellbroadcast API: support multiple sim cards
this.unregisterListener("_cellBroadcastListeners", 0, listener);
},
registerIccMsg: function registerIccMsg(listener) {
debug("Registering for ICC related messages");
this.registerListener("_iccListeners", listener);
//TODO: Bug 814637 - WebIccManager API: support multiple sim cards.
this.registerListener("_iccListeners", 0, listener);
cpmm.sendAsyncMessage("RIL:RegisterIccMsg");
},
unregisterIccMsg: function unregisterIccMsg(listener) {
this.unregisterListener("_iccListeners", listener);
//TODO: Bug 814637 - WebIccManager API: support multiple sim cards.
this.unregisterListener("_iccListeners", 0, listener);
},
// nsIObserver
@ -1511,35 +1566,43 @@ RILContentHelper.prototype = {
debug("Received message '" + msg.name + "': " + JSON.stringify(msg.json));
let data = msg.json.data;
let clientId = msg.json.clientId;
switch (msg.name) {
case "RIL:CardStateChanged":
if (this.rilContext.cardState != data.cardState) {
this.rilContext.cardState = data.cardState;
this._deliverEvent("_iccListeners",
if (this.rilContexts[clientId].cardState != data.cardState) {
this.rilContexts[clientId].cardState = data.cardState;
this._deliverEvent(clientId,
"_iccListeners",
"notifyCardStateChanged",
null);
}
break;
case "RIL:IccInfoChanged":
this.updateIccInfo(data);
this._deliverEvent("_iccListeners", "notifyIccInfoChanged", null);
this.updateIccInfo(clientId, data);
this._deliverEvent(clientId,
"_iccListeners",
"notifyIccInfoChanged",
null);
break;
case "RIL:VoiceInfoChanged":
this.updateConnectionInfo(data,
this.rilContext.voiceConnectionInfo);
this._deliverEvent("_mobileConnectionListeners",
this.rilContexts[clientId].voiceConnectionInfo);
this._deliverEvent(clientId,
"_mobileConnectionListeners",
"notifyVoiceChanged",
null);
break;
case "RIL:DataInfoChanged":
this.updateConnectionInfo(data,
this.rilContext.dataConnectionInfo);
this._deliverEvent("_mobileConnectionListeners",
this.rilContexts[clientId].dataConnectionInfo);
this._deliverEvent(clientId,
"_mobileConnectionListeners",
"notifyDataChanged",
null);
break;
case "RIL:OtaStatusChanged":
this._deliverEvent("_mobileConnectionListeners",
this._deliverEvent(clientId,
"_mobileConnectionListeners",
"notifyOtaStatusChanged",
[data]);
break;
@ -1547,18 +1610,18 @@ RILContentHelper.prototype = {
this.handleGetAvailableNetworks(data);
break;
case "RIL:NetworkSelectionModeChanged":
this.rilContext.networkSelectionMode = data.mode;
this.rilContexts[clientId].networkSelectionMode = data.mode;
break;
case "RIL:SelectNetwork":
this.handleSelectNetwork(data,
this.handleSelectNetwork(clientId, data,
RIL.GECKO_NETWORK_SELECTION_MANUAL);
break;
case "RIL:SelectNetworkAuto":
this.handleSelectNetwork(data,
this.handleSelectNetwork(clientId, data,
RIL.GECKO_NETWORK_SELECTION_AUTOMATIC);
break;
case "RIL:VoicemailNotification":
this.handleVoicemailNotification(data);
this.handleVoicemailNotification(clientId, data);
break;
case "RIL:VoicemailInfoChanged":
this.updateInfo(data, this.voicemailInfo);
@ -1593,7 +1656,8 @@ RILContentHelper.prototype = {
}
break;
case "RIL:USSDReceived":
this._deliverEvent("_mobileConnectionListeners",
this._deliverEvent(clientId,
"_mobileConnectionListeners",
"notifyUssdReceived",
[data.message, data.sessionEnded]);
break;
@ -1602,11 +1666,11 @@ RILContentHelper.prototype = {
this.handleSendCancelMMI(data);
break;
case "RIL:StkCommand":
this._deliverEvent("_iccListeners", "notifyStkCommand",
this._deliverEvent(clientId, "_iccListeners", "notifyStkCommand",
[JSON.stringify(data)]);
break;
case "RIL:StkSessionEnd":
this._deliverEvent("_iccListeners", "notifyStkSessionEnd", null);
this._deliverEvent(clientId, "_iccListeners", "notifyStkSessionEnd", null);
break;
case "RIL:IccOpenChannel":
this.handleSimpleRequest(data.requestId, data.errorMsg,
@ -1625,34 +1689,35 @@ RILContentHelper.prototype = {
this.handleSimpleRequest(data.requestId, data.errorMsg, null);
break;
case "RIL:DataError":
this.updateConnectionInfo(data, this.rilContext.dataConnectionInfo);
this._deliverEvent("_mobileConnectionListeners", "notifyDataError",
this.updateConnectionInfo(data, this.rilContexts[clientId].dataConnectionInfo);
this._deliverEvent(clientId, "_mobileConnectionListeners", "notifyDataError",
[data.errorMsg]);
break;
case "RIL:GetCallForwardingOption":
this.handleGetCallForwardingOption(data);
case "RIL:GetCallForwardingOptions":
this.handleGetCallForwardingOptions(data);
break;
case "RIL:SetCallForwardingOption":
case "RIL:SetCallForwardingOptions":
this.handleSimpleRequest(data.requestId, data.errorMsg, null);
break;
case "RIL:GetCallBarringOption":
this.handleGetCallBarringOption(data);
case "RIL:GetCallBarringOptions":
this.handleGetCallBarringOptions(data);
break;
case "RIL:SetCallBarringOption":
case "RIL:SetCallBarringOptions":
this.handleSimpleRequest(data.requestId, data.errorMsg, null);
break;
case "RIL:ChangeCallBarringPassword":
this.handleSimpleRequest(data.requestId, data.errorMsg, null);
break;
case "RIL:GetCallWaitingOption":
case "RIL:GetCallWaitingOptions":
this.handleSimpleRequest(data.requestId, data.errorMsg,
data.enabled);
break;
case "RIL:SetCallWaitingOption":
case "RIL:SetCallWaitingOptions":
this.handleSimpleRequest(data.requestId, data.errorMsg, null);
break;
case "RIL:CfStateChanged":
this._deliverEvent("_mobileConnectionListeners",
this._deliverEvent(clientId,
"_mobileConnectionListeners",
"notifyCFStateChange",
[data.success, data.action,
data.reason, data.number,
@ -1666,7 +1731,8 @@ RILContentHelper.prototype = {
break;
case "RIL:CellBroadcastReceived": {
let message = new CellBroadcastMessage(data);
this._deliverEvent("_cellBroadcastListeners",
this._deliverEvent(clientId,
"_cellBroadcastListeners",
"notifyMessageReceived",
[message]);
break;
@ -1682,7 +1748,8 @@ RILContentHelper.prototype = {
this.handleExitEmergencyCbMode(data);
break;
case "RIL:EmergencyCbModeChanged":
this._deliverEvent("_mobileConnectionListeners",
this._deliverEvent(clientId,
"_mobileConnectionListeners",
"notifyEmergencyCbModeChanged",
[data.active, data.timeoutMs]);
break;
@ -1723,9 +1790,9 @@ RILContentHelper.prototype = {
this.fireRequestSuccess(message.requestId, networks);
},
handleSelectNetwork: function handleSelectNetwork(message, mode) {
this._selectingNetwork = null;
this.rilContext.networkSelectionMode = mode;
handleSelectNetwork: function handleSelectNetwork(clientId, message, mode) {
this._selectingNetworks[clientId] = null;
this.rilContexts[clientId].networkSelectionMode = mode;
if (message.errorMsg) {
this.fireRequestError(message.requestId, message.errorMsg);
@ -1773,7 +1840,8 @@ RILContentHelper.prototype = {
this.fireRequestSuccess(message.requestId, result);
},
handleVoicemailNotification: function handleVoicemailNotification(message) {
handleVoicemailNotification: function handleVoicemailNotification(clientId, message) {
// Bug 814634 - WebVoicemail API: support multiple sim cards
let changed = false;
if (!this.voicemailStatus) {
this.voicemailStatus = new VoicemailStatus();
@ -1803,7 +1871,8 @@ RILContentHelper.prototype = {
}
if (changed) {
this._deliverEvent("_voicemailListeners",
this._deliverEvent(clientId,
"_voicemailListeners",
"notifyStatusChanged",
[this.voicemailStatus]);
}
@ -1818,7 +1887,7 @@ RILContentHelper.prototype = {
}
},
handleGetCallForwardingOption: function handleGetCallForwardingOption(message) {
handleGetCallForwardingOptions: function handleGetCallForwardingOptions(message) {
if (message.errorMsg) {
this.fireRequestError(message.requestId, message.errorMsg);
return;
@ -1828,12 +1897,12 @@ RILContentHelper.prototype = {
this.fireRequestSuccess(message.requestId, message.rules);
},
handleGetCallBarringOption: function handleGetCallBarringOption(message) {
handleGetCallBarringOptions: function handleGetCallBarringOptions(message) {
if (!message.success) {
this.fireRequestError(message.requestId, message.errorMsg);
} else {
let option = new CallBarringOption(message);
this.fireRequestSuccess(message.requestId, option);
let options = new CallBarringOptions(message);
this.fireRequestSuccess(message.requestId, options);
}
},
@ -1909,8 +1978,11 @@ RILContentHelper.prototype = {
}
},
_deliverEvent: function _deliverEvent(listenerType, name, args) {
let thisListeners = this[listenerType];
_deliverEvent: function _deliverEvent(clientId, listenerType, name, args) {
if (!this[listenerType]) {
return;
}
let thisListeners = this[listenerType][clientId];
if (!thisListeners) {
return;
}
@ -1981,18 +2053,18 @@ RILContentHelper.prototype = {
},
/**
* Helper for guarding us against invalid option for call barring.
* Helper for guarding us against invalid options for call barring.
*/
_isValidCallBarringOption:
function _isValidCallBarringOption(option, usedForSetting) {
if (!option ||
option.serviceClass == null ||
!this._isValidCallBarringProgram(option.program)) {
_isValidCallBarringOptions:
function _isValidCallBarringOptions(options, usedForSetting) {
if (!options ||
options.serviceClass == null ||
!this._isValidCallBarringProgram(options.program)) {
return false;
}
// For setting callbarring option, |enabled| and |password| are required.
if (usedForSetting && (option.enabled == null || option.password == null)) {
// For setting callbarring options, |enabled| and |password| are required.
if (usedForSetting && (options.enabled == null || options.password == null)) {
return false;
}

Просмотреть файл

@ -94,13 +94,13 @@ const RIL_IPC_MOBILECONNECTION_MSG_NAMES = [
"RIL:SendMMI",
"RIL:CancelMMI",
"RIL:RegisterMobileConnectionMsg",
"RIL:SetCallForwardingOption",
"RIL:GetCallForwardingOption",
"RIL:SetCallBarringOption",
"RIL:GetCallBarringOption",
"RIL:SetCallForwardingOptions",
"RIL:GetCallForwardingOptions",
"RIL:SetCallBarringOptions",
"RIL:GetCallBarringOptions",
"RIL:ChangeCallBarringPassword",
"RIL:SetCallWaitingOption",
"RIL:GetCallWaitingOption",
"RIL:SetCallWaitingOptions",
"RIL:GetCallWaitingOptions",
"RIL:SetCallingLineIdRestriction",
"RIL:GetCallingLineIdRestriction",
"RIL:SetRoamingPreference",
@ -946,25 +946,25 @@ RadioInterface.prototype = {
case "RIL:UpdateIccContact":
this.workerMessenger.sendWithIPCMessage(msg, "updateICCContact");
break;
case "RIL:SetCallForwardingOption":
this.setCallForwardingOption(msg.target, msg.json.data);
case "RIL:SetCallForwardingOptions":
this.setCallForwardingOptions(msg.target, msg.json.data);
break;
case "RIL:GetCallForwardingOption":
case "RIL:GetCallForwardingOptions":
this.workerMessenger.sendWithIPCMessage(msg, "queryCallForwardStatus");
break;
case "RIL:SetCallBarringOption":
case "RIL:SetCallBarringOptions":
this.workerMessenger.sendWithIPCMessage(msg, "setCallBarring");
break;
case "RIL:GetCallBarringOption":
case "RIL:GetCallBarringOptions":
this.workerMessenger.sendWithIPCMessage(msg, "queryCallBarringStatus");
break;
case "RIL:ChangeCallBarringPassword":
this.workerMessenger.sendWithIPCMessage(msg, "changeCallBarringPassword");
break;
case "RIL:SetCallWaitingOption":
case "RIL:SetCallWaitingOptions":
this.workerMessenger.sendWithIPCMessage(msg, "setCallWaiting");
break;
case "RIL:GetCallWaitingOption":
case "RIL:GetCallWaitingOptions":
this.workerMessenger.sendWithIPCMessage(msg, "queryCallWaiting");
break;
case "RIL:SetCallingLineIdRestriction":
@ -2200,13 +2200,28 @@ RadioInterface.prototype = {
break;
case kNetworkInterfaceStateChangedTopic:
let network = subject.QueryInterface(Ci.nsINetworkInterface);
if (network.state == Ci.nsINetworkInterface.NETWORK_STATE_CONNECTED) {
// Check SNTP when we have data connection, this may not take
// effect immediately before the setting get enabled.
if (this._sntp.isExpired()) {
this._sntp.request();
if (network.state != Ci.nsINetworkInterface.NETWORK_STATE_CONNECTED) {
return;
}
// SNTP can only update when we have mobile or Wifi connections.
if (network.type != Ci.nsINetworkInterface.NETWORK_TYPE_WIFI &&
network.type != Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE) {
return;
}
// If the network comes from RIL, make sure the RIL service is matched.
if (subject instanceof Ci.nsIRilNetworkInterface) {
network = subject.QueryInterface(Ci.nsIRilNetworkInterface);
if (network.serviceId != this.clientId) {
return;
}
}
// SNTP won't update unless the SNTP is already expired.
if (this._sntp.isExpired()) {
this._sntp.request();
}
break;
case kScreenStateChangedTopic:
this.workerMessenger.send("setScreenState", { on: (data === "on") });
@ -2418,12 +2433,12 @@ RadioInterface.prototype = {
}).bind(this));
},
setCallForwardingOption: function setCallForwardingOption(target, message) {
if (DEBUG) this.debug("setCallForwardingOption: " + JSON.stringify(message));
setCallForwardingOptions: function setCallForwardingOptions(target, message) {
if (DEBUG) this.debug("setCallForwardingOptions: " + JSON.stringify(message));
message.serviceClass = RIL.ICC_SERVICE_CLASS_VOICE;
this.workerMessenger.send("setCallForward", message, (function(response) {
this._sendCfStateChanged(response);
target.sendAsyncMessage("RIL:SetCallForwardingOption", {
target.sendAsyncMessage("RIL:SetCallForwardingOptions", {
clientId: this.clientId,
data: response
});

Просмотреть файл

@ -24,13 +24,13 @@
#include "jsfriendapi.h"
#include "mozilla/dom/workers/Workers.h"
#ifdef MOZ_WIDGET_GONK
#include "mozilla/ipc/Netd.h"
#include "AutoMounter.h"
#include "TimeZoneSettingObserver.h"
#include "AudioManager.h"
#endif
#ifdef MOZ_B2G_RIL
#include "mozilla/ipc/Ril.h"
#endif
#include "mozilla/ipc/KeyStore.h"
#include "nsIObserverService.h"
#include "nsCxPusher.h"
@ -44,9 +44,7 @@ USING_WORKERS_NAMESPACE
using namespace mozilla::dom::gonk;
using namespace mozilla::ipc;
#ifdef MOZ_WIDGET_GONK
using namespace mozilla::system;
#endif
#define NS_NETWORKMANAGER_CID \
{ 0x33901e46, 0x33b8, 0x11e1, \
@ -60,107 +58,6 @@ NS_DEFINE_CID(kNetworkManagerCID, NS_NETWORKMANAGER_CID);
// Doesn't carry a reference, we're owned by services.
SystemWorkerManager *gInstance = nullptr;
class ConnectWorkerToRIL : public WorkerTask
{
public:
ConnectWorkerToRIL()
{ }
virtual bool RunTask(JSContext *aCx);
};
class SendRilSocketDataTask : public nsRunnable
{
public:
SendRilSocketDataTask(unsigned long aClientId,
UnixSocketRawData *aRawData)
: mRawData(aRawData)
, mClientId(aClientId)
{ }
NS_IMETHOD Run()
{
MOZ_ASSERT(NS_IsMainThread());
SystemWorkerManager::SendRilRawData(mClientId, mRawData);
return NS_OK;
}
private:
UnixSocketRawData *mRawData;
unsigned long mClientId;
};
bool
PostToRIL(JSContext *cx, unsigned argc, JS::Value *vp)
{
NS_ASSERTION(!NS_IsMainThread(), "Expecting to be on the worker thread");
if (argc != 2) {
JS_ReportError(cx, "Expecting two arguments with the RIL message");
return false;
}
JS::Value cv = JS_ARGV(cx, vp)[0];
int clientId = cv.toInt32();
JS::Value v = JS_ARGV(cx, vp)[1];
JSAutoByteString abs;
void *data;
size_t size;
if (JSVAL_IS_STRING(v)) {
JSString *str = JSVAL_TO_STRING(v);
if (!abs.encodeUtf8(cx, str)) {
return false;
}
data = abs.ptr();
size = abs.length();
} else if (!JSVAL_IS_PRIMITIVE(v)) {
JSObject *obj = JSVAL_TO_OBJECT(v);
if (!JS_IsTypedArrayObject(obj)) {
JS_ReportError(cx, "Object passed in wasn't a typed array");
return false;
}
uint32_t type = JS_GetArrayBufferViewType(obj);
if (type != js::ArrayBufferView::TYPE_INT8 &&
type != js::ArrayBufferView::TYPE_UINT8 &&
type != js::ArrayBufferView::TYPE_UINT8_CLAMPED) {
JS_ReportError(cx, "Typed array data is not octets");
return false;
}
size = JS_GetTypedArrayByteLength(obj);
data = JS_GetArrayBufferViewData(obj);
} else {
JS_ReportError(cx,
"Incorrect argument. Expecting a string or a typed array");
return false;
}
UnixSocketRawData* raw = new UnixSocketRawData(data, size);
nsRefPtr<SendRilSocketDataTask> task = new SendRilSocketDataTask(clientId, raw);
NS_DispatchToMainThread(task);
return true;
}
bool
ConnectWorkerToRIL::RunTask(JSContext *aCx)
{
// Set up the postRILMessage on the function for worker -> RIL thread
// communication.
NS_ASSERTION(!NS_IsMainThread(), "Expecting to be on the worker thread");
NS_ASSERTION(!JS_IsRunning(aCx), "Are we being called somehow?");
JSObject *workerGlobal = JS::CurrentGlobalOrNull(aCx);
return !!JS_DefineFunction(aCx, workerGlobal, "postRILMessage", PostToRIL, 1,
0);
}
#ifdef MOZ_WIDGET_GONK
bool
DoNetdCommand(JSContext *cx, unsigned argc, JS::Value *vp)
{
@ -306,8 +203,6 @@ NetdReceiver::DispatchNetdEvent::RunTask(JSContext *aCx)
argv, argv);
}
#endif // MOZ_WIDGET_GONK
} // anonymous namespace
SystemWorkerManager::SystemWorkerManager()
@ -345,14 +240,12 @@ SystemWorkerManager::Init()
InitKeyStore(cx);
#ifdef MOZ_WIDGET_GONK
InitAutoMounter();
InitializeTimeZoneSettingObserver();
rv = InitNetd(cx);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIAudioManager> audioManager =
do_GetService(NS_AUDIOMANAGER_CONTRACTID);
#endif
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
if (!obs) {
@ -376,21 +269,14 @@ SystemWorkerManager::Shutdown()
mShutdown = true;
#ifdef MOZ_WIDGET_GONK
ShutdownAutoMounter();
#ifdef MOZ_B2G_RIL
RilConsumer::Shutdown();
#endif
for (unsigned long i = 0; i < mRilConsumers.Length(); i++) {
if (mRilConsumers[i]) {
mRilConsumers[i]->Shutdown();
mRilConsumers[i] = nullptr;
}
}
#ifdef MOZ_WIDGET_GONK
StopNetd();
mNetdWorker = nullptr;
#endif
nsCOMPtr<nsIWifi> wifi(do_QueryInterface(mWifiWorker));
if (wifi) {
@ -433,20 +319,6 @@ SystemWorkerManager::GetInterfaceRequestor()
return gInstance;
}
bool
SystemWorkerManager::SendRilRawData(unsigned long aClientId,
UnixSocketRawData* aRaw)
{
if ((gInstance->mRilConsumers.Length() <= aClientId) ||
!gInstance->mRilConsumers[aClientId] ||
gInstance->mRilConsumers[aClientId]->GetConnectionStatus() != SOCKET_CONNECTED) {
// Probably shuting down.
delete aRaw;
return true;
}
return gInstance->mRilConsumers[aClientId]->SendSocketData(aRaw);
}
NS_IMETHODIMP
SystemWorkerManager::GetInterface(const nsIID &aIID, void **aResult)
{
@ -457,12 +329,10 @@ SystemWorkerManager::GetInterface(const nsIID &aIID, void **aResult)
reinterpret_cast<nsIWifi**>(aResult));
}
#ifdef MOZ_WIDGET_GONK
if (aIID.Equals(NS_GET_IID(nsINetworkManager))) {
return CallQueryInterface(mNetdWorker,
reinterpret_cast<nsINetworkManager**>(aResult));
}
#endif
NS_WARNING("Got nothing for the requested IID!");
return NS_ERROR_NO_INTERFACE;
@ -473,15 +343,11 @@ SystemWorkerManager::RegisterRilWorker(unsigned int aClientId,
const JS::Value& aWorker,
JSContext *aCx)
{
#ifndef MOZ_B2G_RIL
return NS_ERROR_NOT_IMPLEMENTED;
#else
NS_ENSURE_TRUE(!JSVAL_IS_PRIMITIVE(aWorker), NS_ERROR_UNEXPECTED);
mRilConsumers.EnsureLengthAtLeast(aClientId + 1);
if (mRilConsumers[aClientId]) {
NS_WARNING("RilConsumer already registered");
return NS_ERROR_FAILURE;
}
JSAutoCompartment ac(aCx, JSVAL_TO_OBJECT(aWorker));
WorkerCrossThreadDispatcher *wctd =
@ -491,18 +357,10 @@ SystemWorkerManager::RegisterRilWorker(unsigned int aClientId,
return NS_ERROR_FAILURE;
}
nsRefPtr<ConnectWorkerToRIL> connection = new ConnectWorkerToRIL();
if (!wctd->PostTask(connection)) {
NS_WARNING("Failed to connect worker to ril");
return NS_ERROR_UNEXPECTED;
}
// Now that we're set up, connect ourselves to the RIL thread.
mRilConsumers[aClientId] = new RilConsumer(aClientId, wctd);
return NS_OK;
return RilConsumer::Register(aClientId, wctd);
#endif // MOZ_B2G_RIL
}
#ifdef MOZ_WIDGET_GONK
nsresult
SystemWorkerManager::InitNetd(JSContext *cx)
{
@ -535,7 +393,6 @@ SystemWorkerManager::InitNetd(JSContext *cx)
mNetdWorker = worker;
return NS_OK;
}
#endif
nsresult
SystemWorkerManager::InitWifi(JSContext *cx)

Просмотреть файл

@ -23,18 +23,13 @@
#include "nsIObserver.h"
#include "nsAutoPtr.h"
#include "nsCOMPtr.h"
#include "nsDebug.h"
#include "nsDOMEventTargetHelper.h"
#include "nsString.h"
#include "nsTArray.h"
#include "nsXULAppAPI.h" // For XRE_GetProcessType
class nsIWorkerHolder;
namespace mozilla {
namespace ipc {
class RilConsumer;
class UnixSocketRawData;
class KeyStore;
}
@ -60,25 +55,17 @@ public:
static nsIInterfaceRequestor*
GetInterfaceRequestor();
static bool SendRilRawData(unsigned long aClientId,
ipc::UnixSocketRawData* aRaw);
private:
SystemWorkerManager();
~SystemWorkerManager();
#ifdef MOZ_WIDGET_GONK
nsresult InitNetd(JSContext *cx);
#endif
nsresult InitWifi(JSContext *cx);
nsresult InitKeyStore(JSContext *cx);
#ifdef MOZ_WIDGET_GONK
nsCOMPtr<nsIWorkerHolder> mNetdWorker;
#endif
nsCOMPtr<nsIWorkerHolder> mWifiWorker;
nsTArray<nsRefPtr<ipc::RilConsumer> > mRilConsumers;
nsRefPtr<ipc::KeyStore> mKeyStore;
bool mShutdown;

Просмотреть файл

@ -18,7 +18,6 @@ XPIDL_SOURCES += [
'nsIAudioManager.idl',
'nsINetworkInterfaceListService.idl',
'nsINetworkManager.idl',
'nsIRadioInterfaceLayer.idl',
'nsISystemWorkerManager.idl',
'nsIVolume.idl',
'nsIVolumeMountLock.idl',
@ -31,55 +30,61 @@ XPIDL_MODULE = 'dom_system_gonk'
MODULE = 'dom'
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk':
EXPORTS += [
'GonkGPSGeolocationProvider.h',
'nsVolume.h',
'nsVolumeService.h',
]
SOURCES += [
'AudioChannelManager.cpp',
'AudioManager.cpp',
'AutoMounter.cpp',
'AutoMounterSetting.cpp',
'GonkGPSGeolocationProvider.cpp',
'nsVolume.cpp',
'nsVolumeMountLock.cpp',
'nsVolumeService.cpp',
'nsVolumeStat.cpp',
'OpenFileFinder.cpp',
'TimeZoneSettingObserver.cpp',
'Volume.cpp',
'VolumeCommand.cpp',
'VolumeManager.cpp',
'VolumeServiceIOThread.cpp',
'VolumeServiceTest.cpp',
]
EXPORTS += [
'GonkGPSGeolocationProvider.h',
'nsVolume.h',
'nsVolumeService.h',
]
SOURCES += [
'AudioChannelManager.cpp',
'AudioManager.cpp',
'AutoMounter.cpp',
'AutoMounterSetting.cpp',
'GonkGPSGeolocationProvider.cpp',
'nsVolume.cpp',
'nsVolumeMountLock.cpp',
'nsVolumeService.cpp',
'nsVolumeStat.cpp',
'OpenFileFinder.cpp',
'SystemWorkerManager.cpp',
'TimeZoneSettingObserver.cpp',
'Volume.cpp',
'VolumeCommand.cpp',
'VolumeManager.cpp',
'VolumeServiceIOThread.cpp',
'VolumeServiceTest.cpp',
]
if CONFIG['ENABLE_TESTS']:
XPCSHELL_TESTS_MANIFESTS += ['tests/xpcshell.ini']
SOURCES += [
'SystemWorkerManager.cpp',
]
EXTRA_COMPONENTS += [
'NetworkInterfaceListService.js',
'NetworkInterfaceListService.manifest',
'NetworkManager.js',
'NetworkManager.manifest',
'RadioInterfaceLayer.js',
'RadioInterfaceLayer.manifest',
'RILContentHelper.js',
]
EXTRA_PP_COMPONENTS += [
'NetworkManager.js',
]
EXTRA_JS_MODULES += [
'net_worker.js',
'ril_consts.js',
'ril_worker.js',
'systemlibs.js',
]
if CONFIG['MOZ_B2G_RIL']:
XPIDL_SOURCES += [
'nsIRadioInterfaceLayer.idl',
]
EXTRA_COMPONENTS += [
'RadioInterfaceLayer.js',
'RadioInterfaceLayer.manifest',
'RILContentHelper.js',
]
EXTRA_JS_MODULES += [
'ril_consts.js',
'ril_worker.js',
]
FAIL_ON_WARNINGS = True
LIBXUL_LIBRARY = True

Просмотреть файл

@ -14,8 +14,7 @@ elif toolkit == 'cocoa':
DIRS += ['mac']
elif toolkit == 'android':
DIRS += ['android']
if CONFIG['MOZ_B2G_RIL']:
elif toolkit == 'gonk':
DIRS += ['gonk']
TEST_DIRS += ['tests']

Просмотреть файл

@ -4,7 +4,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/dom/telephony/TelephonyFactory.h"
#ifdef MOZ_WIDGET_GONK
#if defined(MOZ_WIDGET_GONK) && defined(MOZ_B2G_RIL)
#include "nsIGonkTelephonyProvider.h"
#endif
#include "nsServiceManagerUtils.h"
@ -20,7 +20,7 @@ TelephonyFactory::CreateTelephonyProvider()
if (XRE_GetProcessType() == GeckoProcessType_Content) {
provider = new TelephonyIPCProvider();
#ifdef MOZ_WIDGET_GONK
#if defined(MOZ_WIDGET_GONK) && defined(MOZ_B2G_RIL)
} else {
provider = do_CreateInstance(GONK_TELEPHONY_PROVIDER_CONTRACTID);
#endif

Просмотреть файл

@ -45,7 +45,7 @@ IPDL_SOURCES += [
'ipc/TelephonyTypes.ipdlh'
]
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk':
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk' and CONFIG['MOZ_B2G_RIL']:
XPIDL_SOURCES += [
'nsIGonkTelephonyProvider.idl',
]

Просмотреть файл

@ -5,3 +5,4 @@ support-files =
[test_notification_basics.html]
[test_notification_storage.html]
[test_bug931307.html]

Просмотреть файл

@ -0,0 +1,31 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<html>
<head>
<title>Bug 931307</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<pre id="test">
<script type="application/javascript"><!--
SimpleTest.waitForExplicitFinish();
new Notification("");
var promise = Notification.get();
promise.then(
function onSuccess() {
ok(true, "No crash!");
SimpleTest.finish();
},
function onFailure() {
ok(false, "Should not get an error in promise callback");
}
);
</script>
</pre>
</body>
</html>

Просмотреть файл

@ -5,5 +5,5 @@
PARALLEL_DIRS += ['interfaces', 'src']
if CONFIG['MOZ_B2G_RIL'] and CONFIG['ENABLE_TESTS']:
if CONFIG['ENABLE_TESTS']:
XPCSHELL_TESTS_MANIFESTS += ['tests/xpcshell.ini']

Просмотреть файл

@ -4,7 +4,7 @@
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
if CONFIG['MOZ_B2G_RIL']:
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk' and CONFIG['MOZ_B2G_RIL']:
EXTRA_JS_MODULES = [
'gonk/CpPduHelper.jsm',
'gonk/SiPduHelper.jsm',

Просмотреть файл

@ -136,6 +136,22 @@ interface CameraControl {
attribute CameraRecorderStateChange? onRecorderStateChange;
attribute CameraPreviewStateChange? onPreviewStateChange;
/* the size of the picture to be returned by a call to takePicture();
an object with 'height' and 'width' properties that corresponds to
one of the options returned by capabilities.pictureSizes. */
[Throws]
attribute any pictureSize;
/* the size of the thumbnail to be included in the picture returned
by a call to takePicture(), assuming the chose fileFormat supports
one; an object with 'height' and 'width' properties that corresponds
to one of the options returned by capabilities.pictureSizes.
this setting should be considered a hint: the implementation will
respect it when possible, and override it if necessary. */
[Throws]
attribute any thumbnailSize;
/* tell the camera to attempt to focus the image */
[Throws]
void autoFocus(CameraAutoFocusCallback onSuccess, optional CameraErrorCallback onError);

Просмотреть файл

@ -7,11 +7,11 @@
[ChromeOnly, Constructor, JSImplementation="@mozilla.org/contactAddress;1"]
interface ContactAddress {
attribute object? type; // DOMString[]
attribute DOMString? streetAddress;
attribute DOMString? locality;
attribute DOMString? region;
attribute DOMString? postalCode;
attribute DOMString? countryName;
[TreatUndefinedAs=Null] attribute DOMString? streetAddress;
[TreatUndefinedAs=Null] attribute DOMString? locality;
[TreatUndefinedAs=Null] attribute DOMString? region;
[TreatUndefinedAs=Null] attribute DOMString? postalCode;
[TreatUndefinedAs=Null] attribute DOMString? countryName;
attribute boolean? pref;
[ChromeOnly]
@ -26,19 +26,19 @@ interface ContactAddress {
dictionary ContactAddressInit {
sequence<DOMString>? type;
DOMString? streetAddress;
DOMString? locality;
DOMString? region;
DOMString? postalCode;
DOMString? countryName;
boolean? pref;
DOMString? streetAddress;
DOMString? locality;
DOMString? region;
DOMString? postalCode;
DOMString? countryName;
boolean? pref;
};
[ChromeOnly, Constructor, JSImplementation="@mozilla.org/contactField;1"]
interface ContactField {
attribute object? type; // DOMString[]
attribute DOMString? value;
[TreatUndefinedAs=Null] attribute DOMString? value;
attribute boolean? pref;
[ChromeOnly]
@ -56,7 +56,7 @@ dictionary ContactFieldInit {
[ChromeOnly, Constructor, JSImplementation="@mozilla.org/contactTelField;1"]
interface ContactTelField : ContactField {
attribute DOMString? carrier;
[TreatUndefinedAs=Null] attribute DOMString? carrier;
[ChromeOnly]
void initialize(optional sequence<DOMString>? type,
@ -111,8 +111,8 @@ interface mozContact {
attribute Date? bday;
attribute Date? anniversary;
attribute DOMString? sex;
attribute DOMString? genderIdentity;
[TreatUndefinedAs=Null] attribute DOMString? sex;
[TreatUndefinedAs=Null] attribute DOMString? genderIdentity;
attribute object? photo;

Просмотреть файл

@ -255,11 +255,6 @@ partial interface Navigator {
};
#ifdef MOZ_B2G_RIL
partial interface Navigator {
[Throws, Func="Navigator::HasTelephonySupport"]
readonly attribute Telephony? mozTelephony;
};
// nsIMozNavigatorMobileConnection
interface MozMobileConnection;
partial interface Navigator {
@ -285,6 +280,11 @@ partial interface Navigator {
};
#endif // MOZ_B2G_RIL
partial interface Navigator {
[Throws, Func="Navigator::HasTelephonySupport"]
readonly attribute Telephony? mozTelephony;
};
#ifdef MOZ_GAMEPAD
// https://dvcs.w3.org/hg/gamepad/raw-file/default/gamepad.html#navigator-interface-extension
partial interface Navigator {

Просмотреть файл

@ -470,12 +470,6 @@ if CONFIG['MOZ_GAMEPAD']:
'Gamepad.webidl',
]
if CONFIG['MOZ_B2G_RIL']:
WEBIDL_FILES += [
'MozStkCommandEvent.webidl',
'MozVoicemail.webidl',
]
WEBIDL_FILES += [
'CloseEvent.webidl',
'CustomEvent.webidl',
@ -518,10 +512,16 @@ if CONFIG['MOZ_B2G_RIL']:
'MozCellBroadcastEvent.webidl',
'MozEmergencyCbModeEvent.webidl',
'MozOtaStatusEvent.webidl',
'MozStkCommandEvent.webidl',
'MozVoicemail.webidl',
'MozVoicemailEvent.webidl',
'USSDReceivedEvent.webidl',
]
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk':
WEBIDL_FILES += [
'MozWifiConnectionInfoEvent.webidl',
'MozWifiStatusChangeEvent.webidl',
'USSDReceivedEvent.webidl',
]
if CONFIG['MOZ_WEBSPEECH']:

Просмотреть файл

@ -104,6 +104,12 @@ SharedSurface_Gralloc::Create(GLContext* prodGL,
GLuint prodTex = 0;
prodGL->fGenTextures(1, &prodTex);
ScopedBindTexture autoTex(prodGL, prodTex);
prodGL->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_MIN_FILTER, LOCAL_GL_LINEAR);
prodGL->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_MAG_FILTER, LOCAL_GL_LINEAR);
prodGL->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_WRAP_S, LOCAL_GL_CLAMP_TO_EDGE);
prodGL->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_WRAP_T, LOCAL_GL_CLAMP_TO_EDGE);
prodGL->fEGLImageTargetTexture2D(LOCAL_GL_TEXTURE_2D, image);
egl->fDestroyImage(display, image);

Просмотреть файл

@ -467,24 +467,6 @@ APZCTreeManager::UpdateCompositionBounds(const ScrollableLayerGuid& aGuid,
}
}
void
APZCTreeManager::CancelDefaultPanZoom(const ScrollableLayerGuid& aGuid)
{
nsRefPtr<AsyncPanZoomController> apzc = GetTargetAPZC(aGuid);
if (apzc) {
apzc->CancelDefaultPanZoom();
}
}
void
APZCTreeManager::DetectScrollableSubframe(const ScrollableLayerGuid& aGuid)
{
nsRefPtr<AsyncPanZoomController> apzc = GetTargetAPZC(aGuid);
if (apzc) {
apzc->DetectScrollableSubframe();
}
}
void
APZCTreeManager::ZoomToRect(const ScrollableLayerGuid& aGuid,
const CSSRect& aRect)

Просмотреть файл

@ -181,22 +181,6 @@ public:
void UpdateCompositionBounds(const ScrollableLayerGuid& aGuid,
const ScreenIntRect& aCompositionBounds);
/**
* We are scrolling a subframe, so disable our machinery until we hit
* a touch end or a new touch start. This prevents us from accidentally
* panning both the subframe and the parent frame.
*
* XXX/bug 775452: We should eventually be supporting async scrollable
* subframes.
*/
void CancelDefaultPanZoom(const ScrollableLayerGuid& aGuid);
/**
* We have found a scrollable subframe, so we need to delay the scrolling
* gesture executed and let subframe do the scrolling first.
*/
void DetectScrollableSubframe(const ScrollableLayerGuid& aGuid);
/**
* Kicks an animation to zoom to a rect. This may be either a zoom out or zoom
* in. The actual animation is done on the compositor thread after being set

Просмотреть файл

@ -279,9 +279,7 @@ AsyncPanZoomController::AsyncPanZoomController(uint64_t aLayersId,
mLastAsyncScrollOffset(0, 0),
mCurrentAsyncScrollOffset(0, 0),
mAsyncScrollTimeoutTask(nullptr),
mDisableNextTouchBatch(false),
mHandlingTouchQueue(false),
mDelayPanning(false),
mTreeManager(aTreeManager)
{
MOZ_COUNT_CTOR(AsyncPanZoomController);
@ -395,29 +393,12 @@ nsEventStatus AsyncPanZoomController::HandleInputEvent(const InputData& aEvent)
nsEventStatus rv = nsEventStatus_eIgnore;
nsRefPtr<GestureEventListener> listener = GetGestureEventListener();
if (listener && !mDisableNextTouchBatch) {
if (listener) {
rv = listener->HandleInputEvent(aEvent);
if (rv == nsEventStatus_eConsumeNoDefault)
return rv;
}
if (mDelayPanning && aEvent.mInputType == MULTITOUCH_INPUT) {
const MultiTouchInput& multiTouchInput = aEvent.AsMultiTouchInput();
if (multiTouchInput.mType == MultiTouchInput::MULTITOUCH_MOVE) {
// Let BrowserElementScrolling perform panning gesture first.
SetState(WAITING_LISTENERS);
mTouchQueue.AppendElement(multiTouchInput);
if (!mTouchListenerTimeoutTask) {
mTouchListenerTimeoutTask =
NewRunnableMethod(this, &AsyncPanZoomController::TimeoutTouchListeners);
PostDelayedTask(mTouchListenerTimeoutTask, gTouchListenerTimeout);
}
return nsEventStatus_eConsumeNoDefault;
}
}
switch (aEvent.mInputType) {
case MULTITOUCH_INPUT: {
const MultiTouchInput& multiTouchInput = aEvent.AsMultiTouchInput();
@ -503,10 +484,6 @@ nsEventStatus AsyncPanZoomController::OnTouchStart(const MultiTouchInput& aEvent
nsEventStatus AsyncPanZoomController::OnTouchMove(const MultiTouchInput& aEvent) {
APZC_LOG("%p got a touch-move in state %d\n", this, mState);
if (mDisableNextTouchBatch) {
return nsEventStatus_eIgnore;
}
switch (mState) {
case FLING:
case NOTHING:
@ -553,11 +530,6 @@ nsEventStatus AsyncPanZoomController::OnTouchMove(const MultiTouchInput& aEvent)
nsEventStatus AsyncPanZoomController::OnTouchEnd(const MultiTouchInput& aEvent) {
APZC_LOG("%p got a touch-end in state %d\n", this, mState);
if (mDisableNextTouchBatch) {
mDisableNextTouchBatch = false;
return nsEventStatus_eIgnore;
}
{
ReentrantMonitorAutoEnter lock(mMonitor);
SendAsyncScrollEvent();
@ -1364,18 +1336,6 @@ void AsyncPanZoomController::UpdateCompositionBounds(const ScreenIntRect& aCompo
}
}
void AsyncPanZoomController::CancelDefaultPanZoom() {
mDisableNextTouchBatch = true;
nsRefPtr<GestureEventListener> listener = GetGestureEventListener();
if (listener) {
listener->CancelGesture();
}
}
void AsyncPanZoomController::DetectScrollableSubframe() {
mDelayPanning = true;
}
void AsyncPanZoomController::ZoomToRect(CSSRect aRect) {
SetState(ANIMATING_ZOOM);
@ -1455,7 +1415,7 @@ void AsyncPanZoomController::ZoomToRect(CSSRect aRect) {
}
void AsyncPanZoomController::ContentReceivedTouch(bool aPreventDefault) {
if (!mFrameMetrics.mMayHaveTouchListeners && !mDelayPanning) {
if (!mFrameMetrics.mMayHaveTouchListeners) {
mTouchQueue.Clear();
return;
}
@ -1467,21 +1427,12 @@ void AsyncPanZoomController::ContentReceivedTouch(bool aPreventDefault) {
if (mState == WAITING_LISTENERS) {
if (!aPreventDefault) {
// Delayed scrolling gesture is pending at TOUCHING state.
if (mDelayPanning) {
SetState(TOUCHING);
} else {
SetState(NOTHING);
}
SetState(NOTHING);
}
mHandlingTouchQueue = true;
while (!mTouchQueue.IsEmpty()) {
// we need to reset mDelayPanning before handling scrolling gesture.
if (!aPreventDefault && mTouchQueue[0].mType == MultiTouchInput::MULTITOUCH_MOVE) {
mDelayPanning = false;
}
if (!aPreventDefault) {
HandleInputEvent(mTouchQueue[0]);
}

Просмотреть файл

@ -111,22 +111,6 @@ public:
*/
void UpdateCompositionBounds(const ScreenIntRect& aCompositionBounds);
/**
* We are scrolling a subframe, so disable our machinery until we hit
* a touch end or a new touch start. This prevents us from accidentally
* panning both the subframe and the parent frame.
*
* XXX/bug 775452: We should eventually be supporting async scrollable
* subframes.
*/
void CancelDefaultPanZoom();
/**
* We have found a scrollable subframe, so we need to delay the scrolling
* gesture executed and let subframe do the scrolling first.
*/
void DetectScrollableSubframe();
/**
* Kicks an animation to zoom to a rect. This may be either a zoom out or zoom
* in. The actual animation is done on the compositor thread after being set
@ -615,22 +599,12 @@ private:
// ensures the last mozbrowserasyncscroll event is always been fired.
CancelableTask* mAsyncScrollTimeoutTask;
// Flag used to determine whether or not we should disable handling of the
// next batch of touch events. This is used for sync scrolling of subframes.
bool mDisableNextTouchBatch;
// Flag used to determine whether or not we should try to enter the
// WAITING_LISTENERS state. This is used in the case that we are processing a
// queued up event block. If set, this means that we are handling this queue
// and we don't want to queue the events back up again.
bool mHandlingTouchQueue;
// Flag used to determine whether or not we should try scrolling by
// BrowserElementScrolling first. If set, we delay delivering
// touchmove events to GestureListener until BrowserElementScrolling
// decides whether it wants to handle panning for this touch series.
bool mDelayPanning;
friend class Axis;
/* The functions and members in this section are used to build a tree

Просмотреть файл

@ -226,7 +226,7 @@ DBusWatcher::Poll()
if (mPollData[i].fd == mControlFdR.get()) {
char data;
res = TEMP_FAILURE_RETRY(read(mControlFdR.get(), &data, sizeof(data)));
NS_ENSURE_TRUE(res > 0, NS_OK);
NS_ENSURE_TRUE(res > 0, false);
switch (data) {
case DBUS_EVENT_LOOP_EXIT:
@ -253,18 +253,19 @@ DBusWatcher::Poll()
}
} else {
short events = mPollData[i].revents;
unsigned int flags = UnixEventsToDBusFlags(events);
dbus_watch_handle(mWatchData[i], flags);
mPollData[i].revents = 0;
dbus_watch_handle(mWatchData[i], UnixEventsToDBusFlags(events));
DBusDispatchStatus dbusDispatchStatus;
do {
dbusDispatchStatus = dbus_connection_dispatch(GetConnection());
} while (dbusDispatchStatus == DBUS_DISPATCH_DATA_REMAINS);
// Break at this point since we don't know if the operation
// was destructive
break;
}
DBusDispatchStatus dbusDispatchStatus;
do {
dbusDispatchStatus = dbus_connection_dispatch(GetConnection());
} while (dbusDispatchStatus == DBUS_DISPATCH_DATA_REMAINS);
}
++i;

Просмотреть файл

@ -53,59 +53,16 @@ protected:
DBusMessageRefPtr mMessage;
};
class DBusConnectionSendSyncRunnable : public DBusConnectionSendRunnableBase
{
public:
bool WaitForCompletion()
{
MOZ_ASSERT(!NS_IsMainThread());
MonitorAutoLock autoLock(mCompletedMonitor);
while (!mCompleted) {
mCompletedMonitor.Wait();
}
return mSuccess;
}
protected:
DBusConnectionSendSyncRunnable(DBusConnection* aConnection,
DBusMessage* aMessage)
: DBusConnectionSendRunnableBase(aConnection, aMessage),
mCompletedMonitor("DBusConnectionSendSyncRunnable.mCompleted"),
mCompleted(false),
mSuccess(false)
{ }
virtual ~DBusConnectionSendSyncRunnable()
{ }
// Call this function at the end of Run() to notify waiting
// threads.
void Completed(bool aSuccess)
{
MonitorAutoLock autoLock(mCompletedMonitor);
MOZ_ASSERT(!mCompleted);
mSuccess = aSuccess;
mCompleted = true;
mCompletedMonitor.Notify();
}
private:
Monitor mCompletedMonitor;
bool mCompleted;
bool mSuccess;
};
//
// Sends a message and returns the message's serial number to the
// disaptching thread. Only run it in DBus thread.
//
class DBusConnectionSendRunnable : public DBusConnectionSendSyncRunnable
class DBusConnectionSendRunnable : public DBusConnectionSendRunnableBase
{
public:
DBusConnectionSendRunnable(DBusConnection* aConnection,
DBusMessage* aMessage)
: DBusConnectionSendSyncRunnable(aConnection, aMessage)
: DBusConnectionSendRunnableBase(aConnection, aMessage)
{ }
NS_IMETHOD Run()
@ -113,7 +70,6 @@ public:
MOZ_ASSERT(!NS_IsMainThread());
dbus_bool_t success = dbus_connection_send(mConnection, mMessage, nullptr);
Completed(success == TRUE);
NS_ENSURE_TRUE(success == TRUE, NS_ERROR_FAILURE);
@ -220,95 +176,6 @@ private:
int mTimeout;
};
//
// Legacy interface, don't use in new code
//
// Sends a message and waits for the reply. Only run it in DBus thread.
//
class DBusConnectionSendAndBlockRunnable : public DBusConnectionSendSyncRunnable
{
private:
static void Notify(DBusPendingCall* aCall, void* aData)
{
DBusConnectionSendAndBlockRunnable* runnable(
static_cast<DBusConnectionSendAndBlockRunnable*>(aData));
runnable->mReply = dbus_pending_call_steal_reply(aCall);
bool success = !!runnable->mReply;
if (runnable->mError) {
success = success && !dbus_error_is_set(runnable->mError);
if (!dbus_set_error_from_message(runnable->mError, runnable->mReply)) {
dbus_error_init(runnable->mError);
}
}
dbus_pending_call_cancel(aCall);
dbus_pending_call_unref(aCall);
runnable->Completed(success);
}
public:
DBusConnectionSendAndBlockRunnable(DBusConnection* aConnection,
DBusMessage* aMessage,
int aTimeout,
DBusError* aError)
: DBusConnectionSendSyncRunnable(aConnection, aMessage),
mError(aError),
mReply(nullptr),
mTimeout(aTimeout)
{ }
NS_IMETHOD Run()
{
MOZ_ASSERT(!NS_IsMainThread());
DBusPendingCall* call = nullptr;
dbus_bool_t success = dbus_connection_send_with_reply(mConnection,
mMessage,
&call,
mTimeout);
if (success == TRUE) {
success = dbus_pending_call_set_notify(call, Notify, this, nullptr);
} else {
if (mError) {
if (!call) {
dbus_set_error(mError, DBUS_ERROR_DISCONNECTED, "Connection is closed");
} else {
dbus_error_init(mError);
}
}
}
dbus_message_unref(mMessage);
if (!success) {
Completed(false);
NS_ENSURE_TRUE(success == TRUE, NS_ERROR_FAILURE);
}
return NS_OK;
}
DBusMessage* GetReply()
{
return mReply;
}
protected:
~DBusConnectionSendAndBlockRunnable()
{ }
private:
DBusError* mError;
DBusMessage* mReply;
int mTimeout;
};
}
}
@ -414,58 +281,6 @@ bool RawDBusConnection::SendWithReply(DBusReplyCallback aCallback,
return SendWithReply(aCallback, aData, aTimeout, msg);
}
bool RawDBusConnection::SendWithError(DBusMessage** aReply,
DBusError* aError,
int aTimeout,
DBusMessage* aMessage)
{
nsRefPtr<DBusConnectionSendAndBlockRunnable> t(
new DBusConnectionSendAndBlockRunnable(mConnection, aMessage,
aTimeout, aError));
MOZ_ASSERT(t);
nsresult rv = DispatchToDBusThread(t);
if (NS_FAILED(rv)) {
if (aMessage) {
dbus_message_unref(aMessage);
}
return false;
}
if (!t->WaitForCompletion()) {
return false;
}
if (aReply) {
*aReply = t->GetReply();
}
return true;
}
bool RawDBusConnection::SendWithError(DBusMessage** aReply,
DBusError* aError,
int aTimeout,
const char* aPath,
const char* aIntf,
const char* aFunc,
int aFirstArgType, ...)
{
va_list args;
va_start(args, aFirstArgType);
DBusMessage* msg = BuildDBusMessage(aPath, aIntf, aFunc,
aFirstArgType, args);
va_end(args);
if (!msg) {
return false;
}
return SendWithError(aReply, aError, aTimeout, msg);
}
DBusMessage* RawDBusConnection::BuildDBusMessage(const char* aPath,
const char* aIntf,
const char* aFunc,

Просмотреть файл

@ -53,15 +53,6 @@ public:
int aTimeout, const char* aPath, const char* aIntf,
const char *aFunc, int aFirstArgType, ...);
/* Legacy interface, don't use in new code */
bool SendWithError(DBusMessage** aReply, DBusError* aError, int aTimeout,
DBusMessage* aMessage);
/* Legacy interface, don't use in new code */
bool SendWithError(DBusMessage** aReply, DBusError* aError, int aTimeout,
const char* aPath, const char* aIntf, const char* aFunc,
int aFirstArgType, ...);
protected:
DBusMessage* BuildDBusMessage(const char* aPath, const char* aIntf,
const char* aFunc, int aFirstArgType,

Просмотреть файл

@ -17,10 +17,10 @@ if CONFIG['MOZ_B2G_RIL']:
if CONFIG['MOZ_B2G_BT_BLUEZ']:
DIRS += ['dbus']
if CONFIG['MOZ_B2G_RIL'] or CONFIG['MOZ_B2G_BT']:
DIRS += ['unixsocket', 'keystore']
if CONFIG['MOZ_B2G_RIL'] or CONFIG['MOZ_B2G_BT'] or CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk':
DIRS += ['unixsocket']
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk':
DIRS += ['netd']
DIRS += ['netd', 'keystore']
TOOL_DIRS += ['app']

Просмотреть файл

@ -4,6 +4,8 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/ipc/Ril.h"
#include <fcntl.h>
#include <sys/socket.h>
#include <sys/un.h>
@ -18,8 +20,8 @@
#endif
#include "jsfriendapi.h"
#include "nsTArray.h"
#include "nsThreadUtils.h" // For NS_IsMainThread.
#include "Ril.h"
USING_WORKERS_NAMESPACE
using namespace mozilla::ipc;
@ -32,17 +34,130 @@ const char* RIL_SOCKET_NAME = "/dev/socket/rilproxy";
// desktop development.
const uint32_t RIL_TEST_PORT = 6200;
class DispatchRILEvent : public WorkerTask
nsTArray<nsRefPtr<mozilla::ipc::RilConsumer> > sRilConsumers;
class ConnectWorkerToRIL : public WorkerTask
{
public:
DispatchRILEvent(UnixSocketRawData* aMessage)
: mMessage(aMessage)
ConnectWorkerToRIL()
{ }
virtual bool RunTask(JSContext *aCx);
};
class SendRilSocketDataTask : public nsRunnable
{
public:
SendRilSocketDataTask(unsigned long aClientId,
UnixSocketRawData *aRawData)
: mRawData(aRawData)
, mClientId(aClientId)
{ }
NS_IMETHOD Run()
{
MOZ_ASSERT(NS_IsMainThread());
if (sRilConsumers.Length() <= mClientId ||
!sRilConsumers[mClientId] ||
sRilConsumers[mClientId]->GetConnectionStatus() != SOCKET_CONNECTED) {
// Probably shuting down.
delete mRawData;
return NS_OK;
}
sRilConsumers[mClientId]->SendSocketData(mRawData);
return NS_OK;
}
private:
nsAutoPtr<UnixSocketRawData> mMessage;
UnixSocketRawData *mRawData;
unsigned long mClientId;
};
bool
PostToRIL(JSContext *aCx,
unsigned aArgc,
JS::Value *aArgv)
{
NS_ASSERTION(!NS_IsMainThread(), "Expecting to be on the worker thread");
if (aArgc != 2) {
JS_ReportError(aCx, "Expecting two arguments with the RIL message");
return false;
}
JS::Value cv = JS_ARGV(aCx, aArgv)[0];
int clientId = cv.toInt32();
JS::Value v = JS_ARGV(aCx, aArgv)[1];
JSAutoByteString abs;
void *data;
size_t size;
if (JSVAL_IS_STRING(v)) {
JSString *str = JSVAL_TO_STRING(v);
if (!abs.encodeUtf8(aCx, str)) {
return false;
}
data = abs.ptr();
size = abs.length();
} else if (!JSVAL_IS_PRIMITIVE(v)) {
JSObject *obj = JSVAL_TO_OBJECT(v);
if (!JS_IsTypedArrayObject(obj)) {
JS_ReportError(aCx, "Object passed in wasn't a typed array");
return false;
}
uint32_t type = JS_GetArrayBufferViewType(obj);
if (type != js::ArrayBufferView::TYPE_INT8 &&
type != js::ArrayBufferView::TYPE_UINT8 &&
type != js::ArrayBufferView::TYPE_UINT8_CLAMPED) {
JS_ReportError(aCx, "Typed array data is not octets");
return false;
}
size = JS_GetTypedArrayByteLength(obj);
data = JS_GetArrayBufferViewData(obj);
} else {
JS_ReportError(aCx,
"Incorrect argument. Expecting a string or a typed array");
return false;
}
UnixSocketRawData* raw = new UnixSocketRawData(data, size);
nsRefPtr<SendRilSocketDataTask> task =
new SendRilSocketDataTask(clientId, raw);
NS_DispatchToMainThread(task);
return true;
}
bool
ConnectWorkerToRIL::RunTask(JSContext *aCx)
{
// Set up the postRILMessage on the function for worker -> RIL thread
// communication.
NS_ASSERTION(!NS_IsMainThread(), "Expecting to be on the worker thread");
NS_ASSERTION(!JS_IsRunning(aCx), "Are we being called somehow?");
JSObject *workerGlobal = JS::CurrentGlobalOrNull(aCx);
return !!JS_DefineFunction(aCx, workerGlobal,
"postRILMessage", PostToRIL, 1, 0);
}
class DispatchRILEvent : public WorkerTask
{
public:
DispatchRILEvent(UnixSocketRawData* aMessage)
: mMessage(aMessage)
{ }
virtual bool RunTask(JSContext *aCx);
private:
nsAutoPtr<UnixSocketRawData> mMessage;
};
bool
@ -192,11 +307,45 @@ RilConsumer::RilConsumer(unsigned long aClientId,
ConnectSocket(new RilConnector(mClientId), mAddress.get());
}
nsresult
RilConsumer::Register(unsigned int aClientId,
WorkerCrossThreadDispatcher* aDispatcher)
{
MOZ_ASSERT(NS_IsMainThread());
sRilConsumers.EnsureLengthAtLeast(aClientId + 1);
if (sRilConsumers[aClientId]) {
NS_WARNING("RilConsumer already registered");
return NS_ERROR_FAILURE;
}
nsRefPtr<ConnectWorkerToRIL> connection = new ConnectWorkerToRIL();
if (!aDispatcher->PostTask(connection)) {
NS_WARNING("Failed to connect worker to ril");
return NS_ERROR_UNEXPECTED;
}
// Now that we're set up, connect ourselves to the RIL thread.
sRilConsumers[aClientId] = new RilConsumer(aClientId, aDispatcher);
return NS_OK;
}
void
RilConsumer::Shutdown()
{
mShutdown = true;
CloseSocket();
MOZ_ASSERT(NS_IsMainThread());
for (unsigned long i = 0; i < sRilConsumers.Length(); i++) {
nsRefPtr<RilConsumer>& instance = sRilConsumers[i];
if (!instance) {
continue;
}
instance->mShutdown = true;
instance->CloseSocket();
instance = nullptr;
}
}
void
@ -212,20 +361,20 @@ void
RilConsumer::OnConnectSuccess()
{
// Nothing to do here.
LOG("RIL[%u]: %s\n", mClientId, __FUNCTION__);
LOG("RIL[%lu]: %s\n", mClientId, __FUNCTION__);
}
void
RilConsumer::OnConnectError()
{
LOG("RIL[%u]: %s\n", mClientId, __FUNCTION__);
LOG("RIL[%lu]: %s\n", mClientId, __FUNCTION__);
CloseSocket();
}
void
RilConsumer::OnDisconnect()
{
LOG("RIL[%u]: %s\n", mClientId, __FUNCTION__);
LOG("RIL[%lu]: %s\n", mClientId, __FUNCTION__);
if (!mShutdown) {
ConnectSocket(new RilConnector(mClientId), mAddress.get(), 1000);
}

Просмотреть файл

@ -16,13 +16,16 @@ namespace ipc {
class RilConsumer : public mozilla::ipc::UnixSocketConsumer
{
public:
RilConsumer(unsigned long aClientId,
mozilla::dom::workers::WorkerCrossThreadDispatcher* aDispatcher);
virtual ~RilConsumer() { }
void Shutdown();
static nsresult Register(unsigned int aClientId,
mozilla::dom::workers::WorkerCrossThreadDispatcher* aDispatcher);
static void Shutdown();
private:
RilConsumer(unsigned long aClientId,
mozilla::dom::workers::WorkerCrossThreadDispatcher* aDispatcher);
virtual void ReceiveSocketData(nsAutoPtr<UnixSocketRawData>& aMessage);
virtual void OnConnectSuccess();

Просмотреть файл

@ -23,6 +23,10 @@ simple_events = [
'StyleRuleChangeEvent',
'StyleSheetChangeEvent',
'StyleSheetApplicableStateChangeEvent',
#ifdef MOZ_WIDGET_GONK
'MozWifiStatusChangeEvent',
'MozWifiConnectionInfoEvent',
#endif
#ifdef MOZ_B2G_BT
'BluetoothDeviceEvent',
'BluetoothStatusChangedEvent',
@ -32,8 +36,6 @@ simple_events = [
'DataErrorEvent',
'MozEmergencyCbModeEvent',
'MozOtaStatusEvent',
'MozWifiStatusChangeEvent',
'MozWifiConnectionInfoEvent',
'MozCellBroadcastEvent',
'MozVoicemailEvent',
'USSDReceivedEvent',

Просмотреть файл

@ -2497,7 +2497,6 @@ nsCSSRendering::PaintGradient(nsPresContext* aPresContext,
// tile with the overall area we're supposed to be filling
gfxRect fillRect =
forceRepeatToCoverTiles ? areaToFill : tileRect.Intersect(areaToFill);
ctx->NewPath();
// Try snapping the fill rect. Snap its top-left and bottom-right
// independently to preserve the orientation.
gfxPoint snappedFillRectTopLeft = fillRect.TopLeft();
@ -2523,6 +2522,7 @@ nsCSSRendering::PaintGradient(nsPresContext* aPresContext,
snappedFillRectBottomRight);
ctx->SetMatrix(transform);
}
ctx->NewPath();
ctx->Rectangle(fillRect);
ctx->Translate(tileRect.TopLeft());
ctx->SetPattern(gradientPattern);

Просмотреть файл

@ -643,8 +643,7 @@ static void RecordFrameMetrics(nsIFrame* aForFrame,
nsRect* aDisplayPort,
nsRect* aCriticalDisplayPort,
ViewID aScrollId,
const nsDisplayItem::ContainerParameters& aContainerParameters,
bool aMayHaveTouchListeners) {
const nsDisplayItem::ContainerParameters& aContainerParameters) {
nsPresContext* presContext = aForFrame->PresContext();
int32_t auPerDevPixel = presContext->AppUnitsPerDevPixel();
LayoutDeviceToLayerScale resolution(aContainerParameters.mXScale, aContainerParameters.mYScale);
@ -719,7 +718,16 @@ static void RecordFrameMetrics(nsIFrame* aForFrame,
metrics.mZoom = metrics.mCumulativeResolution * metrics.mDevPixelsPerCSSPixel
* layerToScreenScale;
metrics.mMayHaveTouchListeners = aMayHaveTouchListeners;
if (presShell) {
nsIDocument* document = nullptr;
document = presShell->GetDocument();
if (document) {
nsCOMPtr<nsPIDOMWindow> innerWin(document->GetInnerWindow());
if (innerWin) {
metrics.mMayHaveTouchListeners = innerWin->HasTouchEventListeners();
}
}
}
// Calculate the composition bounds as the size of the scroll frame and
// its origin relative to the reference frame.
@ -1248,14 +1256,6 @@ void nsDisplayList::PaintForFrame(nsDisplayListBuilder* aBuilder,
}
}
bool mayHaveTouchListeners = false;
if (document) {
nsCOMPtr<nsPIDOMWindow> innerWin(document->GetInnerWindow());
if (innerWin) {
mayHaveTouchListeners = innerWin->HasTouchEventListeners();
}
}
nsRect viewport(aBuilder->ToReferenceFrame(aForFrame), aForFrame->GetSize());
RecordFrameMetrics(aForFrame, rootScrollFrame,
@ -1263,7 +1263,7 @@ void nsDisplayList::PaintForFrame(nsDisplayListBuilder* aBuilder,
root, mVisibleRect, viewport,
(usingDisplayport ? &displayport : nullptr),
(usingCriticalDisplayport ? &criticalDisplayport : nullptr),
id, containerParameters, mayHaveTouchListeners);
id, containerParameters);
if (usingDisplayport &&
!(root->GetContentFlags() & Layer::CONTENT_OPAQUE)) {
// See bug 693938, attachment 567017
@ -3605,7 +3605,7 @@ nsDisplayScrollLayer::BuildLayer(nsDisplayListBuilder* aBuilder,
mVisibleRect, viewport,
(usingDisplayport ? &displayport : nullptr),
(usingCriticalDisplayport ? &criticalDisplayport : nullptr),
scrollId, aContainerParameters, false);
scrollId, aContainerParameters);
return layer.forget();
}

Просмотреть файл

@ -127,9 +127,14 @@ endif #}
SHARED_LIBRARY_LIBS += $(DEPTH)/dom/camera/$(LIB_PREFIX)domcamera_s.$(LIB_SUFFIX)
ifdef MOZ_B2G_RIL #{
ifeq (gonk,$(MOZ_WIDGET_TOOLKIT))
SHARED_LIBRARY_LIBS += \
$(DEPTH)/dom/system/gonk/$(LIB_PREFIX)domsystemgonk_s.$(LIB_SUFFIX) \
$(NULL)
endif #}
ifdef MOZ_B2G_RIL #{
SHARED_LIBRARY_LIBS += \
$(DEPTH)/dom/icc/src/$(LIB_PREFIX)dom_icc_s.$(LIB_SUFFIX) \
$(DEPTH)/dom/cellbroadcast/src/$(LIB_PREFIX)dom_cellbroadcast_s.$(LIB_SUFFIX) \
$(DEPTH)/dom/voicemail/$(LIB_PREFIX)domvoicemail_s.$(LIB_SUFFIX) \
@ -326,7 +331,7 @@ ifdef MOZ_GSTREAMER
LOCAL_INCLUDES += $(GSTREAMER_CFLAGS)
endif
ifdef MOZ_B2G_RIL #{
ifeq (gonk,$(MOZ_WIDGET_TOOLKIT))
LOCAL_INCLUDES += -I$(topsrcdir)/dom/system/gonk
endif #}

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше