зеркало из https://github.com/mozilla/gecko-dev.git
Merge b2ginbound to central, a=merge
This commit is contained in:
Коммит
ed8142204a
|
@ -15,7 +15,7 @@
|
||||||
<project name="platform_build" path="build" remote="b2g" revision="e862ab9177af664f00b4522e2350f4cb13866d73">
|
<project name="platform_build" path="build" remote="b2g" revision="e862ab9177af664f00b4522e2350f4cb13866d73">
|
||||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||||
</project>
|
</project>
|
||||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="2d7f369fd923b6df3b00d76844c413c1202c04ba"/>
|
<project name="gaia" path="gaia" remote="mozillaorg" revision="c7875bbc8b32e7b95cc55c9690b03b140905d84d"/>
|
||||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="62cfa11ae7d77f6330de019a5aa79607e35be7d1"/>
|
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="62cfa11ae7d77f6330de019a5aa79607e35be7d1"/>
|
||||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
|
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
<project name="platform_build" path="build" remote="b2g" revision="e862ab9177af664f00b4522e2350f4cb13866d73">
|
<project name="platform_build" path="build" remote="b2g" revision="e862ab9177af664f00b4522e2350f4cb13866d73">
|
||||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||||
</project>
|
</project>
|
||||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="2d7f369fd923b6df3b00d76844c413c1202c04ba"/>
|
<project name="gaia" path="gaia" remote="mozillaorg" revision="c7875bbc8b32e7b95cc55c9690b03b140905d84d"/>
|
||||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="62cfa11ae7d77f6330de019a5aa79607e35be7d1"/>
|
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="62cfa11ae7d77f6330de019a5aa79607e35be7d1"/>
|
||||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
|
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||||
</project>
|
</project>
|
||||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
||||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="2d7f369fd923b6df3b00d76844c413c1202c04ba"/>
|
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="c7875bbc8b32e7b95cc55c9690b03b140905d84d"/>
|
||||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="62cfa11ae7d77f6330de019a5aa79607e35be7d1"/>
|
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="62cfa11ae7d77f6330de019a5aa79607e35be7d1"/>
|
||||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
|
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
|
||||||
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="2d58f4b9206b50b8fda0d5036da6f0c62608db7c"/>
|
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="2d58f4b9206b50b8fda0d5036da6f0c62608db7c"/>
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
</project>
|
</project>
|
||||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
|
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
|
||||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="2d7f369fd923b6df3b00d76844c413c1202c04ba"/>
|
<project name="gaia" path="gaia" remote="mozillaorg" revision="c7875bbc8b32e7b95cc55c9690b03b140905d84d"/>
|
||||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="62cfa11ae7d77f6330de019a5aa79607e35be7d1"/>
|
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="62cfa11ae7d77f6330de019a5aa79607e35be7d1"/>
|
||||||
<project name="moztt" path="external/moztt" remote="b2g" revision="657894b4a1dc0a926117f4812e0940229f9f676f"/>
|
<project name="moztt" path="external/moztt" remote="b2g" revision="657894b4a1dc0a926117f4812e0940229f9f676f"/>
|
||||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="36b945cb98a4e9009d57b8c20a720fc1a5905452"/>
|
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="36b945cb98a4e9009d57b8c20a720fc1a5905452"/>
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
<project name="platform_build" path="build" remote="b2g" revision="e862ab9177af664f00b4522e2350f4cb13866d73">
|
<project name="platform_build" path="build" remote="b2g" revision="e862ab9177af664f00b4522e2350f4cb13866d73">
|
||||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||||
</project>
|
</project>
|
||||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="2d7f369fd923b6df3b00d76844c413c1202c04ba"/>
|
<project name="gaia" path="gaia" remote="mozillaorg" revision="c7875bbc8b32e7b95cc55c9690b03b140905d84d"/>
|
||||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="62cfa11ae7d77f6330de019a5aa79607e35be7d1"/>
|
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="62cfa11ae7d77f6330de019a5aa79607e35be7d1"/>
|
||||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
|
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
|
||||||
|
@ -124,11 +124,11 @@
|
||||||
<project name="platform/system/vold" path="system/vold" revision="d4455b8cf361f8353e8aebac15ffd64b4aedd2b9"/>
|
<project name="platform/system/vold" path="system/vold" revision="d4455b8cf361f8353e8aebac15ffd64b4aedd2b9"/>
|
||||||
<project name="platform/external/icu4c" path="external/icu4c" remote="aosp" revision="b4c6379528887dc25ca9991a535a8d92a61ad6b6"/>
|
<project name="platform/external/icu4c" path="external/icu4c" remote="aosp" revision="b4c6379528887dc25ca9991a535a8d92a61ad6b6"/>
|
||||||
<project name="platform_frameworks_av" path="frameworks/av" remote="b2g" revision="f313503b5c91aaa6fcf962d4ec9bf260e0c00bf1"/>
|
<project name="platform_frameworks_av" path="frameworks/av" remote="b2g" revision="f313503b5c91aaa6fcf962d4ec9bf260e0c00bf1"/>
|
||||||
<project name="platform_system_core" path="system/core" remote="b2g" revision="9395eb5aa885cf6d305a202de6e9694a58a89717"/>
|
<project name="platform_system_core" path="system/core" remote="b2g" revision="8586f55fe4b015911b48e731b69c592ad82a0807"/>
|
||||||
<default remote="caf" revision="refs/tags/android-4.4.2_r1" sync-j="4"/>
|
<default remote="caf" revision="refs/tags/android-4.4.2_r1" sync-j="4"/>
|
||||||
<!-- Emulator specific things -->
|
<!-- Emulator specific things -->
|
||||||
<project name="device/generic/armv7-a-neon" path="device/generic/armv7-a-neon" revision="72ffdf71c68a96309212eb13d63560d66db14c9e"/>
|
<project name="device/generic/armv7-a-neon" path="device/generic/armv7-a-neon" revision="72ffdf71c68a96309212eb13d63560d66db14c9e"/>
|
||||||
<project name="device_generic_goldfish" path="device/generic/goldfish" remote="b2g" revision="f390788a00706c06e5248edfd8d27b365387e84a"/>
|
<project name="device_generic_goldfish" path="device/generic/goldfish" remote="b2g" revision="85f6a2e1e638dbc8b119896e61383e973e764ffd"/>
|
||||||
<project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="4bebbe8d92368befc31e8b4a99da2d29cc26bfbc"/>
|
<project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="4bebbe8d92368befc31e8b4a99da2d29cc26bfbc"/>
|
||||||
<project name="platform/external/libnfc-nci" path="external/libnfc-nci" revision="f37bd545063039e30a92f2550ae78c0e6e4e2d08"/>
|
<project name="platform/external/libnfc-nci" path="external/libnfc-nci" revision="f37bd545063039e30a92f2550ae78c0e6e4e2d08"/>
|
||||||
<project name="platform_external_wpa_supplicant_8" path="external/wpa_supplicant_8" remote="b2g" revision="0c6a6547cd1fd302fa2b0f6e375654df36bf0ec4"/>
|
<project name="platform_external_wpa_supplicant_8" path="external/wpa_supplicant_8" remote="b2g" revision="0c6a6547cd1fd302fa2b0f6e375654df36bf0ec4"/>
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
<project name="platform_build" path="build" remote="b2g" revision="05a36844c1046a1eb07d5b1325f85ed741f961ea">
|
<project name="platform_build" path="build" remote="b2g" revision="05a36844c1046a1eb07d5b1325f85ed741f961ea">
|
||||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||||
</project>
|
</project>
|
||||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="2d7f369fd923b6df3b00d76844c413c1202c04ba"/>
|
<project name="gaia" path="gaia" remote="mozillaorg" revision="c7875bbc8b32e7b95cc55c9690b03b140905d84d"/>
|
||||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="62cfa11ae7d77f6330de019a5aa79607e35be7d1"/>
|
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="62cfa11ae7d77f6330de019a5aa79607e35be7d1"/>
|
||||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
|
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||||
</project>
|
</project>
|
||||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
||||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="2d7f369fd923b6df3b00d76844c413c1202c04ba"/>
|
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="c7875bbc8b32e7b95cc55c9690b03b140905d84d"/>
|
||||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="62cfa11ae7d77f6330de019a5aa79607e35be7d1"/>
|
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="62cfa11ae7d77f6330de019a5aa79607e35be7d1"/>
|
||||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
|
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
|
||||||
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="2d58f4b9206b50b8fda0d5036da6f0c62608db7c"/>
|
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="2d58f4b9206b50b8fda0d5036da6f0c62608db7c"/>
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
<project name="platform_build" path="build" remote="b2g" revision="e862ab9177af664f00b4522e2350f4cb13866d73">
|
<project name="platform_build" path="build" remote="b2g" revision="e862ab9177af664f00b4522e2350f4cb13866d73">
|
||||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||||
</project>
|
</project>
|
||||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="2d7f369fd923b6df3b00d76844c413c1202c04ba"/>
|
<project name="gaia" path="gaia" remote="mozillaorg" revision="c7875bbc8b32e7b95cc55c9690b03b140905d84d"/>
|
||||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="62cfa11ae7d77f6330de019a5aa79607e35be7d1"/>
|
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="62cfa11ae7d77f6330de019a5aa79607e35be7d1"/>
|
||||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
|
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
{
|
{
|
||||||
"git": {
|
"git": {
|
||||||
"git_revision": "2d7f369fd923b6df3b00d76844c413c1202c04ba",
|
"git_revision": "c7875bbc8b32e7b95cc55c9690b03b140905d84d",
|
||||||
"remote": "https://git.mozilla.org/releases/gaia.git",
|
"remote": "https://git.mozilla.org/releases/gaia.git",
|
||||||
"branch": ""
|
"branch": ""
|
||||||
},
|
},
|
||||||
"revision": "5c86f4cf87b91d2bfe9a3e49aa8706b452e4f97e",
|
"revision": "9db39036600a1c999f93038fa0dd09a48321518e",
|
||||||
"repo_path": "integration/gaia-central"
|
"repo_path": "integration/gaia-central"
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
</project>
|
</project>
|
||||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
|
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
|
||||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="2d7f369fd923b6df3b00d76844c413c1202c04ba"/>
|
<project name="gaia" path="gaia" remote="mozillaorg" revision="c7875bbc8b32e7b95cc55c9690b03b140905d84d"/>
|
||||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="62cfa11ae7d77f6330de019a5aa79607e35be7d1"/>
|
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="62cfa11ae7d77f6330de019a5aa79607e35be7d1"/>
|
||||||
<project name="moztt" path="external/moztt" remote="b2g" revision="657894b4a1dc0a926117f4812e0940229f9f676f"/>
|
<project name="moztt" path="external/moztt" remote="b2g" revision="657894b4a1dc0a926117f4812e0940229f9f676f"/>
|
||||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="36b945cb98a4e9009d57b8c20a720fc1a5905452"/>
|
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="36b945cb98a4e9009d57b8c20a720fc1a5905452"/>
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
<project name="platform_build" path="build" remote="b2g" revision="05a36844c1046a1eb07d5b1325f85ed741f961ea">
|
<project name="platform_build" path="build" remote="b2g" revision="05a36844c1046a1eb07d5b1325f85ed741f961ea">
|
||||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||||
</project>
|
</project>
|
||||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="2d7f369fd923b6df3b00d76844c413c1202c04ba"/>
|
<project name="gaia" path="gaia" remote="mozillaorg" revision="c7875bbc8b32e7b95cc55c9690b03b140905d84d"/>
|
||||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="62cfa11ae7d77f6330de019a5aa79607e35be7d1"/>
|
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="62cfa11ae7d77f6330de019a5aa79607e35be7d1"/>
|
||||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
|
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
|
||||||
|
|
|
@ -168,6 +168,7 @@ extern bool gBluetoothDebugFlag;
|
||||||
*/
|
*/
|
||||||
#define BLUETOOTH_A2DP_STATUS_CHANGED_ID "bluetooth-a2dp-status-changed"
|
#define BLUETOOTH_A2DP_STATUS_CHANGED_ID "bluetooth-a2dp-status-changed"
|
||||||
#define BLUETOOTH_HFP_STATUS_CHANGED_ID "bluetooth-hfp-status-changed"
|
#define BLUETOOTH_HFP_STATUS_CHANGED_ID "bluetooth-hfp-status-changed"
|
||||||
|
#define BLUETOOTH_HFP_NREC_STATUS_CHANGED_ID "bluetooth-hfp-nrec-status-changed"
|
||||||
#define BLUETOOTH_HID_STATUS_CHANGED_ID "bluetooth-hid-status-changed"
|
#define BLUETOOTH_HID_STATUS_CHANGED_ID "bluetooth-hid-status-changed"
|
||||||
#define BLUETOOTH_SCO_STATUS_CHANGED_ID "bluetooth-sco-status-changed"
|
#define BLUETOOTH_SCO_STATUS_CHANGED_ID "bluetooth-sco-status-changed"
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,8 @@ public:
|
||||||
* Returns true if Sco is connected.
|
* Returns true if Sco is connected.
|
||||||
*/
|
*/
|
||||||
virtual bool IsScoConnected() = 0;
|
virtual bool IsScoConnected() = 0;
|
||||||
|
|
||||||
|
virtual bool IsNrecEnabled() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define BT_DECL_HFP_MGR_BASE \
|
#define BT_DECL_HFP_MGR_BASE \
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
/* AG feature masks */
|
/* AG feature masks */
|
||||||
#define BTIF_HF_FEATURES ( BTA_AG_FEAT_3WAY | \
|
#define BTIF_HF_FEATURES ( BTA_AG_FEAT_3WAY | \
|
||||||
|
BTA_AG_FEAT_ECNR | \
|
||||||
BTA_AG_FEAT_REJECT | \
|
BTA_AG_FEAT_REJECT | \
|
||||||
BTA_AG_FEAT_ECS | \
|
BTA_AG_FEAT_ECS | \
|
||||||
BTA_AG_FEAT_EXTERR)
|
BTA_AG_FEAT_EXTERR)
|
||||||
|
|
|
@ -220,6 +220,7 @@ BluetoothHfpManager::Cleanup()
|
||||||
mService = HFP_NETWORK_STATE_NOT_AVAILABLE;
|
mService = HFP_NETWORK_STATE_NOT_AVAILABLE;
|
||||||
mRoam = HFP_SERVICE_TYPE_HOME;
|
mRoam = HFP_SERVICE_TYPE_HOME;
|
||||||
mSignal = 0;
|
mSignal = 0;
|
||||||
|
mNrecEnabled = HFP_NREC_STARTED;
|
||||||
|
|
||||||
mController = nullptr;
|
mController = nullptr;
|
||||||
}
|
}
|
||||||
|
@ -1205,6 +1206,12 @@ BluetoothHfpManager::IsConnected()
|
||||||
return (mConnectionState == HFP_CONNECTION_STATE_SLC_CONNECTED);
|
return (mConnectionState == HFP_CONNECTION_STATE_SLC_CONNECTED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
BluetoothHfpManager::IsNrecEnabled()
|
||||||
|
{
|
||||||
|
return mNrecEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
BluetoothHfpManager::OnConnectError()
|
BluetoothHfpManager::OnConnectError()
|
||||||
{
|
{
|
||||||
|
@ -1389,6 +1396,12 @@ BluetoothHfpManager::ConnectionStateNotification(
|
||||||
DisconnectSco();
|
DisconnectSco();
|
||||||
NotifyConnectionStateChanged(
|
NotifyConnectionStateChanged(
|
||||||
NS_LITERAL_STRING(BLUETOOTH_HFP_STATUS_CHANGED_ID));
|
NS_LITERAL_STRING(BLUETOOTH_HFP_STATUS_CHANGED_ID));
|
||||||
|
|
||||||
|
} else if (aState == HFP_CONNECTION_STATE_CONNECTED) {
|
||||||
|
// Once RFCOMM is connected, enable NREC before each new SLC connection
|
||||||
|
mNrecEnabled = HFP_NREC_STARTED;
|
||||||
|
NotifyConnectionStateChanged(
|
||||||
|
NS_LITERAL_STRING(BLUETOOTH_HFP_NREC_STATUS_CHANGED_ID));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1465,6 +1478,28 @@ BluetoothHfpManager::DtmfNotification(char aDtmf, const nsAString& aBdAddress)
|
||||||
NotifyDialer(NS_ConvertUTF8toUTF16(message));
|
NotifyDialer(NS_ConvertUTF8toUTF16(message));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
BluetoothHfpManager::NRECNotification(BluetoothHandsfreeNRECState aNrec,
|
||||||
|
const nsAString& aBdAddr)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
|
|
||||||
|
// Notify Gecko observers
|
||||||
|
nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
|
||||||
|
NS_ENSURE_TRUE_VOID(obs);
|
||||||
|
|
||||||
|
// Set NREC status once getting AT command
|
||||||
|
mNrecEnabled = static_cast<bool>(aNrec);
|
||||||
|
|
||||||
|
// Notify audio manager
|
||||||
|
if (NS_FAILED(obs->NotifyObservers(this,
|
||||||
|
BLUETOOTH_HFP_NREC_STATUS_CHANGED_ID,
|
||||||
|
mDeviceAddress.get()))) {
|
||||||
|
BT_WARNING("Failed to notify bluetooth-hfp-nrec-status-changed observsers!");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
BluetoothHfpManager::CallHoldNotification(BluetoothHandsfreeCallHoldType aChld,
|
BluetoothHfpManager::CallHoldNotification(BluetoothHandsfreeCallHoldType aChld,
|
||||||
const nsAString& aBdAddress)
|
const nsAString& aBdAddress)
|
||||||
|
|
|
@ -92,6 +92,7 @@ public:
|
||||||
|
|
||||||
bool ConnectSco();
|
bool ConnectSco();
|
||||||
bool DisconnectSco();
|
bool DisconnectSco();
|
||||||
|
bool IsNrecEnabled();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param aSend A boolean indicates whether we need to notify headset or not
|
* @param aSend A boolean indicates whether we need to notify headset or not
|
||||||
|
@ -127,6 +128,8 @@ public:
|
||||||
const nsAString& aBdAddress) override;
|
const nsAString& aBdAddress) override;
|
||||||
void DtmfNotification(char aDtmf,
|
void DtmfNotification(char aDtmf,
|
||||||
const nsAString& aBdAddress) override;
|
const nsAString& aBdAddress) override;
|
||||||
|
void NRECNotification(BluetoothHandsfreeNRECState aNrec,
|
||||||
|
const nsAString& aBdAddr) override;
|
||||||
void CallHoldNotification(BluetoothHandsfreeCallHoldType aChld,
|
void CallHoldNotification(BluetoothHandsfreeCallHoldType aChld,
|
||||||
const nsAString& aBdAddress) override;
|
const nsAString& aBdAddress) override;
|
||||||
void DialCallNotification(const nsAString& aNumber,
|
void DialCallNotification(const nsAString& aNumber,
|
||||||
|
@ -213,6 +216,7 @@ private:
|
||||||
bool mReceiveVgsFlag;
|
bool mReceiveVgsFlag;
|
||||||
// This flag is for HFP only, not for HSP.
|
// This flag is for HFP only, not for HSP.
|
||||||
bool mDialingRequestProcessed;
|
bool mDialingRequestProcessed;
|
||||||
|
bool mNrecEnabled;
|
||||||
PhoneType mPhoneType;
|
PhoneType mPhoneType;
|
||||||
nsString mDeviceAddress;
|
nsString mDeviceAddress;
|
||||||
nsString mMsisdn;
|
nsString mMsisdn;
|
||||||
|
|
|
@ -2105,5 +2105,14 @@ BluetoothHfpManager::OnDisconnect(const nsAString& aErrorStr)
|
||||||
controller->NotifyCompletion(aErrorStr);
|
controller->NotifyCompletion(aErrorStr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
BluetoothHfpManager::IsNrecEnabled()
|
||||||
|
{
|
||||||
|
// Add this function and return default value to avoid build break
|
||||||
|
// since NREC function isn't developed in bluez yet.
|
||||||
|
// Please see Bug 825149 for more information.
|
||||||
|
return HFP_NREC_STARTED;
|
||||||
|
}
|
||||||
|
|
||||||
NS_IMPL_ISUPPORTS(BluetoothHfpManager, nsIObserver)
|
NS_IMPL_ISUPPORTS(BluetoothHfpManager, nsIObserver)
|
||||||
|
|
||||||
|
|
|
@ -103,6 +103,7 @@ public:
|
||||||
*/
|
*/
|
||||||
bool ConnectSco(BluetoothReplyRunnable* aRunnable = nullptr);
|
bool ConnectSco(BluetoothReplyRunnable* aRunnable = nullptr);
|
||||||
bool DisconnectSco();
|
bool DisconnectSco();
|
||||||
|
bool IsNrecEnabled();
|
||||||
bool ListenSco();
|
bool ListenSco();
|
||||||
|
|
||||||
#ifdef MOZ_B2G_RIL
|
#ifdef MOZ_B2G_RIL
|
||||||
|
|
|
@ -372,6 +372,17 @@ AudioManager::HandleBluetoothStatusChanged(nsISupports* aSubject,
|
||||||
audioState, aAddress.get());
|
audioState, aAddress.get());
|
||||||
AudioSystem::setDeviceConnectionState(AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET,
|
AudioSystem::setDeviceConnectionState(AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET,
|
||||||
audioState, aAddress.get());
|
audioState, aAddress.get());
|
||||||
|
} else if (!strcmp(aTopic, BLUETOOTH_HFP_NREC_STATUS_CHANGED_ID)) {
|
||||||
|
String8 cmd;
|
||||||
|
BluetoothHfpManagerBase* hfp =
|
||||||
|
static_cast<BluetoothHfpManagerBase*>(aSubject);
|
||||||
|
if (hfp->IsNrecEnabled()) {
|
||||||
|
cmd.setTo("bt_headset_name=<unknown>;bt_headset_nrec=on");
|
||||||
|
AudioSystem::setParameters(0, cmd);
|
||||||
|
} else {
|
||||||
|
cmd.setTo("bt_headset_name=<unknown>;bt_headset_nrec=off");
|
||||||
|
AudioSystem::setParameters(0, cmd);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -409,6 +420,7 @@ AudioManager::Observe(nsISupports* aSubject,
|
||||||
{
|
{
|
||||||
if ((strcmp(aTopic, BLUETOOTH_SCO_STATUS_CHANGED_ID) == 0) ||
|
if ((strcmp(aTopic, BLUETOOTH_SCO_STATUS_CHANGED_ID) == 0) ||
|
||||||
(strcmp(aTopic, BLUETOOTH_HFP_STATUS_CHANGED_ID) == 0) ||
|
(strcmp(aTopic, BLUETOOTH_HFP_STATUS_CHANGED_ID) == 0) ||
|
||||||
|
(strcmp(aTopic, BLUETOOTH_HFP_NREC_STATUS_CHANGED_ID) == 0) ||
|
||||||
(strcmp(aTopic, BLUETOOTH_A2DP_STATUS_CHANGED_ID) == 0)) {
|
(strcmp(aTopic, BLUETOOTH_A2DP_STATUS_CHANGED_ID) == 0)) {
|
||||||
nsCString address = NS_ConvertUTF16toUTF8(nsDependentString(aData));
|
nsCString address = NS_ConvertUTF16toUTF8(nsDependentString(aData));
|
||||||
if (address.IsEmpty()) {
|
if (address.IsEmpty()) {
|
||||||
|
@ -553,6 +565,9 @@ AudioManager::AudioManager()
|
||||||
if (NS_FAILED(obs->AddObserver(this, BLUETOOTH_HFP_STATUS_CHANGED_ID, false))) {
|
if (NS_FAILED(obs->AddObserver(this, BLUETOOTH_HFP_STATUS_CHANGED_ID, false))) {
|
||||||
NS_WARNING("Failed to add bluetooth hfp status changed observer!");
|
NS_WARNING("Failed to add bluetooth hfp status changed observer!");
|
||||||
}
|
}
|
||||||
|
if (NS_FAILED(obs->AddObserver(this, BLUETOOTH_HFP_NREC_STATUS_CHANGED_ID, false))) {
|
||||||
|
NS_WARNING("Failed to add bluetooth hfp NREC status changed observer!");
|
||||||
|
}
|
||||||
if (NS_FAILED(obs->AddObserver(this, MOZ_SETTINGS_CHANGE_ID, false))) {
|
if (NS_FAILED(obs->AddObserver(this, MOZ_SETTINGS_CHANGE_ID, false))) {
|
||||||
NS_WARNING("Failed to add mozsettings-changed observer!");
|
NS_WARNING("Failed to add mozsettings-changed observer!");
|
||||||
}
|
}
|
||||||
|
@ -583,6 +598,9 @@ AudioManager::~AudioManager() {
|
||||||
if (NS_FAILED(obs->RemoveObserver(this, BLUETOOTH_HFP_STATUS_CHANGED_ID))) {
|
if (NS_FAILED(obs->RemoveObserver(this, BLUETOOTH_HFP_STATUS_CHANGED_ID))) {
|
||||||
NS_WARNING("Failed to remove bluetooth hfp status changed observer!");
|
NS_WARNING("Failed to remove bluetooth hfp status changed observer!");
|
||||||
}
|
}
|
||||||
|
if (NS_FAILED(obs->RemoveObserver(this, BLUETOOTH_HFP_NREC_STATUS_CHANGED_ID))) {
|
||||||
|
NS_WARNING("Failed to remove bluetooth hfp NREC status changed observer!");
|
||||||
|
}
|
||||||
if (NS_FAILED(obs->RemoveObserver(this, MOZ_SETTINGS_CHANGE_ID))) {
|
if (NS_FAILED(obs->RemoveObserver(this, MOZ_SETTINGS_CHANGE_ID))) {
|
||||||
NS_WARNING("Failed to remove mozsettings-changed observer!");
|
NS_WARNING("Failed to remove mozsettings-changed observer!");
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#include "Telephony.h"
|
#include "Telephony.h"
|
||||||
|
|
||||||
#include "mozilla/Preferences.h"
|
#include "mozilla/Preferences.h"
|
||||||
|
#include "mozilla/dom/AudioChannelBinding.h"
|
||||||
#include "mozilla/dom/CallEvent.h"
|
#include "mozilla/dom/CallEvent.h"
|
||||||
#include "mozilla/dom/MozMobileConnectionBinding.h"
|
#include "mozilla/dom/MozMobileConnectionBinding.h"
|
||||||
#include "mozilla/dom/Promise.h"
|
#include "mozilla/dom/Promise.h"
|
||||||
|
@ -20,6 +21,7 @@
|
||||||
#include "nsServiceManagerUtils.h"
|
#include "nsServiceManagerUtils.h"
|
||||||
#include "nsThreadUtils.h"
|
#include "nsThreadUtils.h"
|
||||||
|
|
||||||
|
#include "AudioChannelService.h"
|
||||||
#include "CallsList.h"
|
#include "CallsList.h"
|
||||||
#include "TelephonyCall.h"
|
#include "TelephonyCall.h"
|
||||||
#include "TelephonyCallGroup.h"
|
#include "TelephonyCallGroup.h"
|
||||||
|
@ -62,8 +64,12 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
Telephony::Telephony(nsPIDOMWindow* aOwner)
|
Telephony::Telephony(nsPIDOMWindow* aOwner)
|
||||||
: DOMEventTargetHelper(aOwner)
|
: DOMEventTargetHelper(aOwner),
|
||||||
|
mIsAudioStartPlaying(false),
|
||||||
|
mAudioAgentNotify(nsIAudioChannelAgent::AUDIO_AGENT_NOTIFY),
|
||||||
|
mHaveDispatchedInterruptBeginEvent(false)
|
||||||
{
|
{
|
||||||
|
MOZ_ASSERT(aOwner);
|
||||||
nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(aOwner);
|
nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(aOwner);
|
||||||
MOZ_ASSERT(global);
|
MOZ_ASSERT(global);
|
||||||
|
|
||||||
|
@ -72,6 +78,7 @@ Telephony::Telephony(nsPIDOMWindow* aOwner)
|
||||||
MOZ_ASSERT(!rv.Failed());
|
MOZ_ASSERT(!rv.Failed());
|
||||||
|
|
||||||
mReadyPromise = promise;
|
mReadyPromise = promise;
|
||||||
|
mMuted = AudioChannelService::IsAudioChannelMutedByDefault();
|
||||||
}
|
}
|
||||||
|
|
||||||
Telephony::~Telephony()
|
Telephony::~Telephony()
|
||||||
|
@ -518,6 +525,61 @@ Telephony::StopTone(const Optional<uint32_t>& aServiceId, ErrorResult& aRv)
|
||||||
aRv = mService->StopTone(serviceId);
|
aRv = mService->StopTone(serviceId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Telephony::OwnAudioChannel(ErrorResult& aRv)
|
||||||
|
{
|
||||||
|
if (mAudioAgent) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mAudioAgent = do_CreateInstance("@mozilla.org/audiochannelagent;1");
|
||||||
|
MOZ_ASSERT(mAudioAgent);
|
||||||
|
aRv = mAudioAgent->Init(GetParentObject(),
|
||||||
|
(int32_t)AudioChannel::Telephony, this);
|
||||||
|
if (NS_WARN_IF(aRv.Failed())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
aRv = HandleAudioAgentState();
|
||||||
|
if (NS_WARN_IF(aRv.Failed())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
Telephony::HandleAudioAgentState()
|
||||||
|
{
|
||||||
|
if (!mAudioAgent) {
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
Nullable<OwningTelephonyCallOrTelephonyCallGroup> activeCall;
|
||||||
|
GetActive(activeCall);
|
||||||
|
nsresult rv;
|
||||||
|
// Only stop agent when the call is disconnected.
|
||||||
|
if ((!mCalls.Length() && !mGroup->CallsArray().Length()) &&
|
||||||
|
mIsAudioStartPlaying) {
|
||||||
|
mIsAudioStartPlaying = false;
|
||||||
|
rv = mAudioAgent->NotifyStoppedPlaying(mAudioAgentNotify);
|
||||||
|
mAudioAgent = nullptr;
|
||||||
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
} else if (!activeCall.IsNull() && !mIsAudioStartPlaying) {
|
||||||
|
mIsAudioStartPlaying = true;
|
||||||
|
float volume = 1.0;
|
||||||
|
bool muted = false;
|
||||||
|
rv = mAudioAgent->NotifyStartedPlaying(mAudioAgentNotify, &volume, &muted);
|
||||||
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
rv = WindowVolumeChanged(volume, muted);
|
||||||
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
Telephony::GetMuted(ErrorResult& aRv) const
|
Telephony::GetMuted(ErrorResult& aRv) const
|
||||||
{
|
{
|
||||||
|
@ -591,13 +653,78 @@ Telephony::GetReady(ErrorResult& aRv) const
|
||||||
return promise.forget();
|
return promise.forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// nsIAudioChannelAgentCallback
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
Telephony::WindowVolumeChanged(float aVolume, bool aMuted)
|
||||||
|
{
|
||||||
|
// Check the limitation of the network connection
|
||||||
|
if (mCalls.Length() > 1 ||
|
||||||
|
(mCalls.Length() == 1 && mGroup->CallsArray().Length())) {
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
ErrorResult rv;
|
||||||
|
nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(GetOwner());
|
||||||
|
nsRefPtr<Promise> promise = Promise::Create(global, rv);
|
||||||
|
if (NS_WARN_IF(rv.Failed())) {
|
||||||
|
return rv.StealNSResult();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check the single call or conference call
|
||||||
|
bool isSingleCall = mCalls.Length();
|
||||||
|
nsCOMPtr<nsITelephonyCallback> callback = new TelephonyCallback(promise);
|
||||||
|
if (isSingleCall) {
|
||||||
|
rv = aMuted ? mCalls[0]->Hold(callback) : mCalls[0]->Resume(callback);
|
||||||
|
} else {
|
||||||
|
rv = aMuted ? mGroup->Hold(callback) : mGroup->Resume(callback);
|
||||||
|
}
|
||||||
|
if (NS_WARN_IF(rv.Failed())) {
|
||||||
|
return rv.StealNSResult();
|
||||||
|
}
|
||||||
|
|
||||||
|
// These events will be triggered when the telephony is interrupted by other
|
||||||
|
// audio channel.
|
||||||
|
if (mMuted != aMuted) {
|
||||||
|
mMuted = aMuted;
|
||||||
|
// We should not dispatch "mozinterruptend" when the system app initializes
|
||||||
|
// the telephony audio from muted to unmuted at the first time. The event
|
||||||
|
// "mozinterruptend" must be dispatched after the "mozinterruptbegin".
|
||||||
|
if (!mHaveDispatchedInterruptBeginEvent && mMuted) {
|
||||||
|
DispatchTrustedEvent(NS_LITERAL_STRING("mozinterruptbegin"));
|
||||||
|
mHaveDispatchedInterruptBeginEvent = mMuted;
|
||||||
|
} else if (mHaveDispatchedInterruptBeginEvent && !mMuted) {
|
||||||
|
DispatchTrustedEvent(NS_LITERAL_STRING("mozinterruptend"));
|
||||||
|
mHaveDispatchedInterruptBeginEvent = mMuted;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
Telephony::WindowAudioCaptureChanged()
|
||||||
|
{
|
||||||
|
// Do nothing
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
// nsITelephonyListener
|
// nsITelephonyListener
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
Telephony::CallStateChanged(uint32_t aLength, nsITelephonyCallInfo** aAllInfo)
|
Telephony::CallStateChanged(uint32_t aLength, nsITelephonyCallInfo** aAllInfo)
|
||||||
{
|
{
|
||||||
|
nsresult rv;
|
||||||
for (uint32_t i = 0; i < aLength; ++i) {
|
for (uint32_t i = 0; i < aLength; ++i) {
|
||||||
HandleCallInfo(aAllInfo[i]);
|
rv = HandleCallInfo(aAllInfo[i]);
|
||||||
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
rv = HandleAudioAgentState();
|
||||||
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
|
return rv;
|
||||||
}
|
}
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
@ -605,7 +732,8 @@ Telephony::CallStateChanged(uint32_t aLength, nsITelephonyCallInfo** aAllInfo)
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
Telephony::EnumerateCallState(nsITelephonyCallInfo* aInfo)
|
Telephony::EnumerateCallState(nsITelephonyCallInfo* aInfo)
|
||||||
{
|
{
|
||||||
return HandleCallInfo(aInfo);
|
uint32_t currentCallNum = 1;
|
||||||
|
return CallStateChanged(currentCallNum, &aInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#include "mozilla/dom/Promise.h"
|
#include "mozilla/dom/Promise.h"
|
||||||
#include "mozilla/dom/telephony/TelephonyCommon.h"
|
#include "mozilla/dom/telephony/TelephonyCommon.h"
|
||||||
|
|
||||||
|
#include "nsIAudioChannelAgent.h"
|
||||||
#include "nsITelephonyCallInfo.h"
|
#include "nsITelephonyCallInfo.h"
|
||||||
#include "nsITelephonyService.h"
|
#include "nsITelephonyService.h"
|
||||||
|
|
||||||
|
@ -31,6 +32,7 @@ class TelephonyDialCallback;
|
||||||
class OwningTelephonyCallOrTelephonyCallGroup;
|
class OwningTelephonyCallOrTelephonyCallGroup;
|
||||||
|
|
||||||
class Telephony final : public DOMEventTargetHelper,
|
class Telephony final : public DOMEventTargetHelper,
|
||||||
|
public nsIAudioChannelAgentCallback,
|
||||||
private nsITelephonyListener
|
private nsITelephonyListener
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
|
@ -44,6 +46,8 @@ class Telephony final : public DOMEventTargetHelper,
|
||||||
|
|
||||||
friend class telephony::TelephonyDialCallback;
|
friend class telephony::TelephonyDialCallback;
|
||||||
|
|
||||||
|
// The audio agent is needed to communicate with the audio channel service.
|
||||||
|
nsCOMPtr<nsIAudioChannelAgent> mAudioAgent;
|
||||||
nsCOMPtr<nsITelephonyService> mService;
|
nsCOMPtr<nsITelephonyService> mService;
|
||||||
nsRefPtr<Listener> mListener;
|
nsRefPtr<Listener> mListener;
|
||||||
|
|
||||||
|
@ -54,8 +58,15 @@ class Telephony final : public DOMEventTargetHelper,
|
||||||
|
|
||||||
nsRefPtr<Promise> mReadyPromise;
|
nsRefPtr<Promise> mReadyPromise;
|
||||||
|
|
||||||
|
bool mIsAudioStartPlaying;
|
||||||
|
|
||||||
|
uint32_t mAudioAgentNotify;
|
||||||
|
bool mHaveDispatchedInterruptBeginEvent;
|
||||||
|
bool mMuted;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
NS_DECL_ISUPPORTS_INHERITED
|
NS_DECL_ISUPPORTS_INHERITED
|
||||||
|
NS_DECL_NSIAUDIOCHANNELAGENTCALLBACK
|
||||||
NS_DECL_NSITELEPHONYLISTENER
|
NS_DECL_NSITELEPHONYLISTENER
|
||||||
NS_REALLY_FORWARD_NSIDOMEVENTTARGET(DOMEventTargetHelper)
|
NS_REALLY_FORWARD_NSIDOMEVENTTARGET(DOMEventTargetHelper)
|
||||||
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(Telephony,
|
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(Telephony,
|
||||||
|
@ -94,6 +105,15 @@ public:
|
||||||
void
|
void
|
||||||
StopTone(const Optional<uint32_t>& aServiceId, ErrorResult& aRv);
|
StopTone(const Optional<uint32_t>& aServiceId, ErrorResult& aRv);
|
||||||
|
|
||||||
|
// In the audio channel architecture, the system app needs to know the state
|
||||||
|
// of every audio channel, including the telephony. Therefore, when a
|
||||||
|
// telephony call is activated , the audio channel service would notify the
|
||||||
|
// system app about that. And we need a agent to communicate with the audio
|
||||||
|
// channel service. We would follow the call states to make a correct
|
||||||
|
// notification.
|
||||||
|
void
|
||||||
|
OwnAudioChannel(ErrorResult& aRv);
|
||||||
|
|
||||||
bool
|
bool
|
||||||
GetMuted(ErrorResult& aRv) const;
|
GetMuted(ErrorResult& aRv) const;
|
||||||
|
|
||||||
|
@ -213,6 +233,10 @@ private:
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
HandleCallInfo(nsITelephonyCallInfo* aInfo);
|
HandleCallInfo(nsITelephonyCallInfo* aInfo);
|
||||||
|
|
||||||
|
// Check the call states to decide whether need to send the notificaiton.
|
||||||
|
nsresult
|
||||||
|
HandleAudioAgentState();
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace dom
|
} // namespace dom
|
||||||
|
|
|
@ -324,34 +324,10 @@ TelephonyCall::Hold(ErrorResult& aRv)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mCallState != nsITelephonyService::CALL_STATE_CONNECTED) {
|
|
||||||
NS_WARNING(nsPrintfCString("Hold non-connected call is rejected!"
|
|
||||||
" (State: %u)", mCallState).get());
|
|
||||||
promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR);
|
|
||||||
return promise.forget();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mGroup) {
|
|
||||||
NS_WARNING("Hold a call in conference is rejected!");
|
|
||||||
promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR);
|
|
||||||
return promise.forget();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!mSwitchable) {
|
|
||||||
NS_WARNING("Hold a non-switchable call is rejected!");
|
|
||||||
promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR);
|
|
||||||
return promise.forget();
|
|
||||||
}
|
|
||||||
|
|
||||||
nsCOMPtr<nsITelephonyCallback> callback = new TelephonyCallback(promise);
|
nsCOMPtr<nsITelephonyCallback> callback = new TelephonyCallback(promise);
|
||||||
aRv = mTelephony->Service()->HoldCall(mServiceId, mCallIndex, callback);
|
aRv = Hold(callback);
|
||||||
NS_ENSURE_TRUE(!aRv.Failed(), nullptr);
|
if (NS_WARN_IF(aRv.Failed())) {
|
||||||
|
return nullptr;
|
||||||
if (mSecondId) {
|
|
||||||
// No state transition when we switch two numbers within one TelephonyCall
|
|
||||||
// object. Otherwise, the state here will be inconsistent with the backend
|
|
||||||
// RIL and will never be right.
|
|
||||||
return promise.forget();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return promise.forget();
|
return promise.forget();
|
||||||
|
@ -365,28 +341,77 @@ TelephonyCall::Resume(ErrorResult& aRv)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mCallState != nsITelephonyService::CALL_STATE_HELD) {
|
nsCOMPtr<nsITelephonyCallback> callback = new TelephonyCallback(promise);
|
||||||
NS_WARNING(nsPrintfCString("Resume non-held call is rejected!"
|
aRv = Resume(callback);
|
||||||
|
if (NS_WARN_IF(aRv.Failed())) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return promise.forget();
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
TelephonyCall::Hold(nsITelephonyCallback* aCallback)
|
||||||
|
{
|
||||||
|
if (mCallState != nsITelephonyService::CALL_STATE_CONNECTED) {
|
||||||
|
NS_WARNING(nsPrintfCString("Hold non-connected call is rejected!"
|
||||||
" (State: %u)", mCallState).get());
|
" (State: %u)", mCallState).get());
|
||||||
promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR);
|
aCallback->NotifyError(NS_LITERAL_STRING("InvalidStateError"));
|
||||||
return promise.forget();
|
return NS_ERROR_DOM_INVALID_STATE_ERR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mGroup) {
|
||||||
|
NS_WARNING("Hold a call in conference is rejected!");
|
||||||
|
aCallback->NotifyError(NS_LITERAL_STRING("InvalidStateError"));
|
||||||
|
return NS_ERROR_DOM_INVALID_STATE_ERR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!mSwitchable) {
|
||||||
|
NS_WARNING("Hold a non-switchable call is rejected!");
|
||||||
|
aCallback->NotifyError(NS_LITERAL_STRING("InvalidStateError"));
|
||||||
|
return NS_ERROR_DOM_INVALID_STATE_ERR;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult rv = mTelephony->Service()->HoldCall(mServiceId, mCallIndex, aCallback);
|
||||||
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mSecondId) {
|
||||||
|
// No state transition when we switch two numbers within one TelephonyCall
|
||||||
|
// object. Otherwise, the state here will be inconsistent with the backend
|
||||||
|
// RIL and will never be right.
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
TelephonyCall::Resume(nsITelephonyCallback* aCallback)
|
||||||
|
{
|
||||||
|
if (mCallState != nsITelephonyService::CALL_STATE_HELD) {
|
||||||
|
NS_WARNING("Resume non-held call is rejected!");
|
||||||
|
aCallback->NotifyError(NS_LITERAL_STRING("InvalidStateError"));
|
||||||
|
return NS_ERROR_DOM_INVALID_STATE_ERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mGroup) {
|
if (mGroup) {
|
||||||
NS_WARNING("Resume a call in conference is rejected!");
|
NS_WARNING("Resume a call in conference is rejected!");
|
||||||
promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR);
|
aCallback->NotifyError(NS_LITERAL_STRING("InvalidStateError"));
|
||||||
return promise.forget();
|
return NS_ERROR_DOM_INVALID_STATE_ERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!mSwitchable) {
|
if (!mSwitchable) {
|
||||||
NS_WARNING("Resume a non-switchable call is rejected!");
|
NS_WARNING("Resume a non-switchable call is rejected!");
|
||||||
promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR);
|
aCallback->NotifyError(NS_LITERAL_STRING("InvalidStateError"));
|
||||||
return promise.forget();
|
return NS_ERROR_DOM_INVALID_STATE_ERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsCOMPtr<nsITelephonyCallback> callback = new TelephonyCallback(promise);
|
nsresult rv = mTelephony->Service()->ResumeCall(mServiceId, mCallIndex, aCallback);
|
||||||
aRv = mTelephony->Service()->ResumeCall(mServiceId, mCallIndex, callback);
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
NS_ENSURE_TRUE(!aRv.Failed(), nullptr);
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
return promise.forget();
|
return NS_OK;
|
||||||
}
|
}
|
|
@ -12,6 +12,7 @@
|
||||||
#include "mozilla/dom/TelephonyCallBinding.h"
|
#include "mozilla/dom/TelephonyCallBinding.h"
|
||||||
#include "mozilla/dom/TelephonyCallId.h"
|
#include "mozilla/dom/TelephonyCallId.h"
|
||||||
#include "mozilla/dom/telephony/TelephonyCommon.h"
|
#include "mozilla/dom/telephony/TelephonyCommon.h"
|
||||||
|
#include "nsITelephonyService.h"
|
||||||
|
|
||||||
class nsPIDOMWindow;
|
class nsPIDOMWindow;
|
||||||
|
|
||||||
|
@ -185,6 +186,12 @@ private:
|
||||||
|
|
||||||
~TelephonyCall();
|
~TelephonyCall();
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
Hold(nsITelephonyCallback* aCallback);
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
Resume(nsITelephonyCallback* aCallback);
|
||||||
|
|
||||||
void
|
void
|
||||||
ChangeStateInternal(uint16_t aCallState, bool aFireEvents);
|
ChangeStateInternal(uint16_t aCallState, bool aFireEvents);
|
||||||
|
|
||||||
|
|
|
@ -347,16 +347,12 @@ TelephonyCallGroup::Hold(ErrorResult& aRv)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mCallState != nsITelephonyService::CALL_STATE_CONNECTED) {
|
nsCOMPtr<nsITelephonyCallback> callback = new TelephonyCallback(promise);
|
||||||
NS_WARNING("Holding a non-connected call is rejected!");
|
aRv = Hold(callback);
|
||||||
promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR);
|
if (NS_WARN_IF(aRv.Failed())) {
|
||||||
return promise.forget();
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsCOMPtr<nsITelephonyCallback> callback = new TelephonyCallback(promise);
|
|
||||||
aRv = mTelephony->Service()->HoldConference(mCalls[0]->ServiceId(),
|
|
||||||
callback);
|
|
||||||
NS_ENSURE_TRUE(!aRv.Failed(), nullptr);
|
|
||||||
return promise.forget();
|
return promise.forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -370,15 +366,47 @@ TelephonyCallGroup::Resume(ErrorResult& aRv)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mCallState != nsITelephonyService::CALL_STATE_HELD) {
|
nsCOMPtr<nsITelephonyCallback> callback = new TelephonyCallback(promise);
|
||||||
NS_WARNING("Resuming a non-held call is rejected!");
|
aRv = Resume(callback);
|
||||||
promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR);
|
if (NS_WARN_IF(aRv.Failed())) {
|
||||||
return promise.forget();
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsCOMPtr<nsITelephonyCallback> callback = new TelephonyCallback(promise);
|
|
||||||
aRv = mTelephony->Service()->ResumeConference(mCalls[0]->ServiceId(),
|
|
||||||
callback);
|
|
||||||
NS_ENSURE_TRUE(!aRv.Failed(), nullptr);
|
|
||||||
return promise.forget();
|
return promise.forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
TelephonyCallGroup::Hold(nsITelephonyCallback* aCallback)
|
||||||
|
{
|
||||||
|
if (mCallState != nsITelephonyService::CALL_STATE_CONNECTED) {
|
||||||
|
NS_WARNING("Holding a non-connected call is rejected!");
|
||||||
|
aCallback->NotifyError(NS_LITERAL_STRING("InvalidStateError"));
|
||||||
|
return NS_ERROR_DOM_INVALID_STATE_ERR;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult rv = mTelephony->Service()->HoldConference(mCalls[0]->ServiceId(),
|
||||||
|
aCallback);
|
||||||
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
TelephonyCallGroup::Resume(nsITelephonyCallback* aCallback)
|
||||||
|
{
|
||||||
|
if (mCallState != nsITelephonyService::CALL_STATE_HELD) {
|
||||||
|
NS_WARNING("Resuming a non-held call is rejected!");
|
||||||
|
aCallback->NotifyError(NS_LITERAL_STRING("InvalidStateError"));
|
||||||
|
return NS_ERROR_DOM_INVALID_STATE_ERR;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult rv = mTelephony->Service()->ResumeConference(mCalls[0]->ServiceId(),
|
||||||
|
aCallback);
|
||||||
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
|
@ -30,6 +30,8 @@ public:
|
||||||
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(TelephonyCallGroup,
|
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(TelephonyCallGroup,
|
||||||
DOMEventTargetHelper)
|
DOMEventTargetHelper)
|
||||||
|
|
||||||
|
friend class Telephony;
|
||||||
|
|
||||||
nsPIDOMWindow*
|
nsPIDOMWindow*
|
||||||
GetParentObject() const
|
GetParentObject() const
|
||||||
{
|
{
|
||||||
|
@ -108,6 +110,12 @@ private:
|
||||||
explicit TelephonyCallGroup(nsPIDOMWindow* aOwner);
|
explicit TelephonyCallGroup(nsPIDOMWindow* aOwner);
|
||||||
~TelephonyCallGroup();
|
~TelephonyCallGroup();
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
Hold(nsITelephonyCallback* aCallback);
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
Resume(nsITelephonyCallback* aCallback);
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
NotifyCallsChanged(TelephonyCall* aCall);
|
NotifyCallsChanged(TelephonyCall* aCall);
|
||||||
|
|
||||||
|
|
|
@ -49,6 +49,12 @@ interface Telephony : EventTarget {
|
||||||
[Throws]
|
[Throws]
|
||||||
void stopTone(optional unsigned long serviceId);
|
void stopTone(optional unsigned long serviceId);
|
||||||
|
|
||||||
|
// Calling this method, the app will be treated as owner of the telephony
|
||||||
|
// calls from the AudioChannel policy.
|
||||||
|
[Throws,
|
||||||
|
CheckAllPermissions="audio-channel-telephony"]
|
||||||
|
void ownAudioChannel();
|
||||||
|
|
||||||
[Throws]
|
[Throws]
|
||||||
attribute boolean muted;
|
attribute boolean muted;
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ $inherits:
|
||||||
|
|
||||||
task:
|
task:
|
||||||
scopes:
|
scopes:
|
||||||
- 'docker-worker:cache:workspace-b2g-desktop-objects-debug'
|
- 'docker-worker:cache:workspace-{{project}}-b2g-desktop-objects-debug'
|
||||||
workerType: b2g-desktop-debug
|
workerType: b2g-desktop-debug
|
||||||
extra:
|
extra:
|
||||||
treeherder:
|
treeherder:
|
||||||
|
@ -15,6 +15,6 @@ task:
|
||||||
|
|
||||||
payload:
|
payload:
|
||||||
cache:
|
cache:
|
||||||
workspace-b2g-desktop-objects-debug: '/home/worker/workspace'
|
workspace-{{project}}-b2g-desktop-objects-debug: '/home/worker/workspace'
|
||||||
env:
|
env:
|
||||||
MOZCONFIG: 'b2g/config/mozconfigs/linux64_gecko/debug'
|
MOZCONFIG: 'b2g/config/mozconfigs/linux64_gecko/debug'
|
||||||
|
|
|
@ -5,7 +5,7 @@ $inherits:
|
||||||
build_type: 'opt'
|
build_type: 'opt'
|
||||||
task:
|
task:
|
||||||
scopes:
|
scopes:
|
||||||
- 'docker-worker:cache:workspace-b2g-desktop-objects-opt'
|
- 'docker-worker:cache:workspace-{{project}}-b2g-desktop-objects-opt'
|
||||||
routes:
|
routes:
|
||||||
- 'index.buildbot.branches.{{project}}.linux64_gecko'
|
- 'index.buildbot.branches.{{project}}.linux64_gecko'
|
||||||
- 'index.buildbot.revisions.{{head_rev}}.{{project}}.linux64_gecko'
|
- 'index.buildbot.revisions.{{head_rev}}.{{project}}.linux64_gecko'
|
||||||
|
@ -13,7 +13,7 @@ task:
|
||||||
workerType: b2g-desktop-opt
|
workerType: b2g-desktop-opt
|
||||||
payload:
|
payload:
|
||||||
cache:
|
cache:
|
||||||
workspace-b2g-desktop-objects-opt: '/home/worker/workspace'
|
workspace-{{project}}-b2g-desktop-objects-opt: '/home/worker/workspace'
|
||||||
|
|
||||||
env:
|
env:
|
||||||
MOZCONFIG: 'b2g/config/mozconfigs/linux64_gecko/nightly'
|
MOZCONFIG: 'b2g/config/mozconfigs/linux64_gecko/nightly'
|
||||||
|
|
|
@ -21,8 +21,6 @@ task:
|
||||||
buildbot_step 'Build' ./build-emulator-x86.sh $HOME/workspace
|
buildbot_step 'Build' ./build-emulator-x86.sh $HOME/workspace
|
||||||
|
|
||||||
extra:
|
extra:
|
||||||
treeherder:
|
|
||||||
groupSymbol: x86
|
|
||||||
# Rather then enforcing particular conventions we require that all build
|
# Rather then enforcing particular conventions we require that all build
|
||||||
# tasks provide the "build" extra field to specify where the build and tests
|
# tasks provide the "build" extra field to specify where the build and tests
|
||||||
# files are located.
|
# files are located.
|
||||||
|
|
|
@ -4,7 +4,7 @@ $inherits:
|
||||||
build_name: 'emulator-x86-kk'
|
build_name: 'emulator-x86-kk'
|
||||||
build_type: 'opt'
|
build_type: 'opt'
|
||||||
task:
|
task:
|
||||||
workerType: emualtor-x86-kk
|
workerType: emulator-x86-kk
|
||||||
scopes:
|
scopes:
|
||||||
- 'docker-worker:cache:workspace-emulator-kk-x86-opt'
|
- 'docker-worker:cache:workspace-emulator-kk-x86-opt'
|
||||||
metadata:
|
metadata:
|
||||||
|
@ -15,8 +15,9 @@ task:
|
||||||
- staging
|
- staging
|
||||||
treeherder:
|
treeherder:
|
||||||
# Disable "TC" prefix...
|
# Disable "TC" prefix...
|
||||||
|
groupSymbol: "?"
|
||||||
machine:
|
machine:
|
||||||
platform: b2g-emu-kk
|
platform: b2g-emu-x86-kk
|
||||||
|
|
||||||
payload:
|
payload:
|
||||||
cache:
|
cache:
|
||||||
|
|
|
@ -15,13 +15,13 @@ task:
|
||||||
- 'index.buildbot.revisions.{{head_rev}}.{{project}}.linux64-mulet'
|
- 'index.buildbot.revisions.{{head_rev}}.{{project}}.linux64-mulet'
|
||||||
|
|
||||||
scopes:
|
scopes:
|
||||||
- 'docker-worker:cache:build-mulet-linux-workspace'
|
- 'docker-worker:cache:build-mulet-linux-{{project}}-workspace'
|
||||||
- 'docker-worker:cache:tooltool-cache'
|
- 'docker-worker:cache:tooltool-cache'
|
||||||
- 'docker-worker:relengapi-proxy:tooltool.download.public'
|
- 'docker-worker:relengapi-proxy:tooltool.download.public'
|
||||||
|
|
||||||
payload:
|
payload:
|
||||||
cache:
|
cache:
|
||||||
build-mulet-linux-workspace: '/home/worker/workspace'
|
build-mulet-linux-{{project}}-workspace: '/home/worker/workspace'
|
||||||
tooltool-cache: '/home/worker/tools/tooltool-cache'
|
tooltool-cache: '/home/worker/tools/tooltool-cache'
|
||||||
|
|
||||||
features:
|
features:
|
||||||
|
|
Загрузка…
Ссылка в новой задаче