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

This commit is contained in:
Ryan VanderMeulen 2014-10-30 15:58:07 -04:00
Родитель ec3c49661b aa8a043e5d
Коммит 40eb4a65d8
89 изменённых файлов: 2740 добавлений и 336 удалений

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

@ -982,8 +982,13 @@ pref("apz.asyncscroll.throttle", 40);
pref("apz.pan_repaint_interval", 16);
// APZ physics settings, tuned by UX designers
pref("apz.max_velocity_inches_per_ms", "0.07");
pref("apz.fling_curve_function_x1", "0.0");
pref("apz.fling_curve_function_y1", "0.0");
pref("apz.fling_curve_function_x2", "0.58");
pref("apz.fling_curve_function_y2", "1.0");
pref("apz.fling_curve_threshold_inches_per_ms", "0.03");
pref("apz.fling_friction", "0.003");
pref("apz.max_velocity_inches_per_ms", "0.07");
// Tweak default displayport values to reduce the risk of running out of
// memory when zooming in

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

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="3a2947df41a480de1457a6dcdbf46ad0af70d8e0">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="cddf7f505c4c280bacb74c22af3fa4959ccb555a"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="8ae6598f3ab7b0c34ac42a73083ddb74266affba"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="45c54a55e31758f7e54e5eafe0d01d387f35897a"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>

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

@ -19,7 +19,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="cddf7f505c4c280bacb74c22af3fa4959ccb555a"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="8ae6598f3ab7b0c34ac42a73083ddb74266affba"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="45c54a55e31758f7e54e5eafe0d01d387f35897a"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="cd88d860656c31c7da7bb310d6a160d0011b0961"/>

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

@ -17,7 +17,7 @@
</project>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="cddf7f505c4c280bacb74c22af3fa4959ccb555a"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="8ae6598f3ab7b0c34ac42a73083ddb74266affba"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="45c54a55e31758f7e54e5eafe0d01d387f35897a"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="28be739bcdcbc9eb91c0bdbff1f7d3eab717969b"/>

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

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="3a2947df41a480de1457a6dcdbf46ad0af70d8e0">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="cddf7f505c4c280bacb74c22af3fa4959ccb555a"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="8ae6598f3ab7b0c34ac42a73083ddb74266affba"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="45c54a55e31758f7e54e5eafe0d01d387f35897a"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>

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

@ -19,7 +19,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="cddf7f505c4c280bacb74c22af3fa4959ccb555a"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="8ae6598f3ab7b0c34ac42a73083ddb74266affba"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="45c54a55e31758f7e54e5eafe0d01d387f35897a"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="cd88d860656c31c7da7bb310d6a160d0011b0961"/>

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

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="3a2947df41a480de1457a6dcdbf46ad0af70d8e0">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="cddf7f505c4c280bacb74c22af3fa4959ccb555a"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="8ae6598f3ab7b0c34ac42a73083ddb74266affba"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="45c54a55e31758f7e54e5eafe0d01d387f35897a"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
@ -126,6 +126,8 @@
<remove-project name="platform/frameworks/native"/>
<remove-project name="platform/hardware/libhardware"/>
<remove-project name="platform/external/bluetooth/bluedroid"/>
<remove-project name="platform/system/media"/>
<project name="platform/system/media" path="system/media" revision="c1332c21c608f4932a6d7e83450411cde53315ef"/>
<!--original fetch url was git://github.com/t2m-foxfone/-->
<remote fetch="https://git.mozilla.org/external/t2m-foxfone" name="t2m"/>
<default remote="caf" revision="LNX.LA.3.5.2.1.1" sync-j="4"/>

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

@ -17,7 +17,7 @@
</project>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="cddf7f505c4c280bacb74c22af3fa4959ccb555a"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="8ae6598f3ab7b0c34ac42a73083ddb74266affba"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="45c54a55e31758f7e54e5eafe0d01d387f35897a"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="28be739bcdcbc9eb91c0bdbff1f7d3eab717969b"/>

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

@ -4,6 +4,6 @@
"remote": "",
"branch": ""
},
"revision": "4763231f664a8a94cbea98b35b84749b51a961c9",
"revision": "5b7182e0e489747ff07ca952f5a99dc21a0226c9",
"repo_path": "/integration/gaia-central"
}

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

@ -17,7 +17,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="cddf7f505c4c280bacb74c22af3fa4959ccb555a"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="8ae6598f3ab7b0c34ac42a73083ddb74266affba"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="45c54a55e31758f7e54e5eafe0d01d387f35897a"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>

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

@ -15,7 +15,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="cddf7f505c4c280bacb74c22af3fa4959ccb555a"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="8ae6598f3ab7b0c34ac42a73083ddb74266affba"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="45c54a55e31758f7e54e5eafe0d01d387f35897a"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>

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

@ -17,7 +17,7 @@
</project>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="cddf7f505c4c280bacb74c22af3fa4959ccb555a"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="8ae6598f3ab7b0c34ac42a73083ddb74266affba"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="45c54a55e31758f7e54e5eafe0d01d387f35897a"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="28be739bcdcbc9eb91c0bdbff1f7d3eab717969b"/>

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

@ -17,7 +17,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="cddf7f505c4c280bacb74c22af3fa4959ccb555a"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="8ae6598f3ab7b0c34ac42a73083ddb74266affba"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="45c54a55e31758f7e54e5eafe0d01d387f35897a"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>

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

@ -12,7 +12,6 @@ NS_IMPL_ISUPPORTS_INHERITED0(IccCardLockError, DOMError)
/* static */ already_AddRefed<IccCardLockError>
IccCardLockError::Constructor(const GlobalObject& aGlobal,
const nsAString& aLockType,
const nsAString& aName,
int16_t aRetryCount,
ErrorResult& aRv)
@ -24,16 +23,14 @@ IccCardLockError::Constructor(const GlobalObject& aGlobal,
}
nsRefPtr<IccCardLockError> result =
new IccCardLockError(window, aName, aLockType, aRetryCount);
new IccCardLockError(window, aName, aRetryCount);
return result.forget();
}
IccCardLockError::IccCardLockError(nsPIDOMWindow* aWindow,
const nsAString& aName,
const nsAString& aLockType,
int16_t aRetryCount)
: DOMError(aWindow, aName)
, mLockType(aLockType)
, mRetryCount(aRetryCount)
{
}

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

@ -16,24 +16,17 @@ public:
NS_DECL_ISUPPORTS_INHERITED
IccCardLockError(nsPIDOMWindow* aWindow, const nsAString& aName,
const nsAString& aLockType, int16_t aRetryCount);
int16_t aRetryCount);
static already_AddRefed<IccCardLockError>
Constructor(const GlobalObject& aGlobal, const nsAString& aLockType,
const nsAString& aName, int16_t aRetryCount,
ErrorResult& aRv);
Constructor(const GlobalObject& aGlobal, const nsAString& aName,
int16_t aRetryCount, ErrorResult& aRv);
virtual JSObject*
WrapObject(JSContext* aCx) MOZ_OVERRIDE;
// WebIDL interface
void
GetLockType(nsString& aLockType) const
{
aLockType = mLockType;
}
int16_t
RetryCount() const
{
@ -44,7 +37,6 @@ private:
~IccCardLockError() {}
private:
nsString mLockType;
int16_t mRetryCount;
};

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

@ -17,7 +17,6 @@ taskHelper.push(function testPinChangeFailed() {
request.onerror = function onerror() {
is(request.error.name, "IncorrectPassword");
is(request.error.lockType, "pin");
// The default pin retries is 3, failed once becomes to 2
is(request.error.retryCount, 2);

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

@ -189,6 +189,40 @@ let tests = [
expect: {name: "display_text_cmd_20",
commandQualifier: 0x00,
text: "Toolkit Test GROUP:0xF0, 8BIT"}},
// Bug 1088573: this test case is to ensure that we provide |length| argument
// in |integer| format to GsmPDUHelper.readSeptetsToString().
{command: "D0" +
"81" + // 2-byte length encoded:
"FC" + // 252
"810301210082028102" +
"8D" +
"81" + // 2-byte length encoded:
"F0" + // 240
"00" + // 7BIT
"C332A85D9ECFC3E732685E068DDF6DF8" +
"7B5E0691CB20D96D061A87E5E131BD2C" +
"2FCF416537A8FD269741E3771B2E2FCF" +
"E76517685806B5CBF379F85C0695E774" +
"50D86C4E8FD165D0BC2E07C1D9F579BA" +
"5C97CF41E5B13CEC9E83CA7490BB0C22" +
"BFD374103C3C0795E9F232882E7FBBE3" +
"F5B20B24BBCD40E5391DC42E83DCEFB6" +
"585E06B5C3F874BBDE0691CBA071581E" +
"1ED3CBF2F21C14369BD3637458CC2EBB" +
"40C3329D5E0699DFEE313DFD76BBC3EC" +
"34BD0C0A83CAF432280C87CBDF757BB9" +
"0C8287E5207619346D1E73A0783D0D9A" +
"9FCA733A885C96BFEBEC32280C9A6689" +
"CE621654768382D529551A64268B2E",
func: testDisplayText,
expect: {name: "display_text_cmd_21",
commandQualifier: 0x00,
text: "Ce message se compose de 273 caracteres en mode " +
"compresse. Ce message est affiche sur plusieurs " +
"ecrans et ne doit pas etre tronque. 273 est le " +
"nombre maximum de caracteres affichable. Cette " +
"fonctionnalite a ete approuvee par le SMG9 qui s'est " +
"deroule a SYDNEY en AUSTRALIE."}},
];
runNextTest();

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

@ -28,5 +28,24 @@ ASSERT_MOBILE_RADIO_STATE_EQUALITY(Disabled, MOBILE_RADIO_STATE_DISABLED);
#undef ASSERT_MOBILE_RADIO_STATE_EQUALITY
#define ASSERT_PREFERRED_NETWORK_TYPE_EQUALITY(webidlState, xpidlState) \
static_assert(static_cast<int32_t>(MobilePreferredNetworkType::webidlState) == nsIMobileConnection::xpidlState, \
"MobilePreferredNetworkType::" #webidlState " should equal to nsIMobileConnection::" #xpidlState)
ASSERT_PREFERRED_NETWORK_TYPE_EQUALITY(Wcdma_gsm, PREFERRED_NETWORK_TYPE_WCDMA_GSM);
ASSERT_PREFERRED_NETWORK_TYPE_EQUALITY(Gsm, PREFERRED_NETWORK_TYPE_GSM_ONLY);
ASSERT_PREFERRED_NETWORK_TYPE_EQUALITY(Wcdma, PREFERRED_NETWORK_TYPE_WCDMA_ONLY);
ASSERT_PREFERRED_NETWORK_TYPE_EQUALITY(Wcdma_gsm_auto, PREFERRED_NETWORK_TYPE_WCDMA_GSM_AUTO);
ASSERT_PREFERRED_NETWORK_TYPE_EQUALITY(Cdma_evdo, PREFERRED_NETWORK_TYPE_CDMA_EVDO);
ASSERT_PREFERRED_NETWORK_TYPE_EQUALITY(Cdma, PREFERRED_NETWORK_TYPE_CDMA_ONLY);
ASSERT_PREFERRED_NETWORK_TYPE_EQUALITY(Evdo, PREFERRED_NETWORK_TYPE_EVDO_ONLY);
ASSERT_PREFERRED_NETWORK_TYPE_EQUALITY(Wcdma_gsm_cdma_evdo, PREFERRED_NETWORK_TYPE_WCDMA_GSM_CDMA_EVDO);
ASSERT_PREFERRED_NETWORK_TYPE_EQUALITY(Lte_cdma_evdo, PREFERRED_NETWORK_TYPE_LTE_CDMA_EVDO);
ASSERT_PREFERRED_NETWORK_TYPE_EQUALITY(Lte_wcdma_gsm, PREFERRED_NETWORK_TYPE_LTE_WCDMA_GSM);
ASSERT_PREFERRED_NETWORK_TYPE_EQUALITY(Lte_wcdma_gsm_cdma_evdo, PREFERRED_NETWORK_TYPE_LTE_WCDMA_GSM_CDMA_EVDO);
ASSERT_PREFERRED_NETWORK_TYPE_EQUALITY(Lte, PREFERRED_NETWORK_TYPE_LTE_ONLY);
#undef ASSERT_PREFERRED_NETWORK_TYPE_EQUALITY
} // namespace dom
} // namespace mozilla

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

@ -477,8 +477,7 @@ MobileConnection::SetPreferredNetworkType(MobilePreferredNetworkType& aType,
return nullptr;
}
nsAutoString type;
CONVERT_ENUM_TO_STRING(MobilePreferredNetworkType, aType, type);
int32_t type = static_cast<int32_t>(aType);
nsRefPtr<DOMRequest> request = new DOMRequest(GetOwner());
nsRefPtr<MobileConnectionCallback> requestCallback =

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

@ -15,6 +15,13 @@ namespace mozilla {
namespace dom {
namespace mobileconnection {
#define CONVERT_ENUM_TO_STRING(_enumType, _enum, _string) \
{ \
uint32_t index = uint32_t(_enum); \
_string.AssignASCII(_enumType##Values::strings[index].value, \
_enumType##Values::strings[index].length); \
}
NS_IMPL_ISUPPORTS(MobileConnectionCallback, nsIMobileConnectionCallback)
MobileConnectionCallback::MobileConnectionCallback(nsPIDOMWindow* aWindow,
@ -349,6 +356,18 @@ MobileConnectionCallback::NotifyGetClirStatusSuccess(uint16_t aN, uint16_t aM)
return NotifySuccess(jsResult);
};
NS_IMETHODIMP
MobileConnectionCallback::NotifyGetPreferredNetworkTypeSuccess(int32_t aType)
{
MOZ_ASSERT(aType < static_cast<int32_t>(MobilePreferredNetworkType::EndGuard_));
MobilePreferredNetworkType type = static_cast<MobilePreferredNetworkType>(aType);
nsAutoString typeString;
CONVERT_ENUM_TO_STRING(MobilePreferredNetworkType, type, typeString);
return NotifySuccessWithString(typeString);
};
NS_IMETHODIMP
MobileConnectionCallback::NotifyError(const nsAString& aName,
const nsAString& aMessage,

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

@ -774,7 +774,7 @@ MobileConnectionProvider.prototype = {
return false;
}
aCallback.notifySuccessWithString(aResponse.type);
aCallback.notifyGetPreferredNetworkTypeSuccess(aResponse.type);
return false;
}).bind(this));
},

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

@ -124,7 +124,7 @@ interface nsIMobileConnectionListener : nsISupports
#define NO_ADDITIONAL_INFORMATION 0
%}
[scriptable, builtinclass, uuid(05568ae9-9873-46c6-9acd-0f6994cde756)]
[scriptable, builtinclass, uuid(413e8bff-9f65-41a0-953f-b82e6cdbc00d)]
interface nsIMobileConnectionCallback : nsISupports
{
/**
@ -166,6 +166,8 @@ interface nsIMobileConnectionCallback : nsISupports
void notifyGetClirStatusSuccess(in unsigned short n, in unsigned short m);
void notifyGetPreferredNetworkTypeSuccess(in long type);
/**
* notifyError() will be called, when request is failed.
*/
@ -233,7 +235,7 @@ already_AddRefed<nsIMobileConnectionService>
NS_CreateMobileConnectionService();
%}
[scriptable, uuid(99818dc7-e770-4249-87e2-2de0a928ed08)]
[scriptable, uuid(d6b15551-d290-4e38-9749-d21eb35cdaf1)]
interface nsIMobileConnection : nsISupports
{
/*
@ -310,6 +312,22 @@ interface nsIMobileConnection : nsISupports
const long MOBILE_RADIO_STATE_DISABLING = 2;
const long MOBILE_RADIO_STATE_DISABLED = 3;
/**
* Preferred network type.
*/
const long PREFERRED_NETWORK_TYPE_WCDMA_GSM = 0;
const long PREFERRED_NETWORK_TYPE_GSM_ONLY = 1;
const long PREFERRED_NETWORK_TYPE_WCDMA_ONLY = 2;
const long PREFERRED_NETWORK_TYPE_WCDMA_GSM_AUTO = 3;
const long PREFERRED_NETWORK_TYPE_CDMA_EVDO = 4;
const long PREFERRED_NETWORK_TYPE_CDMA_ONLY = 5;
const long PREFERRED_NETWORK_TYPE_EVDO_ONLY = 6;
const long PREFERRED_NETWORK_TYPE_WCDMA_GSM_CDMA_EVDO = 7;
const long PREFERRED_NETWORK_TYPE_LTE_CDMA_EVDO = 8;
const long PREFERRED_NETWORK_TYPE_LTE_WCDMA_GSM = 9;
const long PREFERRED_NETWORK_TYPE_LTE_WCDMA_GSM_CDMA_EVDO = 10;
const long PREFERRED_NETWORK_TYPE_LTE_ONLY = 11;
readonly attribute unsigned long serviceId;
/**
@ -418,11 +436,7 @@ interface nsIMobileConnection : nsISupports
* Set preferred network type.
*
* @param type
* DOMString indicates the desired preferred network type.
* Possible values: 'wcdma/gsm', 'gsm', 'wcdma', 'wcdma/gsm-auto',
* 'cdma/evdo', 'cdma', 'evdo', 'wcdma/gsm/cdma/evdo',
* 'lte/cdma/evdo', 'lte/wcdma/gsm', 'lte/wcdma/gsm/cdma/evdo' or
* 'lte'.
* One of the nsIMobileConnection.PREFERRED_NETWORK_TYPE_* values.
* @param requestCallback
* Called when request is finished.
*
@ -432,7 +446,7 @@ interface nsIMobileConnection : nsISupports
* 'RadioNotAvailable', 'RequestNotSupported', 'InvalidParameter',
* 'IllegalSIMorME', or 'GenericFailure'.
*/
void setPreferredNetworkType(in DOMString type,
void setPreferredNetworkType(in long type,
in nsIMobileConnectionCallback requestCallback);
/**
@ -441,11 +455,10 @@ interface nsIMobileConnection : nsISupports
* @param requestCallback
* Called when request is finished.
*
* If successful, the notifySuccessString() will be called. And the result
* will be a string indicating the current preferred network type. The value
* will be either 'wcdma/gsm', 'gsm', 'wcdma', 'wcdma/gsm-auto', 'cdma/evdo',
* 'cdma', 'evdo', 'wcdma/gsm/cdma/evdo', 'lte/cdma/evdo', 'lte/wcdma/gsm',
* 'lte/wcdma/gsm/cdma/evdo' or 'lte'.
* If successful, the notifyGetPreferredNetworkTypeSuccess() will be called,
* and the result 'type' will be one of the
* nsIMobileConnection.PREFERRED_NETWORK_TYPE_* values, indicating the current
* preferred network type.
*
* Otherwise, the notifyError() will be called, and the error will be either
* 'RadioNotAvailable', 'RequestNotSupported', 'IllegalSIMorME', or

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

@ -178,11 +178,10 @@ MobileConnectionChild::SelectNetworkAutomatically(nsIMobileConnectionCallback* a
NS_IMETHODIMP
MobileConnectionChild::SetPreferredNetworkType(const nsAString& aType,
MobileConnectionChild::SetPreferredNetworkType(int32_t aType,
nsIMobileConnectionCallback* aCallback)
{
return SendRequest(SetPreferredNetworkTypeRequest(nsAutoString(aType)),
aCallback)
return SendRequest(SetPreferredNetworkTypeRequest(aType), aCallback)
? NS_OK : NS_ERROR_FAILURE;
}
@ -661,6 +660,12 @@ MobileConnectionRequestChild::DoReply(const MobileConnectionReplySuccessClirStat
aReply.m()));
}
bool
MobileConnectionRequestChild::DoReply(const MobileConnectionReplySuccessPreferredNetworkType& aReply)
{
return NS_SUCCEEDED(mRequestCallback->NotifyGetPreferredNetworkTypeSuccess(aReply.type()));
}
bool
MobileConnectionRequestChild::DoReply(const MobileConnectionReplyError& aReply)
{
@ -715,6 +720,8 @@ MobileConnectionRequestChild::Recv__delete__(const MobileConnectionReply& aReply
return DoReply(aReply.get_MobileConnectionReplySuccessCallBarring());
case MobileConnectionReply::TMobileConnectionReplySuccessClirStatus:
return DoReply(aReply.get_MobileConnectionReplySuccessClirStatus());
case MobileConnectionReply::TMobileConnectionReplySuccessPreferredNetworkType:
return DoReply(aReply.get_MobileConnectionReplySuccessPreferredNetworkType());
case MobileConnectionReply::TMobileConnectionReplyError:
return DoReply(aReply.get_MobileConnectionReplyError());
case MobileConnectionReply::TMobileConnectionReplyErrorMmi:

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

@ -163,6 +163,9 @@ public:
bool
DoReply(const MobileConnectionReplySuccessClirStatus& aReply);
bool
DoReply(const MobileConnectionReplySuccessPreferredNetworkType& aReply);
bool
DoReply(const MobileConnectionReplyError& aReply);

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

@ -642,6 +642,12 @@ MobileConnectionRequestParent::NotifyGetClirStatusSuccess(uint16_t aN,
return SendReply(MobileConnectionReplySuccessClirStatus(aN, aM));
}
NS_IMETHODIMP
MobileConnectionRequestParent::NotifyGetPreferredNetworkTypeSuccess(int32_t aType)
{
return SendReply(MobileConnectionReplySuccessPreferredNetworkType(aType));
}
NS_IMETHODIMP
MobileConnectionRequestParent::NotifyError(const nsAString& aName,
const nsAString& aMessage,

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

@ -72,7 +72,7 @@ struct SelectNetworkAutoRequest
struct SetPreferredNetworkTypeRequest
{
nsString type;
int32_t type;
};
struct GetPreferredNetworkTypeRequest

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

@ -70,6 +70,11 @@ struct MobileConnectionReplySuccessClirStatus
uint16_t m;
};
struct MobileConnectionReplySuccessPreferredNetworkType
{
int32_t type;
};
// Error
struct MobileConnectionReplyError
{
@ -95,6 +100,7 @@ union MobileConnectionReply
MobileConnectionReplySuccessCallForwarding;
MobileConnectionReplySuccessCallBarring;
MobileConnectionReplySuccessClirStatus;
MobileConnectionReplySuccessPreferredNetworkType;
// Error
MobileConnectionReplyError;
MobileConnectionReplyErrorMmi;

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

@ -32,6 +32,9 @@
#include "nsServiceManagerUtils.h"
#include "nsThreadUtils.h"
#include "prtime.h"
#include "mozilla/dom/BindingUtils.h"
#include "mozilla/dom/ScriptSettings.h"
#include "mozilla/dom/SettingChangeNotificationBinding.h"
#ifdef MOZ_B2G_RIL
#include "nsIIccInfo.h"
@ -48,6 +51,7 @@
#define FLUSH_AIDE_DATA 0
using namespace mozilla;
using namespace mozilla::dom;
static const int kDefaultPeriod = 1000; // ms
static bool gDebug_isLoggingEnabled = false;
@ -400,9 +404,21 @@ GonkGPSGeolocationProvider::RequestSettingValue(const char* aKey)
MOZ_ASSERT(ss);
return;
}
nsCOMPtr<nsISettingsServiceLock> lock;
ss->CreateLock(nullptr, getter_AddRefs(lock));
lock->Get(aKey, this);
nsresult rv = ss->CreateLock(nullptr, getter_AddRefs(lock));
if (NS_FAILED(rv)) {
nsContentUtils::LogMessageToConsole(
"geo: error while createLock setting '%s': %d\n", aKey, rv);
return;
}
rv = lock->Get(aKey, this);
if (NS_FAILED(rv)) {
nsContentUtils::LogMessageToConsole(
"geo: error while get setting '%s': %d\n", aKey, rv);
return;
}
}
#ifdef MOZ_B2G_RIL
@ -814,6 +830,10 @@ GonkGPSGeolocationProvider::Startup()
{
MOZ_ASSERT(NS_IsMainThread());
if (mStarted) {
return NS_OK;
}
RequestSettingValue(kSettingDebugEnabled);
RequestSettingValue(kSettingDebugGpsIgnored);
@ -826,10 +846,6 @@ GonkGPSGeolocationProvider::Startup()
}
}
if (mStarted) {
return NS_OK;
}
if (!mInitThread) {
nsresult rv = NS_NewThread(getter_AddRefs(mInitThread));
NS_ENSURE_SUCCESS(rv, rv);
@ -868,6 +884,7 @@ GonkGPSGeolocationProvider::Shutdown()
if (!mStarted) {
return NS_OK;
}
mStarted = false;
if (mNetworkLocationProvider) {
mNetworkLocationProvider->Shutdown();
@ -876,10 +893,17 @@ GonkGPSGeolocationProvider::Shutdown()
nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
if (obs) {
nsresult rv;
#ifdef MOZ_B2G_RIL
obs->RemoveObserver(this, kNetworkConnStateChangedTopic);
rv = obs->RemoveObserver(this, kNetworkConnStateChangedTopic);
if (NS_FAILED(rv)) {
NS_WARNING("geo: Gonk GPS network state RemoveObserver failed");
}
#endif
obs->RemoveObserver(this, kMozSettingsChangedTopic);
rv = obs->RemoveObserver(this, kMozSettingsChangedTopic);
if (NS_FAILED(rv)) {
NS_WARNING("geo: Gonk GPS mozsettings RemoveObserver failed");
}
}
mInitThread->Dispatch(NS_NewRunnableMethod(this, &GonkGPSGeolocationProvider::ShutdownGPS),
@ -991,8 +1015,30 @@ GonkGPSGeolocationProvider::Observe(nsISupports* aSubject,
#endif
if (!strcmp(aTopic, kMozSettingsChangedTopic)) {
RequestSettingValue(kSettingDebugEnabled);
RequestSettingValue(kSettingDebugGpsIgnored);
// Read changed setting value
AutoJSAPI jsapi;
jsapi.Init();
JSContext* cx = jsapi.cx();
RootedDictionary<SettingChangeNotification> setting(cx);
if (!WrappedJSToDictionary(cx, aSubject, setting)) {
return NS_OK;
}
if (setting.mKey.EqualsASCII(kSettingDebugGpsIgnored)) {
nsContentUtils::LogMessageToConsole("geo: received mozsettings-changed: ignoring\n");
gDebug_isGPSLocationIgnored =
setting.mValue.isBoolean() ? setting.mValue.toBoolean() : false;
if (gDebug_isLoggingEnabled) {
nsContentUtils::LogMessageToConsole("geo: Debug: GPS ignored %d\n",
gDebug_isGPSLocationIgnored);
}
return NS_OK;
} else if (setting.mKey.EqualsASCII(kSettingDebugEnabled)) {
nsContentUtils::LogMessageToConsole("geo: received mozsettings-changed: logging\n");
gDebug_isLoggingEnabled =
setting.mValue.isBoolean() ? setting.mValue.toBoolean() : false;
return NS_OK;
}
}
return NS_OK;
@ -1020,18 +1066,8 @@ GonkGPSGeolocationProvider::Handle(const nsAString& aName,
SetAGpsDataConn(apn);
}
}
} else
#endif // MOZ_B2G_RIL
if (aName.EqualsASCII(kSettingDebugGpsIgnored)) {
gDebug_isGPSLocationIgnored = aResult.isBoolean() ? aResult.toBoolean() : false;
if (gDebug_isLoggingEnabled) {
nsContentUtils::LogMessageToConsole("geo: Debug: GPS ignored %d\n", gDebug_isGPSLocationIgnored);
}
return NS_OK;
} else if (aName.EqualsASCII(kSettingDebugEnabled)) {
gDebug_isLoggingEnabled = aResult.isBoolean() ? aResult.toBoolean() : false;
return NS_OK;
}
#endif // MOZ_B2G_RIL
return NS_OK;
}

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

@ -683,8 +683,7 @@ RILContentHelper.prototype = {
} else {
if (data.rilMessageType == "iccSetCardLock" ||
data.rilMessageType == "iccUnlockCardLock") {
let cardLockError = new requestWindow.IccCardLockError(data.lockType,
data.errorMsg,
let cardLockError = new requestWindow.IccCardLockError(data.errorMsg,
data.retryCount);
this.fireRequestDetailedError(requestId, cardLockError);
} else {

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

@ -1333,8 +1333,8 @@ RilObject.prototype = {
* RIL_PREFERRED_NETWORK_TYPE_TO_GECKO as its `type` attribute.
*/
setPreferredNetworkType: function(options) {
let networkType = RIL_PREFERRED_NETWORK_TYPE_TO_GECKO.indexOf(options.type);
if (networkType < 0) {
let networkType = options.type;
if (networkType < 0 || networkType >= RIL_PREFERRED_NETWORK_TYPE_TO_GECKO.length) {
options.errorMsg = GECKO_ERROR_INVALID_PARAMETER;
this.sendChromeMessage(options);
return;
@ -5874,6 +5874,12 @@ RilObject.prototype[REQUEST_QUERY_CALL_WAITING] =
options.success = (options.rilRequestError === 0);
if (!options.success) {
options.errorMsg = RIL_ERROR_TO_GECKO_ERROR[options.rilRequestError];
if (options.callback) {
// Prevent DataCloneError when sending chrome messages.
delete options.callback;
}
this.sendChromeMessage(options);
return;
}
@ -5894,6 +5900,12 @@ RilObject.prototype[REQUEST_SET_CALL_WAITING] = function REQUEST_SET_CALL_WAITIN
options.success = (options.rilRequestError === 0);
if (!options.success) {
options.errorMsg = RIL_ERROR_TO_GECKO_ERROR[options.rilRequestError];
if (options.callback) {
// Prevent DataCloneError when sending chrome messages.
delete options.callback;
}
this.sendChromeMessage(options);
return;
}
@ -6292,8 +6304,7 @@ RilObject.prototype[REQUEST_GET_PREFERRED_NETWORK_TYPE] = function REQUEST_GET_P
return;
}
let networkType = this.context.Buf.readInt32List()[0];
options.type = RIL_PREFERRED_NETWORK_TYPE_TO_GECKO[networkType];
options.type = this.context.Buf.readInt32List()[0];
this.sendChromeMessage(options);
};
RilObject.prototype[REQUEST_GET_NEIGHBORING_CELL_IDS] = function REQUEST_GET_NEIGHBORING_CELL_IDS(length, options) {
@ -8519,7 +8530,7 @@ GsmPDUHelperObject.prototype = {
switch (msg.encoding) {
case PDU_DCS_MSG_CODING_7BITS_ALPHABET:
msg.body = this.readSeptetsToString.call(bufAdapter,
(length * 8 / 7), 0,
Math.floor(length * 8 / 7), 0,
PDU_NL_IDENTIFIER_DEFAULT,
PDU_NL_IDENTIFIER_DEFAULT);
if (msg.hasLanguageIndicator) {
@ -8616,7 +8627,7 @@ GsmPDUHelperObject.prototype = {
msg.body = "";
for (let i = 0; i < numOfPages; i++) {
body = this.readSeptetsToString.call(bufAdapter,
(pageLengths[i] * 8 / 7),
Math.floor(pageLengths[i] * 8 / 7),
0,
PDU_NL_IDENTIFIER_DEFAULT,
PDU_NL_IDENTIFIER_DEFAULT);
@ -8846,7 +8857,7 @@ GsmPDUHelperObject.prototype = {
case 0:
// GSM Default alphabet.
resultString = this.readSeptetsToString(
((len - 1) * 8 - spareBits) / 7, 0,
Math.floor(((len - 1) * 8 - spareBits) / 7), 0,
PDU_NL_IDENTIFIER_DEFAULT,
PDU_NL_IDENTIFIER_DEFAULT);
break;
@ -11261,7 +11272,8 @@ StkProactiveCmdHelperObject.prototype = {
length--; // -1 for the codingScheme.
switch (text.codingScheme & 0x0c) {
case STK_TEXT_CODING_GSM_7BIT_PACKED:
text.textString = GsmPDUHelper.readSeptetsToString(length * 8 / 7, 0, 0, 0);
text.textString =
GsmPDUHelper.readSeptetsToString(Math.floor(length * 8 / 7), 0, 0, 0);
break;
case STK_TEXT_CODING_GSM_8BIT:
text.textString =

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

@ -5,19 +5,113 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/dom/TVServiceRunnables.h"
#include "mozilla/dom/TVTypes.h"
#include "nsCOMPtr.h"
#include "nsIMutableArray.h"
#include "nsITimer.h"
#include "nsServiceManagerUtils.h"
#include "prtime.h"
#include "FakeTVService.h"
namespace mozilla {
namespace dom {
NS_IMPL_ISUPPORTS(FakeTVService, nsITVService)
NS_IMPL_CYCLE_COLLECTION_CLASS(FakeTVService)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(FakeTVService)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSourceListener)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mTuners)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mChannels)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPrograms)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mEITBroadcastedTimer)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mScanCompleteTimer)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(FakeTVService)
tmp->Shutdown();
NS_IMPL_CYCLE_COLLECTION_UNLINK(mSourceListener)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mTuners)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mChannels)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mPrograms)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mEITBroadcastedTimer)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mScanCompleteTimer)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTING_ADDREF(FakeTVService)
NS_IMPL_CYCLE_COLLECTING_RELEASE(FakeTVService)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(FakeTVService)
NS_INTERFACE_MAP_ENTRY(nsITVService)
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_END
FakeTVService::FakeTVService()
{
Init();
}
FakeTVService::~FakeTVService()
{
Shutdown();
}
void
FakeTVService::Init()
{
const char* sourceTypes1[2] = {"dvb-t", "dvb-c"};
nsCOMPtr<nsITVTunerData> tunerData1 = MockTuner(NS_LITERAL_STRING("1"), 2, sourceTypes1);
mTuners.AppendElement(tunerData1);
const char* sourceTypes2[1] = {"dvb-s"};
nsCOMPtr<nsITVTunerData> tunerData2 = MockTuner(NS_LITERAL_STRING("2"), 1, sourceTypes2);
mTuners.AppendElement(tunerData2);
nsCOMPtr<nsITVChannelData> channelData1 =
MockChannel(NS_LITERAL_STRING("networkId1"), NS_LITERAL_STRING("transportStreamId1"),
NS_LITERAL_STRING("serviceId1"), NS_LITERAL_STRING("tv"),
NS_LITERAL_STRING("1"), NS_LITERAL_STRING("name1"), true, true);
mChannels.AppendElement(channelData1);
nsCOMPtr<nsITVChannelData> channelData2 =
MockChannel(NS_LITERAL_STRING("networkId2"), NS_LITERAL_STRING("transportStreamId2"),
NS_LITERAL_STRING("serviceId2"), NS_LITERAL_STRING("radio"),
NS_LITERAL_STRING("2"), NS_LITERAL_STRING("name2"), true, true);
mChannels.AppendElement(channelData2);
uint64_t now = PR_Now();
const char* audioLanguages1[2] = {"eng", "jpn"};
const char* subtitleLanguages1[2] = {"fre", "spa"};
nsCOMPtr<nsITVProgramData> programData1 =
MockProgram(NS_LITERAL_STRING("eventId1"), NS_LITERAL_STRING("title1"),
now - 1, 3600000,
NS_LITERAL_STRING("description1"), NS_LITERAL_STRING("rating1"),
2, audioLanguages1, 2, subtitleLanguages1);
mPrograms.AppendElement(programData1);
nsCOMPtr<nsITVProgramData> programData2 =
MockProgram(NS_LITERAL_STRING("eventId2"), NS_LITERAL_STRING("title2"),
now + 3600000 , 3600000,
NS_LITERAL_STRING(""), NS_LITERAL_STRING(""),
0, nullptr, 0, nullptr);
mPrograms.AppendElement(programData2);
}
void
FakeTVService::Shutdown()
{
if (mEITBroadcastedTimer) {
mEITBroadcastedTimer->Cancel();
}
if (mScanCompleteTimer) {
mScanCompleteTimer->Cancel();
}
}
/* virtual */ NS_IMETHODIMP
FakeTVService::GetSourceListener(nsITVSourceListener** aSourceListener)
{
if (!mSourceListener) {
*aSourceListener = nullptr;
return NS_OK;
}
*aSourceListener = mSourceListener;
NS_ADDREF(*aSourceListener);
return NS_OK;
@ -42,7 +136,9 @@ FakeTVService::GetTuners(nsITVServiceCallback* aCallback)
return NS_ERROR_OUT_OF_MEMORY;
}
// TODO Implement in follow-up patches.
for (uint32_t i = 0; i < mTuners.Length(); i++) {
tunerDataList->AppendElement(mTuners[i], false);
}
nsCOMPtr<nsIRunnable> runnable =
new TVServiceNotifyRunnable(aCallback, tunerDataList);
@ -58,13 +154,109 @@ FakeTVService::SetSource(const nsAString& aTunerId,
return NS_ERROR_INVALID_ARG;
}
// TODO Implement in follow-up patches.
for (uint32_t i = 0; i < mTuners.Length(); i++) {
nsString tunerId;
mTuners[i]->GetId(tunerId);
if (aTunerId.Equals(tunerId)) {
uint32_t sourceTypeCount;
char** sourceTypes;
mTuners[i]->GetSupportedSourceTypes(&sourceTypeCount, &sourceTypes);
for (uint32_t j = 0; j < sourceTypeCount; j++) {
nsString sourceType;
sourceType.AssignASCII(sourceTypes[j]);
if (aSourceType.Equals(sourceType)) {
NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(sourceTypeCount, sourceTypes);
nsCOMPtr<nsIRunnable> runnable =
new TVServiceNotifyRunnable(aCallback, nullptr);
return NS_DispatchToCurrentThread(runnable);
}
}
NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(sourceTypeCount, sourceTypes);
}
}
nsCOMPtr<nsIRunnable> runnable =
new TVServiceNotifyRunnable(aCallback, nullptr);
new TVServiceNotifyRunnable(aCallback, nullptr, nsITVServiceCallback::TV_ERROR_FAILURE);
return NS_DispatchToCurrentThread(runnable);
}
class EITBroadcastedCallback : public nsITimerCallback
{
public:
NS_DECL_ISUPPORTS
EITBroadcastedCallback(const nsAString& aTunerId,
const nsAString& aSourceType,
nsITVSourceListener* aSourceListener,
nsITVChannelData* aChannelData)
: mTunerId(aTunerId)
, mSourceType(aSourceType)
, mSourceListener(aSourceListener)
, mChannelData(aChannelData)
{}
NS_IMETHODIMP
Notify(nsITimer* aTimer)
{
// Notify mock EIT broadcasting.
nsITVProgramData** programDataList =
static_cast<nsITVProgramData **>(NS_Alloc(1 * sizeof(nsITVProgramData*)));
programDataList[0] = new TVProgramData();
programDataList[0]->SetEventId(NS_LITERAL_STRING("eventId"));
programDataList[0]->SetTitle(NS_LITERAL_STRING("title"));
programDataList[0]->SetStartTime(PR_Now() + 3600000);
programDataList[0]->SetDuration(3600000);
programDataList[0]->SetDescription(NS_LITERAL_STRING("description"));
programDataList[0]->SetRating(NS_LITERAL_STRING("rating"));
programDataList[0]->SetAudioLanguages(0, nullptr);
programDataList[0]->SetSubtitleLanguages(0, nullptr);
nsresult rv = mSourceListener->NotifyEITBroadcasted(mTunerId, mSourceType,
mChannelData,
programDataList, 1);
NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(1, programDataList);
return rv;
}
private:
~EITBroadcastedCallback() {}
nsString mTunerId;
nsString mSourceType;
nsCOMPtr<nsITVSourceListener> mSourceListener;
nsCOMPtr<nsITVChannelData> mChannelData;
};
NS_IMPL_ISUPPORTS(EITBroadcastedCallback, nsITimerCallback)
class ScanCompleteCallback : public nsITimerCallback
{
public:
NS_DECL_ISUPPORTS
ScanCompleteCallback(const nsAString& aTunerId,
const nsAString& aSourceType,
nsITVSourceListener* aSourceListener)
: mTunerId(aTunerId)
, mSourceType(aSourceType)
, mSourceListener(aSourceListener)
{}
NS_IMETHODIMP
Notify(nsITimer* aTimer)
{
return mSourceListener->NotifyChannelScanComplete(mTunerId, mSourceType);
}
private:
~ScanCompleteCallback() {}
nsString mTunerId;
nsString mSourceType;
nsCOMPtr<nsITVSourceListener> mSourceListener;
};
NS_IMPL_ISUPPORTS(ScanCompleteCallback, nsITimerCallback)
/* virtual */ NS_IMETHODIMP
FakeTVService::StartScanningChannels(const nsAString& aTunerId,
const nsAString& aSourceType,
@ -74,11 +266,39 @@ FakeTVService::StartScanningChannels(const nsAString& aTunerId,
return NS_ERROR_INVALID_ARG;
}
// TODO Implement in follow-up patches.
nsCOMPtr<nsIRunnable> runnable =
new TVServiceNotifyRunnable(aCallback, nullptr);
return NS_DispatchToCurrentThread(runnable);
nsresult rv = NS_DispatchToCurrentThread(runnable);
NS_ENSURE_SUCCESS(rv, rv);
if (IsAllowed(aTunerId, aSourceType)) {
rv = mSourceListener->NotifyChannelScanned(aTunerId, aSourceType, mChannels[0]);
NS_ENSURE_SUCCESS(rv, rv);
// Set a timer. |notifyEITBroadcasted| will be called after the timer
// fires (10ms). (The timer could be canceled if |StopScanningChannels| gets
// called before firing.)
mEITBroadcastedTimer = do_CreateInstance(NS_TIMER_CONTRACTID);
NS_ENSURE_TRUE(mEITBroadcastedTimer, NS_ERROR_OUT_OF_MEMORY);
nsRefPtr<EITBroadcastedCallback> eitBroadcastedCb =
new EITBroadcastedCallback(aTunerId, aSourceType, mSourceListener, mChannels[0]);
rv = mEITBroadcastedTimer->InitWithCallback(eitBroadcastedCb, 10,
nsITimer::TYPE_ONE_SHOT);
NS_ENSURE_SUCCESS(rv, rv);
// Set a timer. |notifyChannelScanComplete| will be called after the timer
// fires (20ms). (The timer could be canceled if |StopScanningChannels| gets
// called before firing.)
mScanCompleteTimer = do_CreateInstance(NS_TIMER_CONTRACTID);
NS_ENSURE_TRUE(mScanCompleteTimer, NS_ERROR_OUT_OF_MEMORY);
nsRefPtr<ScanCompleteCallback> scanCompleteCb =
new ScanCompleteCallback(aTunerId, aSourceType, mSourceListener);
rv = mScanCompleteTimer->InitWithCallback(scanCompleteCb, 20,
nsITimer::TYPE_ONE_SHOT);
NS_ENSURE_SUCCESS(rv, rv);
}
return NS_OK;
}
/* virtual */ NS_IMETHODIMP
@ -90,7 +310,16 @@ FakeTVService::StopScanningChannels(const nsAString& aTunerId,
return NS_ERROR_INVALID_ARG;
}
// TODO Implement in follow-up patches.
if (mEITBroadcastedTimer) {
mEITBroadcastedTimer->Cancel();
mEITBroadcastedTimer = nullptr;
}
if (mScanCompleteTimer) {
mScanCompleteTimer->Cancel();
mScanCompleteTimer = nullptr;
}
nsresult rv = mSourceListener->NotifyChannelScanStopped(aTunerId, aSourceType);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIRunnable> runnable =
new TVServiceNotifyRunnable(aCallback, nullptr);
@ -100,8 +329,7 @@ FakeTVService::StopScanningChannels(const nsAString& aTunerId,
/* virtual */ NS_IMETHODIMP
FakeTVService::ClearScannedChannelsCache()
{
// TODO Implement in follow-up patches.
// Fake service doesn't support channel cache, so there's nothing to do here.
return NS_OK;
}
@ -120,10 +348,26 @@ FakeTVService::SetChannel(const nsAString& aTunerId,
return NS_ERROR_OUT_OF_MEMORY;
}
// TODO Implement in follow-up patches.
if (IsAllowed(aTunerId, aSourceType)) {
for (uint32_t i = 0; i < mChannels.Length(); i++) {
nsString channelNumber;
mChannels[i]->GetNumber(channelNumber);
if (aChannelNumber.Equals(channelNumber)) {
channelDataList->AppendElement(mChannels[i], false);
break;
}
}
}
nsCOMPtr<nsIRunnable> runnable =
new TVServiceNotifyRunnable(aCallback, channelDataList);
uint32_t length;
nsresult rv = channelDataList->GetLength(&length);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIRunnable> runnable = new TVServiceNotifyRunnable(
aCallback,
(length == 1) ? channelDataList : nullptr,
(length == 1) ? nsITVServiceCallback::TV_ERROR_OK : nsITVServiceCallback::TV_ERROR_FAILURE
);
return NS_DispatchToCurrentThread(runnable);
}
@ -141,7 +385,11 @@ FakeTVService::GetChannels(const nsAString& aTunerId,
return NS_ERROR_OUT_OF_MEMORY;
}
// TODO Implement in follow-up patches.
if (IsAllowed(aTunerId, aSourceType)) {
for (uint32_t i = 0; i < mChannels.Length(); i++) {
channelDataList->AppendElement(mChannels[i], false);
}
}
nsCOMPtr<nsIRunnable> runnable =
new TVServiceNotifyRunnable(aCallback, channelDataList);
@ -165,7 +413,14 @@ FakeTVService::GetPrograms(const nsAString& aTunerId,
return NS_ERROR_OUT_OF_MEMORY;
}
// TODO Implement in follow-up patches.
// Only return mock programs for the first channel.
nsString channelNumber;
mChannels[0]->GetNumber(channelNumber);
if (IsAllowed(aTunerId, aSourceType) && aChannelNumber.Equals(channelNumber)) {
for (uint32_t i = 0; i < mPrograms.Length(); i++) {
programDataList->AppendElement(mPrograms[i], false);
}
}
nsCOMPtr<nsIRunnable> runnable =
new TVServiceNotifyRunnable(aCallback, programDataList);
@ -192,5 +447,86 @@ FakeTVService::GetOverlayId(const nsAString& aTunerId,
return NS_DispatchToCurrentThread(runnable);
}
bool
FakeTVService::IsAllowed(const nsAString& aTunerId,
const nsAString& aSourceType)
{
// Only allow for the first source of the first tuner.
nsString tunerId;
mTuners[0]->GetId(tunerId);
if (!aTunerId.Equals(tunerId)) {
return false;
}
uint32_t sourceTypeCount;
char** sourceTypes;
mTuners[0]->GetSupportedSourceTypes(&sourceTypeCount, &sourceTypes);
nsString sourceType;
sourceType.AssignASCII(sourceTypes[0]);
NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(sourceTypeCount, sourceTypes);
if (!aSourceType.Equals(sourceType)) {
return false;
}
return true;
}
already_AddRefed<nsITVTunerData>
FakeTVService::MockTuner(const nsAString& aId,
uint32_t aSupportedSourceTypeCount,
const char** aSupportedSourceTypes)
{
nsCOMPtr<nsITVTunerData> tunerData = new TVTunerData();
tunerData->SetId(aId);
tunerData->SetSupportedSourceTypes(aSupportedSourceTypeCount, aSupportedSourceTypes);
return tunerData.forget();
}
already_AddRefed<nsITVChannelData>
FakeTVService::MockChannel(const nsAString& aNetworkId,
const nsAString& aTransportStreamId,
const nsAString& aServiceId,
const nsAString& aType,
const nsAString& aNumber,
const nsAString& aName,
bool aIsEmergency,
bool aIsFree)
{
nsCOMPtr<nsITVChannelData> channelData = new TVChannelData();
channelData->SetNetworkId(aNetworkId);
channelData->SetTransportStreamId(aTransportStreamId);
channelData->SetServiceId(aServiceId);
channelData->SetType(aType);
channelData->SetNumber(aNumber);
channelData->SetName(aName);
channelData->SetIsEmergency(aIsEmergency);
channelData->SetIsFree(aIsFree);
return channelData.forget();
}
already_AddRefed<nsITVProgramData>
FakeTVService::MockProgram(const nsAString& aEventId,
const nsAString& aTitle,
uint64_t aStartTime,
uint64_t aDuration,
const nsAString& aDescription,
const nsAString& aRating,
uint32_t aAudioLanguageCount,
const char** aAudioLanguages,
uint32_t aSubtitleLanguageCount,
const char** aSubtitleLanguages)
{
nsCOMPtr<nsITVProgramData> programData = new TVProgramData();
programData->SetEventId(aEventId);
programData->SetTitle(aTitle);
programData->SetStartTime(aStartTime);
programData->SetDuration(aDuration);
programData->SetDescription(aDescription);
programData->SetRating(aRating);
programData->SetAudioLanguages(aAudioLanguageCount, aAudioLanguages);
programData->SetSubtitleLanguages(aSubtitleLanguageCount, aSubtitleLanguages);
return programData.forget();
}
} // namespace dom
} // namespace mozilla

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

@ -8,30 +8,74 @@
#define mozilla_dom_FakeTVService_h
#include "nsCOMPtr.h"
#include "nsCycleCollectionParticipant.h"
#include "nsITVService.h"
#include "nsTArray.h"
#define FAKE_TV_SERVICE_CONTRACTID \
"@mozilla.org/tv/faketvservice;1"
#define FAKE_TV_SERVICE_CID \
{ 0x60fb3c53, 0x017f, 0x4340, { 0x91, 0x1b, 0xd5, 0x5c, 0x31, 0x28, 0x88, 0xb6 } }
class nsITimer;
class nsITVTunerData;
class nsITVChannelData;
class nsITVProgramData;
namespace mozilla {
namespace dom {
class FakeTVService MOZ_FINAL : public nsITVService
{
public:
NS_DECL_ISUPPORTS
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_CLASS(FakeTVService)
NS_DECL_NSITVSERVICE
FakeTVService() {}
// TODO More members might be added in follow-up patches to help testing.
FakeTVService();
private:
~FakeTVService() {}
~FakeTVService();
void Init();
void Shutdown();
bool IsAllowed(const nsAString& aTunerId,
const nsAString& aSourceType);
already_AddRefed<nsITVTunerData> MockTuner(const nsAString& aId,
uint32_t aSupportedSourceTypeCount,
const char** aSupportedSourceTypes);
already_AddRefed<nsITVChannelData> MockChannel(const nsAString& aNetworkId,
const nsAString& aTransportStreamId,
const nsAString& aServiceId,
const nsAString& aType,
const nsAString& aNumber,
const nsAString& aName,
bool aIsEmergency,
bool aIsFree);
already_AddRefed<nsITVProgramData> MockProgram(const nsAString& aEventId,
const nsAString& aTitle,
uint64_t aStartTime,
uint64_t aDuration,
const nsAString& aDescription,
const nsAString& aRating,
uint32_t aAudioLanguageCount,
const char** aAudioLanguages,
uint32_t aSubtitleLanguageCount,
const char** aSubtitleLanguages);
nsCOMPtr<nsITVSourceListener> mSourceListener;
// The real implementation may want to use more efficient data structures.
nsTArray<nsCOMPtr<nsITVTunerData>> mTuners;
nsTArray<nsCOMPtr<nsITVChannelData>> mChannels;
nsTArray<nsCOMPtr<nsITVProgramData>> mPrograms;
nsCOMPtr<nsITimer> mEITBroadcastedTimer;
nsCOMPtr<nsITimer> mScanCompleteTimer;
};
} // namespace dom

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

@ -12,39 +12,30 @@
namespace mozilla {
namespace dom {
NS_IMPL_ISUPPORTS(TVSourceListener, nsITVSourceListener)
NS_IMPL_CYCLE_COLLECTION(TVSourceListener, mSources)
NS_IMPL_CYCLE_COLLECTING_ADDREF(TVSourceListener)
NS_IMPL_CYCLE_COLLECTING_RELEASE(TVSourceListener)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(TVSourceListener)
NS_INTERFACE_MAP_ENTRY(nsITVSourceListener)
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_END
void
TVSourceListener::RegisterSource(TVSource* aSource)
{
nsString tunerId;
nsRefPtr<TVTuner> tuner = aSource->Tuner();
tuner->GetId(tunerId);
nsRefPtrHashtable<nsStringHashKey, TVSource>* tunerSources = nullptr;
if (!mSources.Get(tunerId, &tunerSources)) {
tunerSources = new nsRefPtrHashtable<nsStringHashKey, TVSource>();
mSources.Put(tunerId, tunerSources);
}
nsString sourceType = ToTVSourceTypeStr(aSource->Type());
tunerSources->Put(sourceType, aSource);
mSources.AppendElement(aSource);
}
void
TVSourceListener::UnregisterSource(TVSource* aSource)
{
nsString tunerId;
nsRefPtr<TVTuner> tuner = aSource->Tuner();
tuner->GetId(tunerId);
nsRefPtrHashtable<nsStringHashKey, TVSource>* tunerSources = nullptr;
if (!mSources.Get(tunerId, &tunerSources)) {
return;
for (uint32_t i = 0; i < mSources.Length(); i++) {
if (mSources[i] == aSource) {
mSources.RemoveElementsAt(i, 1);
}
}
nsString sourceType = ToTVSourceTypeStr(aSource->Type());
tunerSources->Remove(sourceType);
}
/* virtual */ NS_IMETHODIMP
@ -91,14 +82,20 @@ already_AddRefed<TVSource>
TVSourceListener::GetSource(const nsAString& aTunerId,
const nsAString& aSourceType)
{
nsRefPtrHashtable<nsStringHashKey, TVSource>* tunerSources = nullptr;
if (!mSources.Get(aTunerId, &tunerSources)) {
return nullptr;
for (uint32_t i = 0; i < mSources.Length(); i++) {
nsString tunerId;
nsRefPtr<TVTuner> tuner = mSources[i]->Tuner();
tuner->GetId(tunerId);
nsString sourceType = ToTVSourceTypeStr(mSources[i]->Type());
if (aTunerId.Equals(tunerId) && aSourceType.Equals(sourceType)) {
nsRefPtr<TVSource> source = mSources[i];
return source.forget();
}
}
nsRefPtr<TVSource> source;
tunerSources->Get(aSourceType, getter_AddRefs(source));
return source.forget();
return nullptr;
}
} // namespace dom

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

@ -7,19 +7,19 @@
#ifndef mozilla_dom_TVListeners_h
#define mozilla_dom_TVListeners_h
#include "nsClassHashtable.h"
#include "mozilla/dom/TVSource.h"
#include "nsCycleCollectionParticipant.h"
#include "nsITVService.h"
#include "nsRefPtrHashtable.h"
#include "nsTArray.h"
namespace mozilla {
namespace dom {
class TVSource;
class TVSourceListener : public nsITVSourceListener
{
public:
NS_DECL_ISUPPORTS
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_CLASS(TVSourceListener)
NS_DECL_NSITVSOURCELISTENER
void RegisterSource(TVSource* aSource);
@ -32,9 +32,7 @@ private:
already_AddRefed<TVSource> GetSource(const nsAString& aTunerId,
const nsAString& aSourceType);
// The tuner ID acts as the key of the outer table; whereas the source type is
// the key for the inner one.
nsClassHashtable<nsStringHashKey, nsRefPtrHashtable<nsStringHashKey, TVSource>> mSources;
nsTArray<nsRefPtr<TVSource>> mSources;
};
} // namespace dom

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

@ -17,6 +17,12 @@ namespace dom {
NS_IMPL_ISUPPORTS(TVTunerData, nsITVTunerData)
TVTunerData::TVTunerData()
: mSupportedSourceTypes(nullptr)
, mCount(0)
{
}
TVTunerData::~TVTunerData()
{
if (mSupportedSourceTypes) {
@ -97,6 +103,16 @@ TVTunerData::SetSupportedSourceTypes(uint32_t aCount,
NS_IMPL_ISUPPORTS(TVChannelData, nsITVChannelData)
TVChannelData::TVChannelData()
: mIsEmergency(false)
, mIsFree(false)
{
}
TVChannelData::~TVChannelData()
{
}
/* virtual */ NS_IMETHODIMP
TVChannelData::GetNetworkId(nsAString& aNetworkId)
{
@ -244,6 +260,14 @@ TVChannelData::SetIsFree(bool aIsFree)
NS_IMPL_ISUPPORTS(TVProgramData, nsITVProgramData)
TVProgramData::TVProgramData()
: mAudioLanguages(nullptr)
, mAudioLanguageCount(0)
, mSubtitleLanguages(nullptr)
, mSubtitleLanguageCount(0)
{
}
TVProgramData::~TVProgramData()
{
if (mAudioLanguages) {

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

@ -18,6 +18,8 @@ public:
NS_DECL_ISUPPORTS
NS_DECL_NSITVTUNERDATA
TVTunerData();
private:
~TVTunerData();
@ -32,8 +34,10 @@ public:
NS_DECL_ISUPPORTS
NS_DECL_NSITVCHANNELDATA
TVChannelData();
private:
~TVChannelData() {}
~TVChannelData();
nsString mNetworkId;
nsString mTransportStreamId;
@ -51,6 +55,8 @@ public:
NS_DECL_ISUPPORTS
NS_DECL_NSITVPROGRAMDATA
TVProgramData();
private:
~TVProgramData();

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

@ -4,8 +4,6 @@
# 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/.
TEST_DIRS += ['test']
EXPORTS.mozilla.dom += [
'FakeTVService.h',
'TVChannel.h',
@ -40,6 +38,10 @@ XPIDL_SOURCES += [
XPIDL_MODULE = 'dom_tv'
MOCHITEST_MANIFESTS += ['test/mochitest/mochitest.ini']
XPCSHELL_TESTS_MANIFESTS += ['test/xpcshell/xpcshell.ini']
include('/ipc/chromium/chromium-config.mozbuild')
FINAL_LIBRARY = 'xul'

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

@ -1,7 +0,0 @@
[DEFAULT]
support-files =
file_app.sjs
file_app.template.webapp
file_tv_non_permitted_app.html
[test_tv_non_permitted_app.html]

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

@ -1,4 +1,4 @@
var gBasePath = "tests/dom/tv/test/";
var gBasePath = "tests/dom/tv/test/mochitest/";
function handleRequest(request, response) {
var query = getQuery(request);

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

@ -1,6 +1,6 @@
{
"name": "TV Test App (hosted)",
"description": "Hosted TV test app used for mochitest.",
"launch_path": "/tests/dom/tv/test/TESTTOKEN",
"launch_path": "/tests/dom/tv/test/mochitest/TESTTOKEN",
"icons": { "128": "default_icon" }
}

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

@ -0,0 +1,60 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Test GetChannels for TV API</title>
</head>
<body>
<div id="content"></div>
<script type="application/javascript" src="./test_helpers.js"></script>
<script type="application/javascript;version=1.7">
ok('tv' in navigator, "navigator.tv should exist.");
navigator.tv.getTuners().then(
function(aTuners) {
ok(aTuners.length > 0, "Got at least 1 tuner.");
aTuners[0].getSources().then(
function(aSources) {
ok(aSources.length > 0, "Got at least 1 source.");
aSources[0].getChannels().then(
function(aChannels) {
ok(aChannels.length > 0, "Got at least 1 channel.");
for (var i = 0; i < aChannels.length; i++) {
var channel = aChannels[i];
ok(channel instanceof TVChannel, "Channel " + i + " should be in right type.")
ok('source' in channel, "Channel " + i + " should have a source.");
ok('networkId' in channel, "Channel " + i + " should have a network ID.");
ok('transportStreamId' in channel, "Channel " + i + " should have a transport stream ID.");
ok('serviceId' in channel, "Channel " + i + " should have a service ID.");
ok('type' in channel, "Channel " + i + " should have a type.");
ok('name' in channel, "Channel " + i + " should have a name.");
ok('number' in channel, "Channel " + i + " should have a number.");
}
finish();
},
function(aError) {
ok(false, "Error occurred when getting channels: " + aError);
finish();
}
);
},
function(aError) {
ok(false, "Error occurred when getting sources: " + aError);
finish();
}
);
},
function(aError) {
ok(false, "Error occurred when getting tuners: " + aError);
finish();
}
);
</script>
</body>
</html>

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

@ -0,0 +1,58 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Test an error case for GetChannels during scanning for TV API</title>
</head>
<body>
<div id="content"></div>
<script type="application/javascript" src="./test_helpers.js"></script>
<script type="application/javascript;version=1.7">
ok('tv' in navigator, "navigator.tv should exist.");
navigator.tv.getTuners().then(
function(aTuners) {
ok(aTuners.length > 0, "Got at least 1 tuner.");
aTuners[0].getSources().then(
function(aSources) {
ok(aSources.length > 0, "Got at least 1 source.");
var source = aSources[0];
// TODO Bug 1088818 - Modify the behavior of channel scanning.
source.startScanning({}).then(
function() {
source.getChannels().then(
function() {
ok(false, "Getting channels during scanning should get error.");
finish();
},
function(aError) {
is(aError.name, "InvalidStateError",
"InvalidStateError should be expected.");
finish();
}
);
},
function(aError) {
ok(false, "Error occurred when starting scanning: " + aError);
finish();
}
);
},
function(aError) {
ok(false, "Error occurred when getting sources: " + aError);
finish();
}
);
},
function(aError) {
ok(false, "Error occurred when getting tuners: " + aError);
finish();
}
);
</script>
</body>
</html>

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

@ -0,0 +1,68 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Test GetCurrentProgram for TV API</title>
</head>
<body>
<div id="content"></div>
<script type="application/javascript" src="./test_helpers.js"></script>
<script type="application/javascript;version=1.7">
ok('tv' in navigator, "navigator.tv should exist.");
navigator.tv.getTuners().then(
function(aTuners) {
ok(aTuners.length > 0, "Got at least 1 tuner.");
aTuners[0].getSources().then(
function(aSources) {
ok(aSources.length > 0, "Got at least 1 source.");
aSources[0].getChannels().then(
function(aChannels) {
ok(aChannels.length > 0, "Got at least 1 channel.");
aChannels[0].getCurrentProgram().then(
function(aCurrentProgram) {
ok(aCurrentProgram, "Got the current program.");
ok(aCurrentProgram instanceof TVProgram, "The current program should be in the right type.")
ok('channel' in aCurrentProgram, "The current program should have a channel.");
ok('eventId' in aCurrentProgram, "The current program should have an event ID.");
ok('title' in aCurrentProgram, "The current program should have a title.");
ok('startTime' in aCurrentProgram, "The current program should have start time.");
ok('duration' in aCurrentProgram, "The current program should have duration.");
ok(aCurrentProgram.getAudioLanguages().length >= 0,
"The current program may have audio language(s).");
ok(aCurrentProgram.getSubtitleLanguages().length >= 0,
"The current program may have subtitle language(s).");
finish();
},
function(aError) {
ok(false, "Error occurred when getting programs: " + aError);
finish();
}
);
},
function(aError) {
ok(false, "Error occurred when getting channels: " + aError);
finish();
}
);
},
function(aError) {
ok(false, "Error occurred when getting sources: " + aError);
finish();
}
);
},
function(aError) {
ok(false, "Error occurred when getting tuners: " + aError);
finish();
}
);
</script>
</body>
</html>

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

@ -0,0 +1,71 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Test GetPrograms for TV API</title>
</head>
<body>
<div id="content"></div>
<script type="application/javascript" src="./test_helpers.js"></script>
<script type="application/javascript;version=1.7">
ok('tv' in navigator, "navigator.tv should exist.");
navigator.tv.getTuners().then(
function(aTuners) {
ok(aTuners.length > 0, "Got at least 1 tuner.");
aTuners[0].getSources().then(
function(aSources) {
ok(aSources.length > 0, "Got at least 1 source.");
aSources[0].getChannels().then(
function(aChannels) {
ok(aChannels.length > 0, "Got at least 1 channel.");
aChannels[0].getPrograms().then(
function(aPrograms) {
ok(aPrograms.length > 0, "Got at least 1 program.");
for (var i = 0; i < aPrograms.length; i++) {
var program = aPrograms[i];
ok(program instanceof TVProgram, "Program " + i + " should be in the right type.")
ok('channel' in program, "Program " + i + " should have a channel.");
ok('eventId' in program, "Program " + i + " should have an event ID.");
ok('title' in program, "Program " + i + " should have a title.");
ok('startTime' in program, "Program " + i + " should have start time.");
ok('duration' in program, "Program " + i + " should have duration.");
ok(program.getAudioLanguages().length >= 0,
"Program " + i + " may have audio language(s).");
ok(program.getSubtitleLanguages().length >= 0,
"Program " + i + " may have subtitle language(s).");
}
finish();
},
function(aError) {
ok(false, "Error occurred when getting programs: " + aError);
finish();
}
);
},
function(aError) {
ok(false, "Error occurred when getting channels: " + aError);
finish();
}
);
},
function(aError) {
ok(false, "Error occurred when getting sources: " + aError);
finish();
}
);
},
function(aError) {
ok(false, "Error occurred when getting tuners: " + aError);
finish();
}
);
</script>
</body>
</html>

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

@ -0,0 +1,49 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Test GetSources for TV API</title>
</head>
<body>
<div id="content"></div>
<script type="application/javascript" src="./test_helpers.js"></script>
<script type="application/javascript;version=1.7">
ok('tv' in navigator, "navigator.tv should exist.");
navigator.tv.getTuners().then(
function(aTuners) {
ok(aTuners.length > 0, "Got at least 1 tuner.");
aTuners[0].getSources().then(
function(aSources) {
ok(aSources.length > 0, "Got at least 1 source.");
for (var i = 0; i < aSources.length; i++) {
var source = aSources[i];
ok(source instanceof TVSource, "Source " + i + " should be in the right type.");
ok('tuner' in source, "Source " + i + " should have a tuner.");
ok('type' in source, "Source " + i + " should have a type.");
ok('isScanning' in source, "Source " + i + " should have isScanning.");
ok(!source.isScanning,
"Source " + i + " should not be scanning by default.");
ok(!source.currentChannel,
"Source " + i + " should have no current channel by default.");
}
finish();
},
function(aError) {
ok(false, "Error occurred when getting sources: " + aError);
finish();
}
);
},
function(aError) {
ok(false, "Error occurred when getting tuners: " + aError);
finish();
}
);
</script>
</body>
</html>

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

@ -0,0 +1,38 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Test GetTuners for TV API</title>
</head>
<body>
<div id="content"></div>
<script type="application/javascript" src="./test_helpers.js"></script>
<script type="application/javascript;version=1.7">
ok('tv' in navigator, "navigator.tv should exist.");
navigator.tv.getTuners().then(
function(aTuners) {
ok(aTuners.length > 0, "Got at least 1 tuner.");
for (var i = 0; i < aTuners.length; i++) {
var tuner = aTuners[i];
ok(tuner instanceof TVTuner, "Tuner " + i + " should be in the right type.");
ok('id' in tuner, "Tuner " + i + " should have an ID.");
ok(tuner.getSupportedSourceTypes().length > 0,
"Tuner " + i + " should have supported source type(s).");
ok(!tuner.currentSource,
"Tuner " + i + " should have no current source by default.");
ok(!tuner.stream, "Tuner " + i + " should have no stream by default.");
}
finish();
},
function(aError) {
ok(false, "Error occurred when getting tuners: " + aError);
finish();
}
);
</script>
</body>
</html>

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

@ -6,16 +6,9 @@
</head>
<body>
<div id="content"></div>
<script type="application/javascript" src="./test_helpers.js"></script>
<script type="application/javascript;version=1.7">
function ok(a, msg) {
alert((a ? 'OK' : 'KO')+ ' ' + msg)
}
function finish() {
alert('DONE');
}
ok(!('tv' in navigator),
"navigator.tv should not exist for non-permitted app.");
finish();

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

@ -0,0 +1,16 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Test the availability of TV Manager API for permitted Apps</title>
</head>
<body>
<div id="content"></div>
<script type="application/javascript" src="./test_helpers.js"></script>
<script type="application/javascript;version=1.7">
ok('tv' in navigator, "navigator.tv should exist for permitted app.");
finish();
</script>
</body>
</html>

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

@ -0,0 +1,68 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Test channel scanning complete for TV API</title>
</head>
<body>
<div id="content"></div>
<script type="application/javascript" src="./test_helpers.js"></script>
<script type="application/javascript;version=1.7">
ok('tv' in navigator, "navigator.tv should exist.");
var isScannedEventFired = false;
navigator.tv.getTuners().then(
function(aTuners) {
ok(aTuners.length > 0, "Got at least 1 tuner.");
aTuners[0].getSources().then(
function(aSources) {
ok(aSources.length > 0, "Got at least 1 source.");
var source = aSources[0];
source.oneitbroadcasted = function(aEvent) {
info("Received EIT broadcasted event.");
var programs = aEvent.programs;
for (var i = 0; i < programs.length; i++) {
ok(programs[i], "Program " + i + " should be set.")
}
};
source.onscanningstatechanged = function(aEvent) {
if (aEvent.state === 'scanned') {
isScannedEventFired = true;
info("Received channel scanned event.");
ok(aEvent.channel, "Scanned channel should be set.");
} else if (aEvent.state === 'completed') {
ok(isScannedEventFired, "Received channel scanning completed event after channel scanned event.");
finish();
}
};
// TODO Bug 1088818 - Modify the behavior of channel scanning.
source.startScanning({}).then(
function() {},
function(aError) {
ok(false, "Error occurred when starting scanning: " + aError);
finish();
}
);
},
function(aError) {
ok(false, "Error occurred when getting sources: " + aError);
finish();
}
);
},
function(aError) {
ok(false, "Error occurred when getting tuners: " + aError);
finish();
}
);
</script>
</body>
</html>

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

@ -0,0 +1,66 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Test StartScanning and StopScanning for TV API</title>
</head>
<body>
<div id="content"></div>
<script type="application/javascript" src="./test_helpers.js"></script>
<script type="application/javascript;version=1.7">
ok('tv' in navigator, "navigator.tv should exist.");
var isClearedEventFired = false;
navigator.tv.getTuners().then(
function(aTuners) {
ok(aTuners.length > 0, "Got at least 1 tuner.");
aTuners[0].getSources().then(
function(aSources) {
ok(aSources.length > 0, "Got at least 1 source.");
var source = aSources[0];
source.onscanningstatechanged = function(aEvent) {
if (aEvent.state === 'cleared') {
isClearedEventFired = true;
info("Received channel cache cleared event.");
} else if (aEvent.state === 'stopped') {
ok(isClearedEventFired, "Received channel scanning stopped event after cleared event.");
finish();
}
};
// TODO Bug 1088818 - Modify the behavior of channel scanning.
source.startScanning({ isRescanned: true }).then(
function() {
source.stopScanning().then(
function() {},
function(aError) {
ok(false, "Error occurred when stopping scanning: " + aError);
finish();
}
);
},
function(aError) {
ok(false, "Error occurred when starting scanning: " + aError);
finish();
}
);
},
function(aError) {
ok(false, "Error occurred when getting sources: " + aError);
finish();
}
);
},
function(aError) {
ok(false, "Error occurred when getting tuners: " + aError);
finish();
}
);
</script>
</body>
</html>

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

@ -0,0 +1,70 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Test SetCurrentChannel for TV API</title>
</head>
<body>
<div id="content"></div>
<script type="application/javascript" src="./test_helpers.js"></script>
<script type="application/javascript;version=1.7">
ok('tv' in navigator, "navigator.tv should exist.");
navigator.tv.getTuners().then(
function(aTuners) {
ok(aTuners.length > 0, "Got at least 1 tuner.");
var tuner = aTuners[0];
var selectedSourceType = tuner.getSupportedSourceTypes()[0];
aTuners[0].getSources().then(
function(aSources) {
ok(aSources.length > 0, "Got at least 1 source.");
var source = aSources[0];
source.getChannels().then(
function(aChannels) {
ok(aChannels.length > 0, "Got at least 1 channel.");
var selectedChannelNumber = aChannels[0].number;
source.oncurrentchannelchanged = function(aEvent) {
ok(aEvent instanceof TVCurrentChannelChangedEvent,
"The event is in the right type");
ok(aEvent.channel instanceof TVChannel,
"The channel is in the right type.");
is(aEvent.channel, source.currentChannel,
"The current channel is set.");
is(source.currentChannel.number, selectedChannelNumber,
"The current channel number is correct.");
finish();
};
source.setCurrentChannel(selectedChannelNumber).then(
function() {},
function(aError) {
ok(false, "Error occurred when setting current channel: " + aError);
finish();
}
);
},
function(aError) {
ok(false, "Error occurred when getting channels: " + aError);
finish();
}
);
},
function(aError) {
ok(false, "Error occurred when getting sources: " + aError);
finish();
}
);
},
function(aError) {
ok(false, "Error occurred when getting tuners: " + aError);
finish();
}
);
</script>
</body>
</html>

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

@ -0,0 +1,58 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Test an error case for SetCurrentChannel during scanning for TV API</title>
</head>
<body>
<div id="content"></div>
<script type="application/javascript" src="./test_helpers.js"></script>
<script type="application/javascript;version=1.7">
ok('tv' in navigator, "navigator.tv should exist.");
navigator.tv.getTuners().then(
function(aTuners){
ok(aTuners.length > 0, "Got at least 1 tuner.");
aTuners[0].getSources().then(
function(aSources) {
ok(aSources.length > 0, "Got at least 1 source.");
var source = aSources[0];
// TODO Bug 1088818 - Modify the behavior of channel scanning.
source.startScanning({}).then(
function() {
source.setCurrentChannel("1").then(
function() {
ok(false, "Setting current channel during scanning should get error.");
finish();
},
function(aError) {
is(aError.name, "InvalidStateError",
"InvalidStateError should be expected.");
finish();
}
);
},
function(aError) {
ok(false, "Error occurred when starting scanning: " + aError);
finish();
}
);
},
function(aError) {
ok(false, "Error occurred when getting sources: " + aError);
finish();
}
);
},
function(aError) {
ok(false, "Error occurred when getting tuners: " + aError);
finish();
}
);
</script>
</body>
</html>

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

@ -0,0 +1,48 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Test SetCurrentSource for TV API</title>
</head>
<body>
<div id="content"></div>
<script type="application/javascript" src="./test_helpers.js"></script>
<script type="application/javascript;version=1.7">
ok('tv' in navigator, "navigator.tv should exist.");
navigator.tv.getTuners().then(
function(aTuners) {
ok(aTuners.length > 0, "Got at least 1 tuner.");
var tuner = aTuners[0];
var selectedSourceType = tuner.getSupportedSourceTypes()[0];
tuner.oncurrentsourcechanged = function(aEvent) {
ok(aEvent instanceof TVCurrentSourceChangedEvent,
"The event is in the right type");
ok(aEvent.source instanceof TVSource,
"The source is in the right type.");
is(aEvent.source, tuner.currentSource,
"The current source is set.");
is(tuner.currentSource.type, selectedSourceType,
"The current source type is correct.");
finish();
};
tuner.setCurrentSource(selectedSourceType).then(
function() {},
function(aError) {
ok(false, "Error occurred when setting current source: " + aError);
finish();
}
);
},
function(aError) {
ok(false, "Error occurred when getting tuners: " + aError);
finish();
}
);
</script>
</body>
</html>

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

@ -0,0 +1,49 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Test an error case for SetCurrentChannel for TV API</title>
</head>
<body>
<div id="content"></div>
<script type="application/javascript" src="./test_helpers.js"></script>
<script type="application/javascript;version=1.7">
ok('tv' in navigator, "navigator.tv should exist.");
navigator.tv.getTuners().then(
function(aTuners) {
ok(aTuners.length > 0, "Got at least 1 tuner.");
var tuner = aTuners[0];
var selectedSourceType = tuner.getSupportedSourceTypes()[0];
aTuners[0].getSources().then(
function(aSources) {
ok(aSources.length > 0, "Got at least 1 source.");
aSources[0].setCurrentChannel("NonExistentChannelNumber").then(
function() {
ok(false, "Setting an invalid current channel should get error.");
finish();
},
function(aError) {
is(aError.name, "AbortError", "AbortError should be expected.");
finish();
}
);
},
function(aError) {
ok(false, "Error occurred when getting sources: " + aError);
finish();
}
);
},
function(aError) {
ok(false, "Error occurred when getting tuners: " + aError);
finish();
}
);
</script>
</body>
</html>

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

@ -0,0 +1,36 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Test an error case for SetCurrentSource for TV API</title>
</head>
<body>
<div id="content"></div>
<script type="application/javascript" src="./test_helpers.js"></script>
<script type="application/javascript;version=1.7">
ok('tv' in navigator, "navigator.tv should exist.");
navigator.tv.getTuners().then(
function(aTuners) {
ok(aTuners.length > 0, "Got at least 1 tuner.");
aTuners[0].setCurrentSource("InvalidSourceType").then(
function() {
ok(false, "Setting an invalid current source should get error.");
finish();
},
function(aError) {
is(aError.name, "TypeError", "TypeError should be expected.");
finish();
}
);
},
function(aError) {
ok(false, "Error occurred when getting tuners: " + aError);
finish();
}
);
</script>
</body>
</html>

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

@ -0,0 +1,97 @@
"use strict";
var gAppsService = SpecialPowers.Cc["@mozilla.org/AppsService;1"]
.getService(SpecialPowers.Ci.nsIAppsService);
var gApp;
function cbError(e) {
ok(false, "Error callback invoked: " + this.error.name);
SimpleTest.finish();
}
function installApp(aTestToken, aTemplate) {
var hostedManifestURL = window.location.origin +
'/tests/dom/tv/test/mochitest/file_app.sjs?testToken='
+ aTestToken + '&template=' + aTemplate;
var request = navigator.mozApps.install(hostedManifestURL);
request.onerror = cbError;
request.onsuccess = function() {
gApp = request.result;
var appId = gAppsService.getAppLocalIdByManifestURL(gApp.manifestURL);
SpecialPowers.addPermission("tv", true, { url: gApp.origin,
appId: appId,
isInBrowserElement: false });
runTest();
}
}
function uninstallApp() {
var request = navigator.mozApps.mgmt.uninstall(gApp);
request.onerror = cbError;
request.onsuccess = function() {
// All done.
info("All done");
runTest();
}
}
function testApp() {
var ifr = document.createElement('iframe');
ifr.setAttribute('mozbrowser', 'true');
ifr.setAttribute('mozapp', gApp.manifestURL);
ifr.setAttribute('src', gApp.manifest.launch_path);
var domParent = document.getElementById('content');
// Set us up to listen for messages from the app.
var listener = function(e) {
var message = e.detail.message;
if (/^OK/.exec(message)) {
ok(true, "Message from app: " + message);
} else if (/KO/.exec(message)) {
ok(false, "Message from app: " + message);
} else if (/^INFO/.exec(message)) {
info("Message from app: " + message);
} else if (/DONE/.exec(message)) {
ok(true, "Messaging from app complete");
ifr.removeEventListener('mozbrowsershowmodalprompt', listener);
domParent.removeChild(ifr);
runTest();
}
}
// This event is triggered when the app calls "alert".
ifr.addEventListener('mozbrowsershowmodalprompt', listener, false);
domParent.appendChild(ifr);
}
function runTest() {
if (!tests.length) {
SimpleTest.finish();
return;
}
var test = tests.shift();
test();
}
function setupPrefsAndPermissions() {
SpecialPowers.pushPrefEnv({"set": [["dom.tv.enabled", true],
["dom.testing.tv_enabled_for_hosted_apps", true]]}, function() {
SpecialPowers.pushPermissions(
[{ "type": "browser", "allow": true, "context": document },
{ "type": "embed-apps", "allow": true, "context": document },
{ "type": "webapps-manage", "allow": true, "context": document }],
function() {
SpecialPowers.setAllAppsLaunchable(true);
SpecialPowers.setBoolPref("dom.mozBrowserFramesEnabled", true);
// No confirmation needed when an app is installed and uninstalled.
SpecialPowers.autoConfirmAppInstall(() => {
SpecialPowers.autoConfirmAppUninstall(runTest);
});
});
});
}

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

@ -0,0 +1,37 @@
[DEFAULT]
support-files =
file_app.sjs
file_app.template.webapp
file_tv_non_permitted_app.html
file_tv_permitted_app.html
file_tv_get_tuners.html
file_tv_get_sources.html
file_tv_get_channels.html
file_tv_get_channels_during_scanning.html
file_tv_get_programs.html
file_tv_get_current_program.html
file_tv_set_current_source.html
file_tv_set_invalid_current_source.html
file_tv_set_current_channel.html
file_tv_set_current_channel_during_scanning.html
file_tv_set_invalid_current_channel.html
file_tv_scan_channels_stopped.html
file_tv_scan_channels_completed.html
head.js
test_helpers.js
[test_tv_non_permitted_app.html]
[test_tv_permitted_app.html]
[test_tv_get_tuners.html]
[test_tv_get_sources.html]
[test_tv_get_channels.html]
[test_tv_get_channels_during_scanning.html]
[test_tv_get_programs.html]
[test_tv_get_current_program.html]
[test_tv_set_current_source.html]
[test_tv_set_invalid_current_source.html]
[test_tv_set_current_channel.html]
[test_tv_set_current_channel_during_scanning.html]
[test_tv_set_invalid_current_channel.html]
[test_tv_scan_channels_stopped.html]
[test_tv_scan_channels_completed.html]

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

@ -0,0 +1,17 @@
"use strict";
function is(a, b, msg) {
alert((a === b ? 'OK' : 'KO') + ' ' + msg);
}
function ok(a, msg) {
alert((a ? 'OK' : 'KO')+ ' ' + msg);
}
function info(msg) {
alert('INFO ' + msg);
}
function finish() {
alert('DONE');
}

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

@ -0,0 +1,35 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test GetChannels for TV API</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<p id="display"></p>
<div id="content" style="display: none"></div>
<pre id="test">
<script type="application/javascript" src="./head.js"></script>
<script type="application/javascript">
var tests = [
// Setup preferences and permissions
setupPrefsAndPermissions,
// Installing the app
installApp.bind(this, "file_tv_get_channels.html", "file_app.template.webapp"),
// Run tests in app
testApp,
// Uninstall the app
uninstallApp
];
SimpleTest.waitForExplicitFinish();
runTest();
</script>
</pre>
</body>
</html>

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

@ -0,0 +1,35 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test an error case for GetChannels during scanning for TV API</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<p id="display"></p>
<div id="content" style="display: none"></div>
<pre id="test">
<script type="application/javascript" src="./head.js"></script>
<script type="application/javascript">
var tests = [
// Setup preferences and permissions
setupPrefsAndPermissions,
// Installing the app
installApp.bind(this, "file_tv_get_channels_during_scanning.html", "file_app.template.webapp"),
// Run tests in app
testApp,
// Uninstall the app
uninstallApp
];
SimpleTest.waitForExplicitFinish();
runTest();
</script>
</pre>
</body>
</html>

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

@ -0,0 +1,35 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test GetCurrentProgram for TV API</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<p id="display"></p>
<div id="content" style="display: none"></div>
<pre id="test">
<script type="application/javascript" src="./head.js"></script>
<script type="application/javascript">
var tests = [
// Setup preferences and permissions
setupPrefsAndPermissions,
// Installing the app
installApp.bind(this, "file_tv_get_current_program.html", "file_app.template.webapp"),
// Run tests in app
testApp,
// Uninstall the app
uninstallApp
];
SimpleTest.waitForExplicitFinish();
runTest();
</script>
</pre>
</body>
</html>

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

@ -0,0 +1,35 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test GetPrograms for TV API</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<p id="display"></p>
<div id="content" style="display: none"></div>
<pre id="test">
<script type="application/javascript" src="./head.js"></script>
<script type="application/javascript">
var tests = [
// Setup preferences and permissions
setupPrefsAndPermissions,
// Installing the app
installApp.bind(this, "file_tv_get_programs.html", "file_app.template.webapp"),
// Run tests in app
testApp,
// Uninstall the app
uninstallApp
];
SimpleTest.waitForExplicitFinish();
runTest();
</script>
</pre>
</body>
</html>

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

@ -0,0 +1,37 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test GetSources for TV API</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<p id="display"></p>
<div id="content" style="display: none"></div>
<pre id="test">
<script type="application/javascript" src="./head.js"></script>
<script type="application/javascript">
"use strict";
var tests = [
// Setup preferences and permissions
setupPrefsAndPermissions,
// Installing the app
installApp.bind(this, "file_tv_get_sources.html", "file_app.template.webapp"),
// Run tests in app
testApp,
// Uninstall the app
uninstallApp
];
SimpleTest.waitForExplicitFinish();
runTest();
</script>
</pre>
</body>
</html>

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

@ -0,0 +1,35 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test GetTuners for TV API</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<p id="display"></p>
<div id="content" style="display: none"></div>
<pre id="test">
<script type="application/javascript" src="./head.js"></script>
<script type="application/javascript">
var tests = [
// Setup preferences and permissions
setupPrefsAndPermissions,
// Installing the app
installApp.bind(this, "file_tv_get_tuners.html", "file_app.template.webapp"),
// Run tests in app
testApp,
// Uninstall the app
uninstallApp
];
SimpleTest.waitForExplicitFinish();
runTest();
</script>
</pre>
</body>
</html>

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

@ -0,0 +1,49 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test Non-Permitted Application for TV API</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<p id="display"></p>
<div id="content" style="display: none"></div>
<pre id="test">
<script type="application/javascript" src="./head.js"></script>
<script type="application/javascript">
var tests = [
function() {
SpecialPowers.pushPrefEnv({"set": [["dom.tv.enabled", true]]}, function() {
SpecialPowers.pushPermissions(
[{ "type": "browser", "allow": true, "context": document },
{ "type": "embed-apps", "allow": true, "context": document },
{ "type": "webapps-manage", "allow": true, "context": document }],
function() {
SpecialPowers.setAllAppsLaunchable(true);
SpecialPowers.setBoolPref("dom.mozBrowserFramesEnabled", true);
// No confirmation needed when an app is installed and uninstalled.
SpecialPowers.autoConfirmAppInstall(() => {
SpecialPowers.autoConfirmAppUninstall(runTest);
});
});
});
},
// Installing the app
installApp.bind(this, "file_tv_non_permitted_app.html", "file_app.template.webapp"),
// Run tests in app
testApp,
// Uninstall the app
uninstallApp
];
SimpleTest.waitForExplicitFinish();
runTest();
</script>
</pre>
</body>
</html>

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

@ -0,0 +1,35 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test Permitted Application for TV API</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<p id="display"></p>
<div id="content" style="display: none"></div>
<pre id="test">
<script type="application/javascript" src="./head.js"></script>
<script type="application/javascript">
var tests = [
// Setup preferences and permissions
setupPrefsAndPermissions,
// Installing the app
installApp.bind(this, "file_tv_permitted_app.html", "file_app.template.webapp"),
// Run tests in app
testApp,
// Uninstall the app
uninstallApp
];
SimpleTest.waitForExplicitFinish();
runTest();
</script>
</pre>
</body>
</html>

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

@ -0,0 +1,36 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test channel scanning complete for TV API</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<p id="display"></p>
<div id="content" style="display: none"></div>
<pre id="test">
<script type="application/javascript" src="./head.js"></script>
<script type="application/javascript">
var tests = [
// Setup preferences and permissions
setupPrefsAndPermissions,
// Installing the app
installApp.bind(this, "file_tv_scan_channels_completed.html", "file_app.template.webapp"),
// Run tests in app
testApp,
// Uninstall the app
uninstallApp
];
SimpleTest.expectAssertions(0, 2);
SimpleTest.waitForExplicitFinish();
runTest();
</script>
</pre>
</body>
</html>

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

@ -0,0 +1,35 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test StartScanning and StopScanning for TV API</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<p id="display"></p>
<div id="content" style="display: none"></div>
<pre id="test">
<script type="application/javascript" src="./head.js"></script>
<script type="application/javascript">
var tests = [
// Setup preferences and permissions
setupPrefsAndPermissions,
// Installing the app
installApp.bind(this, "file_tv_scan_channels_stopped.html", "file_app.template.webapp"),
// Run tests in app
testApp,
// Uninstall the app
uninstallApp
];
SimpleTest.waitForExplicitFinish();
runTest();
</script>
</pre>
</body>
</html>

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

@ -0,0 +1,35 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test SetCurrentChannel for TV API</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<p id="display"></p>
<div id="content" style="display: none"></div>
<pre id="test">
<script type="application/javascript" src="./head.js"></script>
<script type="application/javascript">
var tests = [
// Setup preferences and permissions
setupPrefsAndPermissions,
// Installing the app
installApp.bind(this, "file_tv_set_current_channel.html", "file_app.template.webapp"),
// Run tests in app
testApp,
// Uninstall the app
uninstallApp
];
SimpleTest.waitForExplicitFinish();
runTest();
</script>
</pre>
</body>
</html>

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

@ -0,0 +1,35 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test an error case for SetCurrentChannel during scanning for TV API</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<p id="display"></p>
<div id="content" style="display: none"></div>
<pre id="test">
<script type="application/javascript" src="./head.js"></script>
<script type="application/javascript">
var tests = [
// Setup preferences and permissions
setupPrefsAndPermissions,
// Installing the app
installApp.bind(this, "file_tv_set_current_channel_during_scanning.html", "file_app.template.webapp"),
// Run tests in app
testApp,
// Uninstall the app
uninstallApp
];
SimpleTest.waitForExplicitFinish();
runTest();
</script>
</pre>
</body>
</html>

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

@ -0,0 +1,35 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test SetCurrentSource for TV API</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<p id="display"></p>
<div id="content" style="display: none"></div>
<pre id="test">
<script type="application/javascript" src="./head.js"></script>
<script type="application/javascript">
var tests = [
// Setup preferences and permissions
setupPrefsAndPermissions,
// Installing the app
installApp.bind(this, "file_tv_set_current_source.html", "file_app.template.webapp"),
// Run tests in app
testApp,
// Uninstall the app
uninstallApp
];
SimpleTest.waitForExplicitFinish();
runTest();
</script>
</pre>
</body>
</html>

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

@ -0,0 +1,35 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test an error case for SetCurrentChannel for TV API</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<p id="display"></p>
<div id="content" style="display: none"></div>
<pre id="test">
<script type="application/javascript" src="./head.js"></script>
<script type="application/javascript">
var tests = [
// Setup preferences and permissions
setupPrefsAndPermissions,
// Installing the app
installApp.bind(this, "file_tv_set_invalid_current_channel.html", "file_app.template.webapp"),
// Run tests in app
testApp,
// Uninstall the app
uninstallApp
];
SimpleTest.waitForExplicitFinish();
runTest();
</script>
</pre>
</body>
</html>

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

@ -0,0 +1,35 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test an error case for SetCurrentSource for TV API</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<p id="display"></p>
<div id="content" style="display: none"></div>
<pre id="test">
<script type="application/javascript" src="./head.js"></script>
<script type="application/javascript">
var tests = [
// Setup preferences and permissions
setupPrefsAndPermissions,
// Installing the app
installApp.bind(this, "file_tv_set_invalid_current_source.html", "file_app.template.webapp"),
// Run tests in app
testApp,
// Uninstall the app
uninstallApp
];
SimpleTest.waitForExplicitFinish();
runTest();
</script>
</pre>
</body>
</html>

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

@ -1,7 +0,0 @@
# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# 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/.
MOCHITEST_MANIFESTS += ['mochitest.ini']

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

@ -1,112 +0,0 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test Non-Permitted Application for TV API</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<p id="display"></p>
<div id="content" style="display: none"></div>
<pre id="test">
<script type="application/javascript">
"use strict";
var gHostedManifestURL = 'http://test/tests/dom/tv/test/file_app.sjs?testToken=file_tv_non_permitted_app.html&template=file_app.template.webapp';
var gApp;
function cbError(e) {
ok(false, "Error callback invoked: " + this.error.name);
SimpleTest.finish();
}
function installApp() {
var request = navigator.mozApps.install(gHostedManifestURL);
request.onerror = cbError;
request.onsuccess = function() {
gApp = request.result;
runTest();
}
}
function uninstallApp() {
var request = navigator.mozApps.mgmt.uninstall(gApp);
request.onerror = cbError;
request.onsuccess = function() {
// All done.
info("All done");
runTest();
}
}
function testApp() {
var ifr = document.createElement('iframe');
ifr.setAttribute('mozbrowser', 'true');
ifr.setAttribute('mozapp', gApp.manifestURL);
ifr.setAttribute('src', gApp.manifest.launch_path);
var domParent = document.getElementById('content');
// Set us up to listen for messages from the app.
var listener = function(e) {
var message = e.detail.message;
if (/^OK/.exec(message)) {
ok(true, "Message from app: " + message);
} else if (/KO/.exec(message)) {
ok(false, "Message from app: " + message);
} else if (/DONE/.exec(message)) {
ok(true, "Messaging from app complete");
ifr.removeEventListener('mozbrowsershowmodalprompt', listener);
domParent.removeChild(ifr);
runTest();
}
}
// This event is triggered when the app calls "alert".
ifr.addEventListener('mozbrowsershowmodalprompt', listener, false);
domParent.appendChild(ifr);
}
var tests = [
// Installing the app
installApp,
// Run tests in app
testApp,
// Uninstall the app
uninstallApp
];
function runTest() {
if (!tests.length) {
SimpleTest.finish();
return;
}
var test = tests.shift();
test();
}
SimpleTest.waitForExplicitFinish();
SpecialPowers.pushPrefEnv({"set": [["dom.tv.enabled", true]]}, function() {
SpecialPowers.pushPermissions(
[{ "type": "tv", "allow": true, "context": document },
{ "type": "browser", "allow": true, "context": document },
{ "type": "embed-apps", "allow": true, "context": document },
{ "type": "webapps-manage", "allow": true, "context": document }],
function(){
SpecialPowers.setAllAppsLaunchable(true);
SpecialPowers.setBoolPref("dom.mozBrowserFramesEnabled", true);
// No confirmation needed when an app is installed
SpecialPowers.autoConfirmAppInstall(() => {
SpecialPowers.autoConfirmAppUninstall(runTest);
});
});
});
</script>
</pre>
</body>
</html>

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

@ -0,0 +1,169 @@
"use strict";
const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
function run_test() {
run_next_test();
}
add_test(function test_valid_network_id() {
var networkId = "networkId";
var data = Cc["@mozilla.org/tv/tvchanneldata;1"].
createInstance(Ci.nsITVChannelData);
data.networkId = networkId;
equal(data.networkId, networkId);
run_next_test();
});
add_test(function test_empty_network_id() {
var data = Cc["@mozilla.org/tv/tvchanneldata;1"].
createInstance(Ci.nsITVChannelData);
Assert.throws(function() {
data.networkId = "";
}, /NS_ERROR_ILLEGAL_VALUE/i);
run_next_test();
});
add_test(function test_valid_transport_stream_id() {
var transportStreamId = "transportStreamId";
var data = Cc["@mozilla.org/tv/tvchanneldata;1"].
createInstance(Ci.nsITVChannelData);
data.transportStreamId = transportStreamId;
equal(data.transportStreamId, transportStreamId);
run_next_test();
});
add_test(function test_empty_transport_stream_id() {
var data = Cc["@mozilla.org/tv/tvchanneldata;1"].
createInstance(Ci.nsITVChannelData);
Assert.throws(function() {
data.transportStreamId = "";
}, /NS_ERROR_ILLEGAL_VALUE/i);
run_next_test();
});
add_test(function test_valid_service_id() {
var serviceId = "serviceId";
var data = Cc["@mozilla.org/tv/tvchanneldata;1"].
createInstance(Ci.nsITVChannelData);
data.serviceId = serviceId;
equal(data.serviceId, serviceId);
run_next_test();
});
add_test(function test_empty_service_id() {
var data = Cc["@mozilla.org/tv/tvchanneldata;1"].
createInstance(Ci.nsITVChannelData);
Assert.throws(function() {
data.serviceId = "";
}, /NS_ERROR_ILLEGAL_VALUE/i);
run_next_test();
});
add_test(function test_valid_type() {
var type = "tv";
var data = Cc["@mozilla.org/tv/tvchanneldata;1"].
createInstance(Ci.nsITVChannelData);
data.type = type;
equal(data.type, type);
run_next_test();
});
add_test(function test_empty_type() {
var data = Cc["@mozilla.org/tv/tvchanneldata;1"].
createInstance(Ci.nsITVChannelData);
Assert.throws(function() {
data.type = "";
}, /NS_ERROR_ILLEGAL_VALUE/i);
run_next_test();
});
add_test(function test_invalid_type() {
var data = Cc["@mozilla.org/tv/tvchanneldata;1"].
createInstance(Ci.nsITVChannelData);
Assert.throws(function() {
data.type = "invalid";
}, /NS_ERROR_ILLEGAL_VALUE/i);
run_next_test();
});
add_test(function test_valid_number() {
var number = "number";
var data = Cc["@mozilla.org/tv/tvchanneldata;1"].
createInstance(Ci.nsITVChannelData);
data.number = number;
equal(data.number, number);
run_next_test();
});
add_test(function test_empty_number() {
var data = Cc["@mozilla.org/tv/tvchanneldata;1"].
createInstance(Ci.nsITVChannelData);
Assert.throws(function() {
data.number = "";
}, /NS_ERROR_ILLEGAL_VALUE/i);
run_next_test();
});
add_test(function test_valid_name() {
var name = "name";
var data = Cc["@mozilla.org/tv/tvchanneldata;1"].
createInstance(Ci.nsITVChannelData);
data.name = name;
equal(data.name, name);
run_next_test();
});
add_test(function test_empty_name() {
var data = Cc["@mozilla.org/tv/tvchanneldata;1"].
createInstance(Ci.nsITVChannelData);
Assert.throws(function() {
data.name = "";
}, /NS_ERROR_ILLEGAL_VALUE/i);
run_next_test();
});
add_test(function test_is_emergency() {
var data = Cc["@mozilla.org/tv/tvchanneldata;1"].
createInstance(Ci.nsITVChannelData);
data.isEmergency = true;
ok(data.isEmergency);
run_next_test();
});
add_test(function test_is_free() {
var data = Cc["@mozilla.org/tv/tvchanneldata;1"].
createInstance(Ci.nsITVChannelData);
data.isFree = true;
ok(data.isFree);
run_next_test();
});

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

@ -0,0 +1,197 @@
"use strict";
const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
function run_test() {
run_next_test();
}
add_test(function test_valid_event_id() {
var eventId = "eventId";
var data = Cc["@mozilla.org/tv/tvprogramdata;1"].
createInstance(Ci.nsITVProgramData);
data.eventId = eventId;
equal(data.eventId, eventId);
run_next_test();
});
add_test(function test_empty_event_id() {
var data = Cc["@mozilla.org/tv/tvprogramdata;1"].
createInstance(Ci.nsITVProgramData);
Assert.throws(function() {
data.eventId = "";
}, /NS_ERROR_ILLEGAL_VALUE/i);
run_next_test();
});
add_test(function test_valid_title() {
var title = "title";
var data = Cc["@mozilla.org/tv/tvprogramdata;1"].
createInstance(Ci.nsITVProgramData);
data.title = title;
equal(data.title, title);
run_next_test();
});
add_test(function test_empty_title() {
var data = Cc["@mozilla.org/tv/tvprogramdata;1"].
createInstance(Ci.nsITVProgramData);
Assert.throws(function() {
data.title = "";
}, /NS_ERROR_ILLEGAL_VALUE/i);
run_next_test();
});
add_test(function test_start_time() {
var startTime = 1;
var data = Cc["@mozilla.org/tv/tvprogramdata;1"].
createInstance(Ci.nsITVProgramData);
data.startTime = startTime;
equal(data.startTime, startTime);
run_next_test();
});
add_test(function test_duration() {
var duration = 1;
var data = Cc["@mozilla.org/tv/tvprogramdata;1"].
createInstance(Ci.nsITVProgramData);
data.duration = duration;
equal(data.duration, duration);
run_next_test();
});
add_test(function test_valid_description() {
var description = "description";
var data = Cc["@mozilla.org/tv/tvprogramdata;1"].
createInstance(Ci.nsITVProgramData);
data.description = description;
equal(data.description, description);
run_next_test();
});
add_test(function test_empty_description() {
var description = "";
var data = Cc["@mozilla.org/tv/tvprogramdata;1"].
createInstance(Ci.nsITVProgramData);
data.description = description;
equal(data.description, description);
run_next_test();
});
add_test(function test_valid_rating() {
var rating = "rating";
var data = Cc["@mozilla.org/tv/tvprogramdata;1"].
createInstance(Ci.nsITVProgramData);
data.rating = rating;
equal(data.rating, rating);
run_next_test();
});
add_test(function test_empty_rating() {
var rating = "";
var data = Cc["@mozilla.org/tv/tvprogramdata;1"].
createInstance(Ci.nsITVProgramData);
data.rating = rating;
equal(data.rating, rating);
run_next_test();
});
add_test(function test_valid_audio_languages() {
var languages = ["eng", "jpn"];
var data = Cc["@mozilla.org/tv/tvprogramdata;1"].
createInstance(Ci.nsITVProgramData);
data.setAudioLanguages(languages.length, languages);
var audioLanguages = data.getAudioLanguages();
equal(audioLanguages.length, languages.length);
for (var i = 0; i < audioLanguages.length; i++) {
equal(audioLanguages[i], languages[i]);
}
run_next_test();
});
add_test(function test_empty_audio_languages() {
var data = Cc["@mozilla.org/tv/tvprogramdata;1"].
createInstance(Ci.nsITVProgramData);
data.setAudioLanguages(0, []);
var audioLanguages = data.getAudioLanguages();
equal(audioLanguages.length, 0);
run_next_test();
});
add_test(function test_mismatched_audio_languages() {
var data = Cc["@mozilla.org/tv/tvprogramdata;1"].
createInstance(Ci.nsITVProgramData);
Assert.throws(function() {
data.setAudioLanguages(1, []);
}, /NS_ERROR_XPC_NOT_ENOUGH_ELEMENTS_IN_ARRAY/i);
run_next_test();
});
add_test(function test_valid_subtitle_languages() {
var languages = ["eng", "jpn"];
var data = Cc["@mozilla.org/tv/tvprogramdata;1"].
createInstance(Ci.nsITVProgramData);
data.setSubtitleLanguages(languages.length, languages);
var subtitleLanguages = data.getSubtitleLanguages();
equal(subtitleLanguages.length, languages.length);
for (var i = 0; i < subtitleLanguages.length; i++) {
equal(subtitleLanguages[i], languages[i]);
}
run_next_test();
});
add_test(function test_empty_subtitle_languages() {
var data = Cc["@mozilla.org/tv/tvprogramdata;1"].
createInstance(Ci.nsITVProgramData);
data.setSubtitleLanguages(0, []);
var subtitleLanguages = data.getSubtitleLanguages();
equal(subtitleLanguages.length, 0);
run_next_test();
});
add_test(function test_mismatched_subtitle_languages() {
var data = Cc["@mozilla.org/tv/tvprogramdata;1"].
createInstance(Ci.nsITVProgramData);
Assert.throws(function() {
data.setSubtitleLanguages(1, []);
}, /NS_ERROR_XPC_NOT_ENOUGH_ELEMENTS_IN_ARRAY/i);
run_next_test();
});

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

@ -0,0 +1,65 @@
"use strict";
const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
function run_test() {
run_next_test();
}
add_test(function test_valid_id() {
var id = "id";
var data = Cc["@mozilla.org/tv/tvtunerdata;1"].
createInstance(Ci.nsITVTunerData);
data.id = id;
equal(data.id, id);
run_next_test();
});
add_test(function test_empty_id() {
var data = Cc["@mozilla.org/tv/tvtunerdata;1"].
createInstance(Ci.nsITVTunerData);
Assert.throws(function() {
data.id = "";
}, /NS_ERROR_ILLEGAL_VALUE/i);
run_next_test();
});
add_test(function test_valid_supported_source_types() {
var sourceTypes = ["dvb-t", "dvb-s"];
var data = Cc["@mozilla.org/tv/tvtunerdata;1"].
createInstance(Ci.nsITVTunerData);
data.setSupportedSourceTypes(sourceTypes.length, sourceTypes);
var types = data.getSupportedSourceTypes();
equal(types.length, sourceTypes.length);
for (var i = 0; i < types.length; i++) {
equal(types[i], sourceTypes[i]);
}
run_next_test();
});
add_test(function test_empty_supported_source_types() {
var data = Cc["@mozilla.org/tv/tvtunerdata;1"].
createInstance(Ci.nsITVTunerData);
Assert.throws(function() {
data.setSupportedSourceTypes(0, []);
}, /NS_ERROR_ILLEGAL_VALUE/i);
run_next_test();
});
add_test(function test_mismatched_supported_source_types() {
var data = Cc["@mozilla.org/tv/tvtunerdata;1"].
createInstance(Ci.nsITVTunerData);
Assert.throws(function() {
data.setSupportedSourceTypes(1, []);
}, /NS_ERROR_XPC_NOT_ENOUGH_ELEMENTS_IN_ARRAY/i);
run_next_test();
});

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

@ -0,0 +1,7 @@
[DEFAULT]
head =
tail =
[test_tv_tuner_data.js]
[test_tv_channel_data.js]
[test_tv_program_data.js]

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

@ -3,9 +3,8 @@
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
[Constructor(DOMString lockType, DOMString errorName, short retryCount),
[Constructor(DOMString errorName, short retryCount),
Pref="dom.icc.enabled"]
interface IccCardLockError : DOMError {
readonly attribute DOMString lockType;
readonly attribute short retryCount;
};

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

@ -218,6 +218,30 @@ typedef mozilla::gfx::Matrix4x4 Matrix4x4;
* these prefs. Note that "old_velocity" here is the initial velocity of the
* previous fling _after_ acceleration was applied to it (if applicable).
*
* "apz.fling_curve_function_x1"
* "apz.fling_curve_function_y1"
* "apz.fling_curve_function_x2"
* "apz.fling_curve_function_y2"
* "apz.fling_curve_threshold_inches_per_ms"
* These five parameters define a Bezier curve function and threshold used to
* increase the actual velocity relative to the user's finger velocity. When the
* finger velocity is below the threshold (or if the threshold is not positive),
* the velocity is used as-is. If the finger velocity exceeds the threshold
* velocity, then the function defined by the curve is applied on the part of
* the velocity that exceeds the threshold. Note that the upper bound of the
* velocity is still specified by the apz.max_velocity_inches_per_ms pref, and
* the function will smoothly curve the velocity from the threshold to the
* max. In general the function parameters chosen should define an ease-out
* curve in order to increase the velocity in this range, or an ease-in curve to
* decrease the velocity. A straight-line curve is equivalent to disabling the
* curve entirely by setting the threshold to -1. The max velocity pref must
* also be set in order for the curving to take effect, as it defines the upper
* bound of the velocity curve.
* The points (x1, y1) and (x2, y2) used as the two intermediate control points
* in the cubic bezier curve; the first and last points are (0,0) and (1,1).
* Some example values for these prefs can be found at
* http://mxr.mozilla.org/mozilla-central/source/layout/style/nsStyleStruct.cpp?rev=21282be9ad95#2462
*
* "apz.fling_friction"
* Amount of friction applied during flings.
*
@ -351,7 +375,12 @@ typedef mozilla::gfx::Matrix4x4 Matrix4x4;
/**
* Computed time function used for sampling frames of a zoom to animation.
*/
StaticAutoPtr<ComputedTimingFunction> gComputedTimingFunction;
StaticAutoPtr<ComputedTimingFunction> gZoomAnimationFunction;
/**
* Computed time function used for curving up velocity when it gets high.
*/
StaticAutoPtr<ComputedTimingFunction> gVelocityCurveFunction;
/**
* Maximum zoom amount, always used, even if a page asks for higher.
@ -638,7 +667,7 @@ public:
// Sample the zoom at the current time point. The sampled zoom
// will affect the final computed resolution.
float sampledPosition = gComputedTimingFunction->GetValue(animPosition);
float sampledPosition = gZoomAnimationFunction->GetValue(animPosition);
// We scale the scrollOffset linearly with sampledPosition, so the zoom
// needs to scale inversely to match.
@ -859,10 +888,17 @@ AsyncPanZoomController::InitializeGlobalState()
return;
sInitialized = true;
gComputedTimingFunction = new ComputedTimingFunction();
gComputedTimingFunction->Init(
gZoomAnimationFunction = new ComputedTimingFunction();
gZoomAnimationFunction->Init(
nsTimingFunction(NS_STYLE_TRANSITION_TIMING_FUNCTION_EASE));
ClearOnShutdown(&gComputedTimingFunction);
ClearOnShutdown(&gZoomAnimationFunction);
gVelocityCurveFunction = new ComputedTimingFunction();
gVelocityCurveFunction->Init(
nsTimingFunction(gfxPrefs::APZCurveFunctionX1(),
gfxPrefs::APZCurveFunctionY2(),
gfxPrefs::APZCurveFunctionX2(),
gfxPrefs::APZCurveFunctionY2()));
ClearOnShutdown(&gVelocityCurveFunction);
}
AsyncPanZoomController::AsyncPanZoomController(uint64_t aLayersId,

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

@ -8,6 +8,7 @@
#include <math.h> // for fabsf, pow, powf
#include <algorithm> // for max
#include "AsyncPanZoomController.h" // for AsyncPanZoomController
#include "mozilla/dom/AnimationPlayer.h" // for ComputedTimingFunction
#include "mozilla/layers/APZCTreeManager.h" // for APZCTreeManager
#include "FrameMetrics.h" // for FrameMetrics
#include "mozilla/Attributes.h" // for MOZ_FINAL
@ -15,15 +16,21 @@
#include "mozilla/gfx/Rect.h" // for RoundedIn
#include "mozilla/mozalloc.h" // for operator new
#include "mozilla/FloatingPoint.h" // for FuzzyEqualsAdditive
#include "mozilla/StaticPtr.h" // for StaticAutoPtr
#include "nsMathUtils.h" // for NS_lround
#include "nsPrintfCString.h" // for nsPrintfCString
#include "nsThreadUtils.h" // for NS_DispatchToMainThread, etc
#include "nscore.h" // for NS_IMETHOD
#include "gfxPrefs.h" // for the preferences
#define AXIS_LOG(...)
// #define AXIS_LOG(...) printf_stderr("AXIS: " __VA_ARGS__)
namespace mozilla {
namespace layers {
extern StaticAutoPtr<ComputedTimingFunction> gVelocityCurveFunction;
Axis::Axis(AsyncPanZoomController* aAsyncPanZoomController)
: mPos(0),
mPosTimeMs(0),
@ -34,6 +41,12 @@ Axis::Axis(AsyncPanZoomController* aAsyncPanZoomController)
{
}
float Axis::ToLocalVelocity(float aVelocityInchesPerMs) {
ScreenPoint aVelocityPoint = MakePoint(aVelocityInchesPerMs * APZCTreeManager::GetDPI());
mAsyncPanZoomController->ToLocalScreenCoordinates(&aVelocityPoint, mAsyncPanZoomController->PanStart());
return aVelocityPoint.Length();
}
void Axis::UpdateWithTouchAtDevicePoint(ScreenCoord aPos, uint32_t aTimestampMs) {
// mVelocityQueue is controller-thread only
AsyncPanZoomController::AssertOnControllerThread();
@ -52,9 +65,21 @@ void Axis::UpdateWithTouchAtDevicePoint(ScreenCoord aPos, uint32_t aTimestampMs)
bool velocityIsNegative = (newVelocity < 0);
newVelocity = fabs(newVelocity);
ScreenPoint maxVelocity = MakePoint(gfxPrefs::APZMaxVelocity() * APZCTreeManager::GetDPI());
mAsyncPanZoomController->ToLocalScreenCoordinates(&maxVelocity, mAsyncPanZoomController->PanStart());
newVelocity = std::min(newVelocity, maxVelocity.Length());
float maxVelocity = ToLocalVelocity(gfxPrefs::APZMaxVelocity());
newVelocity = std::min(newVelocity, maxVelocity);
if (gfxPrefs::APZCurveThreshold() > 0.0f && gfxPrefs::APZCurveThreshold() < gfxPrefs::APZMaxVelocity()) {
float curveThreshold = ToLocalVelocity(gfxPrefs::APZCurveThreshold());
if (newVelocity > curveThreshold) {
// here, 0 < curveThreshold < newVelocity <= maxVelocity, so we apply the curve
float scale = maxVelocity - curveThreshold;
float funcInput = (newVelocity - curveThreshold) / scale;
float funcOutput = gVelocityCurveFunction->GetValue(funcInput);
float curvedVelocity = (funcOutput * scale) + curveThreshold;
AXIS_LOG("Curving up velocity from %f to %f\n", newVelocity, curvedVelocity);
newVelocity = curvedVelocity;
}
}
if (velocityIsNegative) {
newVelocity = -newVelocity;

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

@ -232,6 +232,9 @@ protected:
// Adjust a requested overscroll amount for resistance, yielding a smaller
// actual overscroll amount.
ScreenCoord ApplyResistance(ScreenCoord aOverscroll) const;
// Convert a velocity from global inches/ms into local ScreenCoords per ms
float ToLocalVelocity(float aVelocityInchesPerMs);
};
class AxisX : public Axis {

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

@ -65,6 +65,10 @@
#endif
#include "mozilla/VsyncDispatcher.h"
#ifdef MOZ_WIDGET_GONK
#include "GeckoTouchDispatcher.h"
#endif
namespace mozilla {
namespace layers {
@ -273,6 +277,8 @@ CompositorVsyncObserver::Composite(TimeStamp aVsyncTimestamp)
// unregister the vsync.
UnobserveVsync();
}
DispatchTouchEvents(aVsyncTimestamp);
}
bool
@ -302,6 +308,16 @@ CompositorVsyncObserver::UnobserveVsync()
mIsObservingVsync = false;
}
void
CompositorVsyncObserver::DispatchTouchEvents(TimeStamp aVsyncTimestamp)
{
#ifdef MOZ_WIDGET_GONK
if (gfxPrefs::TouchResampling()) {
GeckoTouchDispatcher::NotifyVsync(aVsyncTimestamp);
}
#endif
}
void CompositorParent::StartUp()
{
MOZ_ASSERT(NS_IsMainThread(), "Should be on the main Thread!");

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

@ -113,6 +113,7 @@ private:
void NotifyCompositeTaskExecuted();
void ObserveVsync();
void UnobserveVsync();
void DispatchTouchEvents(TimeStamp aVsyncTimestamp);
bool mNeedsComposite;
bool mIsObservingVsync;

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

@ -146,6 +146,11 @@ private:
DECL_GFX_PREF(Live, "apz.fling_accel_interval_ms", APZFlingAccelInterval, int32_t, 500);
DECL_GFX_PREF(Live, "apz.fling_accel_base_mult", APZFlingAccelBaseMultiplier, float, 1.0f);
DECL_GFX_PREF(Live, "apz.fling_accel_supplemental_mult", APZFlingAccelSupplementalMultiplier, float, 1.0f);
DECL_GFX_PREF(Once, "apz.fling_curve_function_x1", APZCurveFunctionX1, float, 0.0f);
DECL_GFX_PREF(Once, "apz.fling_curve_function_y1", APZCurveFunctionY1, float, 0.0f);
DECL_GFX_PREF(Once, "apz.fling_curve_function_x2", APZCurveFunctionX2, float, 1.0f);
DECL_GFX_PREF(Once, "apz.fling_curve_function_y2", APZCurveFunctionY2, float, 1.0f);
DECL_GFX_PREF(Live, "apz.fling_curve_threshold_inches_per_ms", APZCurveThreshold, float, -1.0f);
DECL_GFX_PREF(Once, "apz.fling_friction", APZFlingFriction, float, 0.002f);
DECL_GFX_PREF(Live, "apz.fling_repaint_interval", APZFlingRepaintInterval, int32_t, 75);
DECL_GFX_PREF(Once, "apz.fling_stop_on_tap_threshold", APZFlingStopOnTapThreshold, float, 0.05f);

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

@ -466,6 +466,11 @@ pref("apz.enlarge_displayport_when_clipped", false);
pref("apz.fling_accel_base_mult", "1.0");
pref("apz.fling_accel_interval_ms", 500);
pref("apz.fling_accel_supplemental_mult", "1.0");
pref("apz.fling_curve_function_x1", "0.0");
pref("apz.fling_curve_function_y1", "0.0");
pref("apz.fling_curve_function_x2", "1.0");
pref("apz.fling_curve_function_y2", "1.0");
pref("apz.fling_curve_threshold_inches_per_ms", "-1.0");
pref("apz.fling_friction", "0.002");
pref("apz.fling_stop_on_tap_threshold", "0.05");
pref("apz.fling_stopped_threshold", "0.01");

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

@ -724,6 +724,8 @@ bool LoadSymbols(const string& obj_file,
names_end, elf_header->e_shnum);
if (gnu_debuglink_section) {
if (!info->debug_dirs().empty()) {
found_debug_info_section = true;
const char* debuglink_contents =
GetOffset<ElfClass, char>(elf_header,
gnu_debuglink_section->sh_offset);
@ -740,55 +742,48 @@ bool LoadSymbols(const string& obj_file,
fprintf(stderr, "%s does not contain a .gnu_debuglink section.\n",
obj_file.c_str());
}
} else {
if (symbol_data != ONLY_CFI) {
// The caller doesn't want to consult .gnu_debuglink.
// See if there are export symbols available.
const Shdr* dynsym_section =
FindElfSectionByName<ElfClass>(".dynsym", SHT_DYNSYM,
sections, names, names_end,
elf_header->e_shnum);
const Shdr* dynstr_section =
FindElfSectionByName<ElfClass>(".dynstr", SHT_STRTAB,
sections, names, names_end,
elf_header->e_shnum);
if (dynsym_section && dynstr_section) {
info->LoadedSection(".dynsym");
const uint8_t* dynsyms =
GetOffset<ElfClass, uint8_t>(elf_header,
dynsym_section->sh_offset);
const uint8_t* dynstrs =
GetOffset<ElfClass, uint8_t>(elf_header,
dynstr_section->sh_offset);
bool result =
ELFSymbolsToModule(dynsyms,
dynsym_section->sh_size,
dynstrs,
dynstr_section->sh_size,
big_endian,
ElfClass::kAddrSize,
module);
found_usable_info = found_usable_info || result;
}
}
// Return true if some usable information was found, since
// the caller doesn't want to use .gnu_debuglink.
BPLOG(INFO) << "LoadSymbols: "
<< (found_usable_info ? "SUCCESS " : "FAILURE ")
<< obj_file;
return found_usable_info;
}
// No debug info was found, let the user try again with .gnu_debuglink
// if present.
BPLOG(INFO) << "LoadSymbols: FAILURE " << obj_file;
return false;
}
BPLOG(INFO) << "LoadSymbols: SUCCESS " << obj_file;
return true;
if (symbol_data != ONLY_CFI) {
const Shdr* dynsym_section =
FindElfSectionByName<ElfClass>(".dynsym", SHT_DYNSYM,
sections, names, names_end,
elf_header->e_shnum);
const Shdr* dynstr_section =
FindElfSectionByName<ElfClass>(".dynstr", SHT_STRTAB,
sections, names, names_end,
elf_header->e_shnum);
if (dynsym_section && dynstr_section) {
info->LoadedSection(".dynsym");
const uint8_t* dynsyms =
GetOffset<ElfClass, uint8_t>(elf_header,
dynsym_section->sh_offset);
const uint8_t* dynstrs =
GetOffset<ElfClass, uint8_t>(elf_header,
dynstr_section->sh_offset);
bool result =
ELFSymbolsToModule(dynsyms,
dynsym_section->sh_size,
dynstrs,
dynstr_section->sh_size,
big_endian,
ElfClass::kAddrSize,
module);
found_usable_info = found_usable_info || result;
}
}
if (read_gnu_debug_link) {
return found_debug_info_section;
}
// Return true if some usable information was found
BPLOG(INFO) << "LoadSymbols: "
<< (found_usable_info ? "SUCCESS " : "FAILURE ")
<< obj_file;
return found_usable_info;
}
// Return the breakpad symbol file identifier for the architecture of

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

@ -105,10 +105,21 @@ void Module::AddStackFrameEntry(StackFrameEntry* stack_frame_entry) {
}
void Module::AddExtern(Extern *ext) {
std::pair<ExternSet::iterator,bool> ret = externs_.insert(ext);
if (!ret.second) {
// Free the duplicate that was not inserted because this Module
// now owns it.
Function func;
func.name = ext->name;
func.address = ext->address;
// Since parsing debug section and public info are not necessarily
// mutually exclusive, check if the symbol has already been read
// as a function to avoid duplicates.
if (functions_.find(&func) == functions_.end()) {
std::pair<ExternSet::iterator,bool> ret = externs_.insert(ext);
if (!ret.second) {
// Free the duplicate that was not inserted because this Module
// now owns it.
delete ext;
}
} else {
delete ext;
}
}