diff options
Diffstat (limited to 'dom')
119 files changed, 6 insertions, 25921 deletions
diff --git a/dom/base/moz.build b/dom/base/moz.build index 76c765b1c..77eb01ba6 100755 --- a/dom/base/moz.build +++ b/dom/base/moz.build @@ -462,11 +462,6 @@ LOCAL_INCLUDES += [ '/xpcom/ds', ] -if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk': - LOCAL_INCLUDES += [ - '../system/gonk', - ] - if CONFIG['MOZ_WEBRTC']: LOCAL_INCLUDES += [ '/netwerk/sctp/datachannel', diff --git a/dom/canvas/test/webgl-mochitest/driver-info.js b/dom/canvas/test/webgl-mochitest/driver-info.js index e2f6e003a..3f2fe102c 100644 --- a/dom/canvas/test/webgl-mochitest/driver-info.js +++ b/dom/canvas/test/webgl-mochitest/driver-info.js @@ -81,9 +81,6 @@ DriverInfo = (function() { var versionMatch = /Mac OS X (\d+.\d+)/.exec(navigator.userAgent); version = versionMatch ? parseFloat(versionMatch[1]) : null; - } else if (runtime.widgetToolkit == 'gonk') { - os = OS.B2G; - } else if (navigator.appVersion.indexOf('Android') != -1) { os = OS.ANDROID; // From layout/tools/reftest/reftest.js: diff --git a/dom/events/moz.build b/dom/events/moz.build index ee4946038..ec3813207 100644 --- a/dom/events/moz.build +++ b/dom/events/moz.build @@ -153,10 +153,5 @@ LOCAL_INCLUDES += [ '/layout/xul/tree/', ] -if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk': - LOCAL_INCLUDES += [ - '/dom/wifi', - ] - if CONFIG['GNU_CXX']: CXXFLAGS += ['-Wno-error=shadow'] diff --git a/dom/geolocation/moz.build b/dom/geolocation/moz.build index bb3fcb583..4339d5a7f 100644 --- a/dom/geolocation/moz.build +++ b/dom/geolocation/moz.build @@ -30,10 +30,6 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'android': LOCAL_INCLUDES += [ '/dom/system/android', ] -elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk': - LOCAL_INCLUDES += [ - '/dom/system/gonk', - ] elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa': LOCAL_INCLUDES += [ '/dom/system/mac', diff --git a/dom/indexedDB/test/unit/xpcshell-child-process.ini b/dom/indexedDB/test/unit/xpcshell-child-process.ini index 970fe8c3d..5918471ea 100644 --- a/dom/indexedDB/test/unit/xpcshell-child-process.ini +++ b/dom/indexedDB/test/unit/xpcshell-child-process.ini @@ -6,7 +6,7 @@ dupe-manifest = head = xpcshell-head-child-process.js tail = -skip-if = toolkit == 'android' || toolkit == 'gonk' +skip-if = toolkit == 'android' support-files = GlobalObjectsChild.js GlobalObjectsComponent.js diff --git a/dom/indexedDB/test/unit/xpcshell-parent-process.ini b/dom/indexedDB/test/unit/xpcshell-parent-process.ini index 22bc861cc..04df5f552 100644 --- a/dom/indexedDB/test/unit/xpcshell-parent-process.ini +++ b/dom/indexedDB/test/unit/xpcshell-parent-process.ini @@ -6,7 +6,6 @@ dupe-manifest = head = xpcshell-head-parent-process.js tail = -skip-if = toolkit == 'gonk' support-files = bug1056939_profile.zip defaultStorageUpgrade_profile.zip diff --git a/dom/ipc/moz.build b/dom/ipc/moz.build index 1dbe1fedb..c34ac5d48 100644 --- a/dom/ipc/moz.build +++ b/dom/ipc/moz.build @@ -147,7 +147,7 @@ if CONFIG['OS_ARCH'] != 'WINNT': DEFINES['BIN_SUFFIX'] = '"%s"' % CONFIG['BIN_SUFFIX'] -if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('android', 'gtk2', 'gonk'): +if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('android', 'gtk2'): DEFINES['MOZ_ENABLE_FREETYPE'] = True if CONFIG['MOZ_TOOLKIT_SEARCH']: diff --git a/dom/media/encoder/fmp4_muxer/AMRBox.cpp b/dom/media/encoder/fmp4_muxer/AMRBox.cpp deleted file mode 100644 index cd1a34fae..000000000 --- a/dom/media/encoder/fmp4_muxer/AMRBox.cpp +++ /dev/null @@ -1,84 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-*/ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "ISOControl.h" -#include "ISOMediaBoxes.h" -#include "AMRBox.h" -#include "ISOTrackMetadata.h" - -namespace mozilla { - -nsresult -AMRSampleEntry::Generate(uint32_t* aBoxSize) -{ - uint32_t box_size; - nsresult rv = amr_special_box->Generate(&box_size); - NS_ENSURE_SUCCESS(rv, rv); - size += box_size; - - *aBoxSize = size; - return NS_OK; -} - -nsresult -AMRSampleEntry::Write() -{ - BoxSizeChecker checker(mControl, size); - nsresult rv; - rv = AudioSampleEntry::Write(); - NS_ENSURE_SUCCESS(rv, rv); - rv = amr_special_box->Write(); - NS_ENSURE_SUCCESS(rv, rv); - - return NS_OK; -} - -AMRSampleEntry::AMRSampleEntry(ISOControl* aControl) - : AudioSampleEntry(NS_LITERAL_CSTRING("samr"), aControl) -{ - amr_special_box = new AMRSpecificBox(aControl); - MOZ_COUNT_CTOR(AMRSampleEntry); -} - -AMRSampleEntry::~AMRSampleEntry() -{ - MOZ_COUNT_DTOR(AMRSampleEntry); -} - -nsresult -AMRSpecificBox::Generate(uint32_t* aBoxSize) -{ - nsresult rv; - FragmentBuffer* frag = mControl->GetFragment(Audio_Track); - rv = frag->GetCSD(amrDecSpecInfo); - NS_ENSURE_SUCCESS(rv, rv); - - size += amrDecSpecInfo.Length(); - *aBoxSize = size; - - return NS_OK; -} - -nsresult -AMRSpecificBox::Write() -{ - BoxSizeChecker checker(mControl, size); - Box::Write(); - mControl->Write(amrDecSpecInfo.Elements(), amrDecSpecInfo.Length()); - return NS_OK; -} - -AMRSpecificBox::AMRSpecificBox(ISOControl* aControl) - : Box(NS_LITERAL_CSTRING("damr"), aControl) -{ - MOZ_COUNT_CTOR(AMRSpecificBox); -} - -AMRSpecificBox::~AMRSpecificBox() -{ - MOZ_COUNT_DTOR(AMRSpecificBox); -} - -} diff --git a/dom/media/encoder/fmp4_muxer/AMRBox.h b/dom/media/encoder/fmp4_muxer/AMRBox.h deleted file mode 100644 index 645d7f89c..000000000 --- a/dom/media/encoder/fmp4_muxer/AMRBox.h +++ /dev/null @@ -1,50 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-*/ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef AMRBOX_h_ -#define AMRBOX_h_ - -#include "nsTArray.h" -#include "MuxerOperation.h" - -namespace mozilla { - -class ISOControl; - -// 3GPP TS 26.244 6.7 'AMRSpecificBox field for AMRSampleEntry box' -// Box type: 'damr' -class AMRSpecificBox : public Box { -public: - // 3GPP members - nsTArray<uint8_t> amrDecSpecInfo; - - // MuxerOperation methods - nsresult Generate(uint32_t* aBoxSize) override; - nsresult Write() override; - - // AMRSpecificBox methods - AMRSpecificBox(ISOControl* aControl); - ~AMRSpecificBox(); -}; - -// 3GPP TS 26.244 6.5 'AMRSampleEntry box' -// Box type: 'sawb' -class AMRSampleEntry : public AudioSampleEntry { -public: - // 3GPP members - RefPtr<AMRSpecificBox> amr_special_box; - - // MuxerOperation methods - nsresult Generate(uint32_t* aBoxSize) override; - nsresult Write() override; - - // AMRSampleEntry methods - AMRSampleEntry(ISOControl* aControl); - ~AMRSampleEntry(); -}; - -} - -#endif // AMRBOX_h_ diff --git a/dom/media/encoder/fmp4_muxer/AVCBox.cpp b/dom/media/encoder/fmp4_muxer/AVCBox.cpp deleted file mode 100644 index a45cda8b7..000000000 --- a/dom/media/encoder/fmp4_muxer/AVCBox.cpp +++ /dev/null @@ -1,87 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-*/ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include <climits> -#include "ISOControl.h" -#include "ISOMediaBoxes.h" -#include "AVCBox.h" - -namespace mozilla { - -nsresult -AVCSampleEntry::Generate(uint32_t* aBoxSize) -{ - uint32_t avc_box_size = 0; - nsresult rv; - rv = avcConfigBox->Generate(&avc_box_size); - NS_ENSURE_SUCCESS(rv, rv); - - size += avc_box_size; - - *aBoxSize = size; - - return NS_OK; -} - -nsresult -AVCSampleEntry::Write() -{ - BoxSizeChecker checker(mControl, size); - nsresult rv; - rv = VisualSampleEntry::Write(); - NS_ENSURE_SUCCESS(rv, rv); - rv = avcConfigBox->Write(); - NS_ENSURE_SUCCESS(rv, rv); - - return NS_OK; -} - -AVCSampleEntry::AVCSampleEntry(ISOControl* aControl) - : VisualSampleEntry(NS_LITERAL_CSTRING("avc1"), aControl) -{ - avcConfigBox = new AVCConfigurationBox(aControl); - MOZ_COUNT_CTOR(AVCSampleEntry); -} - -AVCSampleEntry::~AVCSampleEntry() -{ - MOZ_COUNT_DTOR(AVCSampleEntry); -} - -AVCConfigurationBox::AVCConfigurationBox(ISOControl* aControl) - : Box(NS_LITERAL_CSTRING("avcC"), aControl) -{ - MOZ_COUNT_CTOR(AVCConfigurationBox); -} - -AVCConfigurationBox::~AVCConfigurationBox() -{ - MOZ_COUNT_DTOR(AVCConfigurationBox); -} - -nsresult -AVCConfigurationBox::Generate(uint32_t* aBoxSize) -{ - nsresult rv; - FragmentBuffer* frag = mControl->GetFragment(Video_Track); - rv = frag->GetCSD(avcConfig); - NS_ENSURE_SUCCESS(rv, rv); - size += avcConfig.Length(); - *aBoxSize = size; - return NS_OK; -} - -nsresult -AVCConfigurationBox::Write() -{ - BoxSizeChecker checker(mControl, size); - Box::Write(); - - mControl->Write(avcConfig.Elements(), avcConfig.Length()); - - return NS_OK; -} - -} diff --git a/dom/media/encoder/fmp4_muxer/AVCBox.h b/dom/media/encoder/fmp4_muxer/AVCBox.h deleted file mode 100644 index 9640d9e8f..000000000 --- a/dom/media/encoder/fmp4_muxer/AVCBox.h +++ /dev/null @@ -1,59 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-*/ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef AVCBox_h_ -#define AVCBox_h_ - -#include "nsTArray.h" -#include "ISOMediaBoxes.h" - -namespace mozilla { - -class ISOControl; - -// 14496-12 8.5.2.2 -#define resolution_72_dpi 0x00480000 -#define video_depth 0x0018 - -// 14496-15 5.3.4.1 'Sample description name and format' -// Box type: 'avcC' -class AVCConfigurationBox : public Box { -public: - // ISO BMFF members - - // avcConfig is CodecSpecificData from 14496-15 '5.3.4.1 Sample description - // name and format. - // These data are generated by encoder and we encapsulated the generated - // bitstream into box directly. - nsTArray<uint8_t> avcConfig; - - // MuxerOperation methods - nsresult Generate(uint32_t* aBoxSize) override; - nsresult Write() override; - - // AVCConfigurationBox methods - AVCConfigurationBox(ISOControl* aControl); - ~AVCConfigurationBox(); -}; - -// 14496-15 5.3.4.1 'Sample description name and format' -// Box type: 'avc1' -class AVCSampleEntry : public VisualSampleEntry { -public: - // ISO BMFF members - RefPtr<AVCConfigurationBox> avcConfigBox; - - // MuxerOperation methods - nsresult Generate(uint32_t* aBoxSize) override; - nsresult Write() override; - - // VisualSampleEntry methods - AVCSampleEntry(ISOControl* aControl); - ~AVCSampleEntry(); -}; - -} - -#endif // AVCBox_h_ diff --git a/dom/media/encoder/fmp4_muxer/EVRCBox.cpp b/dom/media/encoder/fmp4_muxer/EVRCBox.cpp deleted file mode 100644 index 096e4013d..000000000 --- a/dom/media/encoder/fmp4_muxer/EVRCBox.cpp +++ /dev/null @@ -1,84 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-*/ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "ISOControl.h" -#include "ISOMediaBoxes.h" -#include "EVRCBox.h" -#include "ISOTrackMetadata.h" - -namespace mozilla { - -nsresult -EVRCSampleEntry::Generate(uint32_t* aBoxSize) -{ - uint32_t box_size; - nsresult rv = evrc_special_box->Generate(&box_size); - NS_ENSURE_SUCCESS(rv, rv); - size += box_size; - - *aBoxSize = size; - return NS_OK; -} - -nsresult -EVRCSampleEntry::Write() -{ - BoxSizeChecker checker(mControl, size); - nsresult rv; - rv = AudioSampleEntry::Write(); - NS_ENSURE_SUCCESS(rv, rv); - rv = evrc_special_box->Write(); - NS_ENSURE_SUCCESS(rv, rv); - - return NS_OK; -} - -EVRCSampleEntry::EVRCSampleEntry(ISOControl* aControl) - : AudioSampleEntry(NS_LITERAL_CSTRING("sevc"), aControl) -{ - evrc_special_box = new EVRCSpecificBox(aControl); - MOZ_COUNT_CTOR(EVRCSampleEntry); -} - -EVRCSampleEntry::~EVRCSampleEntry() -{ - MOZ_COUNT_DTOR(EVRCSampleEntry); -} - -nsresult -EVRCSpecificBox::Generate(uint32_t* aBoxSize) -{ - nsresult rv; - FragmentBuffer* frag = mControl->GetFragment(Audio_Track); - rv = frag->GetCSD(evrcDecSpecInfo); - NS_ENSURE_SUCCESS(rv, rv); - - size += evrcDecSpecInfo.Length(); - *aBoxSize = size; - - return NS_OK; -} - -nsresult -EVRCSpecificBox::Write() -{ - BoxSizeChecker checker(mControl, size); - Box::Write(); - mControl->Write(evrcDecSpecInfo.Elements(), evrcDecSpecInfo.Length()); - return NS_OK; -} - -EVRCSpecificBox::EVRCSpecificBox(ISOControl* aControl) - : Box(NS_LITERAL_CSTRING("devc"), aControl) -{ - MOZ_COUNT_CTOR(EVRCSpecificBox); -} - -EVRCSpecificBox::~EVRCSpecificBox() -{ - MOZ_COUNT_DTOR(EVRCSpecificBox); -} - -} diff --git a/dom/media/encoder/fmp4_muxer/EVRCBox.h b/dom/media/encoder/fmp4_muxer/EVRCBox.h deleted file mode 100644 index 31355849a..000000000 --- a/dom/media/encoder/fmp4_muxer/EVRCBox.h +++ /dev/null @@ -1,50 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-*/ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef EVRCBOX_h_ -#define EVRCBOX_h_ - -#include "nsTArray.h" -#include "MuxerOperation.h" - -namespace mozilla { - -class ISOControl; - -// 3GPP TS 26.244 6.7 'EVRCSpecificBox field for EVRCSampleEntry box' -// Box type: 'devc' -class EVRCSpecificBox : public Box { -public: - // 3GPP members - nsTArray<uint8_t> evrcDecSpecInfo; - - // MuxerOperation methods - nsresult Generate(uint32_t* aBoxSize) override; - nsresult Write() override; - - // EVRCSpecificBox methods - EVRCSpecificBox(ISOControl* aControl); - ~EVRCSpecificBox(); -}; - -// 3GPP TS 26.244 6.5 'EVRCSampleEntry box' -// Box type: 'sevc' -class EVRCSampleEntry : public AudioSampleEntry { -public: - // 3GPP members - RefPtr<EVRCSpecificBox> evrc_special_box; - - // MuxerOperation methods - nsresult Generate(uint32_t* aBoxSize) override; - nsresult Write() override; - - // EVRCSampleEntry methods - EVRCSampleEntry(ISOControl* aControl); - ~EVRCSampleEntry(); -}; - -} - -#endif // EVRCBOX_h_ diff --git a/dom/media/encoder/fmp4_muxer/ISOControl.cpp b/dom/media/encoder/fmp4_muxer/ISOControl.cpp deleted file mode 100644 index 6addaeb30..000000000 --- a/dom/media/encoder/fmp4_muxer/ISOControl.cpp +++ /dev/null @@ -1,415 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-*/ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include <time.h> -#include "nsAutoPtr.h" -#include "ISOControl.h" -#include "ISOMediaBoxes.h" -#include "EncodedFrameContainer.h" - -namespace mozilla { - -// For MP4 creation_time and modification_time offset from January 1, 1904 to -// January 1, 1970. -#define iso_time_offset 2082844800 - -FragmentBuffer::FragmentBuffer(uint32_t aTrackType, uint32_t aFragDuration) - : mTrackType(aTrackType) - , mFragDuration(aFragDuration) - , mMediaStartTime(0) - , mFragmentNumber(0) - , mLastFrameTimeOfLastFragment(0) - , mEOS(false) -{ - mFragArray.AppendElement(); - MOZ_COUNT_CTOR(FragmentBuffer); -} - -FragmentBuffer::~FragmentBuffer() -{ - MOZ_COUNT_DTOR(FragmentBuffer); -} - -bool -FragmentBuffer::HasEnoughData() -{ - // Audio or video frame is enough to form a moof. - return (mFragArray.Length() > 1); -} - -nsresult -FragmentBuffer::GetCSD(nsTArray<uint8_t>& aCSD) -{ - if (!mCSDFrame) { - return NS_ERROR_FAILURE; - } - aCSD.AppendElements(mCSDFrame->GetFrameData().Elements(), - mCSDFrame->GetFrameData().Length()); - - return NS_OK; -} - -nsresult -FragmentBuffer::AddFrame(EncodedFrame* aFrame) -{ - // already EOS, it rejects all new data. - if (mEOS) { - MOZ_ASSERT(0); - return NS_OK; - } - - EncodedFrame::FrameType type = aFrame->GetFrameType(); - if (type == EncodedFrame::AAC_CSD || type == EncodedFrame::AVC_CSD || - type == EncodedFrame::AMR_AUDIO_CSD || type == EncodedFrame::EVRC_AUDIO_CSD) { - mCSDFrame = aFrame; - // Use CSD's timestamp as the start time. Encoder should send CSD frame first - // and then data frames. - mMediaStartTime = aFrame->GetTimeStamp(); - mFragmentNumber = 1; - return NS_OK; - } - - // if the timestamp is incorrect, abort it. - if (aFrame->GetTimeStamp() < mMediaStartTime) { - MOZ_ASSERT(false); - return NS_ERROR_FAILURE; - } - - mFragArray.LastElement().AppendElement(aFrame); - - // check if current fragment is reach the fragment duration. - if ((aFrame->GetTimeStamp() - mMediaStartTime) >= (mFragDuration * mFragmentNumber)) { - mFragArray.AppendElement(); - mFragmentNumber++; - } - - return NS_OK; -} - -nsresult -FragmentBuffer::GetFirstFragment(nsTArray<RefPtr<EncodedFrame>>& aFragment, - bool aFlush) -{ - // It should be called only if there is a complete fragment in mFragArray. - if (mFragArray.Length() <= 1 && !mEOS) { - MOZ_ASSERT(false); - return NS_ERROR_FAILURE; - } - - if (aFlush) { - aFragment.SwapElements(mFragArray.ElementAt(0)); - mFragArray.RemoveElementAt(0); - } else { - aFragment.AppendElements(mFragArray.ElementAt(0)); - } - return NS_OK; -} - -uint32_t -FragmentBuffer::GetFirstFragmentSampleNumber() -{ - return mFragArray.ElementAt(0).Length(); -} - -uint32_t -FragmentBuffer::GetFirstFragmentSampleSize() -{ - uint32_t size = 0; - uint32_t len = mFragArray.ElementAt(0).Length(); - for (uint32_t i = 0; i < len; i++) { - size += mFragArray.ElementAt(0).ElementAt(i)->GetFrameData().Length(); - } - return size; -} - -ISOControl::ISOControl(uint32_t aMuxingType) - : mMuxingType(aMuxingType) - , mAudioFragmentBuffer(nullptr) - , mVideoFragmentBuffer(nullptr) - , mFragNum(0) - , mOutputSize(0) - , mBitCount(0) - , mBit(0) -{ - // Create a data array for first mp4 Box, ftyp. - mOutBuffers.SetLength(1); - MOZ_COUNT_CTOR(ISOControl); -} - -ISOControl::~ISOControl() -{ - MOZ_COUNT_DTOR(ISOControl); -} - -uint32_t -ISOControl::GetNextTrackID() -{ - return (mMetaArray.Length() + 1); -} - -uint32_t -ISOControl::GetTrackID(TrackMetadataBase::MetadataKind aKind) -{ - for (uint32_t i = 0; i < mMetaArray.Length(); i++) { - if (mMetaArray[i]->GetKind() == aKind) { - return (i + 1); - } - } - - // Track ID shouldn't be 0. It must be something wrong here. - MOZ_ASSERT(0); - return 0; -} - -nsresult -ISOControl::SetMetadata(TrackMetadataBase* aTrackMeta) -{ - if (aTrackMeta->GetKind() == TrackMetadataBase::METADATA_AAC || - aTrackMeta->GetKind() == TrackMetadataBase::METADATA_AMR || - aTrackMeta->GetKind() == TrackMetadataBase::METADATA_AVC || - aTrackMeta->GetKind() == TrackMetadataBase::METADATA_EVRC) { - mMetaArray.AppendElement(aTrackMeta); - return NS_OK; - } - return NS_ERROR_FAILURE; -} - -nsresult -ISOControl::GetAudioMetadata(RefPtr<AudioTrackMetadata>& aAudMeta) -{ - for (uint32_t i = 0; i < mMetaArray.Length() ; i++) { - if (mMetaArray[i]->GetKind() == TrackMetadataBase::METADATA_AAC || - mMetaArray[i]->GetKind() == TrackMetadataBase::METADATA_AMR || - mMetaArray[i]->GetKind() == TrackMetadataBase::METADATA_EVRC) { - aAudMeta = static_cast<AudioTrackMetadata*>(mMetaArray[i].get()); - return NS_OK; - } - } - return NS_ERROR_FAILURE; -} - -nsresult -ISOControl::GetVideoMetadata(RefPtr<VideoTrackMetadata>& aVidMeta) -{ - for (uint32_t i = 0; i < mMetaArray.Length() ; i++) { - if (mMetaArray[i]->GetKind() == TrackMetadataBase::METADATA_AVC) { - aVidMeta = static_cast<VideoTrackMetadata*>(mMetaArray[i].get()); - return NS_OK; - } - } - return NS_ERROR_FAILURE; -} - -bool -ISOControl::HasAudioTrack() -{ - RefPtr<AudioTrackMetadata> audMeta; - GetAudioMetadata(audMeta); - return audMeta; -} - -bool -ISOControl::HasVideoTrack() -{ - RefPtr<VideoTrackMetadata> vidMeta; - GetVideoMetadata(vidMeta); - return vidMeta; -} - -nsresult -ISOControl::SetFragment(FragmentBuffer* aFragment) -{ - if (aFragment->GetType() == Audio_Track) { - mAudioFragmentBuffer = aFragment; - } else { - mVideoFragmentBuffer = aFragment; - } - return NS_OK; -} - -FragmentBuffer* -ISOControl::GetFragment(uint32_t aType) -{ - if (aType == Audio_Track) { - return mAudioFragmentBuffer; - } else if (aType == Video_Track){ - return mVideoFragmentBuffer; - } - MOZ_ASSERT(0); - return nullptr; -} - -nsresult -ISOControl::GetBufs(nsTArray<nsTArray<uint8_t>>* aOutputBufs) -{ - uint32_t len = mOutBuffers.Length(); - for (uint32_t i = 0; i < len; i++) { - mOutBuffers[i].SwapElements(*aOutputBufs->AppendElement()); - } - return FlushBuf(); -} - -nsresult -ISOControl::FlushBuf() -{ - mOutBuffers.SetLength(1); - return NS_OK; -} - -uint32_t -ISOControl::WriteAVData(nsTArray<uint8_t>& aArray) -{ - MOZ_ASSERT(!mBitCount); - - uint32_t len = aArray.Length(); - if (!len) { - return 0; - } - - mOutputSize += len; - - // The last element already has data, allocated a new element for pointer - // swapping. - if (mOutBuffers.LastElement().Length()) { - mOutBuffers.AppendElement(); - } - // Swap the video/audio data pointer. - mOutBuffers.LastElement().SwapElements(aArray); - // Following data could be boxes, so appending a new uint8_t array here. - mOutBuffers.AppendElement(); - - return len; -} - -uint32_t -ISOControl::WriteBits(uint64_t aBits, size_t aNumBits) -{ - uint8_t output_byte = 0; - - MOZ_ASSERT(aNumBits <= 64); - // TODO: rewritten following with bitset? - for (size_t i = aNumBits; i > 0; i--) { - mBit |= (((aBits >> (i - 1)) & 1) << (8 - ++mBitCount)); - if (mBitCount == 8) { - Write(&mBit, sizeof(uint8_t)); - mBit = 0; - mBitCount = 0; - output_byte++; - } - } - return output_byte; -} - -uint32_t -ISOControl::Write(uint8_t* aBuf, uint32_t aSize) -{ - mOutBuffers.LastElement().AppendElements(aBuf, aSize); - mOutputSize += aSize; - return aSize; -} - -uint32_t -ISOControl::Write(uint8_t aData) -{ - MOZ_ASSERT(!mBitCount); - Write((uint8_t*)&aData, sizeof(uint8_t)); - return sizeof(uint8_t); -} - -uint32_t -ISOControl::GetBufPos() -{ - uint32_t len = mOutBuffers.Length(); - uint32_t pos = 0; - for (uint32_t i = 0; i < len; i++) { - pos += mOutBuffers.ElementAt(i).Length(); - } - return pos; -} - -uint32_t -ISOControl::WriteFourCC(const char* aType) -{ - // Bit operation should be aligned to byte before writing any byte data. - MOZ_ASSERT(!mBitCount); - - uint32_t size = strlen(aType); - if (size == 4) { - return Write((uint8_t*)aType, size); - } - - return 0; -} - -nsresult -ISOControl::GenerateFtyp() -{ - nsresult rv; - uint32_t size; - nsAutoPtr<FileTypeBox> type_box(new FileTypeBox(this)); - rv = type_box->Generate(&size); - NS_ENSURE_SUCCESS(rv, rv); - rv = type_box->Write(); - NS_ENSURE_SUCCESS(rv, rv); - return NS_OK; -} - -nsresult -ISOControl::GenerateMoov() -{ - nsresult rv; - uint32_t size; - nsAutoPtr<MovieBox> moov_box(new MovieBox(this)); - rv = moov_box->Generate(&size); - NS_ENSURE_SUCCESS(rv, rv); - rv = moov_box->Write(); - NS_ENSURE_SUCCESS(rv, rv); - return NS_OK; -} - -nsresult -ISOControl::GenerateMoof(uint32_t aTrackType) -{ - mFragNum++; - - nsresult rv; - uint32_t size; - uint64_t first_sample_offset = mOutputSize; - nsAutoPtr<MovieFragmentBox> moof_box(new MovieFragmentBox(aTrackType, this)); - nsAutoPtr<MediaDataBox> mdat_box(new MediaDataBox(aTrackType, this)); - - rv = moof_box->Generate(&size); - NS_ENSURE_SUCCESS(rv, rv); - first_sample_offset += size; - rv = mdat_box->Generate(&size); - NS_ENSURE_SUCCESS(rv, rv); - first_sample_offset += mdat_box->FirstSampleOffsetInMediaDataBox(); - - // correct offset info - nsTArray<RefPtr<MuxerOperation>> tfhds; - rv = moof_box->Find(NS_LITERAL_CSTRING("tfhd"), tfhds); - NS_ENSURE_SUCCESS(rv, rv); - uint32_t len = tfhds.Length(); - for (uint32_t i = 0; i < len; i++) { - TrackFragmentHeaderBox* tfhd = (TrackFragmentHeaderBox*) tfhds.ElementAt(i).get(); - rv = tfhd->UpdateBaseDataOffset(first_sample_offset); - NS_ENSURE_SUCCESS(rv, rv); - } - - rv = moof_box->Write(); - NS_ENSURE_SUCCESS(rv, rv); - rv = mdat_box->Write(); - NS_ENSURE_SUCCESS(rv, rv); - - return NS_OK; -} - -uint32_t -ISOControl::GetTime() -{ - return (uint64_t)time(nullptr) + iso_time_offset; -} - -} diff --git a/dom/media/encoder/fmp4_muxer/ISOControl.h b/dom/media/encoder/fmp4_muxer/ISOControl.h deleted file mode 100644 index 3c445caee..000000000 --- a/dom/media/encoder/fmp4_muxer/ISOControl.h +++ /dev/null @@ -1,250 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-*/ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef ISOCOMPOSITOR_H_ -#define ISOCOMPOSITOR_H_ - -#include "mozilla/EndianUtils.h" -#include "nsTArray.h" -#include "ISOTrackMetadata.h" -#include "EncodedFrameContainer.h" - -namespace mozilla { - -class Box; -class ISOControl; - -/** - * This class collects elementary stream data to form a fragment. - * ISOMediaWriter will check if the data is enough; if yes, the corresponding - * moof will be created and write to ISOControl. - * Each audio and video has its own fragment and only one during the whole - * life cycle, when a fragment is formed in ISOControl, Flush() needs to - * be called to reset it. - */ -class FragmentBuffer { -public: - // aTrackType: it could be Audio_Track or Video_Track. - // aFragDuration: it is the fragment duration. (microsecond per unit) - // Audio and video have the same fragment duration. - FragmentBuffer(uint32_t aTrackType, uint32_t aFragDuration); - ~FragmentBuffer(); - - // Get samples of first fragment, that will swap all the elements in the - // mFragArray[0] when aFlush = true, and caller is responsible for drop - // EncodedFrame reference count. - nsresult GetFirstFragment(nsTArray<RefPtr<EncodedFrame>>& aFragment, - bool aFlush = false); - - // Add sample frame to the last element fragment of mFragArray. If sample - // number is enough, it will append a new fragment element. And the new - // sample will be added to the new fragment element of mFragArray. - nsresult AddFrame(EncodedFrame* aFrame); - - // Get total sample size of first complete fragment size. - uint32_t GetFirstFragmentSampleSize(); - - // Get sample number of first complete fragment. - uint32_t GetFirstFragmentSampleNumber(); - - // Check if it accumulates enough frame data. - // It returns true when data is enough to form a fragment. - bool HasEnoughData(); - - // Called by ISOMediaWriter when TrackEncoder has sent the last frame. The - // remains frame data will form the last moof and move the state machine to - // in ISOMediaWriter to last phrase. - nsresult SetEndOfStream() { - mEOS = true; - return NS_OK; - } - bool EOS() { return mEOS; } - - // CSD (codec specific data), it is generated by encoder and the data depends - // on codec type. This data will be sent as a special frame from encoder to - // ISOMediaWriter and pass to this class via AddFrame(). - nsresult GetCSD(nsTArray<uint8_t>& aCSD); - - bool HasCSD() { return mCSDFrame; } - - uint32_t GetType() { return mTrackType; } - - void SetLastFragmentLastFrameTime(uint32_t aTime) { - mLastFrameTimeOfLastFragment = aTime; - } - - uint32_t GetLastFragmentLastFrameTime() { - return mLastFrameTimeOfLastFragment; - } - -private: - uint32_t mTrackType; - - // Fragment duration, microsecond per unit. - uint32_t mFragDuration; - - // Media start time, microsecond per unit. - // Together with mFragDuration, mFragmentNumber and EncodedFrame->GetTimeStamp(), - // when the difference between current frame time and mMediaStartTime is - // exceeded current fragment ceiling timeframe, that means current fragment has - // enough data and a new element in mFragArray will be added. - uint64_t mMediaStartTime; - - // Current fragment number. It will be increase when a new element of - // mFragArray is created. - // Note: - // It only means the fragment number of current accumulated frames, not - // the current 'creating' fragment mFragNum in ISOControl. - uint32_t mFragmentNumber; - - // The last frame time stamp of last fragment. It is for calculating the - // play duration of first frame in current fragment. The frame duration is - // defined as "current frame timestamp - last frame timestamp" here. So it - // needs to keep the last timestamp of last fragment. - uint32_t mLastFrameTimeOfLastFragment; - - // Array of fragments, each element has enough samples to form a - // complete fragment. - nsTArray<nsTArray<RefPtr<EncodedFrame>>> mFragArray; - - // Codec specific data frame, it will be generated by encoder and send to - // ISOMediaWriter through WriteEncodedTrack(). The data will be vary depends - // on codec type. - RefPtr<EncodedFrame> mCSDFrame; - - // END_OF_STREAM from ContainerWriter - bool mEOS; -}; - -/** - * ISOControl will be carried to each box when box is created. It is the main - * bridge for box to output stream to ContainerWriter and retrieve information. - * ISOControl acts 3 different roles: - * 1. Holds the pointer of audio metadata, video metadata, fragment and - * pass them to boxes. - * 2. Provide the functions to generate the base structure of MP4; they are - * GenerateFtyp, GenerateMoov, GenerateMoof, and GenerateMfra. - * 3. The actually writer used by MuxOperation::Write() in each box. It provides - * writing methods for different kind of data; they are Write, WriteArray, - * WriteBits...etc. - */ -class ISOControl { - -friend class Box; - -public: - ISOControl(uint32_t aMuxingType); - ~ISOControl(); - - nsresult GenerateFtyp(); - nsresult GenerateMoov(); - nsresult GenerateMoof(uint32_t aTrackType); - - // Swap elementary stream pointer to output buffers. - uint32_t WriteAVData(nsTArray<uint8_t>& aArray); - - uint32_t Write(uint8_t* aBuf, uint32_t aSize); - - uint32_t Write(uint8_t aData); - - template <typename T> - uint32_t Write(T aData) { - MOZ_ASSERT(!mBitCount); - - aData = NativeEndian::swapToNetworkOrder(aData); - Write((uint8_t*)&aData, sizeof(T)); - return sizeof(T); - } - - template <typename T> - uint32_t WriteArray(const T &aArray, uint32_t aSize) { - MOZ_ASSERT(!mBitCount); - - uint32_t size = 0; - for (uint32_t i = 0; i < aSize; i++) { - size += Write(aArray[i]); - } - return size; - } - - uint32_t WriteFourCC(const char* aType); - - // Bit writing. Note: it needs to be byte-boundary before using - // others non-bit writing function. - uint32_t WriteBits(uint64_t aBits, size_t aNumBits); - - // This is called by GetContainerData and swap all the buffers to aOutputBuffers. - nsresult GetBufs(nsTArray<nsTArray<uint8_t>>* aOutputBufs); - - // Presentation time in seconds since midnight, Jan. 1, 1904, in UTC time. - uint32_t GetTime(); - - // current fragment number - uint32_t GetCurFragmentNumber() { return mFragNum; } - - nsresult SetFragment(FragmentBuffer* aFragment); - FragmentBuffer* GetFragment(uint32_t aType); - - uint32_t GetMuxingType() { return mMuxingType; } - - nsresult SetMetadata(TrackMetadataBase* aTrackMeta); - nsresult GetAudioMetadata(RefPtr<AudioTrackMetadata>& aAudMeta); - nsresult GetVideoMetadata(RefPtr<VideoTrackMetadata>& aVidMeta); - - // Track ID is the Metadata index in mMetaArray. It allows only 1 audio - // track and 1 video track in this muxer. In this muxer, it is prohibt to have - // mutiple audio track or video track in the same file. - uint32_t GetTrackID(TrackMetadataBase::MetadataKind aKind); - uint32_t GetNextTrackID(); - - bool HasAudioTrack(); - bool HasVideoTrack(); - -private: - uint32_t GetBufPos(); - nsresult FlushBuf(); - - // One of value in TYPE_XXX, defined in ISOMediaWriter. - uint32_t mMuxingType; - - // Audio and video fragments are owned by ISOMediaWriter. - // They don't need to worry about pointer going stale because ISOMediaWriter's - // lifetime is longer than ISOControl. - FragmentBuffer* mAudioFragmentBuffer; - FragmentBuffer* mVideoFragmentBuffer; - - // Generated fragment number - uint32_t mFragNum; - - // The (index + 1) will be the track ID. - nsTArray<RefPtr<TrackMetadataBase>> mMetaArray; - - // Array of output buffers. - // To save memory usage, audio/video sample will be swapped into a new element - // of this array. - // - // For example, - // mOutBuffers[0] --> boxes (allocated by muxer) - // mOutBuffers[1] --> video raw data (allocated by encoder) - // mOutBuffers[2] --> video raw data (allocated by encoder) - // mOutBuffers[3] --> video raw data (allocated by encoder) - // mOutBuffers[4] --> boxes (allocated by muxer) - // mOutBuffers[5] --> audio raw data (allocated by encoder) - // ...etc. - // - nsTArray<nsTArray<uint8_t>> mOutBuffers; - - // Accumulate output size from Write(). - uint64_t mOutputSize; - - // Bit writing operation. Note: the mBitCount should be 0 before any - // byte-boundary writing method be called (Write(uint32_t), Write(uint16_t)...etc); - // otherwise, there will be assertion on these functions. - uint8_t mBitCount; - uint8_t mBit; -}; - -} -#endif diff --git a/dom/media/encoder/fmp4_muxer/ISOMediaBoxes.cpp b/dom/media/encoder/fmp4_muxer/ISOMediaBoxes.cpp deleted file mode 100644 index 32a0c577b..000000000 --- a/dom/media/encoder/fmp4_muxer/ISOMediaBoxes.cpp +++ /dev/null @@ -1,1550 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-*/ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include <climits> -#include "TrackMetadataBase.h" -#include "ISOMediaBoxes.h" -#include "ISOControl.h" -#include "ISOMediaWriter.h" -#include "EncodedFrameContainer.h" -#include "ISOTrackMetadata.h" -#include "MP4ESDS.h" -#include "AMRBox.h" -#include "AVCBox.h" -#include "EVRCBox.h" -#include "VideoUtils.h" - -namespace mozilla { - -// 14496-12 6.2.2 'Data Types and fields' -const uint32_t iso_matrix[] = { 0x00010000, 0, 0, - 0, 0x00010000, 0, - 0, 0, 0x40000000 }; - -uint32_t -set_sample_flags(bool aSync) -{ - std::bitset<32> flags; - flags.set(16, !aSync); - return flags.to_ulong(); -} - -Box::BoxSizeChecker::BoxSizeChecker(ISOControl* aControl, uint32_t aSize) -{ - mControl = aControl; - ori_size = mControl->GetBufPos(); - box_size = aSize; - MOZ_COUNT_CTOR(BoxSizeChecker); -} - -Box::BoxSizeChecker::~BoxSizeChecker() -{ - uint32_t cur_size = mControl->GetBufPos(); - if ((cur_size - ori_size) != box_size) { - MOZ_ASSERT(false); - } - - MOZ_COUNT_DTOR(BoxSizeChecker); -} - -nsresult -MediaDataBox::Generate(uint32_t* aBoxSize) -{ - mFirstSampleOffset = size; - mAllSampleSize = 0; - - if (mTrackType & Audio_Track) { - FragmentBuffer* frag = mControl->GetFragment(Audio_Track); - mAllSampleSize += frag->GetFirstFragmentSampleSize(); - } - if (mTrackType & Video_Track) { - FragmentBuffer* frag = mControl->GetFragment(Video_Track); - mAllSampleSize += frag->GetFirstFragmentSampleSize(); - } - - size += mAllSampleSize; - *aBoxSize = size; - return NS_OK; -} - -nsresult -MediaDataBox::Write() -{ - nsresult rv; - BoxSizeChecker checker(mControl, size); - Box::Write(); - nsTArray<uint32_t> types; - types.AppendElement(Audio_Track); - types.AppendElement(Video_Track); - - for (uint32_t l = 0; l < types.Length(); l++) { - if (mTrackType & types[l]) { - FragmentBuffer* frag = mControl->GetFragment(types[l]); - nsTArray<RefPtr<EncodedFrame>> frames; - - // Here is the last time we get fragment frames, flush it! - rv = frag->GetFirstFragment(frames, true); - NS_ENSURE_SUCCESS(rv, rv); - - uint32_t len = frames.Length(); - for (uint32_t i = 0; i < len; i++) { - nsTArray<uint8_t> frame_buffer; - frames.ElementAt(i)->SwapOutFrameData(frame_buffer); - mControl->WriteAVData(frame_buffer); - } - } - } - - return NS_OK; -} - -MediaDataBox::MediaDataBox(uint32_t aTrackType, ISOControl* aControl) - : Box(NS_LITERAL_CSTRING("mdat"), aControl) - , mAllSampleSize(0) - , mFirstSampleOffset(0) - , mTrackType(aTrackType) -{ - MOZ_COUNT_CTOR(MediaDataBox); -} - -MediaDataBox::~MediaDataBox() -{ - MOZ_COUNT_DTOR(MediaDataBox); -} - -uint32_t -TrackRunBox::fillSampleTable() -{ - uint32_t table_size = 0; - nsresult rv; - nsTArray<RefPtr<EncodedFrame>> frames; - FragmentBuffer* frag = mControl->GetFragment(mTrackType); - - rv = frag->GetFirstFragment(frames); - if (NS_FAILED(rv)) { - return 0; - } - uint32_t len = frames.Length(); - sample_info_table = MakeUnique<tbl[]>(len); - // Create sample table according to 14496-12 8.8.8.2. - for (uint32_t i = 0; i < len; i++) { - // Sample size. - sample_info_table[i].sample_size = 0; - if (flags.to_ulong() & flags_sample_size_present) { - sample_info_table[i].sample_size = frames.ElementAt(i)->GetFrameData().Length(); - mAllSampleSize += sample_info_table[i].sample_size; - table_size += sizeof(uint32_t); - } - - // Sample flags. - sample_info_table[i].sample_flags = 0; - if (flags.to_ulong() & flags_sample_flags_present) { - sample_info_table[i].sample_flags = - set_sample_flags( - (frames.ElementAt(i)->GetFrameType() == EncodedFrame::AVC_I_FRAME)); - table_size += sizeof(uint32_t); - } - - // Sample duration. - sample_info_table[i].sample_duration = 0; - if (flags.to_ulong() & flags_sample_duration_present) { - // Calculate each frame's duration, it is decided by "current frame - // timestamp - last frame timestamp". - uint64_t frame_time = 0; - if (i == 0) { - frame_time = frames.ElementAt(i)->GetTimeStamp() - - frag->GetLastFragmentLastFrameTime(); - } else { - frame_time = frames.ElementAt(i)->GetTimeStamp() - - frames.ElementAt(i - 1)->GetTimeStamp(); - // Keep the last frame time of current fagment, it will be used to calculate - // the first frame duration of next fragment. - if ((len - 1) == i) { - frag->SetLastFragmentLastFrameTime(frames.ElementAt(i)->GetTimeStamp()); - } - } - - // In TrackRunBox, there should be exactly one type, either audio or video. - MOZ_ASSERT((mTrackType & Video_Track) ^ (mTrackType & Audio_Track)); - sample_info_table[i].sample_duration = (mTrackType & Video_Track ? - frame_time * mVideoMeta->GetVideoClockRate() / USECS_PER_S : - frame_time * mAudioMeta->GetAudioSampleRate() / USECS_PER_S); - - table_size += sizeof(uint32_t); - } - - sample_info_table[i].sample_composition_time_offset = 0; - } - return table_size; -} - -nsresult -TrackRunBox::Generate(uint32_t* aBoxSize) -{ - FragmentBuffer* frag = mControl->GetFragment(mTrackType); - sample_count = frag->GetFirstFragmentSampleNumber(); - size += sizeof(sample_count); - - // data_offset needs to be updated if there is other - // TrackRunBox before this one. - if (flags.to_ulong() & flags_data_offset_present) { - data_offset = 0; - size += sizeof(data_offset); - } - size += fillSampleTable(); - - *aBoxSize = size; - - return NS_OK; -} - -nsresult -TrackRunBox::SetDataOffset(uint32_t aOffset) -{ - data_offset = aOffset; - return NS_OK; -} - -nsresult -TrackRunBox::Write() -{ - WRITE_FULLBOX(mControl, size) - mControl->Write(sample_count); - if (flags.to_ulong() & flags_data_offset_present) { - mControl->Write(data_offset); - } - for (uint32_t i = 0; i < sample_count; i++) { - if (flags.to_ulong() & flags_sample_duration_present) { - mControl->Write(sample_info_table[i].sample_duration); - } - if (flags.to_ulong() & flags_sample_size_present) { - mControl->Write(sample_info_table[i].sample_size); - } - if (flags.to_ulong() & flags_sample_flags_present) { - mControl->Write(sample_info_table[i].sample_flags); - } - } - - return NS_OK; -} - -TrackRunBox::TrackRunBox(uint32_t aType, uint32_t aFlags, ISOControl* aControl) - : FullBox(NS_LITERAL_CSTRING("trun"), 0, aFlags, aControl) - , sample_count(0) - , data_offset(0) - , first_sample_flags(0) - , mAllSampleSize(0) - , mTrackType(aType) -{ - MOZ_COUNT_CTOR(TrackRunBox); -} - -TrackRunBox::~TrackRunBox() -{ - MOZ_COUNT_DTOR(TrackRunBox); -} - -nsresult -TrackFragmentHeaderBox::UpdateBaseDataOffset(uint64_t aOffset) -{ - base_data_offset = aOffset; - return NS_OK; -} - -nsresult -TrackFragmentHeaderBox::Generate(uint32_t* aBoxSize) -{ - track_ID = (mTrackType == Audio_Track ? - mControl->GetTrackID(mAudioMeta->GetKind()) : - mControl->GetTrackID(mVideoMeta->GetKind())); - size += sizeof(track_ID); - - if (flags.to_ulong() & base_data_offset_present) { - // base_data_offset needs to add size of 'trun', 'tfhd' and - // header of 'mdat' later. - base_data_offset = 0; - size += sizeof(base_data_offset); - } - if (flags.to_ulong() & default_sample_duration_present) { - if (mTrackType == Video_Track) { - if (!mVideoMeta->GetVideoFrameRate()) { - // 0 means frame rate is variant, so it is wrong to write - // default_sample_duration. - MOZ_ASSERT(0); - default_sample_duration = 0; - } else { - default_sample_duration = mVideoMeta->GetVideoClockRate() / mVideoMeta->GetVideoFrameRate(); - } - } else if (mTrackType == Audio_Track) { - default_sample_duration = mAudioMeta->GetAudioFrameDuration(); - } else { - MOZ_ASSERT(0); - return NS_ERROR_FAILURE; - } - size += sizeof(default_sample_duration); - } - *aBoxSize = size; - return NS_OK; -} - -nsresult -TrackFragmentHeaderBox::Write() -{ - WRITE_FULLBOX(mControl, size) - mControl->Write(track_ID); - if (flags.to_ulong() & base_data_offset_present) { - mControl->Write(base_data_offset); - } - if (flags.to_ulong() & default_sample_duration_present) { - mControl->Write(default_sample_duration); - } - return NS_OK; -} - -TrackFragmentHeaderBox::TrackFragmentHeaderBox(uint32_t aType, - uint32_t aFlags, - ISOControl* aControl) - : FullBox(NS_LITERAL_CSTRING("tfhd"), 0, aFlags, aControl) - , track_ID(0) - , base_data_offset(0) - , default_sample_duration(0) -{ - mTrackType = aType; - MOZ_COUNT_CTOR(TrackFragmentHeaderBox); -} - -TrackFragmentHeaderBox::~TrackFragmentHeaderBox() -{ - MOZ_COUNT_DTOR(TrackFragmentHeaderBox); -} - -TrackFragmentBox::TrackFragmentBox(uint32_t aType, ISOControl* aControl) - : DefaultContainerImpl(NS_LITERAL_CSTRING("traf"), aControl) - , mTrackType(aType) -{ - // Flags in TrackFragmentHeaderBox. - uint32_t tf_flags = base_data_offset_present; - - // Ideally, audio encoder generates audio frame in const rate. However, some - // audio encoders don't do it so the audio frame duration needs to be checked - // here. - if ((mTrackType & Audio_Track) && mAudioMeta->GetAudioFrameDuration()) { - tf_flags |= default_sample_duration_present; - } - - boxes.AppendElement(new TrackFragmentHeaderBox(aType, tf_flags, aControl)); - - // Always adds flags_data_offset_present in each TrackRunBox, Android - // parser requires this flag to calculate the correct bitstream offset. - uint32_t tr_flags = flags_sample_size_present | flags_data_offset_present; - - // Flags in TrackRunBox. - // If there is no default sample duration exists, each frame duration needs to - // be recored in the TrackRunBox. - tr_flags |= (tf_flags & default_sample_duration_present ? 0 : flags_sample_duration_present); - - // For video, add sample_flags to record I frame. - tr_flags |= (mTrackType & Video_Track ? flags_sample_flags_present : 0); - - boxes.AppendElement(new TrackRunBox(mTrackType, tr_flags, aControl)); - MOZ_COUNT_CTOR(TrackFragmentBox); -} - -TrackFragmentBox::~TrackFragmentBox() -{ - MOZ_COUNT_DTOR(TrackFragmentBox); -} - -nsresult -MovieFragmentHeaderBox::Generate(uint32_t* aBoxSize) -{ - sequence_number = mControl->GetCurFragmentNumber(); - size += sizeof(sequence_number); - *aBoxSize = size; - return NS_OK; -} - -nsresult -MovieFragmentHeaderBox::Write() -{ - WRITE_FULLBOX(mControl, size) - mControl->Write(sequence_number); - return NS_OK; -} - -MovieFragmentHeaderBox::MovieFragmentHeaderBox(uint32_t aTrackType, - ISOControl* aControl) - : FullBox(NS_LITERAL_CSTRING("mfhd"), 0, 0, aControl) - , sequence_number(0) - , mTrackType(aTrackType) -{ - MOZ_COUNT_CTOR(MovieFragmentHeaderBox); -} - -MovieFragmentHeaderBox::~MovieFragmentHeaderBox() -{ - MOZ_COUNT_DTOR(MovieFragmentHeaderBox); -} - -MovieFragmentBox::MovieFragmentBox(uint32_t aType, ISOControl* aControl) - : DefaultContainerImpl(NS_LITERAL_CSTRING("moof"), aControl) - , mTrackType(aType) -{ - boxes.AppendElement(new MovieFragmentHeaderBox(mTrackType, aControl)); - - if (mTrackType & Audio_Track) { - boxes.AppendElement( - new TrackFragmentBox(Audio_Track, aControl)); - } - if (mTrackType & Video_Track) { - boxes.AppendElement( - new TrackFragmentBox(Video_Track, aControl)); - } - MOZ_COUNT_CTOR(MovieFragmentBox); -} - -MovieFragmentBox::~MovieFragmentBox() -{ - MOZ_COUNT_DTOR(MovieFragmentBox); -} - -nsresult -MovieFragmentBox::Generate(uint32_t* aBoxSize) -{ - nsresult rv = DefaultContainerImpl::Generate(aBoxSize); - NS_ENSURE_SUCCESS(rv, rv); - - // Correct data_offset if there are both audio and video track in - // this fragment. This offset means the offset in the MediaDataBox. - if (mTrackType & (Audio_Track | Video_Track)) { - nsTArray<RefPtr<MuxerOperation>> truns; - rv = Find(NS_LITERAL_CSTRING("trun"), truns); - NS_ENSURE_SUCCESS(rv, rv); - uint32_t len = truns.Length(); - uint32_t data_offset = 0; - for (uint32_t i = 0; i < len; i++) { - TrackRunBox* trun = (TrackRunBox*) truns.ElementAt(i).get(); - rv = trun->SetDataOffset(data_offset); - NS_ENSURE_SUCCESS(rv, rv); - data_offset += trun->GetAllSampleSize(); - } - } - - return NS_OK; -} - -nsresult -TrackExtendsBox::Generate(uint32_t* aBoxSize) -{ - track_ID = (mTrackType == Audio_Track ? - mControl->GetTrackID(mAudioMeta->GetKind()) : - mControl->GetTrackID(mVideoMeta->GetKind())); - - if (mTrackType == Audio_Track) { - default_sample_description_index = 1; - default_sample_duration = mAudioMeta->GetAudioFrameDuration(); - default_sample_size = mAudioMeta->GetAudioFrameSize(); - default_sample_flags = set_sample_flags(1); - } else if (mTrackType == Video_Track) { - default_sample_description_index = 1; - // Video meta data has assigned framerate, it implies that this video's - // frame rate should be fixed. - if (mVideoMeta->GetVideoFrameRate()) { - default_sample_duration = - mVideoMeta->GetVideoClockRate() / mVideoMeta->GetVideoFrameRate(); - } - default_sample_size = 0; - default_sample_flags = set_sample_flags(0); - } else { - MOZ_ASSERT(0); - return NS_ERROR_FAILURE; - } - - size += sizeof(track_ID) + - sizeof(default_sample_description_index) + - sizeof(default_sample_duration) + - sizeof(default_sample_size) + - sizeof(default_sample_flags); - - *aBoxSize = size; - - return NS_OK; -} - -nsresult -TrackExtendsBox::Write() -{ - WRITE_FULLBOX(mControl, size) - mControl->Write(track_ID); - mControl->Write(default_sample_description_index); - mControl->Write(default_sample_duration); - mControl->Write(default_sample_size); - mControl->Write(default_sample_flags); - - return NS_OK; -} - -TrackExtendsBox::TrackExtendsBox(uint32_t aType, ISOControl* aControl) - : FullBox(NS_LITERAL_CSTRING("trex"), 0, 0, aControl) - , track_ID(0) - , default_sample_description_index(0) - , default_sample_duration(0) - , default_sample_size(0) - , default_sample_flags(0) - , mTrackType(aType) -{ - MOZ_COUNT_CTOR(TrackExtendsBox); -} - -TrackExtendsBox::~TrackExtendsBox() -{ - MOZ_COUNT_DTOR(TrackExtendsBox); -} - -MovieExtendsBox::MovieExtendsBox(ISOControl* aControl) - : DefaultContainerImpl(NS_LITERAL_CSTRING("mvex"), aControl) -{ - if (mAudioMeta) { - boxes.AppendElement(new TrackExtendsBox(Audio_Track, aControl)); - } - if (mVideoMeta) { - boxes.AppendElement(new TrackExtendsBox(Video_Track, aControl)); - } - MOZ_COUNT_CTOR(MovieExtendsBox); -} - -MovieExtendsBox::~MovieExtendsBox() -{ - MOZ_COUNT_DTOR(MovieExtendsBox); -} - -nsresult -ChunkOffsetBox::Generate(uint32_t* aBoxSize) -{ - // We don't need time to sample table in fragmented mp4. - entry_count = 0; - size += sizeof(entry_count); - *aBoxSize = size; - return NS_OK; -} - -nsresult -ChunkOffsetBox::Write() -{ - WRITE_FULLBOX(mControl, size) - mControl->Write(entry_count); - return NS_OK; -} - -ChunkOffsetBox::ChunkOffsetBox(uint32_t aType, ISOControl* aControl) - : FullBox(NS_LITERAL_CSTRING("stco"), 0, 0, aControl) - , entry_count(0) -{ - MOZ_COUNT_CTOR(ChunkOffsetBox); -} - -ChunkOffsetBox::~ChunkOffsetBox() -{ - MOZ_COUNT_DTOR(ChunkOffsetBox); -} - -nsresult -SampleToChunkBox::Generate(uint32_t* aBoxSize) -{ - // We don't need time to sample table in fragmented mp4 - entry_count = 0; - size += sizeof(entry_count); - *aBoxSize = size; - return NS_OK; -} - -nsresult -SampleToChunkBox::Write() -{ - WRITE_FULLBOX(mControl, size) - mControl->Write(entry_count); - return NS_OK; -} - -SampleToChunkBox::SampleToChunkBox(uint32_t aType, ISOControl* aControl) - : FullBox(NS_LITERAL_CSTRING("stsc"), 0, 0, aControl) - , entry_count(0) -{ - MOZ_COUNT_CTOR(SampleToChunkBox); -} - -SampleToChunkBox::~SampleToChunkBox() -{ - MOZ_COUNT_DTOR(SampleToChunkBox); -} - -nsresult -TimeToSampleBox::Generate(uint32_t* aBoxSize) -{ - // We don't need time to sample table in fragmented mp4. - entry_count = 0; - size += sizeof(entry_count); - *aBoxSize = size; - return NS_OK; -} - -nsresult -TimeToSampleBox::Write() -{ - WRITE_FULLBOX(mControl, size) - mControl->Write(entry_count); - return NS_OK; -} - -TimeToSampleBox::TimeToSampleBox(uint32_t aType, ISOControl* aControl) - : FullBox(NS_LITERAL_CSTRING("stts"), 0, 0, aControl) - , entry_count(0) -{ - MOZ_COUNT_CTOR(TimeToSampleBox); -} - -TimeToSampleBox::~TimeToSampleBox() -{ - MOZ_COUNT_DTOR(TimeToSampleBox); -} - -nsresult -SampleDescriptionBox::Generate(uint32_t* aBoxSize) -{ - entry_count = 1; - size += sizeof(entry_count); - - nsresult rv; - uint32_t box_size; - rv = sample_entry_box->Generate(&box_size); - NS_ENSURE_SUCCESS(rv, rv); - size += box_size; - *aBoxSize = size; - - return NS_OK; -} - -nsresult -SampleDescriptionBox::Write() -{ - WRITE_FULLBOX(mControl, size) - nsresult rv; - mControl->Write(entry_count); - rv = sample_entry_box->Write(); - NS_ENSURE_SUCCESS(rv, rv); - - return NS_OK; -} - -SampleDescriptionBox::SampleDescriptionBox(uint32_t aType, ISOControl* aControl) - : FullBox(NS_LITERAL_CSTRING("stsd"), 0, 0, aControl) - , entry_count(0) -{ - mTrackType = aType; - - switch (mTrackType) { - case Audio_Track: - { - CreateAudioSampleEntry(sample_entry_box); - } - break; - case Video_Track: - { - CreateVideoSampleEntry(sample_entry_box); - } - break; - } - MOZ_ASSERT(sample_entry_box); - MOZ_COUNT_CTOR(SampleDescriptionBox); -} - -nsresult -SampleDescriptionBox::CreateAudioSampleEntry(RefPtr<SampleEntryBox>& aSampleEntry) -{ - if (mAudioMeta->GetKind() == TrackMetadataBase::METADATA_AMR) { - aSampleEntry = new AMRSampleEntry(mControl); - } else if (mAudioMeta->GetKind() == TrackMetadataBase::METADATA_AAC) { - aSampleEntry = new MP4AudioSampleEntry(mControl); - } else if (mAudioMeta->GetKind() == TrackMetadataBase::METADATA_EVRC) { - aSampleEntry = new EVRCSampleEntry(mControl); - } else { - MOZ_ASSERT(0); - } - return NS_OK; -} - -nsresult -SampleDescriptionBox::CreateVideoSampleEntry(RefPtr<SampleEntryBox>& aSampleEntry) -{ - if (mVideoMeta->GetKind() == TrackMetadataBase::METADATA_AVC) { - aSampleEntry = new AVCSampleEntry(mControl); - } else { - MOZ_ASSERT(0); - } - return NS_OK; -} - -SampleDescriptionBox::~SampleDescriptionBox() -{ - MOZ_COUNT_DTOR(SampleDescriptionBox); -} - -nsresult -SampleSizeBox::Generate(uint32_t* aBoxSize) -{ - size += sizeof(sample_size) + - sizeof(sample_count); - *aBoxSize = size; - return NS_OK; -} - -nsresult -SampleSizeBox::Write() -{ - WRITE_FULLBOX(mControl, size) - mControl->Write(sample_size); - mControl->Write(sample_count); - return NS_OK; -} - -SampleSizeBox::SampleSizeBox(ISOControl* aControl) - : FullBox(NS_LITERAL_CSTRING("stsz"), 0, 0, aControl) - , sample_size(0) - , sample_count(0) -{ - MOZ_COUNT_CTOR(SampleSizeBox); -} - -SampleSizeBox::~SampleSizeBox() -{ - MOZ_COUNT_DTOR(SampleSizeBox); -} - -SampleTableBox::SampleTableBox(uint32_t aType, ISOControl* aControl) - : DefaultContainerImpl(NS_LITERAL_CSTRING("stbl"), aControl) -{ - boxes.AppendElement(new SampleDescriptionBox(aType, aControl)); - boxes.AppendElement(new TimeToSampleBox(aType, aControl)); - boxes.AppendElement(new SampleToChunkBox(aType, aControl)); - boxes.AppendElement(new SampleSizeBox(aControl)); - boxes.AppendElement(new ChunkOffsetBox(aType, aControl)); - MOZ_COUNT_CTOR(SampleTableBox); -} - -SampleTableBox::~SampleTableBox() -{ - MOZ_COUNT_DTOR(SampleTableBox); -} - -nsresult -DataEntryUrlBox::Generate(uint32_t* aBoxSize) -{ - // location is null here, do nothing - size += location.Length(); - *aBoxSize = size; - - return NS_OK; -} - -nsresult -DataEntryUrlBox::Write() -{ - WRITE_FULLBOX(mControl, size) - return NS_OK; -} - -DataEntryUrlBox::DataEntryUrlBox() - : FullBox(NS_LITERAL_CSTRING("url "), 0, 0, (ISOControl*) nullptr) -{ - MOZ_COUNT_CTOR(DataEntryUrlBox); -} - -DataEntryUrlBox::DataEntryUrlBox(ISOControl* aControl) - : FullBox(NS_LITERAL_CSTRING("url "), 0, flags_media_at_the_same_file, aControl) -{ - MOZ_COUNT_CTOR(DataEntryUrlBox); -} - -DataEntryUrlBox::DataEntryUrlBox(const DataEntryUrlBox& aBox) - : FullBox(aBox.boxType, aBox.version, aBox.flags.to_ulong(), aBox.mControl) -{ - location = aBox.location; - MOZ_COUNT_CTOR(DataEntryUrlBox); -} - -DataEntryUrlBox::~DataEntryUrlBox() -{ - MOZ_COUNT_DTOR(DataEntryUrlBox); -} - -nsresult DataReferenceBox::Generate(uint32_t* aBoxSize) -{ - entry_count = 1; // only allow on entry here - size += sizeof(uint32_t); - - for (uint32_t i = 0; i < entry_count; i++) { - uint32_t box_size = 0; - DataEntryUrlBox* url = new DataEntryUrlBox(mControl); - url->Generate(&box_size); - size += box_size; - urls.AppendElement(url); - } - - *aBoxSize = size; - - return NS_OK; -} - -nsresult DataReferenceBox::Write() -{ - WRITE_FULLBOX(mControl, size) - mControl->Write(entry_count); - - for (uint32_t i = 0; i < entry_count; i++) { - urls[i]->Write(); - } - - return NS_OK; -} - -DataReferenceBox::DataReferenceBox(ISOControl* aControl) - : FullBox(NS_LITERAL_CSTRING("dref"), 0, 0, aControl) - , entry_count(0) -{ - MOZ_COUNT_CTOR(DataReferenceBox); -} - -DataReferenceBox::~DataReferenceBox() -{ - MOZ_COUNT_DTOR(DataReferenceBox); -} - -DataInformationBox::DataInformationBox(ISOControl* aControl) - : DefaultContainerImpl(NS_LITERAL_CSTRING("dinf"), aControl) -{ - boxes.AppendElement(new DataReferenceBox(aControl)); - MOZ_COUNT_CTOR(DataInformationBox); -} - -DataInformationBox::~DataInformationBox() -{ - MOZ_COUNT_DTOR(DataInformationBox); -} - -nsresult -VideoMediaHeaderBox::Generate(uint32_t* aBoxSize) -{ - size += sizeof(graphicsmode) + - sizeof(opcolor); - - *aBoxSize = size; - - return NS_OK; -} - -nsresult -VideoMediaHeaderBox::Write() -{ - WRITE_FULLBOX(mControl, size) - mControl->Write(graphicsmode); - mControl->WriteArray(opcolor, 3); - return NS_OK; -} - -VideoMediaHeaderBox::VideoMediaHeaderBox(ISOControl* aControl) - : FullBox(NS_LITERAL_CSTRING("vmhd"), 0, 1, aControl) - , graphicsmode(0) -{ - memset(opcolor, 0 , sizeof(opcolor)); - MOZ_COUNT_CTOR(VideoMediaHeaderBox); -} - -VideoMediaHeaderBox::~VideoMediaHeaderBox() -{ - MOZ_COUNT_DTOR(VideoMediaHeaderBox); -} - -nsresult -SoundMediaHeaderBox::Generate(uint32_t* aBoxSize) -{ - balance = 0; - reserved = 0; - size += sizeof(balance) + - sizeof(reserved); - - *aBoxSize = size; - - return NS_OK; -} - -nsresult -SoundMediaHeaderBox::Write() -{ - WRITE_FULLBOX(mControl, size) - mControl->Write(balance); - mControl->Write(reserved); - - return NS_OK; -} - -SoundMediaHeaderBox::SoundMediaHeaderBox(ISOControl* aControl) - : FullBox(NS_LITERAL_CSTRING("smhd"), 0, 0, aControl) -{ - MOZ_COUNT_CTOR(SoundMediaHeaderBox); -} - -SoundMediaHeaderBox::~SoundMediaHeaderBox() -{ - MOZ_COUNT_DTOR(SoundMediaHeaderBox); -} - -MediaInformationBox::MediaInformationBox(uint32_t aType, ISOControl* aControl) - : DefaultContainerImpl(NS_LITERAL_CSTRING("minf"), aControl) -{ - mTrackType = aType; - - if (mTrackType == Audio_Track) { - boxes.AppendElement(new SoundMediaHeaderBox(aControl)); - } else if (mTrackType == Video_Track) { - boxes.AppendElement(new VideoMediaHeaderBox(aControl)); - } else { - MOZ_ASSERT(0); - } - - boxes.AppendElement(new DataInformationBox(aControl)); - boxes.AppendElement(new SampleTableBox(aType, aControl)); - MOZ_COUNT_CTOR(MediaInformationBox); -} - -MediaInformationBox::~MediaInformationBox() -{ - MOZ_COUNT_DTOR(MediaInformationBox); -} - -nsresult -HandlerBox::Generate(uint32_t* aBoxSize) -{ - pre_defined = 0; - if (mTrackType == Audio_Track) { - handler_type = FOURCC('s', 'o', 'u', 'n'); - } else if (mTrackType == Video_Track) { - handler_type = FOURCC('v', 'i', 'd', 'e'); - } - - size += sizeof(pre_defined) + - sizeof(handler_type) + - sizeof(reserved); - - *aBoxSize = size; - - return NS_OK; -} - -nsresult -HandlerBox::Write() -{ - WRITE_FULLBOX(mControl, size) - mControl->Write(pre_defined); - mControl->Write(handler_type); - mControl->WriteArray(reserved, 3); - - return NS_OK; -} - -HandlerBox::HandlerBox(uint32_t aType, ISOControl* aControl) - : FullBox(NS_LITERAL_CSTRING("hdlr"), 0, 0, aControl) - , pre_defined(0) - , handler_type(0) -{ - mTrackType = aType; - memset(reserved, 0 , sizeof(reserved)); - MOZ_COUNT_CTOR(HandlerBox); -} - -HandlerBox::~HandlerBox() -{ - MOZ_COUNT_DTOR(HandlerBox); -} - -MediaHeaderBox::MediaHeaderBox(uint32_t aType, ISOControl* aControl) - : FullBox(NS_LITERAL_CSTRING("mdhd"), 0, 0, aControl) - , creation_time(0) - , modification_time(0) - , timescale(0) - , duration(0) - , pad(0) - , lang1(0) - , lang2(0) - , lang3(0) - , pre_defined(0) -{ - mTrackType = aType; - MOZ_COUNT_CTOR(MediaHeaderBox); -} - -MediaHeaderBox::~MediaHeaderBox() -{ - MOZ_COUNT_DTOR(MediaHeaderBox); -} - -uint32_t -MediaHeaderBox::GetTimeScale() -{ - if (mTrackType == Audio_Track) { - return mAudioMeta->GetAudioSampleRate(); - } - - return mVideoMeta->GetVideoClockRate(); -} - -nsresult -MediaHeaderBox::Generate(uint32_t* aBoxSize) -{ - creation_time = mControl->GetTime(); - modification_time = mControl->GetTime(); - timescale = GetTimeScale(); - duration = 0; // fragmented mp4 - - pad = 0; - lang1 = 'u' - 0x60; // "und" underdetermined language - lang2 = 'n' - 0x60; - lang3 = 'd' - 0x60; - size += (pad.size() + lang1.size() + lang2.size() + lang3.size()) / CHAR_BIT; - - pre_defined = 0; - size += sizeof(creation_time) + - sizeof(modification_time) + - sizeof(timescale) + - sizeof(duration) + - sizeof(pre_defined); - - *aBoxSize = size; - - return NS_OK; -} - -nsresult -MediaHeaderBox::Write() -{ - WRITE_FULLBOX(mControl, size) - mControl->Write(creation_time); - mControl->Write(modification_time); - mControl->Write(timescale); - mControl->Write(duration); - mControl->WriteBits(pad.to_ulong(), pad.size()); - mControl->WriteBits(lang1.to_ulong(), lang1.size()); - mControl->WriteBits(lang2.to_ulong(), lang2.size()); - mControl->WriteBits(lang3.to_ulong(), lang3.size()); - mControl->Write(pre_defined); - - return NS_OK; -} - -MovieBox::MovieBox(ISOControl* aControl) - : DefaultContainerImpl(NS_LITERAL_CSTRING("moov"), aControl) -{ - boxes.AppendElement(new MovieHeaderBox(aControl)); - if (aControl->HasAudioTrack()) { - boxes.AppendElement(new TrackBox(Audio_Track, aControl)); - } - if (aControl->HasVideoTrack()) { - boxes.AppendElement(new TrackBox(Video_Track, aControl)); - } - boxes.AppendElement(new MovieExtendsBox(aControl)); - MOZ_COUNT_CTOR(MovieBox); -} - -MovieBox::~MovieBox() -{ - MOZ_COUNT_DTOR(MovieBox); -} - -nsresult -MovieHeaderBox::Generate(uint32_t* aBoxSize) -{ - creation_time = mControl->GetTime(); - modification_time = mControl->GetTime(); - timescale = GetTimeScale(); - duration = 0; // The duration is always 0 in fragmented mp4. - next_track_ID = mControl->GetNextTrackID(); - - size += sizeof(next_track_ID) + - sizeof(creation_time) + - sizeof(modification_time) + - sizeof(timescale) + - sizeof(duration) + - sizeof(rate) + - sizeof(volume) + - sizeof(reserved16) + - sizeof(reserved32) + - sizeof(matrix) + - sizeof(pre_defined); - - *aBoxSize = size; - - return NS_OK; -} - -nsresult -MovieHeaderBox::Write() -{ - WRITE_FULLBOX(mControl, size) - mControl->Write(creation_time); - mControl->Write(modification_time); - mControl->Write(timescale); - mControl->Write(duration); - mControl->Write(rate); - mControl->Write(volume); - mControl->Write(reserved16); - mControl->WriteArray(reserved32, 2); - mControl->WriteArray(matrix, 9); - mControl->WriteArray(pre_defined, 6); - mControl->Write(next_track_ID); - - return NS_OK; -} - -uint32_t -MovieHeaderBox::GetTimeScale() -{ - // Only audio track in container. - if (mAudioMeta && !mVideoMeta) { - return mAudioMeta->GetAudioSampleRate(); - } - - // return video rate - return mVideoMeta->GetVideoClockRate(); -} - -MovieHeaderBox::~MovieHeaderBox() -{ - MOZ_COUNT_DTOR(MovieHeaderBox); -} - -MovieHeaderBox::MovieHeaderBox(ISOControl* aControl) - : FullBox(NS_LITERAL_CSTRING("mvhd"), 0, 0, aControl) - , creation_time(0) - , modification_time(0) - , timescale(90000) - , duration(0) - , rate(0x00010000) - , volume(0x0100) - , reserved16(0) - , next_track_ID(1) -{ - memcpy(matrix, iso_matrix, sizeof(matrix)); - memset(reserved32, 0, sizeof(reserved32)); - memset(pre_defined, 0, sizeof(pre_defined)); - MOZ_COUNT_CTOR(MovieHeaderBox); -} - -TrackHeaderBox::TrackHeaderBox(uint32_t aType, ISOControl* aControl) - : FullBox(NS_LITERAL_CSTRING("tkhd"), 0, - flags_track_enabled | flags_track_in_movie | flags_track_in_preview, - aControl) - , creation_time(0) - , modification_time(0) - , track_ID(0) - , reserved(0) - , duration(0) - , layer(0) - , alternate_group(0) - , volume(0) - , reserved3(0) - , width(0) - , height(0) -{ - mTrackType = aType; - memcpy(matrix, iso_matrix, sizeof(matrix)); - memset(reserved2, 0, sizeof(reserved2)); - MOZ_COUNT_CTOR(TrackHeaderBox); -} - -TrackHeaderBox::~TrackHeaderBox() -{ - MOZ_COUNT_DTOR(TrackHeaderBox); -} - -nsresult -TrackHeaderBox::Generate(uint32_t* aBoxSize) -{ - creation_time = mControl->GetTime(); - modification_time = mControl->GetTime(); - track_ID = (mTrackType == Audio_Track ? - mControl->GetTrackID(mAudioMeta->GetKind()) : - mControl->GetTrackID(mVideoMeta->GetKind())); - // fragmented mp4 - duration = 0; - - // volume, audiotrack is always 0x0100 in 14496-12 8.3.2.2 - volume = (mTrackType == Audio_Track ? 0x0100 : 0); - - if (mTrackType == Video_Track) { - width = mVideoMeta->GetVideoDisplayWidth() << 16; - height = mVideoMeta->GetVideoDisplayHeight() << 16; - // Check display size, using the pixel size if any of them is invalid. - if (!width || !height) { - width = mVideoMeta->GetVideoWidth() << 16; - height = mVideoMeta->GetVideoHeight() << 16; - } - } - - size += sizeof(creation_time) + - sizeof(modification_time) + - sizeof(track_ID) + - sizeof(reserved) + - sizeof(duration) + - sizeof(reserved2) + - sizeof(layer) + - sizeof(alternate_group) + - sizeof(volume) + - sizeof(reserved3) + - sizeof(matrix) + - sizeof(width) + - sizeof(height); - - *aBoxSize = size; - - return NS_OK; -} - -nsresult -TrackHeaderBox::Write() -{ - WRITE_FULLBOX(mControl, size) - mControl->Write(creation_time); - mControl->Write(modification_time); - mControl->Write(track_ID); - mControl->Write(reserved); - mControl->Write(duration); - mControl->WriteArray(reserved2, 2); - mControl->Write(layer); - mControl->Write(alternate_group); - mControl->Write(volume); - mControl->Write(reserved3); - mControl->WriteArray(matrix, 9); - mControl->Write(width); - mControl->Write(height); - - return NS_OK; -} - -nsresult -FileTypeBox::Generate(uint32_t* aBoxSize) -{ - minor_version = 0; - - if (mControl->GetMuxingType() == ISOMediaWriter::TYPE_FRAG_MP4) { - if (!mControl->HasVideoTrack() && mControl->HasAudioTrack()) { - major_brand = "M4A "; - } else { - major_brand = "MP42"; - } - compatible_brands.AppendElement("mp42"); - compatible_brands.AppendElement("isom"); - } else if (mControl->GetMuxingType() == ISOMediaWriter::TYPE_FRAG_3GP) { - major_brand = "3gp9"; - // According to 3GPP TS 26.244 V12.2.0, section 5.3.4, it's recommended to - // list all compatible brands here. 3GP spec supports fragment from '3gp6'. - compatible_brands.AppendElement("3gp9"); - compatible_brands.AppendElement("3gp8"); - compatible_brands.AppendElement("3gp7"); - compatible_brands.AppendElement("3gp6"); - compatible_brands.AppendElement("isom"); - } else if (mControl->GetMuxingType() == ISOMediaWriter::TYPE_FRAG_3G2) { - major_brand = "3g2a"; - // 3GPP2 Release 0 and A and 3GPP Release 6 allow movie fragmentation - compatible_brands.AppendElement("3gp9"); - compatible_brands.AppendElement("3gp8"); - compatible_brands.AppendElement("3gp7"); - compatible_brands.AppendElement("3gp6"); - compatible_brands.AppendElement("isom"); - compatible_brands.AppendElement("3g2c"); - compatible_brands.AppendElement("3g2b"); - compatible_brands.AppendElement("3g2a"); - } else { - MOZ_ASSERT(0); - } - - size += major_brand.Length() + - sizeof(minor_version) + - compatible_brands.Length() * 4; - - *aBoxSize = size; - - return NS_OK; -} - -nsresult -FileTypeBox::Write() -{ - BoxSizeChecker checker(mControl, size); - Box::Write(); - mControl->WriteFourCC(major_brand.get()); - mControl->Write(minor_version); - uint32_t len = compatible_brands.Length(); - for (uint32_t i = 0; i < len; i++) { - mControl->WriteFourCC(compatible_brands[i].get()); - } - - return NS_OK; -} - -FileTypeBox::FileTypeBox(ISOControl* aControl) - : Box(NS_LITERAL_CSTRING("ftyp"), aControl) - , minor_version(0) -{ - MOZ_COUNT_CTOR(FileTypeBox); -} - -FileTypeBox::~FileTypeBox() -{ - MOZ_COUNT_DTOR(FileTypeBox); -} - -MediaBox::MediaBox(uint32_t aType, ISOControl* aControl) - : DefaultContainerImpl(NS_LITERAL_CSTRING("mdia"), aControl) -{ - mTrackType = aType; - boxes.AppendElement(new MediaHeaderBox(aType, aControl)); - boxes.AppendElement(new HandlerBox(aType, aControl)); - boxes.AppendElement(new MediaInformationBox(aType, aControl)); - MOZ_COUNT_CTOR(MediaBox); -} - -MediaBox::~MediaBox() -{ - MOZ_COUNT_DTOR(MediaBox); -} - -nsresult -DefaultContainerImpl::Generate(uint32_t* aBoxSize) -{ - nsresult rv; - uint32_t box_size; - uint32_t len = boxes.Length(); - for (uint32_t i = 0; i < len; i++) { - rv = boxes.ElementAt(i)->Generate(&box_size); - NS_ENSURE_SUCCESS(rv, rv); - size += box_size; - } - *aBoxSize = size; - return NS_OK; -} - -nsresult -DefaultContainerImpl::Find(const nsACString& aType, - nsTArray<RefPtr<MuxerOperation>>& aOperations) -{ - nsresult rv = Box::Find(aType, aOperations); - NS_ENSURE_SUCCESS(rv, rv); - - uint32_t len = boxes.Length(); - for (uint32_t i = 0; i < len; i++) { - rv = boxes.ElementAt(i)->Find(aType, aOperations); - NS_ENSURE_SUCCESS(rv, rv); - } - return NS_OK; -} - -nsresult -DefaultContainerImpl::Write() -{ - BoxSizeChecker checker(mControl, size); - Box::Write(); - - nsresult rv; - uint32_t len = boxes.Length(); - for (uint32_t i = 0; i < len; i++) { - rv = boxes.ElementAt(i)->Write(); - NS_ENSURE_SUCCESS(rv, rv); - } - - return NS_OK; -} - -DefaultContainerImpl::DefaultContainerImpl(const nsACString& aType, - ISOControl* aControl) - : Box(aType, aControl) -{ -} - -nsresult -Box::Write() -{ - mControl->Write(size); - mControl->WriteFourCC(boxType.get()); - return NS_OK; -} - -nsresult -Box::Find(const nsACString& aType, nsTArray<RefPtr<MuxerOperation>>& aOperations) -{ - if (boxType == aType) { - aOperations.AppendElement(this); - } - return NS_OK; -} - -Box::Box(const nsACString& aType, ISOControl* aControl) - : size(8), mControl(aControl) -{ - MOZ_ASSERT(aType.Length() == 4); - boxType = aType; - aControl->GetAudioMetadata(mAudioMeta); - aControl->GetVideoMetadata(mVideoMeta); -} - -FullBox::FullBox(const nsACString& aType, uint8_t aVersion, uint32_t aFlags, - ISOControl* aControl) - : Box(aType, aControl) -{ - std::bitset<24> tmp_flags(aFlags); - version = aVersion; - flags = tmp_flags; - size += sizeof(version) + flags.size() / CHAR_BIT; -} - -nsresult -FullBox::Write() -{ - Box::Write(); - mControl->Write(version); - mControl->WriteBits(flags.to_ulong(), flags.size()); - return NS_OK; -} - -TrackBox::TrackBox(uint32_t aTrackType, ISOControl* aControl) - : DefaultContainerImpl(NS_LITERAL_CSTRING("trak"), aControl) -{ - boxes.AppendElement(new TrackHeaderBox(aTrackType, aControl)); - boxes.AppendElement(new MediaBox(aTrackType, aControl)); - MOZ_COUNT_CTOR(TrackBox); -} - -TrackBox::~TrackBox() -{ - MOZ_COUNT_DTOR(TrackBox); -} - -SampleEntryBox::SampleEntryBox(const nsACString& aFormat, ISOControl* aControl) - : Box(aFormat, aControl) - , data_reference_index(0) -{ - data_reference_index = 1; // There is only one data reference in each track. - size += sizeof(reserved) + - sizeof(data_reference_index); - memset(reserved, 0, sizeof(reserved)); -} - -nsresult -SampleEntryBox::Write() -{ - Box::Write(); - mControl->Write(reserved, sizeof(reserved)); - mControl->Write(data_reference_index); - return NS_OK; -} - -nsresult -AudioSampleEntry::Write() -{ - SampleEntryBox::Write(); - mControl->Write(sound_version); - mControl->Write(reserved2, sizeof(reserved2)); - mControl->Write(channels); - mControl->Write(sample_size); - mControl->Write(compressionId); - mControl->Write(packet_size); - mControl->Write(timeScale); - return NS_OK; -} - -AudioSampleEntry::AudioSampleEntry(const nsACString& aFormat, ISOControl* aControl) - : SampleEntryBox(aFormat, aControl) - , sound_version(0) - , channels(2) - , sample_size(16) - , compressionId(0) - , packet_size(0) - , timeScale(0) -{ - memset(reserved2, 0 , sizeof(reserved2)); - channels = mAudioMeta->GetAudioChannels(); - timeScale = mAudioMeta->GetAudioSampleRate() << 16; - - size += sizeof(sound_version) + - sizeof(reserved2) + - sizeof(sample_size) + - sizeof(channels) + - sizeof(packet_size) + - sizeof(compressionId) + - sizeof(timeScale); - - MOZ_COUNT_CTOR(AudioSampleEntry); -} - -AudioSampleEntry::~AudioSampleEntry() -{ - MOZ_COUNT_DTOR(AudioSampleEntry); -} - -nsresult -VisualSampleEntry::Write() -{ - SampleEntryBox::Write(); - - mControl->Write(reserved, sizeof(reserved)); - mControl->Write(width); - mControl->Write(height); - mControl->Write(horizresolution); - mControl->Write(vertresolution); - mControl->Write(reserved2); - mControl->Write(frame_count); - mControl->Write(compressorName, sizeof(compressorName)); - mControl->Write(depth); - mControl->Write(pre_defined); - - return NS_OK; -} - -VisualSampleEntry::VisualSampleEntry(const nsACString& aFormat, ISOControl* aControl) - : SampleEntryBox(aFormat, aControl) - , width(0) - , height(0) - , horizresolution(resolution_72_dpi) - , vertresolution(resolution_72_dpi) - , reserved2(0) - , frame_count(1) - , depth(video_depth) - , pre_defined(-1) -{ - memset(reserved, 0 , sizeof(reserved)); - memset(compressorName, 0 , sizeof(compressorName)); - - // both fields occupy 16 bits defined in 14496-2 6.2.3. - width = mVideoMeta->GetVideoWidth(); - height = mVideoMeta->GetVideoHeight(); - - size += sizeof(reserved) + - sizeof(width) + - sizeof(height) + - sizeof(horizresolution) + - sizeof(vertresolution) + - sizeof(reserved2) + - sizeof(frame_count) + - sizeof(compressorName) + - sizeof(depth) + - sizeof(pre_defined); - - MOZ_COUNT_CTOR(VisualSampleEntry); -} - -VisualSampleEntry::~VisualSampleEntry() -{ - MOZ_COUNT_DTOR(VisualSampleEntry); -} - -} diff --git a/dom/media/encoder/fmp4_muxer/ISOMediaBoxes.h b/dom/media/encoder/fmp4_muxer/ISOMediaBoxes.h deleted file mode 100644 index a6dc1b046..000000000 --- a/dom/media/encoder/fmp4_muxer/ISOMediaBoxes.h +++ /dev/null @@ -1,781 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-*/ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef ISOMediaBoxes_h_ -#define ISOMediaBoxes_h_ - -#include <bitset> -#include "nsString.h" -#include "nsTArray.h" -#include "nsAutoPtr.h" -#include "MuxerOperation.h" -#include "mozilla/UniquePtr.h" - -#define WRITE_FULLBOX(_compositor, _size) \ - BoxSizeChecker checker(_compositor, _size); \ - FullBox::Write(); - -#define FOURCC(a, b, c, d) ( ((a) << 24) | ((b) << 16) | ((c) << 8) | (d) ) - -namespace mozilla { - -/** - * track type from spec 8.4.3.3 - */ -#define Audio_Track 0x01 -#define Video_Track 0x02 - -class AudioTrackMetadata; -class VideoTrackMetadata; -class ISOControl; - -/** - * This is the base class for all ISO media format boxes. - * It provides the fields of box type(four CC) and size. - * The data members in the beginning of a Box (or its descendants) - * are the 14496-12 defined member. Other members prefix with 'm' - * are private control data. - * - * This class is for inherited only, it shouldn't be instanced directly. - */ -class Box : public MuxerOperation { -protected: - // ISO BMFF members - uint32_t size; // 14496-12 4-2 'Object Structure'. Size of this box. - nsCString boxType; // four CC name, all table names are listed in - // 14496-12 table 1. - -public: - // MuxerOperation methods - nsresult Write() override; - nsresult Find(const nsACString& aType, - nsTArray<RefPtr<MuxerOperation>>& aOperations) override; - - // This helper class will compare the written size in Write() and the size in - // Generate(). If their are not equal, it will assert. - class BoxSizeChecker { - public: - BoxSizeChecker(ISOControl* aControl, uint32_t aSize); - ~BoxSizeChecker(); - - uint32_t ori_size; - uint32_t box_size; - ISOControl* mControl; - }; - -protected: - Box() = delete; - Box(const nsACString& aType, ISOControl* aControl); - - ISOControl* mControl; - RefPtr<AudioTrackMetadata> mAudioMeta; - RefPtr<VideoTrackMetadata> mVideoMeta; -}; - -/** - * FullBox (and its descendants) is the box which contains the 'real' data - * members. It is the edge in the ISO box structure and it doesn't contain - * any box. - * - * This class is for inherited only, it shouldn't be instanced directly. - */ -class FullBox : public Box { -public: - // ISO BMFF members - uint8_t version; // 14496-12 4.2 'Object Structure' - std::bitset<24> flags; // - - // MuxerOperation methods - nsresult Write() override; - -protected: - // FullBox methods - FullBox(const nsACString& aType, uint8_t aVersion, uint32_t aFlags, - ISOControl* aControl); - FullBox() = delete; -}; - -/** - * The default implementation of the container box. - * Basically, the container box inherits this class and overrides the - * constructor only. - * - * According to 14496-12 3.1.1 'container box', a container box is - * 'box whose sole purpose is to contain and group a set of related boxes' - * - * This class is for inherited only, it shouldn't be instanced directly. - */ -class DefaultContainerImpl : public Box { -public: - // MuxerOperation methods - nsresult Generate(uint32_t* aBoxSize) override; - nsresult Write() override; - nsresult Find(const nsACString& aType, - nsTArray<RefPtr<MuxerOperation>>& aOperations) override; - -protected: - // DefaultContainerImpl methods - DefaultContainerImpl(const nsACString& aType, ISOControl* aControl); - DefaultContainerImpl() = delete; - - nsTArray<RefPtr<MuxerOperation>> boxes; -}; - -// 14496-12 4.3 'File Type Box' -// Box type: 'ftyp' -class FileTypeBox : public Box { -public: - // ISO BMFF members - nsCString major_brand; // four chars - uint32_t minor_version; - nsTArray<nsCString> compatible_brands; - - // MuxerOperation methods - nsresult Generate(uint32_t* aBoxSize) override; - nsresult Write() override; - - // FileTypeBox methods - FileTypeBox(ISOControl* aControl); - ~FileTypeBox(); -}; - -// 14496-12 8.2.1 'Movie Box' -// Box type: 'moov' -// MovieBox contains MovieHeaderBox, TrackBox and MovieExtendsBox. -class MovieBox : public DefaultContainerImpl { -public: - MovieBox(ISOControl* aControl); - ~MovieBox(); -}; - -// 14496-12 8.2.2 'Movie Header Box' -// Box type: 'mvhd' -class MovieHeaderBox : public FullBox { -public: - // ISO BMFF members - uint32_t creation_time; - uint32_t modification_time; - uint32_t timescale; - uint32_t duration; - uint32_t rate; - uint16_t volume; - uint16_t reserved16; - uint32_t reserved32[2]; - uint32_t matrix[9]; - uint32_t pre_defined[6]; - uint32_t next_track_ID; - - // MuxerOperation methods - nsresult Generate(uint32_t* aBoxSize) override; - nsresult Write() override; - - // MovieHeaderBox methods - MovieHeaderBox(ISOControl* aControl); - ~MovieHeaderBox(); - uint32_t GetTimeScale(); -}; - -// 14496-12 8.4.2 'Media Header Box' -// Box type: 'mdhd' -class MediaHeaderBox : public FullBox { -public: - // ISO BMFF members - uint32_t creation_time; - uint32_t modification_time; - uint32_t timescale; - uint32_t duration; - std::bitset<1> pad; - std::bitset<5> lang1; - std::bitset<5> lang2; - std::bitset<5> lang3; - uint16_t pre_defined; - - // MuxerOperation methods - nsresult Generate(uint32_t* aBoxSize) override; - nsresult Write() override; - - // MediaHeaderBox methods - MediaHeaderBox(uint32_t aType, ISOControl* aControl); - ~MediaHeaderBox(); - uint32_t GetTimeScale(); - -protected: - uint32_t mTrackType; -}; - -// 14496-12 8.3.1 'Track Box' -// Box type: 'trak' -// TrackBox contains TrackHeaderBox and MediaBox. -class TrackBox : public DefaultContainerImpl { -public: - TrackBox(uint32_t aTrackType, ISOControl* aControl); - ~TrackBox(); -}; - -// 14496-12 8.1.1 'Media Data Box' -// Box type: 'mdat' -class MediaDataBox : public Box { -public: - // MuxerOperation methods - nsresult Generate(uint32_t* aBoxSize) override; - nsresult Write() override; - - // MediaDataBox methods - uint32_t GetAllSampleSize() { return mAllSampleSize; } - uint32_t FirstSampleOffsetInMediaDataBox() { return mFirstSampleOffset; } - MediaDataBox(uint32_t aTrackType, ISOControl* aControl); - ~MediaDataBox(); - -protected: - uint32_t mAllSampleSize; // All audio and video sample size in this box. - uint32_t mFirstSampleOffset; // The offset of first sample in this box from - // the beginning of this mp4 file. - uint32_t mTrackType; -}; - -// flags for TrackRunBox::flags, 14496-12 8.8.8.1. -#define flags_data_offset_present 0x000001 -#define flags_first_sample_flags_present 0x000002 -#define flags_sample_duration_present 0x000100 -#define flags_sample_size_present 0x000200 -#define flags_sample_flags_present 0x000400 -#define flags_sample_composition_time_offsets_present 0x000800 - -// flag for TrackRunBox::tbl::sample_flags and TrackExtendsBox::default_sample_flags -// which is defined in 14496-12 8.8.3.1. -uint32_t set_sample_flags(bool aSync); - -// 14496-12 8.8.8 'Track Fragment Run Box' -// Box type: 'trun' -class TrackRunBox : public FullBox { -public: - // ISO BMFF members - typedef struct { - uint32_t sample_duration; - uint32_t sample_size; - uint32_t sample_flags; - uint32_t sample_composition_time_offset; - } tbl; - - uint32_t sample_count; - // the following are optional fields - uint32_t data_offset; // data offset exists when audio/video are present in file. - uint32_t first_sample_flags; - UniquePtr<tbl[]> sample_info_table; - - // MuxerOperation methods - nsresult Generate(uint32_t* aBoxSize) override; - nsresult Write() override; - - // TrackRunBox methods - uint32_t GetAllSampleSize() { return mAllSampleSize; } - nsresult SetDataOffset(uint32_t aOffset); - - TrackRunBox(uint32_t aType, uint32_t aFlags, ISOControl* aControl); - ~TrackRunBox(); - -protected: - uint32_t fillSampleTable(); - - uint32_t mAllSampleSize; - uint32_t mTrackType; -}; - -// tf_flags in TrackFragmentHeaderBox, 14496-12 8.8.7.1. -#define base_data_offset_present 0x000001 -#define sample_description_index_present 0x000002 -#define default_sample_duration_present 0x000008 -#define default_sample_size_present 0x000010 -#define default_sample_flags_present 0x000020 -#define duration_is_empty 0x010000 -#define default_base_is_moof 0x020000 - -// 14496-12 8.8.7 'Track Fragment Header Box' -// Box type: 'tfhd' -class TrackFragmentHeaderBox : public FullBox { -public: - // ISO BMFF members - uint32_t track_ID; - uint64_t base_data_offset; - uint32_t default_sample_duration; - - // MuxerOperation methods - nsresult Generate(uint32_t* aBoxSize) override; - nsresult Write() override; - - // TrackFragmentHeaderBox methods - nsresult UpdateBaseDataOffset(uint64_t aOffset); // The offset of the first - // sample in file. - - TrackFragmentHeaderBox(uint32_t aType, uint32_t aFlags, ISOControl* aControl); - ~TrackFragmentHeaderBox(); - -protected: - uint32_t mTrackType; -}; - -// 14496-12 8.8.6 'Track Fragment Box' -// Box type: 'traf' -// TrackFragmentBox cotains TrackFragmentHeaderBox and TrackRunBox. -class TrackFragmentBox : public DefaultContainerImpl { -public: - TrackFragmentBox(uint32_t aType, ISOControl* aControl); - ~TrackFragmentBox(); - -protected: - uint32_t mTrackType; -}; - -// 14496-12 8.8.5 'Movie Fragment Header Box' -// Box type: 'mfhd' -class MovieFragmentHeaderBox : public FullBox { -public: - // ISO BMFF members - uint32_t sequence_number; - - // MuxerOperation methods - nsresult Generate(uint32_t* aBoxSize) override; - nsresult Write() override; - - // MovieFragmentHeaderBox methods - MovieFragmentHeaderBox(uint32_t aType, ISOControl* aControl); - ~MovieFragmentHeaderBox(); - -protected: - uint32_t mTrackType; -}; - -// 14496-12 8.8.4 'Movie Fragment Box' -// Box type: 'moof' -// MovieFragmentBox contains MovieFragmentHeaderBox and TrackFragmentBox. -class MovieFragmentBox : public DefaultContainerImpl { -public: - // MuxerOperation methods - nsresult Generate(uint32_t* aBoxSize) override; - - // MovieFragmentBox methods - MovieFragmentBox(uint32_t aType, ISOControl* aControl); - ~MovieFragmentBox(); - -protected: - uint32_t mTrackType; -}; - -// 14496-12 8.8.3 'Track Extends Box' -// Box type: 'trex' -class TrackExtendsBox : public FullBox { -public: - // ISO BMFF members - uint32_t track_ID; - uint32_t default_sample_description_index; - uint32_t default_sample_duration; - uint32_t default_sample_size; - uint32_t default_sample_flags; - - // MuxerOperation methods - nsresult Generate(uint32_t* aBoxSize) override; - nsresult Write() override; - - // TrackExtendsBox methods - TrackExtendsBox(uint32_t aType, ISOControl* aControl); - ~TrackExtendsBox(); - -protected: - uint32_t mTrackType; -}; - -// 14496-12 8.8.1 'Movie Extends Box' -// Box type: 'mvex' -// MovieExtendsBox contains TrackExtendsBox. -class MovieExtendsBox : public DefaultContainerImpl { -public: - MovieExtendsBox(ISOControl* aControl); - ~MovieExtendsBox(); -}; - -// 14496-12 8.7.5 'Chunk Offset Box' -// Box type: 'stco' -class ChunkOffsetBox : public FullBox { -public: - // ISO BMFF members - typedef struct { - uint32_t chunk_offset; - } tbl; - - uint32_t entry_count; - UniquePtr<tbl[]> sample_tbl; - - // MuxerOperation methods - nsresult Generate(uint32_t* aBoxSize) override; - nsresult Write() override; - - // ChunkOffsetBox methods - ChunkOffsetBox(uint32_t aType, ISOControl* aControl); - ~ChunkOffsetBox(); - -protected: - uint32_t mTrackType; -}; - -// 14496-12 8.7.4 'Sample To Chunk Box' -// Box type: 'stsc' -class SampleToChunkBox : public FullBox { -public: - // ISO BMFF members - typedef struct { - uint32_t first_chunk; - uint32_t sample_per_chunk; - uint32_t sample_description_index; - } tbl; - - uint32_t entry_count; - UniquePtr<tbl[]> sample_tbl; - - // MuxerOperation methods - nsresult Generate(uint32_t* aBoxSize) override; - nsresult Write() override; - - // SampleToChunkBox methods - SampleToChunkBox(uint32_t aType, ISOControl* aControl); - ~SampleToChunkBox(); - -protected: - uint32_t mTrackType; -}; - -// 14496-12 8.6.1.2 'Decoding Time to Sample Box' -// Box type: 'stts' -class TimeToSampleBox : public FullBox { -public: - // ISO BMFF members - typedef struct { - uint32_t sample_count; - uint32_t sample_delta; - } tbl; - - uint32_t entry_count; - UniquePtr<tbl[]> sample_tbl; - - // MuxerOperation methods - nsresult Generate(uint32_t* aBoxSize) override; - nsresult Write() override; - - // TimeToSampleBox methods - TimeToSampleBox(uint32_t aType, ISOControl* aControl); - ~TimeToSampleBox(); - -protected: - uint32_t mTrackType; -}; - -/** - * 14496-12 8.5.2 'Sample Description Box' - * This is the base class for VisualSampleEntry and AudioSampleEntry. - * - * This class is for inherited only, it shouldn't be instanced directly. - * - * The inhertied tree of a codec box should be: - * - * +--> AVCSampleEntry - * +--> VisualSampleEntryBox + - * | +--> ... - * SampleEntryBox + - * | +--> MP4AudioSampleEntry - * +--> AudioSampleEntryBox + - * +--> AMRSampleEntry - * + - * +--> ... - * - */ -class SampleEntryBox : public Box { -public: - // ISO BMFF members - uint8_t reserved[6]; - uint16_t data_reference_index; - - // sampleentrybox methods - SampleEntryBox(const nsACString& aFormat, ISOControl* aControl); - - // MuxerOperation methods - nsresult Write() override; - -protected: - SampleEntryBox() = delete; -}; - -// 14496-12 8.5.2 'Sample Description Box' -// Box type: 'stsd' -class SampleDescriptionBox : public FullBox { -public: - // ISO BMFF members - uint32_t entry_count; - RefPtr<SampleEntryBox> sample_entry_box; - - // MuxerOperation methods - nsresult Generate(uint32_t* aBoxSize) override; - nsresult Write() override; - - // SampleDescriptionBox methods - SampleDescriptionBox(uint32_t aType, ISOControl* aControl); - ~SampleDescriptionBox(); - -protected: - nsresult CreateAudioSampleEntry(RefPtr<SampleEntryBox>& aSampleEntry); - nsresult CreateVideoSampleEntry(RefPtr<SampleEntryBox>& aSampleEntry); - - uint32_t mTrackType; -}; - -// 14496-12 8.5.2.2 -// The base class for audio codec box. -// This class is for inherited only, it shouldn't be instanced directly. -class AudioSampleEntry : public SampleEntryBox { -public: - // ISO BMFF members - uint16_t sound_version; - uint8_t reserved2[6]; - uint16_t channels; - uint16_t sample_size; - uint16_t compressionId; - uint16_t packet_size; - uint32_t timeScale; // (sample rate of media) <<16 - - // MuxerOperation methods - nsresult Write() override; - - ~AudioSampleEntry(); - -protected: - AudioSampleEntry(const nsACString& aFormat, ISOControl* aControl); -}; - -// 14496-12 8.5.2.2 -// The base class for video codec box. -// This class is for inherited only, it shouldn't be instanced directly. -class VisualSampleEntry : public SampleEntryBox { -public: - // ISO BMFF members - uint8_t reserved[16]; - uint16_t width; - uint16_t height; - - uint32_t horizresolution; // 72 dpi - uint32_t vertresolution; // 72 dpi - uint32_t reserved2; - uint16_t frame_count; // 1, defined in 14496-12 8.5.2.2 - - uint8_t compressorName[32]; - uint16_t depth; // 0x0018, defined in 14496-12 8.5.2.2; - uint16_t pre_defined; // -1, defined in 14496-12 8.5.2.2; - - // MuxerOperation methods - nsresult Write() override; - - // VisualSampleEntry methods - ~VisualSampleEntry(); - -protected: - VisualSampleEntry(const nsACString& aFormat, ISOControl* aControl); -}; - -// 14496-12 8.7.3.2 'Sample Size Box' -// Box type: 'stsz' -class SampleSizeBox : public FullBox { -public: - // ISO BMFF members - uint32_t sample_size; - uint32_t sample_count; - - // MuxerOperation methods - nsresult Generate(uint32_t* aBoxSize) override; - nsresult Write() override; - - // SampleSizeBox methods - SampleSizeBox(ISOControl* aControl); - ~SampleSizeBox(); -}; - -// 14496-12 8.5.1 'Sample Table Box' -// Box type: 'stbl' -// -// SampleTableBox contains SampleDescriptionBox, -// TimeToSampleBox, -// SampleToChunkBox, -// SampleSizeBox and -// ChunkOffsetBox. -class SampleTableBox : public DefaultContainerImpl { -public: - SampleTableBox(uint32_t aType, ISOControl* aControl); - ~SampleTableBox(); -}; - -// 14496-12 8.7.2 'Data Reference Box' -// Box type: 'url ' -class DataEntryUrlBox : public FullBox { -public: - // ISO BMFF members - // flags in DataEntryUrlBox::flags - const static uint16_t flags_media_at_the_same_file = 0x0001; - - nsCString location; - - // MuxerOperation methods - nsresult Generate(uint32_t* aBoxSize) override; - nsresult Write() override; - - // DataEntryUrlBox methods - DataEntryUrlBox(); - DataEntryUrlBox(ISOControl* aControl); - DataEntryUrlBox(const DataEntryUrlBox& aBox); - ~DataEntryUrlBox(); -}; - -// 14496-12 8.7.2 'Data Reference Box' -// Box type: 'dref' -class DataReferenceBox : public FullBox { -public: - // ISO BMFF members - uint32_t entry_count; - nsTArray<nsAutoPtr<DataEntryUrlBox>> urls; - - // MuxerOperation methods - nsresult Generate(uint32_t* aBoxSize) override; - nsresult Write() override; - - // DataReferenceBox methods - DataReferenceBox(ISOControl* aControl); - ~DataReferenceBox(); -}; - -// 14496-12 8.7.1 'Data Information Box' -// Box type: 'dinf' -// DataInformationBox contains DataReferenceBox. -class DataInformationBox : public DefaultContainerImpl { -public: - DataInformationBox(ISOControl* aControl); - ~DataInformationBox(); -}; - -// 14496-12 8.4.5.2 'Video Media Header Box' -// Box type: 'vmhd' -class VideoMediaHeaderBox : public FullBox { -public: - // ISO BMFF members - uint16_t graphicsmode; - uint16_t opcolor[3]; - - // MuxerOperation methods - nsresult Generate(uint32_t* aBoxSize) override; - nsresult Write() override; - - // VideoMediaHeaderBox methods - VideoMediaHeaderBox(ISOControl* aControl); - ~VideoMediaHeaderBox(); -}; - -// 14496-12 8.4.5.3 'Sound Media Header Box' -// Box type: 'smhd' -class SoundMediaHeaderBox : public FullBox { -public: - // ISO BMFF members - uint16_t balance; - uint16_t reserved; - - // MuxerOperation methods - nsresult Generate(uint32_t* aBoxSize) override; - nsresult Write() override; - - // SoundMediaHeaderBox methods - SoundMediaHeaderBox(ISOControl* aControl); - ~SoundMediaHeaderBox(); -}; - -// 14496-12 8.4.4 'Media Information Box' -// Box type: 'minf' -// MediaInformationBox contains SoundMediaHeaderBox, DataInformationBox and -// SampleTableBox. -class MediaInformationBox : public DefaultContainerImpl { -public: - MediaInformationBox(uint32_t aType, ISOControl* aControl); - ~MediaInformationBox(); - -protected: - uint32_t mTrackType; -}; - -// flags for TrackHeaderBox::flags. -#define flags_track_enabled 0x000001 -#define flags_track_in_movie 0x000002 -#define flags_track_in_preview 0x000004 - -// 14496-12 8.3.2 'Track Header Box' -// Box type: 'tkhd' -class TrackHeaderBox : public FullBox { -public: - // ISO BMFF members - // version = 0 - uint32_t creation_time; - uint32_t modification_time; - uint32_t track_ID; - uint32_t reserved; - uint32_t duration; - - uint32_t reserved2[2]; - uint16_t layer; - uint16_t alternate_group; - uint16_t volume; - uint16_t reserved3; - uint32_t matrix[9]; - uint32_t width; - uint32_t height; - - // MuxerOperation methods - nsresult Generate(uint32_t* aBoxSize) override; - nsresult Write() override; - - // TrackHeaderBox methods - TrackHeaderBox(uint32_t aType, ISOControl* aControl); - ~TrackHeaderBox(); - -protected: - uint32_t mTrackType; -}; - -// 14496-12 8.4.3 'Handler Reference Box' -// Box type: 'hdlr' -class HandlerBox : public FullBox { -public: - // ISO BMFF members - uint32_t pre_defined; - uint32_t handler_type; - uint32_t reserved[3]; - nsCString name; - - // MuxerOperation methods - nsresult Generate(uint32_t* aBoxSize) override; - nsresult Write() override; - - // HandlerBox methods - HandlerBox(uint32_t aType, ISOControl* aControl); - ~HandlerBox(); - -protected: - uint32_t mTrackType; -}; - -// 14496-12 8.4.1 'Media Box' -// Box type: 'mdia' -// MediaBox contains MediaHeaderBox, HandlerBox, and MediaInformationBox. -class MediaBox : public DefaultContainerImpl { -public: - MediaBox(uint32_t aType, ISOControl* aControl); - ~MediaBox(); - -protected: - uint32_t mTrackType; -}; - -} -#endif // ISOMediaBoxes_h_ diff --git a/dom/media/encoder/fmp4_muxer/ISOMediaWriter.cpp b/dom/media/encoder/fmp4_muxer/ISOMediaWriter.cpp deleted file mode 100644 index cb4524e00..000000000 --- a/dom/media/encoder/fmp4_muxer/ISOMediaWriter.cpp +++ /dev/null @@ -1,229 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-*/ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "ISOMediaWriter.h" -#include "ISOControl.h" -#include "ISOMediaBoxes.h" -#include "ISOTrackMetadata.h" -#include "nsThreadUtils.h" -#include "MediaEncoder.h" -#include "VideoUtils.h" -#include "GeckoProfiler.h" - -#undef LOG -#define LOG(args, ...) - -namespace mozilla { - -const static uint32_t FRAG_DURATION = 2 * USECS_PER_S; // microsecond per unit - -ISOMediaWriter::ISOMediaWriter(uint32_t aType, uint32_t aHint) - : ContainerWriter() - , mState(MUXING_HEAD) - , mBlobReady(false) - , mType(0) -{ - if (aType & CREATE_AUDIO_TRACK) { - mType |= Audio_Track; - } - if (aType & CREATE_VIDEO_TRACK) { - mType |= Video_Track; - } - mControl = new ISOControl(aHint); - MOZ_COUNT_CTOR(ISOMediaWriter); -} - -ISOMediaWriter::~ISOMediaWriter() -{ - MOZ_COUNT_DTOR(ISOMediaWriter); -} - -nsresult -ISOMediaWriter::RunState() -{ - nsresult rv; - switch (mState) { - case MUXING_HEAD: - { - rv = mControl->GenerateFtyp(); - NS_ENSURE_SUCCESS(rv, rv); - rv = mControl->GenerateMoov(); - NS_ENSURE_SUCCESS(rv, rv); - mState = MUXING_FRAG; - break; - } - case MUXING_FRAG: - { - rv = mControl->GenerateMoof(mType); - NS_ENSURE_SUCCESS(rv, rv); - - bool EOS; - if (ReadyToRunState(EOS) && EOS) { - mState = MUXING_DONE; - } - break; - } - case MUXING_DONE: - { - break; - } - } - mBlobReady = true; - return NS_OK; -} - -nsresult -ISOMediaWriter::WriteEncodedTrack(const EncodedFrameContainer& aData, - uint32_t aFlags) -{ - PROFILER_LABEL("ISOMediaWriter", "WriteEncodedTrack", - js::ProfileEntry::Category::OTHER); - // Muxing complete, it doesn't allowed to reentry again. - if (mState == MUXING_DONE) { - MOZ_ASSERT(false); - return NS_ERROR_FAILURE; - } - - FragmentBuffer* frag = nullptr; - uint32_t len = aData.GetEncodedFrames().Length(); - - if (!len) { - // no frame? why bother to WriteEncodedTrack - return NS_OK; - } - for (uint32_t i = 0; i < len; i++) { - RefPtr<EncodedFrame> frame(aData.GetEncodedFrames()[i]); - EncodedFrame::FrameType type = frame->GetFrameType(); - if (type == EncodedFrame::AAC_AUDIO_FRAME || - type == EncodedFrame::AAC_CSD || - type == EncodedFrame::AMR_AUDIO_FRAME || - type == EncodedFrame::AMR_AUDIO_CSD || - type == EncodedFrame::EVRC_AUDIO_FRAME || - type == EncodedFrame::EVRC_AUDIO_CSD) { - frag = mAudioFragmentBuffer; - } else if (type == EncodedFrame::AVC_I_FRAME || - type == EncodedFrame::AVC_P_FRAME || - type == EncodedFrame::AVC_B_FRAME || - type == EncodedFrame::AVC_CSD) { - frag = mVideoFragmentBuffer; - } else { - MOZ_ASSERT(0); - return NS_ERROR_FAILURE; - } - - frag->AddFrame(frame); - } - - // Encoder should send CSD (codec specific data) frame before sending the - // audio/video frames. When CSD data is ready, it is sufficient to generate a - // moov data. If encoder doesn't send CSD yet, muxer needs to wait before - // generating anything. - if (mType & Audio_Track && (!mAudioFragmentBuffer || - !mAudioFragmentBuffer->HasCSD())) { - return NS_OK; - } - if (mType & Video_Track && (!mVideoFragmentBuffer || - !mVideoFragmentBuffer->HasCSD())) { - return NS_OK; - } - - // Only one FrameType in EncodedFrameContainer so it doesn't need to be - // inside the for-loop. - if (frag && (aFlags & END_OF_STREAM)) { - frag->SetEndOfStream(); - } - - nsresult rv; - bool EOS; - if (ReadyToRunState(EOS)) { - // Because track encoder won't generate new data after EOS, it needs to make - // sure the state reaches MUXING_DONE when EOS is signaled. - do { - rv = RunState(); - } while (EOS && mState != MUXING_DONE); - NS_ENSURE_SUCCESS(rv, rv); - } - - return NS_OK; -} - -bool -ISOMediaWriter::ReadyToRunState(bool& aEOS) -{ - aEOS = false; - bool bReadyToMux = true; - if ((mType & Audio_Track) && (mType & Video_Track)) { - if (!mAudioFragmentBuffer->HasEnoughData()) { - bReadyToMux = false; - } - if (!mVideoFragmentBuffer->HasEnoughData()) { - bReadyToMux = false; - } - - if (mAudioFragmentBuffer->EOS() && mVideoFragmentBuffer->EOS()) { - aEOS = true; - bReadyToMux = true; - } - } else if (mType == Audio_Track) { - if (!mAudioFragmentBuffer->HasEnoughData()) { - bReadyToMux = false; - } - if (mAudioFragmentBuffer->EOS()) { - aEOS = true; - bReadyToMux = true; - } - } else if (mType == Video_Track) { - if (!mVideoFragmentBuffer->HasEnoughData()) { - bReadyToMux = false; - } - if (mVideoFragmentBuffer->EOS()) { - aEOS = true; - bReadyToMux = true; - } - } - - return bReadyToMux; -} - -nsresult -ISOMediaWriter::GetContainerData(nsTArray<nsTArray<uint8_t>>* aOutputBufs, - uint32_t aFlags) -{ - PROFILER_LABEL("ISOMediaWriter", "GetContainerData", - js::ProfileEntry::Category::OTHER); - if (mBlobReady) { - if (mState == MUXING_DONE) { - mIsWritingComplete = true; - } - mBlobReady = false; - return mControl->GetBufs(aOutputBufs); - } - return NS_OK; -} - -nsresult -ISOMediaWriter::SetMetadata(TrackMetadataBase* aMetadata) -{ - PROFILER_LABEL("ISOMediaWriter", "SetMetadata", - js::ProfileEntry::Category::OTHER); - if (aMetadata->GetKind() == TrackMetadataBase::METADATA_AAC || - aMetadata->GetKind() == TrackMetadataBase::METADATA_AMR || - aMetadata->GetKind() == TrackMetadataBase::METADATA_EVRC) { - mControl->SetMetadata(aMetadata); - mAudioFragmentBuffer = new FragmentBuffer(Audio_Track, FRAG_DURATION); - mControl->SetFragment(mAudioFragmentBuffer); - return NS_OK; - } - if (aMetadata->GetKind() == TrackMetadataBase::METADATA_AVC) { - mControl->SetMetadata(aMetadata); - mVideoFragmentBuffer = new FragmentBuffer(Video_Track, FRAG_DURATION); - mControl->SetFragment(mVideoFragmentBuffer); - return NS_OK; - } - - return NS_ERROR_FAILURE; -} - -} // namespace mozilla diff --git a/dom/media/encoder/fmp4_muxer/ISOMediaWriter.h b/dom/media/encoder/fmp4_muxer/ISOMediaWriter.h deleted file mode 100644 index cccbbe3cb..000000000 --- a/dom/media/encoder/fmp4_muxer/ISOMediaWriter.h +++ /dev/null @@ -1,108 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-*/ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef ISOMediaWriter_h_ -#define ISOMediaWriter_h_ - -#include "ContainerWriter.h" -#include "nsAutoPtr.h" -#include "nsIRunnable.h" - -namespace mozilla { - -class ISOControl; -class FragmentBuffer; - -class ISOMediaWriter : public ContainerWriter -{ -public: - // Generate an fragmented MP4 stream, ISO/IEC 14496-12. - // Brand names in 'ftyp' box are 'isom' and 'mp42'. - const static uint32_t TYPE_FRAG_MP4 = 1 << 0; - - // Generate an fragmented 3GP stream, 3GPP TS 26.244, - // '5.4.3 Basic profile'. - // Brand names in 'ftyp' box are '3gp9' and 'isom'. - const static uint32_t TYPE_FRAG_3GP = 1 << 1; - - // Generate an fragmented 3G2 stream, 3GPP2 C.S0050-B - // Brand names in 'ftyp' box are '3g2c' and 'isom' - const static uint32_t TYPE_FRAG_3G2 = 1 << 2; - - // aType is the combination of CREATE_AUDIO_TRACK and CREATE_VIDEO_TRACK. - // It is a hint to muxer that the output streaming contains audio, video - // or both. - // - // aHint is one of the value in TYPE_XXXXXXXX. It is a hint to muxer what kind - // of ISO format should be generated. - ISOMediaWriter(uint32_t aType, uint32_t aHint = TYPE_FRAG_MP4); - ~ISOMediaWriter(); - - // ContainerWriter methods - nsresult WriteEncodedTrack(const EncodedFrameContainer &aData, - uint32_t aFlags = 0) override; - - nsresult GetContainerData(nsTArray<nsTArray<uint8_t>>* aOutputBufs, - uint32_t aFlags = 0) override; - - nsresult SetMetadata(TrackMetadataBase* aMetadata) override; - -protected: - /** - * The state of each state will generate one or more blob. - * Each blob will be a moov, moof, moof... until receiving EOS. - * The generated sequence is: - * - * moov -> moof -> moof -> ... -> moof -> moof - * - * Following is the details of each state. - * MUXING_HEAD: - * It collects the metadata to generate a moov. The state transits to - * MUXING_HEAD after output moov blob. - * - * MUXING_FRAG: - * It collects enough audio/video data to generate a fragment blob. This - * will be repeated until END_OF_STREAM and then transiting to MUXING_DONE. - * - * MUXING_DONE: - * End of ISOMediaWriter life cycle. - */ - enum MuxState { - MUXING_HEAD, - MUXING_FRAG, - MUXING_DONE, - }; - -private: - nsresult RunState(); - - // True if one of following conditions hold: - // 1. Audio/Video accumulates enough data to generate a moof. - // 2. Get EOS signal. - // aEOS will be assigned to true if it gets EOS signal. - bool ReadyToRunState(bool& aEOS); - - // The main class to generate and iso box. Its life time is same as - // ISOMediaWriter and deleted only if ISOMediaWriter is destroyed. - nsAutoPtr<ISOControl> mControl; - - // Buffers to keep audio/video data frames, they are created when metadata is - // received. Only one instance for each media type is allowed and they will be - // deleted only if ISOMediaWriter is destroyed. - nsAutoPtr<FragmentBuffer> mAudioFragmentBuffer; - nsAutoPtr<FragmentBuffer> mVideoFragmentBuffer; - - MuxState mState; - - // A flag to indicate the output buffer is ready to blob out. - bool mBlobReady; - - // Combination of Audio_Track or Video_Track. - uint32_t mType; -}; - -} // namespace mozilla - -#endif // ISOMediaWriter_h_ diff --git a/dom/media/encoder/fmp4_muxer/ISOTrackMetadata.h b/dom/media/encoder/fmp4_muxer/ISOTrackMetadata.h deleted file mode 100644 index 3613e1e9e..000000000 --- a/dom/media/encoder/fmp4_muxer/ISOTrackMetadata.h +++ /dev/null @@ -1,131 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-*/ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef ISOTrackMetadata_h_ -#define ISOTrackMetadata_h_ - -#include "TrackMetadataBase.h" - -namespace mozilla { - -class AACTrackMetadata : public AudioTrackMetadata { -public: - // AudioTrackMetadata members - uint32_t GetAudioFrameDuration() override { return mFrameDuration; } - uint32_t GetAudioFrameSize() override { return mFrameSize; } - uint32_t GetAudioSampleRate() override { return mSampleRate; } - uint32_t GetAudioChannels() override { return mChannels; } - - // TrackMetadataBase member - MetadataKind GetKind() const override { return METADATA_AAC; } - - // AACTrackMetadata members - AACTrackMetadata() - : mSampleRate(0) - , mFrameDuration(0) - , mFrameSize(0) - , mChannels(0) { - MOZ_COUNT_CTOR(AACTrackMetadata); - } - ~AACTrackMetadata() { MOZ_COUNT_DTOR(AACTrackMetadata); } - - uint32_t mSampleRate; // From 14496-3 table 1.16, it could be 7350 ~ 96000. - uint32_t mFrameDuration; // Audio frame duration based on SampleRate. - uint32_t mFrameSize; // Audio frame size, 0 is variant size. - uint32_t mChannels; // Channel number, it should be 1 or 2. -}; - -// AVC clock rate is 90k Hz. -#define AVC_CLOCK_RATE 90000 - -class AVCTrackMetadata : public VideoTrackMetadata { -public: - // VideoTrackMetadata members - uint32_t GetVideoHeight() override { return mHeight; } - uint32_t GetVideoWidth() override {return mWidth; } - uint32_t GetVideoDisplayHeight() override { return mDisplayHeight; } - uint32_t GetVideoDisplayWidth() override { return mDisplayWidth; } - uint32_t GetVideoClockRate() override { return AVC_CLOCK_RATE; } - uint32_t GetVideoFrameRate() override { return mFrameRate; } - - // TrackMetadataBase member - MetadataKind GetKind() const override { return METADATA_AVC; } - - // AVCTrackMetadata - AVCTrackMetadata() - : mHeight(0) - , mWidth(0) - , mDisplayHeight(0) - , mDisplayWidth(0) - , mFrameRate(0) { - MOZ_COUNT_CTOR(AVCTrackMetadata); - } - ~AVCTrackMetadata() { MOZ_COUNT_DTOR(AVCTrackMetadata); } - - uint32_t mHeight; - uint32_t mWidth; - uint32_t mDisplayHeight; - uint32_t mDisplayWidth; - uint32_t mFrameRate; // frames per second -}; - - -// AMR sample rate is 8000 samples/s. -#define AMR_SAMPLE_RATE 8000 - -// Channel number is always 1. -#define AMR_CHANNELS 1 - -// AMR speech codec, 3GPP TS 26.071. Encoder and continer support AMR-NB only -// currently. -class AMRTrackMetadata : public AudioTrackMetadata { -public: - // AudioTrackMetadata members - // - // The number of sample sets generates by encoder is variant. So the - // frame duration and frame size are both 0. - uint32_t GetAudioFrameDuration() override { return 0; } - uint32_t GetAudioFrameSize() override { return 0; } - uint32_t GetAudioSampleRate() override { return AMR_SAMPLE_RATE; } - uint32_t GetAudioChannels() override { return AMR_CHANNELS; } - - // TrackMetadataBase member - MetadataKind GetKind() const override { return METADATA_AMR; } - - // AMRTrackMetadata members - AMRTrackMetadata() { MOZ_COUNT_CTOR(AMRTrackMetadata); } - ~AMRTrackMetadata() { MOZ_COUNT_DTOR(AMRTrackMetadata); } -}; - -// EVRC sample rate is 8000 samples/s. -#define EVRC_SAMPLE_RATE 8000 - -class EVRCTrackMetadata : public AudioTrackMetadata { -public: - // AudioTrackMetadata members - // - // The number of sample sets generates by encoder is variant. So the - // frame duration and frame size are both 0. - uint32_t GetAudioFrameDuration() override { return 0; } - uint32_t GetAudioFrameSize() override { return 0; } - uint32_t GetAudioSampleRate() override { return EVRC_SAMPLE_RATE; } - uint32_t GetAudioChannels() override { return mChannels; } - - // TrackMetadataBase member - MetadataKind GetKind() const override { return METADATA_EVRC; } - - // EVRCTrackMetadata members - EVRCTrackMetadata() - : mChannels(0) { - MOZ_COUNT_CTOR(EVRCTrackMetadata); - } - ~EVRCTrackMetadata() { MOZ_COUNT_DTOR(EVRCTrackMetadata); } - - uint32_t mChannels; // Channel number, it should be 1 or 2. -}; - -} - -#endif // ISOTrackMetadata_h_ diff --git a/dom/media/encoder/fmp4_muxer/MP4ESDS.cpp b/dom/media/encoder/fmp4_muxer/MP4ESDS.cpp deleted file mode 100644 index 72880b5cb..000000000 --- a/dom/media/encoder/fmp4_muxer/MP4ESDS.cpp +++ /dev/null @@ -1,138 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-*/ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include <climits> -#include "ISOControl.h" -#include "ISOMediaBoxes.h" -#include "MP4ESDS.h" - -namespace mozilla { - -nsresult -MP4AudioSampleEntry::Generate(uint32_t* aBoxSize) -{ - uint32_t box_size; - nsresult rv = es->Generate(&box_size); - NS_ENSURE_SUCCESS(rv, rv); - size += box_size; - - *aBoxSize = size; - return NS_OK; -} - -nsresult -MP4AudioSampleEntry::Write() -{ - BoxSizeChecker checker(mControl, size); - nsresult rv; - rv = AudioSampleEntry::Write(); - NS_ENSURE_SUCCESS(rv, rv); - rv = es->Write(); - NS_ENSURE_SUCCESS(rv, rv); - - return NS_OK; -} - -MP4AudioSampleEntry::MP4AudioSampleEntry(ISOControl* aControl) - : AudioSampleEntry(NS_LITERAL_CSTRING("mp4a"), aControl) -{ - es = new ESDBox(aControl); - MOZ_COUNT_CTOR(MP4AudioSampleEntry); -} - -MP4AudioSampleEntry::~MP4AudioSampleEntry() -{ - MOZ_COUNT_DTOR(MP4AudioSampleEntry); -} - -nsresult -ESDBox::Generate(uint32_t* aBoxSize) -{ - uint32_t box_size; - es_descriptor->Generate(&box_size); - size += box_size; - *aBoxSize = size; - return NS_OK; -} - -nsresult -ESDBox::Write() -{ - WRITE_FULLBOX(mControl, size) - es_descriptor->Write(); - return NS_OK; -} - -ESDBox::ESDBox(ISOControl* aControl) - : FullBox(NS_LITERAL_CSTRING("esds"), 0, 0, aControl) -{ - es_descriptor = new ES_Descriptor(aControl); - MOZ_COUNT_CTOR(ESDBox); -} - -ESDBox::~ESDBox() -{ - MOZ_COUNT_DTOR(ESDBox); -} - -nsresult -ES_Descriptor::Find(const nsACString& aType, - nsTArray<RefPtr<MuxerOperation>>& aOperations) -{ - // ES_Descriptor is not a real ISOMediaBox, so we return nothing here. - return NS_OK; -} - -nsresult -ES_Descriptor::Write() -{ - mControl->Write(tag); - mControl->Write(length); - mControl->Write(ES_ID); - mControl->WriteBits(streamDependenceFlag.to_ulong(), streamDependenceFlag.size()); - mControl->WriteBits(URL_Flag.to_ulong(), URL_Flag.size()); - mControl->WriteBits(reserved.to_ulong(), reserved.size()); - mControl->WriteBits(streamPriority.to_ulong(), streamPriority.size()); - mControl->Write(DecodeSpecificInfo.Elements(), DecodeSpecificInfo.Length()); - - return NS_OK; -} - -nsresult -ES_Descriptor::Generate(uint32_t* aBoxSize) -{ - nsresult rv; - // 14496-1 '8.3.4 DecoderConfigDescriptor' - // 14496-1 '10.2.3 SL Packet Header Configuration' - FragmentBuffer* frag = mControl->GetFragment(Audio_Track); - rv = frag->GetCSD(DecodeSpecificInfo); - NS_ENSURE_SUCCESS(rv, rv); - - length = sizeof(ES_ID) + 1; - length += DecodeSpecificInfo.Length(); - - *aBoxSize = sizeof(tag) + sizeof(length) + length; - return NS_OK; -} - -ES_Descriptor::ES_Descriptor(ISOControl* aControl) - : tag(ESDescrTag) - , length(0) - , ES_ID(0) - , streamDependenceFlag(0) - , URL_Flag(0) - , reserved(0) - , streamPriority(0) - , mControl(aControl) -{ - MOZ_COUNT_CTOR(ES_Descriptor); -} - -ES_Descriptor::~ES_Descriptor() -{ - MOZ_COUNT_DTOR(ES_Descriptor); -} - -} diff --git a/dom/media/encoder/fmp4_muxer/MP4ESDS.h b/dom/media/encoder/fmp4_muxer/MP4ESDS.h deleted file mode 100644 index ee91312c1..000000000 --- a/dom/media/encoder/fmp4_muxer/MP4ESDS.h +++ /dev/null @@ -1,87 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-*/ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef MP4ESDS_h_ -#define MP4ESDS_h_ - -#include "nsTArray.h" -#include "MuxerOperation.h" - -namespace mozilla { - -class ISOControl; - -/** - * ESDS tag - */ -#define ESDescrTag 0x03 - -/** - * 14496-1 '8.3.3 ES_Descriptor'. - * It will get DecoderConfigDescriptor and SLConfigDescriptor from - * AAC CSD data. - */ -class ES_Descriptor : public MuxerOperation { -public: - // ISO BMFF members - uint8_t tag; // ESDescrTag - uint8_t length; - uint16_t ES_ID; - std::bitset<1> streamDependenceFlag; - std::bitset<1> URL_Flag; - std::bitset<1> reserved; - std::bitset<5> streamPriority; - - nsTArray<uint8_t> DecodeSpecificInfo; - - // MuxerOperation methods - nsresult Generate(uint32_t* aBoxSize) override; - nsresult Write() override; - nsresult Find(const nsACString& aType, - nsTArray<RefPtr<MuxerOperation>>& aOperations) override; - - // ES_Descriptor methods - ES_Descriptor(ISOControl* aControl); - ~ES_Descriptor(); - -protected: - ISOControl* mControl; -}; - -// 14496-14 5.6 'Sample Description Boxes' -// Box type: 'esds' -class ESDBox : public FullBox { -public: - // ISO BMFF members - RefPtr<ES_Descriptor> es_descriptor; - - // MuxerOperation methods - nsresult Generate(uint32_t* aBoxSize) override; - nsresult Write() override; - - // ESDBox methods - ESDBox(ISOControl* aControl); - ~ESDBox(); -}; - -// 14496-14 5.6 'Sample Description Boxes' -// Box type: 'mp4a' -class MP4AudioSampleEntry : public AudioSampleEntry { -public: - // ISO BMFF members - RefPtr<ESDBox> es; - - // MuxerOperation methods - nsresult Generate(uint32_t* aBoxSize) override; - nsresult Write() override; - - // MP4AudioSampleEntry methods - MP4AudioSampleEntry(ISOControl* aControl); - ~MP4AudioSampleEntry(); -}; - -} - -#endif // MP4ESDS_h_ diff --git a/dom/media/encoder/fmp4_muxer/MuxerOperation.h b/dom/media/encoder/fmp4_muxer/MuxerOperation.h deleted file mode 100644 index 0b83c89b0..000000000 --- a/dom/media/encoder/fmp4_muxer/MuxerOperation.h +++ /dev/null @@ -1,57 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-*/ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "nsString.h" -#include "nsTArray.h" - -#ifndef MuxerOperation_h_ -#define MuxerOperation_h_ - -namespace mozilla { - -/** - * The interface for ISO box. All Boxes inherit from this interface. - * Generate() and Write() are needed to be called to produce a complete box. - * - * Generate() will generate all the data structures and their size. - * - * Write() will write all data into muxing output stream (ISOControl actually) - * and update the data which can't be known at Generate() (for example, the - * offset of the video data in mp4 file). - * - * ISO base media format is composed of several container boxes and the contained - * boxes. The container boxes hold a list of MuxerOperation which is implemented - * by contained boxes. The contained boxes will be called via the list. - * For example: - * MovieBox (container) ---> boxes (array of MuxerOperation) - * |---> MovieHeaderBox (full box) - * |---> TrakBox (container) - * |---> MovieExtendsBox (container) - * - * The complete box structure can be found at 14496-12 E.2 "The‘isom’brand". - */ -class MuxerOperation { -public: - NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MuxerOperation) - - // Generate data of this box and its contained box, and calculate box size. - virtual nsresult Generate(uint32_t* aBoxSize) = 0; - - // Write data to stream. - virtual nsresult Write() = 0; - - // Find the box type via its name (name is the box type defined in 14496-12; - // for example, 'moov' is the name of MovieBox). - // It can only look child boxes including itself and the box in the boxes - // list if exists. It can't look parent boxes. - virtual nsresult Find(const nsACString& aType, - nsTArray<RefPtr<MuxerOperation>>& aOperations) = 0; - -protected: - virtual ~MuxerOperation() {} -}; - -} -#endif diff --git a/dom/media/encoder/fmp4_muxer/moz.build b/dom/media/encoder/fmp4_muxer/moz.build deleted file mode 100644 index 5ff274be5..000000000 --- a/dom/media/encoder/fmp4_muxer/moz.build +++ /dev/null @@ -1,22 +0,0 @@ -# -*- Mode: python; 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/. - -EXPORTS += [ - 'ISOMediaWriter.h', - 'ISOTrackMetadata.h', -] - -UNIFIED_SOURCES += [ - 'AMRBox.cpp', - 'AVCBox.cpp', - 'EVRCBox.cpp', - 'ISOControl.cpp', - 'ISOMediaBoxes.cpp', - 'ISOMediaWriter.cpp', - 'MP4ESDS.cpp', -] - -FINAL_LIBRARY = 'xul' diff --git a/dom/media/encoder/moz.build b/dom/media/encoder/moz.build index 0d5cdc16f..f29430cb0 100644 --- a/dom/media/encoder/moz.build +++ b/dom/media/encoder/moz.build @@ -7,9 +7,6 @@ with Files('*'): BUG_COMPONENT = ('Core', 'Video/Audio: Recording') -if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk': - DIRS += ['fmp4_muxer'] - EXPORTS += [ 'ContainerWriter.h', 'EncodedFrameContainer.h', @@ -37,16 +34,6 @@ FINAL_LIBRARY = 'xul' # These includes are from Android JB, for use of MediaCodec. LOCAL_INCLUDES += ['/ipc/chromium/src'] -if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk' and CONFIG['ANDROID_VERSION'] > '15': - LOCAL_INCLUDES += [ - '%' + '%s/%s' % (CONFIG['ANDROID_SOURCE'], d) for d in [ - 'frameworks/av/include/media', - 'frameworks/native/include', - 'frameworks/native/opengl/include', - ] - - ] - include('/ipc/chromium/chromium-config.mozbuild') # Suppress some GCC warnings being treated as errors: diff --git a/dom/media/platforms/omx/GonkOmxPlatformLayer.cpp b/dom/media/platforms/omx/GonkOmxPlatformLayer.cpp deleted file mode 100644 index 870566cf5..000000000 --- a/dom/media/platforms/omx/GonkOmxPlatformLayer.cpp +++ /dev/null @@ -1,667 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim:set ts=2 sw=2 sts=2 et cindent: */ -/* 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/. */ - -#include "GonkOmxPlatformLayer.h" - -#include <binder/MemoryDealer.h> -#include <cutils/properties.h> -#include <media/IOMX.h> -#include <media/stagefright/MediaCodecList.h> -#include <utils/List.h> - -#include "mozilla/Monitor.h" -#include "mozilla/layers/TextureClient.h" -#include "mozilla/layers/GrallocTextureClient.h" -#include "mozilla/layers/ImageBridgeChild.h" -#include "mozilla/layers/TextureClientRecycleAllocator.h" - -#include "ImageContainer.h" -#include "MediaInfo.h" -#include "OmxDataDecoder.h" - - -#ifdef LOG -#undef LOG -#endif - -#define LOG(arg, ...) MOZ_LOG(sPDMLog, mozilla::LogLevel::Debug, ("GonkOmxPlatformLayer(%p)::%s: " arg, this, __func__, ##__VA_ARGS__)) - -#define CHECK_ERR(err) \ - if (err != OK) { \ - LOG("error %d at %s", err, __func__); \ - return NS_ERROR_FAILURE; \ - } \ - -// Android proprietary value. -#define ANDROID_OMX_VIDEO_CodingVP8 (static_cast<OMX_VIDEO_CODINGTYPE>(9)) - -using namespace android; - -namespace mozilla { - -// In Gonk, the software component name has prefix "OMX.google". It needs to -// have a way to use hardware codec first. -bool IsSoftwareCodec(const char* aComponentName) -{ - nsAutoCString str(aComponentName); - return (str.Find(NS_LITERAL_CSTRING("OMX.google.")) == -1 ? false : true); -} - -bool IsInEmulator() -{ - char propQemu[PROPERTY_VALUE_MAX]; - property_get("ro.kernel.qemu", propQemu, ""); - return !strncmp(propQemu, "1", 1); -} - -class GonkOmxObserver : public BnOMXObserver { -public: - void onMessage(const omx_message& aMsg) - { - switch (aMsg.type) { - case omx_message::EVENT: - { - sp<GonkOmxObserver> self = this; - nsCOMPtr<nsIRunnable> r = NS_NewRunnableFunction([self, aMsg] () { - if (self->mClient && self->mClient->Event(aMsg.u.event_data.event, - aMsg.u.event_data.data1, - aMsg.u.event_data.data2)) - { - return; - } - }); - mTaskQueue->Dispatch(r.forget()); - break; - } - case omx_message::EMPTY_BUFFER_DONE: - { - sp<GonkOmxObserver> self = this; - nsCOMPtr<nsIRunnable> r = NS_NewRunnableFunction([self, aMsg] () { - if (!self->mPromiseLayer) { - return; - } - BufferData::BufferID id = (BufferData::BufferID)aMsg.u.buffer_data.buffer; - self->mPromiseLayer->EmptyFillBufferDone(OMX_DirInput, id); - }); - mTaskQueue->Dispatch(r.forget()); - break; - } - case omx_message::FILL_BUFFER_DONE: - { - sp<GonkOmxObserver> self = this; - nsCOMPtr<nsIRunnable> r = NS_NewRunnableFunction([self, aMsg] () { - if (!self->mPromiseLayer) { - return; - } - - // TODO: these codes look a little ugly, it'd be better to improve them. - RefPtr<BufferData> buf; - BufferData::BufferID id = (BufferData::BufferID)aMsg.u.extended_buffer_data.buffer; - buf = self->mPromiseLayer->FindAndRemoveBufferHolder(OMX_DirOutput, id); - MOZ_RELEASE_ASSERT(buf); - GonkBufferData* gonkBuffer = static_cast<GonkBufferData*>(buf.get()); - - // Copy the critical information to local buffer. - if (gonkBuffer->IsLocalBuffer()) { - gonkBuffer->mBuffer->nOffset = aMsg.u.extended_buffer_data.range_offset; - gonkBuffer->mBuffer->nFilledLen = aMsg.u.extended_buffer_data.range_length; - gonkBuffer->mBuffer->nFlags = aMsg.u.extended_buffer_data.flags; - gonkBuffer->mBuffer->nTimeStamp = aMsg.u.extended_buffer_data.timestamp; - } - self->mPromiseLayer->EmptyFillBufferDone(OMX_DirOutput, buf); - }); - mTaskQueue->Dispatch(r.forget()); - break; - } - default: - { - LOG("Unhandle event %d", aMsg.type); - } - } - } - - void Shutdown() - { - MOZ_ASSERT(mTaskQueue->IsCurrentThreadIn()); - mPromiseLayer = nullptr; - mClient = nullptr; - } - - GonkOmxObserver(TaskQueue* aTaskQueue, OmxPromiseLayer* aPromiseLayer, OmxDataDecoder* aDataDecoder) - : mTaskQueue(aTaskQueue) - , mPromiseLayer(aPromiseLayer) - , mClient(aDataDecoder) - {} - -protected: - RefPtr<TaskQueue> mTaskQueue; - // TODO: - // we should combine both event handlers into one. And we should provide - // an unified way for event handling in OmxPlatformLayer class. - RefPtr<OmxPromiseLayer> mPromiseLayer; - RefPtr<OmxDataDecoder> mClient; -}; - -// This class allocates Gralloc buffer and manages TextureClient's recycle. -class GonkTextureClientRecycleHandler : public layers::ITextureClientRecycleAllocator -{ - typedef MozPromise<layers::TextureClient*, nsresult, /* IsExclusive = */ true> TextureClientRecyclePromise; - -public: - GonkTextureClientRecycleHandler(OMX_VIDEO_PORTDEFINITIONTYPE& aDef) - : ITextureClientRecycleAllocator() - , mMonitor("GonkTextureClientRecycleHandler") - { - RefPtr<layers::ImageBridgeChild> bridge = layers::ImageBridgeChild::GetSingleton(); - - // Allocate Gralloc texture memory. - layers::GrallocTextureData* textureData = - layers::GrallocTextureData::Create(gfx::IntSize(aDef.nFrameWidth, aDef.nFrameHeight), - aDef.eColorFormat, - gfx::BackendType::NONE, - GraphicBuffer::USAGE_HW_TEXTURE | GraphicBuffer::USAGE_SW_READ_OFTEN, - bridge); - - mGraphBuffer = textureData->GetGraphicBuffer(); - MOZ_ASSERT(mGraphBuffer.get()); - - mTextureClient = - layers::TextureClient::CreateWithData(textureData, - layers::TextureFlags::DEALLOCATE_CLIENT | layers::TextureFlags::RECYCLE, - bridge); - MOZ_ASSERT(mTextureClient); - - mPromise.SetMonitor(&mMonitor); - } - - RefPtr<TextureClientRecyclePromise> WaitforRecycle() - { - MonitorAutoLock lock(mMonitor); - MOZ_ASSERT(!!mGraphBuffer.get()); - - mTextureClient->SetRecycleAllocator(this); - return mPromise.Ensure(__func__); - } - - // DO NOT use smart pointer to receive TextureClient; otherwise it will - // distrupt the reference count. - layers::TextureClient* GetTextureClient() - { - return mTextureClient; - } - - GraphicBuffer* GetGraphicBuffer() - { - MonitorAutoLock lock(mMonitor); - return mGraphBuffer.get(); - } - - // This function is called from layers thread. - void RecycleTextureClient(layers::TextureClient* aClient) override - { - MOZ_ASSERT(mTextureClient == aClient); - - // Clearing the recycle allocator drops a reference, so make sure we stay alive - // for the duration of this function. - RefPtr<GonkTextureClientRecycleHandler> kungFuDeathGrip(this); - aClient->SetRecycleAllocator(nullptr); - - { - MonitorAutoLock lock(mMonitor); - mPromise.ResolveIfExists(mTextureClient, __func__); - } - } - - void Shutdown() - { - MonitorAutoLock lock(mMonitor); - - mPromise.RejectIfExists(NS_ERROR_FAILURE, __func__); - - // DO NOT clear TextureClient here. - // The ref count could be 1 and RecycleCallback will be called if we clear - // the ref count here. That breaks the whole mechanism. (RecycleCallback - // should be called from layers) - mGraphBuffer = nullptr; - } - -private: - // Because TextureClient calls RecycleCallbackl when ref count is 1, so we - // should hold only one reference here and use raw pointer when out of this - // class. - RefPtr<layers::TextureClient> mTextureClient; - - // It is protected by mMonitor. - sp<android::GraphicBuffer> mGraphBuffer; - - // It is protected by mMonitor. - MozPromiseHolder<TextureClientRecyclePromise> mPromise; - - Monitor mMonitor; -}; - -GonkBufferData::GonkBufferData(bool aLiveInLocal, - GonkOmxPlatformLayer* aGonkPlatformLayer) - : BufferData(nullptr) - , mId(0) - , mGonkPlatformLayer(aGonkPlatformLayer) -{ - if (!aLiveInLocal) { - mMirrorBuffer = new OMX_BUFFERHEADERTYPE; - PodZero(mMirrorBuffer.get()); - mBuffer = mMirrorBuffer.get(); - } -} - -void -GonkBufferData::ReleaseBuffer() -{ - if (mTextureClientRecycleHandler) { - mTextureClientRecycleHandler->Shutdown(); - mTextureClientRecycleHandler = nullptr; - } -} - -nsresult -GonkBufferData::InitSharedMemory(android::IMemory* aMemory) -{ - MOZ_RELEASE_ASSERT(mMirrorBuffer.get()); - - // aMemory is a IPC memory, it is safe to use it here. - mBuffer->pBuffer = (OMX_U8*)aMemory->pointer(); - mBuffer->nAllocLen = aMemory->size(); - return NS_OK; -} - -nsresult -GonkBufferData::InitLocalBuffer(IOMX::buffer_id aId) -{ - MOZ_RELEASE_ASSERT(!mMirrorBuffer.get()); - - mBuffer = (OMX_BUFFERHEADERTYPE*)aId; - return NS_OK; -} - -nsresult -GonkBufferData::InitGraphicBuffer(OMX_VIDEO_PORTDEFINITIONTYPE& aDef) -{ - mTextureClientRecycleHandler = new GonkTextureClientRecycleHandler(aDef); - - if (!mTextureClientRecycleHandler->GetGraphicBuffer()) { - return NS_ERROR_FAILURE; - } - - return NS_OK; -} - -already_AddRefed<MediaData> -GonkBufferData::GetPlatformMediaData() -{ - if (mGonkPlatformLayer->GetTrackInfo()->GetAsAudioInfo()) { - // This is audio decoding. - return nullptr; - } - - if (!mTextureClientRecycleHandler) { - // There is no GraphicBuffer, it should fallback to normal YUV420 VideoData. - return nullptr; - } - - VideoInfo info(*mGonkPlatformLayer->GetTrackInfo()->GetAsVideoInfo()); - RefPtr<VideoData> data = - VideoData::CreateAndCopyIntoTextureClient(info, - 0, - mBuffer->nTimeStamp, - 1, - mTextureClientRecycleHandler->GetTextureClient(), - false, - 0, - info.ImageRect()); - LOG("%p, disp width %d, height %d, pic width %d, height %d, time %ld", - this, info.mDisplay.width, info.mDisplay.height, - info.mImage.width, info.mImage.height, mBuffer->nTimeStamp); - - // Get TextureClient Promise here to wait for resolved. - RefPtr<GonkBufferData> self(this); - mTextureClientRecycleHandler->WaitforRecycle() - ->Then(mGonkPlatformLayer->GetTaskQueue(), __func__, - [self] () { - self->mPromise.ResolveIfExists(self, __func__); - }, - [self] () { - OmxBufferFailureHolder failure(OMX_ErrorUndefined, self); - self->mPromise.RejectIfExists(failure, __func__); - }); - - return data.forget(); -} - -GonkOmxPlatformLayer::GonkOmxPlatformLayer(OmxDataDecoder* aDataDecoder, - OmxPromiseLayer* aPromiseLayer, - TaskQueue* aTaskQueue, - layers::ImageContainer* aImageContainer) - : mTaskQueue(aTaskQueue) - , mImageContainer(aImageContainer) - , mNode(0) -{ - mOmxObserver = new GonkOmxObserver(mTaskQueue, aPromiseLayer, aDataDecoder); -} - -nsresult -GonkOmxPlatformLayer::AllocateOmxBuffer(OMX_DIRTYPE aType, - BUFFERLIST* aBufferList) -{ - MOZ_ASSERT(!mMemoryDealer[aType].get()); - - // Get port definition. - OMX_PARAM_PORTDEFINITIONTYPE def; - nsTArray<uint32_t> portindex; - GetPortIndices(portindex); - for (auto idx : portindex) { - InitOmxParameter(&def); - def.nPortIndex = idx; - - OMX_ERRORTYPE err = GetParameter(OMX_IndexParamPortDefinition, - &def, - sizeof(OMX_PARAM_PORTDEFINITIONTYPE)); - if (err != OMX_ErrorNone) { - return NS_ERROR_FAILURE; - } else if (def.eDir == aType) { - LOG("Get OMX_IndexParamPortDefinition: port: %d, type: %d", def.nPortIndex, def.eDir); - break; - } - } - - size_t t = 0; - - // Configure video output GraphicBuffer for video decoding acceleration. - bool useGralloc = false; - if (aType == OMX_DirOutput && mQuirks.test(kRequiresAllocateBufferOnOutputPorts) && - (def.eDomain == OMX_PortDomainVideo)) { - if (NS_FAILED(EnableOmxGraphicBufferPort(def))) { - return NS_ERROR_FAILURE; - } - - LOG("Enable OMX GraphicBuffer port, number %d, width %d, height %d", def.nBufferCountActual, - def.format.video.nFrameWidth, def.format.video.nFrameHeight); - - useGralloc = true; - - t = 1024; // MemoryDealer doesn't like 0, it's just for MemoryDealer happy. - } else { - t = def.nBufferCountActual * def.nBufferSize; - LOG("Buffer count %d, buffer size %d", def.nBufferCountActual, def.nBufferSize); - } - - bool liveinlocal = mOmx->livesLocally(mNode, getpid()); - - // MemoryDealer is a IPC buffer allocator in Gonk because IOMX is actually - // lives in mediaserver. - mMemoryDealer[aType] = new MemoryDealer(t, "Gecko-OMX"); - for (OMX_U32 i = 0; i < def.nBufferCountActual; ++i) { - RefPtr<GonkBufferData> buffer; - IOMX::buffer_id bufferID; - status_t st; - nsresult rv; - - buffer = new GonkBufferData(liveinlocal, this); - if (useGralloc) { - // Buffer is lived remotely. Use GraphicBuffer for decoded video frame display. - rv = buffer->InitGraphicBuffer(def.format.video); - NS_ENSURE_SUCCESS(rv, rv); - st = mOmx->useGraphicBuffer(mNode, - def.nPortIndex, - buffer->mTextureClientRecycleHandler->GetGraphicBuffer(), - &bufferID); - CHECK_ERR(st); - } else { - sp<IMemory> mem = mMemoryDealer[aType]->allocate(def.nBufferSize); - MOZ_ASSERT(mem.get()); - - if ((mQuirks.test(kRequiresAllocateBufferOnInputPorts) && aType == OMX_DirInput) || - (mQuirks.test(kRequiresAllocateBufferOnOutputPorts) && aType == OMX_DirOutput)) { - // Buffer is lived remotely. We allocate a local OMX_BUFFERHEADERTYPE - // as the mirror of the remote OMX_BUFFERHEADERTYPE. - st = mOmx->allocateBufferWithBackup(mNode, aType, mem, &bufferID); - CHECK_ERR(st); - rv = buffer->InitSharedMemory(mem.get()); - NS_ENSURE_SUCCESS(rv, rv); - } else { - // Buffer is lived locally, bufferID is the actually OMX_BUFFERHEADERTYPE - // pointer. - st = mOmx->useBuffer(mNode, aType, mem, &bufferID); - CHECK_ERR(st); - rv = buffer->InitLocalBuffer(bufferID); - NS_ENSURE_SUCCESS(rv, rv); - } - } - - rv = buffer->SetBufferId(bufferID); - NS_ENSURE_SUCCESS(rv, rv); - - aBufferList->AppendElement(buffer); - } - - return NS_OK; -} - -nsresult -GonkOmxPlatformLayer::ReleaseOmxBuffer(OMX_DIRTYPE aType, - BUFFERLIST* aBufferList) -{ - status_t st; - uint32_t len = aBufferList->Length(); - for (uint32_t i = 0; i < len; i++) { - GonkBufferData* buffer = static_cast<GonkBufferData*>(aBufferList->ElementAt(i).get()); - IOMX::buffer_id id = (OMX_BUFFERHEADERTYPE*) buffer->ID(); - st = mOmx->freeBuffer(mNode, aType, id); - if (st != OK) { - return NS_ERROR_FAILURE; - } - buffer->ReleaseBuffer(); - } - aBufferList->Clear(); - mMemoryDealer[aType].clear(); - - return NS_OK; -} - -nsresult -GonkOmxPlatformLayer::EnableOmxGraphicBufferPort(OMX_PARAM_PORTDEFINITIONTYPE& aDef) -{ - status_t st; - - st = mOmx->enableGraphicBuffers(mNode, aDef.nPortIndex, OMX_TRUE); - CHECK_ERR(st); - - return NS_OK; -} - -OMX_ERRORTYPE -GonkOmxPlatformLayer::GetState(OMX_STATETYPE* aType) -{ - return (OMX_ERRORTYPE)mOmx->getState(mNode, aType); -} - -OMX_ERRORTYPE -GonkOmxPlatformLayer::GetParameter(OMX_INDEXTYPE aParamIndex, - OMX_PTR aComponentParameterStructure, - OMX_U32 aComponentParameterSize) -{ - return (OMX_ERRORTYPE)mOmx->getParameter(mNode, - aParamIndex, - aComponentParameterStructure, - aComponentParameterSize); -} - -OMX_ERRORTYPE -GonkOmxPlatformLayer::SetParameter(OMX_INDEXTYPE aParamIndex, - OMX_PTR aComponentParameterStructure, - OMX_U32 aComponentParameterSize) -{ - return (OMX_ERRORTYPE)mOmx->setParameter(mNode, - aParamIndex, - aComponentParameterStructure, - aComponentParameterSize); -} - -nsresult -GonkOmxPlatformLayer::Shutdown() -{ - mOmx->freeNode(mNode); - mOmxObserver->Shutdown(); - mOmxObserver = nullptr; - mOmxClient.disconnect(); - - return NS_OK; -} - -OMX_ERRORTYPE -GonkOmxPlatformLayer::InitOmxToStateLoaded(const TrackInfo* aInfo) -{ - mInfo = aInfo; - status_t err = mOmxClient.connect(); - if (err != OK) { - return OMX_ErrorUndefined; - } - mOmx = mOmxClient.interface(); - if (!mOmx.get()) { - return OMX_ErrorUndefined; - } - - LOG("find componenet for mime type %s", mInfo->mMimeType.Data()); - - nsTArray<ComponentInfo> components; - if (FindComponents(mInfo->mMimeType, &components)) { - for (auto comp : components) { - if (LoadComponent(comp)) { - return OMX_ErrorNone; - } - } - } - - LOG("no component is loaded"); - return OMX_ErrorUndefined; -} - -OMX_ERRORTYPE -GonkOmxPlatformLayer::EmptyThisBuffer(BufferData* aData) -{ - return (OMX_ERRORTYPE)mOmx->emptyBuffer(mNode, - (IOMX::buffer_id)aData->ID(), - aData->mBuffer->nOffset, - aData->mBuffer->nFilledLen, - aData->mBuffer->nFlags, - aData->mBuffer->nTimeStamp); -} - -OMX_ERRORTYPE -GonkOmxPlatformLayer::FillThisBuffer(BufferData* aData) -{ - return (OMX_ERRORTYPE)mOmx->fillBuffer(mNode, (IOMX::buffer_id)aData->ID()); -} - -OMX_ERRORTYPE -GonkOmxPlatformLayer::SendCommand(OMX_COMMANDTYPE aCmd, - OMX_U32 aParam1, - OMX_PTR aCmdData) -{ - return (OMX_ERRORTYPE)mOmx->sendCommand(mNode, aCmd, aParam1); -} - -bool -GonkOmxPlatformLayer::LoadComponent(const ComponentInfo& aComponent) -{ - status_t err = mOmx->allocateNode(aComponent.mName, mOmxObserver, &mNode); - if (err == OK) { - mQuirks = aComponent.mQuirks; - LOG("Load OpenMax component %s, alloc input %d, alloc output %d, live locally %d", - aComponent.mName, mQuirks.test(kRequiresAllocateBufferOnInputPorts), - mQuirks.test(kRequiresAllocateBufferOnOutputPorts), - mOmx->livesLocally(mNode, getpid())); - return true; - } - return false; -} - -layers::ImageContainer* -GonkOmxPlatformLayer::GetImageContainer() -{ - return mImageContainer; -} - -const TrackInfo* -GonkOmxPlatformLayer::GetTrackInfo() -{ - return mInfo; -} - -bool -GonkOmxPlatformLayer::FindComponents(const nsACString& aMimeType, - nsTArray<ComponentInfo>* aComponents) -{ - static const MediaCodecList* codecs = MediaCodecList::getInstance(); - - bool useHardwareCodecOnly = false; - - // H264 and H263 has different profiles, software codec doesn't support high profile. - // So we use hardware codec only. - if (!IsInEmulator() && - (aMimeType.EqualsLiteral("video/avc") || - aMimeType.EqualsLiteral("video/mp4") || - aMimeType.EqualsLiteral("video/mp4v-es") || - aMimeType.EqualsLiteral("video/3gp"))) { - useHardwareCodecOnly = true; - } - - const char* mime = aMimeType.Data(); - // Translate VP8 MIME type to Android format. - if (aMimeType.EqualsLiteral("video/webm; codecs=vp8")) { - mime = "video/x-vnd.on2.vp8"; - } - - size_t start = 0; - bool found = false; - while (true) { - ssize_t index = codecs->findCodecByType(mime, false /* encoder */, start); - if (index < 0) { - break; - } - start = index + 1; - - const char* name = codecs->getCodecName(index); - if (IsSoftwareCodec(name) && useHardwareCodecOnly) { - continue; - } - - found = true; - - if (!aComponents) { - continue; - } - ComponentInfo* comp = aComponents->AppendElement(); - comp->mName = name; - if (codecs->codecHasQuirk(index, "requires-allocate-on-input-ports")) { - comp->mQuirks.set(kRequiresAllocateBufferOnInputPorts); - } - if (codecs->codecHasQuirk(index, "requires-allocate-on-output-ports")) { - comp->mQuirks.set(kRequiresAllocateBufferOnOutputPorts); - } - } - - return found; -} - -OMX_VIDEO_CODINGTYPE -GonkOmxPlatformLayer::CompressionFormat() -{ - MOZ_ASSERT(mInfo); - - return mInfo->mMimeType.EqualsLiteral("video/webm; codecs=vp8") ? - ANDROID_OMX_VIDEO_CodingVP8 : OmxPlatformLayer::CompressionFormat(); -} - -} // mozilla diff --git a/dom/media/platforms/omx/GonkOmxPlatformLayer.h b/dom/media/platforms/omx/GonkOmxPlatformLayer.h deleted file mode 100644 index aaa8c654d..000000000 --- a/dom/media/platforms/omx/GonkOmxPlatformLayer.h +++ /dev/null @@ -1,205 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim:set ts=2 sw=2 sts=2 et cindent: */ -/* 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/. */ - -#if !defined(GonkOmxPlatformLayer_h_) -#define GonkOmxPlatformLayer_h_ - -#pragma GCC visibility push(default) - -#include <bitset> - -#include <utils/RefBase.h> -#include <media/stagefright/OMXClient.h> -#include "nsAutoPtr.h" - -#include "OMX_Component.h" - -#include "OmxPlatformLayer.h" - -class nsACString; - -namespace android { -class IMemory; -class MemoryDealer; -} - -namespace mozilla { - -class GonkOmxObserver; -class GonkOmxPlatformLayer; -class GonkTextureClientRecycleHandler; - -/* - * Due to Android's omx node could live in local process (client) or remote - * process (mediaserver). And there are 3 kinds of buffer in Android OMX. - * - * 1. - * When buffer is in local process, the IOMX::buffer_id is OMX_BUFFERHEADERTYPE - * pointer actually, it is safe to use it directly. - * - * 2. - * When buffer is in remote process, the OMX_BUFFERHEADERTYPE pointer is 'IN' the - * remote process. It can't be used in local process, so here it allocates a - * local OMX_BUFFERHEADERTYPE. The raw/decoded data is in the android shared - * memory, IMemory. - * - * 3. - * When buffer is in remote process for the display output port. It uses - * GraphicBuffer to accelerate the decoding and display. - * - */ -class GonkBufferData : public OmxPromiseLayer::BufferData { -protected: - virtual ~GonkBufferData() {} - -public: - GonkBufferData(bool aLiveInLocal, - GonkOmxPlatformLayer* aLayer); - - BufferID ID() override - { - return mId; - } - - already_AddRefed<MediaData> GetPlatformMediaData() override; - - bool IsLocalBuffer() - { - return !!mMirrorBuffer.get(); - } - - void ReleaseBuffer(); - - nsresult SetBufferId(android::IOMX::buffer_id aId) - { - mId = aId; - return NS_OK; - } - - // The mBuffer is in local process. And aId is actually the OMX_BUFFERHEADERTYPE - // pointer. It doesn't need a mirror buffer. - nsresult InitLocalBuffer(android::IOMX::buffer_id aId); - - // aMemory is an IPC based memory which will be used as the pBuffer in - // mBuffer. And the mBuffer will be the mirror OMX_BUFFERHEADERTYPE - // of the one in the remote process. - nsresult InitSharedMemory(android::IMemory* aMemory); - - // GraphicBuffer is for video decoding acceleration on output port. - // Then mBuffer is the mirror OMX_BUFFERHEADERTYPE of the one in the remote - // process. - nsresult InitGraphicBuffer(OMX_VIDEO_PORTDEFINITIONTYPE& aDef); - - // Android OMX uses this id to pass the buffer between OMX component and - // client. - android::IOMX::buffer_id mId; - - // mMirrorBuffer are used only when the omx node is in mediaserver. - // Due to IPC problem, the mId is the OMX_BUFFERHEADERTYPE address in mediaserver. - // It can't mapping to client process, so we need a local OMX_BUFFERHEADERTYPE - // here to mirror the remote OMX_BUFFERHEADERTYPE in mediaserver. - nsAutoPtr<OMX_BUFFERHEADERTYPE> mMirrorBuffer; - - // It creates GraphicBuffer and manages TextureClient. - RefPtr<GonkTextureClientRecycleHandler> mTextureClientRecycleHandler; - - GonkOmxPlatformLayer* mGonkPlatformLayer; -}; - -class GonkOmxPlatformLayer : public OmxPlatformLayer { -public: - enum { - kRequiresAllocateBufferOnInputPorts = 0, - kRequiresAllocateBufferOnOutputPorts, - QUIRKS, - }; - typedef std::bitset<QUIRKS> Quirks; - - struct ComponentInfo { - const char* mName; - Quirks mQuirks; - }; - - GonkOmxPlatformLayer(OmxDataDecoder* aDataDecoder, - OmxPromiseLayer* aPromiseLayer, - TaskQueue* aTaskQueue, - layers::ImageContainer* aImageContainer); - - nsresult AllocateOmxBuffer(OMX_DIRTYPE aType, BUFFERLIST* aBufferList) override; - - nsresult ReleaseOmxBuffer(OMX_DIRTYPE aType, BUFFERLIST* aBufferList) override; - - OMX_ERRORTYPE GetState(OMX_STATETYPE* aType) override; - - OMX_ERRORTYPE GetParameter(OMX_INDEXTYPE aParamIndex, - OMX_PTR aComponentParameterStructure, - OMX_U32 aComponentParameterSize) override; - - OMX_ERRORTYPE SetParameter(OMX_INDEXTYPE nIndex, - OMX_PTR aComponentParameterStructure, - OMX_U32 aComponentParameterSize) override; - - OMX_ERRORTYPE InitOmxToStateLoaded(const TrackInfo* aInfo) override; - - OMX_ERRORTYPE EmptyThisBuffer(BufferData* aData) override; - - OMX_ERRORTYPE FillThisBuffer(BufferData* aData) override; - - OMX_ERRORTYPE SendCommand(OMX_COMMANDTYPE aCmd, - OMX_U32 aParam1, - OMX_PTR aCmdData) override; - - nsresult Shutdown() override; - - static bool FindComponents(const nsACString& aMimeType, - nsTArray<ComponentInfo>* aComponents = nullptr); - - // Android/QCOM decoder uses its own OMX_VIDEO_CodingVP8 definition in - // frameworks/native/media/include/openmax/OMX_Video.h, not the one defined - // in OpenMAX v1.1.2 OMX_VideoExt.h - OMX_VIDEO_CODINGTYPE CompressionFormat() override; - -protected: - friend GonkBufferData; - - layers::ImageContainer* GetImageContainer(); - - const TrackInfo* GetTrackInfo(); - - TaskQueue* GetTaskQueue() - { - return mTaskQueue; - } - - nsresult EnableOmxGraphicBufferPort(OMX_PARAM_PORTDEFINITIONTYPE& aDef); - - bool LoadComponent(const ComponentInfo& aComponent); - - friend class GonkOmxObserver; - - RefPtr<TaskQueue> mTaskQueue; - - RefPtr<layers::ImageContainer> mImageContainer; - - // OMX_DirInput is 0, OMX_DirOutput is 1. - android::sp<android::MemoryDealer> mMemoryDealer[2]; - - android::sp<GonkOmxObserver> mOmxObserver; - - android::sp<android::IOMX> mOmx; - - android::IOMX::node_id mNode; - - android::OMXClient mOmxClient; - - Quirks mQuirks; -}; - -} - -#pragma GCC visibility pop - -#endif // GonkOmxPlatformLayer_h_ diff --git a/dom/media/platforms/omx/moz.build b/dom/media/platforms/omx/moz.build index 9f641d937..661e280e0 100644 --- a/dom/media/platforms/omx/moz.build +++ b/dom/media/platforms/omx/moz.build @@ -21,29 +21,6 @@ LOCAL_INCLUDES += [ include('/ipc/chromium/chromium-config.mozbuild') -if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk' and (CONFIG['ANDROID_VERSION'] == '19' or CONFIG['ANDROID_VERSION'] == '20'): - # Suppress some GCC/clang warnings being treated as errors: - # - about attributes on forward declarations for types that are already - # defined, which complains about an important MOZ_EXPORT for android::AString - # - about multi-character constants which are used in codec-related code - if CONFIG['GNU_CC'] or CONFIG['CLANG_CL']: - CXXFLAGS += [ - '-Wno-error=attributes', - '-Wno-error=multichar' - ] - CXXFLAGS += [ - '-I%s/%s' % (CONFIG['ANDROID_SOURCE'], d) for d in [ - 'frameworks/base/include/binder', - 'frameworks/base/include/utils', - ] - ] - UNIFIED_SOURCES += [ - 'GonkOmxPlatformLayer.cpp', - ] - EXTRA_DSO_LDOPTS += [ - '-libbinder', - ] - FINAL_LIBRARY = 'xul' if CONFIG['GNU_CXX']: diff --git a/dom/media/standalone/moz.build b/dom/media/standalone/moz.build index 5d2c5a6e7..959703765 100644 --- a/dom/media/standalone/moz.build +++ b/dom/media/standalone/moz.build @@ -4,7 +4,7 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. -if CONFIG['OS_TARGET'] != 'WINNT' and CONFIG['MOZ_WIDGET_TOOLKIT'] != 'gonk': +if CONFIG['OS_TARGET'] != 'WINNT': Library('media_standalone') UNIFIED_SOURCES += [ diff --git a/dom/media/systemservices/moz.build b/dom/media/systemservices/moz.build index 33e5ed1f1..82a5c5e72 100644 --- a/dom/media/systemservices/moz.build +++ b/dom/media/systemservices/moz.build @@ -42,16 +42,6 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa': UNIFIED_SOURCES += ['OSXRunLoopSingleton.cpp'] EXPORTS += ['OSXRunLoopSingleton.h'] -if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk': - if CONFIG['ANDROID_VERSION'] >= '17': - LOCAL_INCLUDES += [ - '%' + '%s/frameworks/wilhelm/include' % CONFIG['ANDROID_SOURCE'], - ] - else: - LOCAL_INCLUDES += [ - '%' + '%s/system/media/wilhelm/include' % CONFIG['ANDROID_SOURCE'], - ] - if CONFIG['_MSC_VER']: DEFINES['__PRETTY_FUNCTION__'] = '__FUNCSIG__' diff --git a/dom/moz.build b/dom/moz.build index 90ea60cbe..358fc6411 100644 --- a/dom/moz.build +++ b/dom/moz.build @@ -105,13 +105,6 @@ DIRS += [ if CONFIG['OS_ARCH'] == 'WINNT': DIRS += ['plugins/ipc/hangui'] -if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk': - DIRS += [ - 'speakermanager', - 'tethering', - 'wifi', - ] - if CONFIG['MOZ_SECUREELEMENT']: DIRS += ['secureelement'] diff --git a/dom/network/EthernetManager.js b/dom/network/EthernetManager.js deleted file mode 100644 index 4b11e5666..000000000 --- a/dom/network/EthernetManager.js +++ /dev/null @@ -1,655 +0,0 @@ -/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -"use strict"; - -const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components; - -Cu.import("resource://gre/modules/Services.jsm"); -Cu.import("resource://gre/modules/XPCOMUtils.jsm"); - -const TOPIC_INTERFACE_STATE_CHANGED = "network-interface-state-changed"; - -const ETHERNET_NETWORK_IFACE_PREFIX = "eth"; -const DEFAULT_ETHERNET_NETWORK_IFACE = "eth0"; - -const INTERFACE_IPADDR_NULL = "0.0.0.0"; -const INTERFACE_GATEWAY_NULL = "0.0.0.0"; -const INTERFACE_PREFIX_NULL = 0; -const INTERFACE_MACADDR_NULL = "00:00:00:00:00:00"; - -const NETWORK_INTERFACE_UP = "up"; -const NETWORK_INTERFACE_DOWN = "down"; - -const IP_MODE_DHCP = "dhcp"; -const IP_MODE_STATIC = "static"; - -const PREF_NETWORK_DEBUG_ENABLED = "network.debugging.enabled"; - -XPCOMUtils.defineLazyServiceGetter(this, "gNetworkManager", - "@mozilla.org/network/manager;1", - "nsINetworkManager"); - -XPCOMUtils.defineLazyServiceGetter(this, "gNetworkService", - "@mozilla.org/network/service;1", - "nsINetworkService"); - -let debug; -function updateDebug() { - let debugPref = false; // set default value here. - try { - debugPref = debugPref || Services.prefs.getBoolPref(PREF_NETWORK_DEBUG_ENABLED); - } catch (e) {} - - if (debugPref) { - debug = function(s) { - dump("-*- EthernetManager: " + s + "\n"); - }; - } else { - debug = function(s) {}; - } -} -updateDebug(); - -// nsINetworkInterface - -function EthernetInterface(attr) { - this.info.state = attr.state; - this.info.type = attr.type; - this.info.name = attr.name; - this.info.ipMode = attr.ipMode; - this.info.ips = [attr.ip]; - this.info.prefixLengths = [attr.prefixLength]; - this.info.gateways = [attr.gateway]; - this.info.dnses = attr.dnses; - this.httpProxyHost = ""; - this.httpProxyPort = 0; -} -EthernetInterface.prototype = { - QueryInterface: XPCOMUtils.generateQI([Ci.nsINetworkInterface]), - - updateConfig: function(config) { - debug("Interface " + this.info.name + " updateConfig " + JSON.stringify(config)); - this.info.state = (config.state != undefined) ? - config.state : this.info.state; - this.info.ips = (config.ip != undefined) ? [config.ip] : this.info.ips; - this.info.prefixLengths = (config.prefixLength != undefined) ? - [config.prefixLength] : this.info.prefixLengths; - this.info.gateways = (config.gateway != undefined) ? - [config.gateway] : this.info.gateways; - this.info.dnses = (config.dnses != undefined) ? config.dnses : this.info.dnses; - this.httpProxyHost = (config.httpProxyHost != undefined) ? - config.httpProxyHost : this.httpProxyHost; - this.httpProxyPort = (config.httpProxyPort != undefined) ? - config.httpProxyPort : this.httpProxyPort; - this.info.ipMode = (config.ipMode != undefined) ? - config.ipMode : this.info.ipMode; - }, - - info: { - getAddresses: function(ips, prefixLengths) { - ips.value = this.ips.slice(); - prefixLengths.value = this.prefixLengths.slice(); - - return this.ips.length; - }, - - getGateways: function(count) { - if (count) { - count.value = this.gateways.length; - } - return this.gateways.slice(); - }, - - getDnses: function(count) { - if (count) { - count.value = this.dnses.length; - } - return this.dnses.slice(); - } - } -}; - -// nsIEthernetManager - -/* - * Network state transition diagram - * - * ---------- enable --------- connect ----------- disconnect -------------- - * | Disabled | -----> | Enabled | -------> | Connected | <----------> | Disconnected | - * ---------- --------- ----------- connect -------------- - * ^ | | | - * | disable | | | - * ----------------------------------------------------------------------- - */ - -function EthernetManager() { - debug("EthernetManager start"); - - // Interface list. - this.ethernetInterfaces = {}; - - // Used to memorize last connection information. - this.lastStaticConfig = {}; - - Services.obs.addObserver(this, "xpcom-shutdown", false); -} - -EthernetManager.prototype = { - classID: Components.ID("a96441dd-36b3-4f7f-963b-2c032e28a039"), - QueryInterface: XPCOMUtils.generateQI([Ci.nsIEthernetManager]), - - ethernetInterfaces: null, - lastStaticConfig: null, - - observer: function(subject, topic, data) { - switch (topic) { - case "xpcom-shutdown": - debug("xpcom-shutdown"); - - this._shutdown(); - - Services.obs.removeObserver(this, "xpcom-shutdown"); - break; - } - }, - - _shutdown: function() { - debug("Shuting down"); - (function onRemove(ifnameList) { - if (!ifnameList.length) { - return; - } - - let ifname = ifnameList.shift(); - this.removeInterface(ifname, { notify: onRemove.bind(this, ifnameList) }); - }).call(this, Object.keys(this.ethernetInterfaces)); - }, - - get interfaceList() { - return Object.keys(this.ethernetInterfaces); - }, - - scan: function(callback) { - debug("Scan"); - - gNetworkService.getInterfaces(function(success, list) { - let ethList = []; - - if (!success) { - if (callback) { - callback.notify(ethList); - } - return; - } - - for (let i = 0; i < list.length; i++) { - debug("Found interface " + list[i]); - if (!list[i].startsWith(ETHERNET_NETWORK_IFACE_PREFIX)) { - continue; - } - ethList.push(list[i]); - } - - if (callback) { - callback.notify(ethList); - } - }); - }, - - addInterface: function(ifname, callback) { - debug("Add interface " + ifname); - - if (!ifname || !ifname.startsWith(ETHERNET_NETWORK_IFACE_PREFIX)) { - if (callback) { - callback.notify(false, "Invalid interface."); - } - return; - } - - if (this.ethernetInterfaces[ifname]) { - if (callback) { - callback.notify(true, "Interface already exists."); - } - return; - } - - gNetworkService.getInterfaceConfig(ifname, function(success, result) { - if (!success) { - if (callback) { - callback.notify(false, "Netd error."); - } - return; - } - - // Since the operation may still succeed with an invalid interface name, - // check the mac address as well. - if (result.macAddr == INTERFACE_MACADDR_NULL) { - if (callback) { - callback.notify(false, "Interface not found."); - } - return; - } - - this.ethernetInterfaces[ifname] = new EthernetInterface({ - state: result.link == NETWORK_INTERFACE_UP ? - Ci.nsINetworkInfo.NETWORK_STATE_DISABLED : - Ci.nsINetworkInfo.NETWORK_STATE_ENABLED, - name: ifname, - type: Ci.nsINetworkInfo.NETWORK_TYPE_ETHERNET, - ip: result.ip, - prefixLength: result.prefix, - ipMode: IP_MODE_DHCP - }); - - // Register the interface to NetworkManager. - gNetworkManager.registerNetworkInterface(this.ethernetInterfaces[ifname]); - - debug("Add interface " + ifname + " succeeded with " + - JSON.stringify(this.ethernetInterfaces[ifname])); - - if (callback) { - callback.notify(true, "ok"); - } - }.bind(this)); - }, - - removeInterface: function(ifname, callback) { - debug("Remove interface " + ifname); - - if (!ifname || !ifname.startsWith(ETHERNET_NETWORK_IFACE_PREFIX)) { - if (callback) { - callback.notify(false, "Invalid interface."); - } - return; - } - - if (!this.ethernetInterfaces[ifname]) { - if (callback) { - callback.notify(true, "Interface does not exist."); - } - return; - } - - // Make sure interface is disable before removing. - this.disable(ifname, { notify: function(success, message) { - // Unregister the interface from NetworkManager and also remove it from - // the interface list. - gNetworkManager.unregisterNetworkInterface(this.ethernetInterfaces[ifname]); - delete this.ethernetInterfaces[ifname]; - - debug("Remove interface " + ifname + " succeeded."); - - if (callback) { - callback.notify(true, "ok"); - } - }.bind(this)}); - }, - - updateInterfaceConfig: function(ifname, config, callback) { - debug("Update interface config with " + ifname); - - this._ensureIfname(ifname, callback, function(iface) { - if (!config) { - if (callback) { - callback.notify(false, "No config to update."); - } - return; - } - - // Network state can not be modified externally. - if (config.state) { - delete config.state; - } - - let currentIpMode = iface.info.ipMode; - - // Update config. - this.ethernetInterfaces[iface.info.name].updateConfig(config); - - // Do not automatically re-connect if the interface is not in connected - // state. - if (iface.info.state != Ci.nsINetworkInfo.NETWORK_STATE_CONNECTED) { - if (callback) { - callback.notify(true, "ok"); - } - return; - } - - let newIpMode = this.ethernetInterfaces[iface.info.name].info.ipMode; - - if (newIpMode == IP_MODE_STATIC) { - this._setStaticIP(iface.info.name, callback); - return; - } - if ((currentIpMode == IP_MODE_STATIC) && (newIpMode == IP_MODE_DHCP)) { - gNetworkService.stopDhcp(iface.info.name, function(success) { - if (success) { - debug("DHCP for " + iface.info.name + " stopped."); - } - }); - - // Clear the current network settings before do dhcp request, otherwise - // dhcp settings could fail. - this.disconnect(iface.info.name, { notify: function(success, message) { - if (!success) { - if (callback) { - callback.notify("Disconnect failed."); - } - return; - } - this._runDhcp(iface.info.name, callback); - }.bind(this) }); - return; - } - - if (callback) { - callback.notify(true, "ok"); - } - }.bind(this)); - }, - - enable: function(ifname, callback) { - debug("Enable interface " + ifname); - - this._ensureIfname(ifname, callback, function(iface) { - // Interface can be only enabled in the state of disabled. - if (iface.info.state != Ci.nsINetworkInfo.NETWORK_STATE_DISABLED) { - if (callback) { - callback.notify(true, "Interface already enabled."); - } - return; - } - - let ips = {}; - let prefixLengths = {}; - iface.info.getAddresses(ips, prefixLengths); - let config = { ifname: iface.info.name, - ip: ips.value[0], - prefix: prefixLengths.value[0], - link: NETWORK_INTERFACE_UP }; - gNetworkService.setInterfaceConfig(config, function(success) { - if (!success) { - if (callback) { - callback.notify(false, "Netd Error."); - } - return; - } - - this.ethernetInterfaces[iface.info.name].updateConfig({ - state: Ci.nsINetworkInfo.NETWORK_STATE_ENABLED - }); - - debug("Enable interface " + iface.info.name + " succeeded."); - - if (callback) { - callback.notify(true, "ok"); - } - }.bind(this)); - }.bind(this)); - }, - - disable: function(ifname, callback) { - debug("Disable interface " + ifname); - - this._ensureIfname(ifname, callback, function(iface) { - if (iface.info.state == Ci.nsINetworkInfo.NETWORK_STATE_DISABLED) { - if (callback) { - callback.notify(true, "Interface already disabled."); - } - return; - } - - if (iface.info.state == Ci.nsINetworkInfo.NETWORK_STATE_CONNECTED) { - gNetworkService.stopDhcp(iface.info.name, function(success) { - if (success) { - debug("DHCP for " + iface.info.name + " stopped."); - } - }); - } - - let ips = {}; - let prefixLengths = {}; - iface.info.getAddresses(ips, prefixLengths); - let config = { ifname: iface.info.name, - ip: ips.value[0], - prefix: prefixLengths.value[0], - link: NETWORK_INTERFACE_DOWN }; - gNetworkService.setInterfaceConfig(config, function(success) { - if (!success) { - if (callback) { - callback.notify(false, "Netd Error."); - } - return; - } - - this.ethernetInterfaces[iface.info.name].updateConfig({ - state: Ci.nsINetworkInfo.NETWORK_STATE_DISABLED - }); - - debug("Disable interface " + iface.info.name + " succeeded."); - - if (callback) { - callback.notify(true, "ok"); - } - }.bind(this)); - }.bind(this)); - }, - - connect: function(ifname, callback) { - debug("Connect interface " + ifname); - - this._ensureIfname(ifname, callback, function(iface) { - // Interface can only be connected in the state of enabled or - // disconnected. - if (iface.info.state == Ci.nsINetworkInfo.NETWORK_STATE_DISABLED || - iface.info.state == Ci.nsINetworkInfo.NETWORK_STATE_CONNECTED) { - if (callback) { - callback.notify(true, "Interface " + ifname + " is not available or " - + " already connected."); - } - return; - } - - if (iface.info.ipMode == IP_MODE_DHCP) { - this._runDhcp(iface.info.name, callback); - return; - } - - if (iface.info.ipMode == IP_MODE_STATIC) { - if (this._checkConfigNull(iface) && this.lastStaticConfig[iface.info.name]) { - debug("Connect with lastStaticConfig " + - JSON.stringify(this.lastStaticConfig[iface.info.name])); - this.ethernetInterfaces[iface.info.name].updateConfig( - this.lastStaticConfig[iface.info.name]); - } - this._setStaticIP(iface.info.name, callback); - return; - } - - if (callback) { - callback.notify(false, "IP mode is wrong or not set."); - } - }.bind(this)); - }, - - disconnect: function(ifname, callback) { - debug("Disconnect interface " + ifname); - - this._ensureIfname(ifname, callback, function(iface) { - // Interface can be only disconnected in the state of connected. - if (iface.info.state != Ci.nsINetworkInfo.NETWORK_STATE_CONNECTED) { - if (callback) { - callback.notify(true, "Interface is already disconnected"); - } - return; - } - - let config = { ifname: iface.info.name, - ip: INTERFACE_IPADDR_NULL, - prefix: INTERFACE_PREFIX_NULL, - link: NETWORK_INTERFACE_UP }; - gNetworkService.setInterfaceConfig(config, function(success) { - if (!success) { - if (callback) { - callback.notify(false, "Netd error."); - } - return; - } - - // Stop dhcp daemon. - gNetworkService.stopDhcp(iface.info.name, function(success) { - if (success) { - debug("DHCP for " + iface.info.name + " stopped."); - } - }); - - this.ethernetInterfaces[iface.info.name].updateConfig({ - state: Ci.nsINetworkInfo.NETWORK_STATE_DISCONNECTED, - ip: INTERFACE_IPADDR_NULL, - prefixLength: INTERFACE_PREFIX_NULL, - gateway: INTERFACE_GATEWAY_NULL - }); - - gNetworkManager.updateNetworkInterface(this.ethernetInterfaces[ifname]); - - debug("Disconnect interface " + iface.info.name + " succeeded."); - - if (callback) { - callback.notify(true, "ok"); - } - }.bind(this)); - }.bind(this)); - }, - - _checkConfigNull: function(iface) { - let ips = {}; - let prefixLengths = {}; - let gateways = iface.info.getGateways(); - iface.info.getAddresses(ips, prefixLengths); - - if (ips.value[0] == INTERFACE_IPADDR_NULL && - prefixLengths.value[0] == INTERFACE_PREFIX_NULL && - gateways[0] == INTERFACE_GATEWAY_NULL) { - return true; - } - - return false; - }, - - _ensureIfname: function(ifname, callback, func) { - // If no given ifname, use the default one. - if (!ifname) { - ifname = DEFAULT_ETHERNET_NETWORK_IFACE; - } - - let iface = this.ethernetInterfaces[ifname]; - if (!iface) { - if (callback) { - callback.notify(true, "Interface " + ifname + " is not available."); - } - return; - } - - func.call(this, iface); - }, - - _runDhcp: function(ifname, callback) { - debug("runDhcp with " + ifname); - - if (!this.ethernetInterfaces[ifname]) { - if (callback) { - callback.notify(false, "Invalid interface."); - } - return; - } - - gNetworkService.dhcpRequest(ifname, function(success, result) { - if (!success) { - if (callback) { - callback.notify(false, "DHCP failed."); - } - return; - } - - debug("DHCP succeeded with " + JSON.stringify(result)); - - // Clear last static network information when connecting with dhcp mode. - if (this.lastStaticConfig[ifname]) { - this.lastStaticConfig[ifname] = null; - } - - this.ethernetInterfaces[ifname].updateConfig({ - state: Ci.nsINetworkInfo.NETWORK_STATE_CONNECTED, - ip: result.ipaddr_str, - gateway: result.gateway_str, - prefixLength: result.prefixLength, - dnses: [result.dns1_str, result.dns2_str] - }); - - gNetworkManager.updateNetworkInterface(this.ethernetInterfaces[ifname]); - - debug("Connect interface " + ifname + " with DHCP succeeded."); - - if (callback) { - callback.notify(true, "ok"); - } - }.bind(this)); - }, - - _setStaticIP: function(ifname, callback) { - let iface = this.ethernetInterfaces[ifname]; - if (!iface) { - if (callback) { - callback.notify(false, "Invalid interface."); - } - return; - } - - let ips = {}; - let prefixLengths = {}; - iface.info.getAddresses(ips, prefixLengths); - - let config = { ifname: iface.info.name, - ip: ips.value[0], - prefix: prefixLengths.value[0], - link: NETWORK_INTERFACE_UP }; - gNetworkService.setInterfaceConfig(config, function(success) { - if (!success) { - if (callback) { - callback.notify(false, "Netd Error."); - } - return; - } - - // Keep the lastest static network information. - let ips = {}; - let prefixLengths = {}; - let gateways = iface.info.getGateways(); - iface.info.getAddresses(ips, prefixLengths); - - this.lastStaticConfig[iface.info.name] = { - ip: ips.value[0], - prefixLength: prefixLengths.value[0], - gateway: gateways[0] - }; - - this.ethernetInterfaces[ifname].updateConfig({ - state: Ci.nsINetworkInfo.NETWORK_STATE_CONNECTED, - }); - - gNetworkManager.updateNetworkInterface(this.ethernetInterfaces[ifname]); - - debug("Connect interface " + ifname + " with static ip succeeded."); - - if (callback) { - callback.notify(true, "ok"); - } - }.bind(this)); - }, -} - -this.NSGetFactory = XPCOMUtils.generateNSGetFactory([EthernetManager]); diff --git a/dom/network/EthernetManager.manifest b/dom/network/EthernetManager.manifest deleted file mode 100644 index d25a069e1..000000000 --- a/dom/network/EthernetManager.manifest +++ /dev/null @@ -1,2 +0,0 @@ -component {a96441dd-36b3-4f7f-963b-2c032e28a039} EthernetManager.js -contract @mozilla.org/ethernetManager;1 {a96441dd-36b3-4f7f-963b-2c032e28a039} diff --git a/dom/network/NetUtils.cpp b/dom/network/NetUtils.cpp deleted file mode 100644 index 78c5be802..000000000 --- a/dom/network/NetUtils.cpp +++ /dev/null @@ -1,200 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -#include "NetUtils.h" -#include <dlfcn.h> -#include <errno.h> -#include "prinit.h" -#include "mozilla/Assertions.h" -#include "nsDebug.h" -#include "SystemProperty.h" - -using mozilla::system::Property; - -static void* sNetUtilsLib; -static PRCallOnceType sInitNetUtilsLib; - -static PRStatus -InitNetUtilsLib() -{ - sNetUtilsLib = dlopen("/system/lib/libnetutils.so", RTLD_LAZY); - // We might fail to open the hardware lib. That's OK. - return PR_SUCCESS; -} - -static void* -GetNetUtilsLibHandle() -{ - PR_CallOnce(&sInitNetUtilsLib, InitNetUtilsLib); - return sNetUtilsLib; -} - -// static -void* -NetUtils::GetSharedLibrary() -{ - void* netLib = GetNetUtilsLibHandle(); - if (!netLib) { - NS_WARNING("No /system/lib/libnetutils.so"); - } - return netLib; -} - -// static -int32_t -NetUtils::SdkVersion() -{ - char propVersion[Property::VALUE_MAX_LENGTH]; - Property::Get("ro.build.version.sdk", propVersion, "0"); - int32_t version = strtol(propVersion, nullptr, 10); - return version; -} - -DEFINE_DLFUNC(ifc_enable, int32_t, const char*) -DEFINE_DLFUNC(ifc_disable, int32_t, const char*) -DEFINE_DLFUNC(ifc_configure, int32_t, const char*, in_addr_t, uint32_t, - in_addr_t, in_addr_t, in_addr_t) -DEFINE_DLFUNC(ifc_reset_connections, int32_t, const char*, const int32_t) -DEFINE_DLFUNC(ifc_set_default_route, int32_t, const char*, in_addr_t) -DEFINE_DLFUNC(ifc_add_route, int32_t, const char*, const char*, uint32_t, const char*) -DEFINE_DLFUNC(ifc_remove_route, int32_t, const char*, const char*, uint32_t, const char*) -DEFINE_DLFUNC(ifc_remove_host_routes, int32_t, const char*) -DEFINE_DLFUNC(ifc_remove_default_route, int32_t, const char*) -DEFINE_DLFUNC(dhcp_stop, int32_t, const char*) - -NetUtils::NetUtils() -{ -} - -int32_t NetUtils::do_ifc_enable(const char *ifname) -{ - USE_DLFUNC(ifc_enable) - return ifc_enable(ifname); -} - -int32_t NetUtils::do_ifc_disable(const char *ifname) -{ - USE_DLFUNC(ifc_disable) - return ifc_disable(ifname); -} - -int32_t NetUtils::do_ifc_configure(const char *ifname, - in_addr_t address, - uint32_t prefixLength, - in_addr_t gateway, - in_addr_t dns1, - in_addr_t dns2) -{ - USE_DLFUNC(ifc_configure) - int32_t ret = ifc_configure(ifname, address, prefixLength, gateway, dns1, dns2); - return ret; -} - -int32_t NetUtils::do_ifc_reset_connections(const char *ifname, - const int32_t resetMask) -{ - USE_DLFUNC(ifc_reset_connections) - return ifc_reset_connections(ifname, resetMask); -} - -int32_t NetUtils::do_ifc_set_default_route(const char *ifname, - in_addr_t gateway) -{ - USE_DLFUNC(ifc_set_default_route) - return ifc_set_default_route(ifname, gateway); -} - -int32_t NetUtils::do_ifc_add_route(const char *ifname, - const char *dst, - uint32_t prefixLength, - const char *gateway) -{ - USE_DLFUNC(ifc_add_route) - return ifc_add_route(ifname, dst, prefixLength, gateway); -} - -int32_t NetUtils::do_ifc_remove_route(const char *ifname, - const char *dst, - uint32_t prefixLength, - const char *gateway) -{ - USE_DLFUNC(ifc_remove_route) - return ifc_remove_route(ifname, dst, prefixLength, gateway); -} - -int32_t NetUtils::do_ifc_remove_host_routes(const char *ifname) -{ - USE_DLFUNC(ifc_remove_host_routes) - return ifc_remove_host_routes(ifname); -} - -int32_t NetUtils::do_ifc_remove_default_route(const char *ifname) -{ - USE_DLFUNC(ifc_remove_default_route) - return ifc_remove_default_route(ifname); -} - -int32_t NetUtils::do_dhcp_stop(const char *ifname) -{ - USE_DLFUNC(dhcp_stop) - return dhcp_stop(ifname); -} - -int32_t NetUtils::do_dhcp_do_request(const char *ifname, - char *ipaddr, - char *gateway, - uint32_t *prefixLength, - char *dns1, - char *dns2, - char *server, - uint32_t *lease, - char* vendorinfo) -{ - int32_t ret = -1; - uint32_t sdkVersion = SdkVersion(); - - if (sdkVersion == 15) { - // ICS - // http://androidxref.com/4.0.4/xref/system/core/libnetutils/dhcp_utils.c#149 - DEFINE_DLFUNC(dhcp_do_request, int32_t, const char*, char*, char*, uint32_t*, char*, char*, char*, uint32_t*) - USE_DLFUNC(dhcp_do_request) - vendorinfo[0] = '\0'; - - ret = dhcp_do_request(ifname, ipaddr, gateway, prefixLength, dns1, dns2, - server, lease); - } else if (sdkVersion == 16 || sdkVersion == 17) { - // JB 4.1 and 4.2 - // http://androidxref.com/4.1.2/xref/system/core/libnetutils/dhcp_utils.c#175 - // http://androidxref.com/4.2.2_r1/xref/system/core/include/netutils/dhcp.h#26 - DEFINE_DLFUNC(dhcp_do_request, int32_t, const char*, char*, char*, uint32_t*, char*, char*, char*, uint32_t*, char*) - USE_DLFUNC(dhcp_do_request) - ret = dhcp_do_request(ifname, ipaddr, gateway, prefixLength, dns1, dns2, - server, lease, vendorinfo); - } else if (sdkVersion == 18) { - // JB 4.3 - // http://androidxref.com/4.3_r2.1/xref/system/core/libnetutils/dhcp_utils.c#181 - DEFINE_DLFUNC(dhcp_do_request, int32_t, const char*, char*, char*, uint32_t*, char**, char*, uint32_t*, char*, char*) - USE_DLFUNC(dhcp_do_request) - char *dns[3] = {dns1, dns2, nullptr}; - char domains[Property::VALUE_MAX_LENGTH]; - ret = dhcp_do_request(ifname, ipaddr, gateway, prefixLength, dns, - server, lease, vendorinfo, domains); - } else if (sdkVersion >= 19) { - // KitKat 4.4.X - // http://androidxref.com/4.4_r1/xref/system/core/libnetutils/dhcp_utils.c#18 - // Lollipop 5.0 - //http://androidxref.com/5.0.0_r2/xref/system/core/libnetutils/dhcp_utils.c#186 - DEFINE_DLFUNC(dhcp_do_request, int32_t, const char*, char*, char*, uint32_t*, char**, char*, uint32_t*, char*, char*, char*) - USE_DLFUNC(dhcp_do_request) - char *dns[3] = {dns1, dns2, nullptr}; - char domains[Property::VALUE_MAX_LENGTH]; - char mtu[Property::VALUE_MAX_LENGTH]; - ret = dhcp_do_request(ifname, ipaddr, gateway, prefixLength, dns, server, lease, vendorinfo, domains, mtu); - } else { - NS_WARNING("Unable to perform do_dhcp_request: unsupported sdk version!"); - } - return ret; -} diff --git a/dom/network/NetUtils.h b/dom/network/NetUtils.h deleted file mode 100644 index 4af365406..000000000 --- a/dom/network/NetUtils.h +++ /dev/null @@ -1,75 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/** - * Abstraction on top of the network support from libnetutils that we - * use to set up network connections. - */ - -#ifndef NetUtils_h -#define NetUtils_h - -#include "arpa/inet.h" - -// Copied from ifc.h -#define RESET_IPV4_ADDRESSES 0x01 -#define RESET_IPV6_ADDRESSES 0x02 -#define RESET_ALL_ADDRESSES (RESET_IPV4_ADDRESSES | RESET_IPV6_ADDRESSES) - -// Implements netutils functions. No need for an abstract class here since we -// only have a one sdk specific method (dhcp_do_request) -class NetUtils -{ -public: - static void* GetSharedLibrary(); - - NetUtils(); - - int32_t do_ifc_enable(const char *ifname); - int32_t do_ifc_disable(const char *ifname); - int32_t do_ifc_configure(const char *ifname, - in_addr_t address, - uint32_t prefixLength, - in_addr_t gateway, - in_addr_t dns1, - in_addr_t dns2); - int32_t do_ifc_reset_connections(const char *ifname, const int32_t resetMask); - int32_t do_ifc_set_default_route(const char *ifname, in_addr_t gateway); - int32_t do_ifc_add_route(const char *ifname, - const char *dst, - uint32_t prefixLength, - const char *gateway); - int32_t do_ifc_remove_route(const char *ifname, - const char *dst, - uint32_t prefixLength, - const char *gateway); - int32_t do_ifc_remove_host_routes(const char *ifname); - int32_t do_ifc_remove_default_route(const char *ifname); - int32_t do_dhcp_stop(const char *ifname); - int32_t do_dhcp_do_request(const char *ifname, - char *ipaddr, - char *gateway, - uint32_t *prefixLength, - char *dns1, - char *dns2, - char *server, - uint32_t *lease, - char* vendorinfo); - - static int32_t SdkVersion(); -}; - -// Defines a function type with the right arguments and return type. -#define DEFINE_DLFUNC(name, ret, args...) typedef ret (*FUNC##name)(args); - -// Set up a dlsymed function ready to use. -#define USE_DLFUNC(name) \ - FUNC##name name = (FUNC##name) dlsym(GetSharedLibrary(), #name); \ - if (!name) { \ - MOZ_CRASH("Symbol not found in shared library : " #name); \ - } - -#endif // NetUtils_h diff --git a/dom/network/NetworkStatsDB.jsm b/dom/network/NetworkStatsDB.jsm deleted file mode 100644 index aa74d40ad..000000000 --- a/dom/network/NetworkStatsDB.jsm +++ /dev/null @@ -1,1285 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -"use strict"; - -this.EXPORTED_SYMBOLS = ['NetworkStatsDB']; - -const DEBUG = false; -function debug(s) { dump("-*- NetworkStatsDB: " + s + "\n"); } - -const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components; - -Cu.import("resource://gre/modules/XPCOMUtils.jsm"); -Cu.import("resource://gre/modules/Services.jsm"); -Cu.import("resource://gre/modules/IndexedDBHelper.jsm"); -Cu.importGlobalProperties(["indexedDB"]); - -XPCOMUtils.defineLazyServiceGetter(this, "appsService", - "@mozilla.org/AppsService;1", - "nsIAppsService"); - -const DB_NAME = "net_stats"; -const DB_VERSION = 9; -const DEPRECATED_STATS_STORE_NAME = - [ - "net_stats_v2", // existed only in DB version 2 - "net_stats", // existed in DB version 1 and 3 to 5 - "net_stats_store", // existed in DB version 6 to 8 - ]; -const STATS_STORE_NAME = "net_stats_store_v3"; // since DB version 9 -const ALARMS_STORE_NAME = "net_alarm"; - -// Constant defining the maximum values allowed per interface. If more, older -// will be erased. -const VALUES_MAX_LENGTH = 6 * 30; - -// Constant defining the rate of the samples. Daily. -const SAMPLE_RATE = 1000 * 60 * 60 * 24; - -this.NetworkStatsDB = function NetworkStatsDB() { - if (DEBUG) { - debug("Constructor"); - } - this.initDBHelper(DB_NAME, DB_VERSION, [STATS_STORE_NAME, ALARMS_STORE_NAME]); -} - -NetworkStatsDB.prototype = { - __proto__: IndexedDBHelper.prototype, - - dbNewTxn: function dbNewTxn(store_name, txn_type, callback, txnCb) { - function successCb(result) { - txnCb(null, result); - } - function errorCb(error) { - txnCb(error, null); - } - return this.newTxn(txn_type, store_name, callback, successCb, errorCb); - }, - - /** - * The onupgradeneeded handler of the IDBOpenDBRequest. - * This function is called in IndexedDBHelper open() method. - * - * @param {IDBTransaction} aTransaction - * {IDBDatabase} aDb - * {64-bit integer} aOldVersion The version number on local storage. - * {64-bit integer} aNewVersion The version number to be upgraded to. - * - * @note Be careful with the database upgrade pattern. - * Because IndexedDB operations are performed asynchronously, we must - * apply a recursive approach instead of an iterative approach while - * upgrading versions. - */ - upgradeSchema: function upgradeSchema(aTransaction, aDb, aOldVersion, aNewVersion) { - if (DEBUG) { - debug("upgrade schema from: " + aOldVersion + " to " + aNewVersion + " called!"); - } - let db = aDb; - let objectStore; - - // An array of upgrade functions for each version. - let upgradeSteps = [ - function upgrade0to1() { - if (DEBUG) debug("Upgrade 0 to 1: Create object stores and indexes."); - - // Create the initial database schema. - objectStore = db.createObjectStore(DEPRECATED_STATS_STORE_NAME[1], - { keyPath: ["connectionType", "timestamp"] }); - objectStore.createIndex("connectionType", "connectionType", { unique: false }); - objectStore.createIndex("timestamp", "timestamp", { unique: false }); - objectStore.createIndex("rxBytes", "rxBytes", { unique: false }); - objectStore.createIndex("txBytes", "txBytes", { unique: false }); - objectStore.createIndex("rxTotalBytes", "rxTotalBytes", { unique: false }); - objectStore.createIndex("txTotalBytes", "txTotalBytes", { unique: false }); - - upgradeNextVersion(); - }, - - function upgrade1to2() { - if (DEBUG) debug("Upgrade 1 to 2: Do nothing."); - upgradeNextVersion(); - }, - - function upgrade2to3() { - if (DEBUG) debug("Upgrade 2 to 3: Add keyPath appId to object store."); - - // In order to support per-app traffic data storage, the original - // objectStore needs to be replaced by a new objectStore with new - // key path ("appId") and new index ("appId"). - // Also, since now networks are identified by their - // [networkId, networkType] not just by their connectionType, - // to modify the keyPath is mandatory to delete the object store - // and create it again. Old data is going to be deleted because the - // networkId for each sample can not be set. - - // In version 1.2 objectStore name was 'net_stats_v2', to avoid errors when - // upgrading from 1.2 to 1.3 objectStore name should be checked. - let stores = db.objectStoreNames; - let deprecatedName = DEPRECATED_STATS_STORE_NAME[0]; - let storeName = DEPRECATED_STATS_STORE_NAME[1]; - if(stores.contains(deprecatedName)) { - // Delete the obsolete stats store. - db.deleteObjectStore(deprecatedName); - } else { - // Re-create stats object store without copying records. - db.deleteObjectStore(storeName); - } - - objectStore = db.createObjectStore(storeName, { keyPath: ["appId", "network", "timestamp"] }); - objectStore.createIndex("appId", "appId", { unique: false }); - objectStore.createIndex("network", "network", { unique: false }); - objectStore.createIndex("networkType", "networkType", { unique: false }); - objectStore.createIndex("timestamp", "timestamp", { unique: false }); - objectStore.createIndex("rxBytes", "rxBytes", { unique: false }); - objectStore.createIndex("txBytes", "txBytes", { unique: false }); - objectStore.createIndex("rxTotalBytes", "rxTotalBytes", { unique: false }); - objectStore.createIndex("txTotalBytes", "txTotalBytes", { unique: false }); - - upgradeNextVersion(); - }, - - function upgrade3to4() { - if (DEBUG) debug("Upgrade 3 to 4: Delete redundant indexes."); - - // Delete redundant indexes (leave "network" only). - objectStore = aTransaction.objectStore(DEPRECATED_STATS_STORE_NAME[1]); - if (objectStore.indexNames.contains("appId")) { - objectStore.deleteIndex("appId"); - } - if (objectStore.indexNames.contains("networkType")) { - objectStore.deleteIndex("networkType"); - } - if (objectStore.indexNames.contains("timestamp")) { - objectStore.deleteIndex("timestamp"); - } - if (objectStore.indexNames.contains("rxBytes")) { - objectStore.deleteIndex("rxBytes"); - } - if (objectStore.indexNames.contains("txBytes")) { - objectStore.deleteIndex("txBytes"); - } - if (objectStore.indexNames.contains("rxTotalBytes")) { - objectStore.deleteIndex("rxTotalBytes"); - } - if (objectStore.indexNames.contains("txTotalBytes")) { - objectStore.deleteIndex("txTotalBytes"); - } - - upgradeNextVersion(); - }, - - function upgrade4to5() { - if (DEBUG) debug("Upgrade 4 to 5: Create object store for alarms."); - - // In order to manage alarms, it is necessary to use a global counter - // (totalBytes) that will increase regardless of the system reboot. - objectStore = aTransaction.objectStore(DEPRECATED_STATS_STORE_NAME[1]); - - // Now, systemBytes will hold the old totalBytes and totalBytes will - // keep the increasing counter. |counters| will keep the track of - // accumulated values. - let counters = {}; - - objectStore.openCursor().onsuccess = function(event) { - let cursor = event.target.result; - if (!cursor){ - // upgrade4to5 completed now. - upgradeNextVersion(); - return; - } - - cursor.value.rxSystemBytes = cursor.value.rxTotalBytes; - cursor.value.txSystemBytes = cursor.value.txTotalBytes; - - if (cursor.value.appId == 0) { - let netId = cursor.value.network[0] + '' + cursor.value.network[1]; - if (!counters[netId]) { - counters[netId] = { - rxCounter: 0, - txCounter: 0, - lastRx: 0, - lastTx: 0 - }; - } - - let rxDiff = cursor.value.rxSystemBytes - counters[netId].lastRx; - let txDiff = cursor.value.txSystemBytes - counters[netId].lastTx; - if (rxDiff < 0 || txDiff < 0) { - // System reboot between samples, so take the current one. - rxDiff = cursor.value.rxSystemBytes; - txDiff = cursor.value.txSystemBytes; - } - - counters[netId].rxCounter += rxDiff; - counters[netId].txCounter += txDiff; - cursor.value.rxTotalBytes = counters[netId].rxCounter; - cursor.value.txTotalBytes = counters[netId].txCounter; - - counters[netId].lastRx = cursor.value.rxSystemBytes; - counters[netId].lastTx = cursor.value.txSystemBytes; - } else { - cursor.value.rxTotalBytes = cursor.value.rxSystemBytes; - cursor.value.txTotalBytes = cursor.value.txSystemBytes; - } - - cursor.update(cursor.value); - cursor.continue(); - }; - - // Create object store for alarms. - objectStore = db.createObjectStore(ALARMS_STORE_NAME, { keyPath: "id", autoIncrement: true }); - objectStore.createIndex("alarm", ['networkId','threshold'], { unique: false }); - objectStore.createIndex("manifestURL", "manifestURL", { unique: false }); - }, - - function upgrade5to6() { - if (DEBUG) debug("Upgrade 5 to 6: Add keyPath serviceType to object store."); - - // In contrast to "per-app" traffic data, "system-only" traffic data - // refers to data which can not be identified by any applications. - // To further support "system-only" data storage, the data can be - // saved by service type (e.g., Tethering, OTA). Thus it's needed to - // have a new key ("serviceType") for the ojectStore. - let newObjectStore; - let deprecatedName = DEPRECATED_STATS_STORE_NAME[1]; - newObjectStore = db.createObjectStore(DEPRECATED_STATS_STORE_NAME[2], - { keyPath: ["appId", "serviceType", "network", "timestamp"] }); - newObjectStore.createIndex("network", "network", { unique: false }); - - // Copy the data from the original objectStore to the new objectStore. - objectStore = aTransaction.objectStore(deprecatedName); - objectStore.openCursor().onsuccess = function(event) { - let cursor = event.target.result; - if (!cursor) { - db.deleteObjectStore(deprecatedName); - // upgrade5to6 completed now. - upgradeNextVersion(); - return; - } - - let newStats = cursor.value; - newStats.serviceType = ""; - newObjectStore.put(newStats); - cursor.continue(); - }; - }, - - function upgrade6to7() { - if (DEBUG) debug("Upgrade 6 to 7: Replace alarm threshold by relativeThreshold."); - - // Replace threshold attribute of alarm index by relativeThreshold in alarms DB. - // Now alarms are indexed by relativeThreshold, which is the threshold relative - // to current system stats. - let alarmsStore = aTransaction.objectStore(ALARMS_STORE_NAME); - - // Delete "alarm" index. - if (alarmsStore.indexNames.contains("alarm")) { - alarmsStore.deleteIndex("alarm"); - } - - // Create new "alarm" index. - alarmsStore.createIndex("alarm", ['networkId','relativeThreshold'], { unique: false }); - - // Populate new "alarm" index attributes. - alarmsStore.openCursor().onsuccess = function(event) { - let cursor = event.target.result; - if (!cursor) { - upgrade6to7_updateTotalBytes(); - return; - } - - cursor.value.relativeThreshold = cursor.value.threshold; - cursor.value.absoluteThreshold = cursor.value.threshold; - delete cursor.value.threshold; - - cursor.update(cursor.value); - cursor.continue(); - } - - function upgrade6to7_updateTotalBytes() { - if (DEBUG) debug("Upgrade 6 to 7: Update TotalBytes."); - // Previous versions save accumulative totalBytes, increasing although the system - // reboots or resets stats. But is necessary to reset the total counters when reset - // through 'clearInterfaceStats'. - let statsStore = aTransaction.objectStore(DEPRECATED_STATS_STORE_NAME[2]); - let networks = []; - - // Find networks stored in the database. - statsStore.index("network").openKeyCursor(null, "nextunique").onsuccess = function(event) { - let cursor = event.target.result; - - // Store each network into an array. - if (cursor) { - networks.push(cursor.key); - cursor.continue(); - return; - } - - // Start to deal with each network. - let pending = networks.length; - - if (pending === 0) { - // Found no records of network. upgrade6to7 completed now. - upgradeNextVersion(); - return; - } - - networks.forEach(function(network) { - let lowerFilter = [0, "", network, 0]; - let upperFilter = [0, "", network, ""]; - let range = IDBKeyRange.bound(lowerFilter, upperFilter, false, false); - - // Find number of samples for a given network. - statsStore.count(range).onsuccess = function(event) { - let recordCount = event.target.result; - - // If there are more samples than the max allowed, there is no way to know - // when does reset take place. - if (recordCount === 0 || recordCount >= VALUES_MAX_LENGTH) { - pending--; - if (pending === 0) { - upgradeNextVersion(); - } - return; - } - - let last = null; - // Reset detected if the first sample totalCounters are different than bytes - // counters. If so, the total counters should be recalculated. - statsStore.openCursor(range).onsuccess = function(event) { - let cursor = event.target.result; - if (!cursor) { - pending--; - if (pending === 0) { - upgradeNextVersion(); - } - return; - } - if (!last) { - if (cursor.value.rxTotalBytes == cursor.value.rxBytes && - cursor.value.txTotalBytes == cursor.value.txBytes) { - pending--; - if (pending === 0) { - upgradeNextVersion(); - } - return; - } - - cursor.value.rxTotalBytes = cursor.value.rxBytes; - cursor.value.txTotalBytes = cursor.value.txBytes; - cursor.update(cursor.value); - last = cursor.value; - cursor.continue(); - return; - } - - // Recalculate the total counter for last / current sample - cursor.value.rxTotalBytes = last.rxTotalBytes + cursor.value.rxBytes; - cursor.value.txTotalBytes = last.txTotalBytes + cursor.value.txBytes; - cursor.update(cursor.value); - last = cursor.value; - cursor.continue(); - } - } - }, this); // end of networks.forEach() - }; // end of statsStore.index("network").openKeyCursor().onsuccess callback - } // end of function upgrade6to7_updateTotalBytes - }, - - function upgrade7to8() { - if (DEBUG) debug("Upgrade 7 to 8: Create index serviceType."); - - // Create index for 'ServiceType' in order to make it retrievable. - let statsStore = aTransaction.objectStore(DEPRECATED_STATS_STORE_NAME[2]); - statsStore.createIndex("serviceType", "serviceType", { unique: false }); - - upgradeNextVersion(); - }, - - function upgrade8to9() { - if (DEBUG) debug("Upgrade 8 to 9: Add keyPath isInBrowser to " + - "network stats object store"); - - // Since B2G v2.0, there is no stand-alone browser app anymore. - // The browser app is a mozbrowser iframe element owned by system app. - // In order to separate traffic generated from system and browser, we - // have to add a new attribute |isInBrowser| as keyPath. - // Refer to bug 1070944 for more detail. - let newObjectStore; - let deprecatedName = DEPRECATED_STATS_STORE_NAME[2]; - newObjectStore = db.createObjectStore(STATS_STORE_NAME, - { keyPath: ["appId", "isInBrowser", "serviceType", - "network", "timestamp"] }); - newObjectStore.createIndex("network", "network", { unique: false }); - newObjectStore.createIndex("serviceType", "serviceType", { unique: false }); - - // Copy records from the current object store to the new one. - objectStore = aTransaction.objectStore(deprecatedName); - objectStore.openCursor().onsuccess = function (event) { - let cursor = event.target.result; - if (!cursor) { - db.deleteObjectStore(deprecatedName); - // upgrade8to9 completed now. - return; - } - let newStats = cursor.value; - // Augment records by adding the new isInBrowser attribute. - // Notes: - // 1. Key value cannot be boolean type. Use 1/0 instead of true/false. - // 2. Most traffic of system app should come from its browser iframe, - // thus assign isInBrowser as 1 for system app. - let manifestURL = appsService.getManifestURLByLocalId(newStats.appId); - if (manifestURL && manifestURL.search(/app:\/\/system\./) === 0) { - newStats.isInBrowser = 1; - } else { - newStats.isInBrowser = 0; - } - newObjectStore.put(newStats); - cursor.continue(); - }; - } - ]; - - let index = aOldVersion; - let outer = this; - - function upgradeNextVersion() { - if (index == aNewVersion) { - debug("Upgrade finished."); - return; - } - - try { - var i = index++; - if (DEBUG) debug("Upgrade step: " + i + "\n"); - upgradeSteps[i].call(outer); - } catch (ex) { - dump("Caught exception " + ex); - throw ex; - return; - } - } - - if (aNewVersion > upgradeSteps.length) { - debug("No migration steps for the new version!"); - aTransaction.abort(); - return; - } - - upgradeNextVersion(); - }, - - importData: function importData(aStats) { - let stats = { appId: aStats.appId, - isInBrowser: aStats.isInBrowser ? 1 : 0, - serviceType: aStats.serviceType, - network: [aStats.networkId, aStats.networkType], - timestamp: aStats.timestamp, - rxBytes: aStats.rxBytes, - txBytes: aStats.txBytes, - rxSystemBytes: aStats.rxSystemBytes, - txSystemBytes: aStats.txSystemBytes, - rxTotalBytes: aStats.rxTotalBytes, - txTotalBytes: aStats.txTotalBytes }; - - return stats; - }, - - exportData: function exportData(aStats) { - let stats = { appId: aStats.appId, - isInBrowser: aStats.isInBrowser ? true : false, - serviceType: aStats.serviceType, - networkId: aStats.network[0], - networkType: aStats.network[1], - timestamp: aStats.timestamp, - rxBytes: aStats.rxBytes, - txBytes: aStats.txBytes, - rxTotalBytes: aStats.rxTotalBytes, - txTotalBytes: aStats.txTotalBytes }; - - return stats; - }, - - normalizeDate: function normalizeDate(aDate) { - // Convert to UTC according to timezone and - // filter timestamp to get SAMPLE_RATE precission - let timestamp = aDate.getTime() - aDate.getTimezoneOffset() * 60 * 1000; - timestamp = Math.floor(timestamp / SAMPLE_RATE) * SAMPLE_RATE; - return timestamp; - }, - - saveStats: function saveStats(aStats, aResultCb) { - let isAccumulative = aStats.isAccumulative; - let timestamp = this.normalizeDate(aStats.date); - - let stats = { appId: aStats.appId, - isInBrowser: aStats.isInBrowser, - serviceType: aStats.serviceType, - networkId: aStats.networkId, - networkType: aStats.networkType, - timestamp: timestamp, - rxBytes: isAccumulative ? 0 : aStats.rxBytes, - txBytes: isAccumulative ? 0 : aStats.txBytes, - rxSystemBytes: isAccumulative ? aStats.rxBytes : 0, - txSystemBytes: isAccumulative ? aStats.txBytes : 0, - rxTotalBytes: isAccumulative ? aStats.rxBytes : 0, - txTotalBytes: isAccumulative ? aStats.txBytes : 0 }; - - stats = this.importData(stats); - - this.dbNewTxn(STATS_STORE_NAME, "readwrite", function(aTxn, aStore) { - if (DEBUG) { - debug("Filtered time: " + new Date(timestamp)); - debug("New stats: " + JSON.stringify(stats)); - } - - let lowerFilter = [stats.appId, stats.isInBrowser, stats.serviceType, - stats.network, 0]; - let upperFilter = [stats.appId, stats.isInBrowser, stats.serviceType, - stats.network, ""]; - let range = IDBKeyRange.bound(lowerFilter, upperFilter, false, false); - - let request = aStore.openCursor(range, 'prev'); - request.onsuccess = function onsuccess(event) { - let cursor = event.target.result; - if (!cursor) { - // Empty, so save first element. - - if (!isAccumulative) { - this._saveStats(aTxn, aStore, stats); - return; - } - - // There could be a time delay between the point when the network - // interface comes up and the point when the database is initialized. - // In this short interval some traffic data are generated but are not - // registered by the first sample. - stats.rxBytes = stats.rxTotalBytes; - stats.txBytes = stats.txTotalBytes; - - // However, if the interface is not switched on after the database is - // initialized (dual sim use case) stats should be set to 0. - let req = aStore.index("network").openKeyCursor(null, "nextunique"); - req.onsuccess = function onsuccess(event) { - let cursor = event.target.result; - if (cursor) { - if (cursor.key[1] == stats.network[1]) { - stats.rxBytes = 0; - stats.txBytes = 0; - this._saveStats(aTxn, aStore, stats); - return; - } - - cursor.continue(); - return; - } - - this._saveStats(aTxn, aStore, stats); - }.bind(this); - - return; - } - - // There are old samples - if (DEBUG) { - debug("Last value " + JSON.stringify(cursor.value)); - } - - // Remove stats previous to now - VALUE_MAX_LENGTH - this._removeOldStats(aTxn, aStore, stats.appId, stats.isInBrowser, - stats.serviceType, stats.network, stats.timestamp); - - // Process stats before save - this._processSamplesDiff(aTxn, aStore, cursor, stats, isAccumulative); - }.bind(this); - }.bind(this), aResultCb); - }, - - /* - * This function check that stats are saved in the database following the sample rate. - * In this way is easier to find elements when stats are requested. - */ - _processSamplesDiff: function _processSamplesDiff(aTxn, - aStore, - aLastSampleCursor, - aNewSample, - aIsAccumulative) { - let lastSample = aLastSampleCursor.value; - - // Get difference between last and new sample. - let diff = (aNewSample.timestamp - lastSample.timestamp) / SAMPLE_RATE; - if (diff % 1) { - // diff is decimal, so some error happened because samples are stored as a multiple - // of SAMPLE_RATE - aTxn.abort(); - throw new Error("Error processing samples"); - } - - if (DEBUG) { - debug("New: " + aNewSample.timestamp + " - Last: " + - lastSample.timestamp + " - diff: " + diff); - } - - // If the incoming data has a accumulation feature, the new - // |txBytes|/|rxBytes| is assigend by differnces between the new - // |txTotalBytes|/|rxTotalBytes| and the last |txTotalBytes|/|rxTotalBytes|. - // Else, if incoming data is non-accumulative, the |txBytes|/|rxBytes| - // is the new |txBytes|/|rxBytes|. - let rxDiff = 0; - let txDiff = 0; - if (aIsAccumulative) { - rxDiff = aNewSample.rxSystemBytes - lastSample.rxSystemBytes; - txDiff = aNewSample.txSystemBytes - lastSample.txSystemBytes; - if (rxDiff < 0 || txDiff < 0) { - rxDiff = aNewSample.rxSystemBytes; - txDiff = aNewSample.txSystemBytes; - } - aNewSample.rxBytes = rxDiff; - aNewSample.txBytes = txDiff; - - aNewSample.rxTotalBytes = lastSample.rxTotalBytes + rxDiff; - aNewSample.txTotalBytes = lastSample.txTotalBytes + txDiff; - } else { - rxDiff = aNewSample.rxBytes; - txDiff = aNewSample.txBytes; - } - - if (diff == 1) { - // New element. - - // If the incoming data is non-accumulative, the new - // |rxTotalBytes|/|txTotalBytes| needs to be updated by adding new - // |rxBytes|/|txBytes| to the last |rxTotalBytes|/|txTotalBytes|. - if (!aIsAccumulative) { - aNewSample.rxTotalBytes = aNewSample.rxBytes + lastSample.rxTotalBytes; - aNewSample.txTotalBytes = aNewSample.txBytes + lastSample.txTotalBytes; - } - - this._saveStats(aTxn, aStore, aNewSample); - return; - } - if (diff > 1) { - // Some samples lost. Device off during one or more samplerate periods. - // Time or timezone changed - // Add lost samples with 0 bytes and the actual one. - if (diff > VALUES_MAX_LENGTH) { - diff = VALUES_MAX_LENGTH; - } - - let data = []; - for (let i = diff - 2; i >= 0; i--) { - let time = aNewSample.timestamp - SAMPLE_RATE * (i + 1); - let sample = { appId: aNewSample.appId, - isInBrowser: aNewSample.isInBrowser, - serviceType: aNewSample.serviceType, - network: aNewSample.network, - timestamp: time, - rxBytes: 0, - txBytes: 0, - rxSystemBytes: lastSample.rxSystemBytes, - txSystemBytes: lastSample.txSystemBytes, - rxTotalBytes: lastSample.rxTotalBytes, - txTotalBytes: lastSample.txTotalBytes }; - - data.push(sample); - } - - data.push(aNewSample); - this._saveStats(aTxn, aStore, data); - return; - } - if (diff == 0 || diff < 0) { - // New element received before samplerate period. It means that device has - // been restarted (or clock / timezone change). - // Update element. If diff < 0, clock or timezone changed back. Place data - // in the last sample. - - // Old |rxTotalBytes|/|txTotalBytes| needs to get updated by adding the - // last |rxTotalBytes|/|txTotalBytes|. - lastSample.rxBytes += rxDiff; - lastSample.txBytes += txDiff; - lastSample.rxSystemBytes = aNewSample.rxSystemBytes; - lastSample.txSystemBytes = aNewSample.txSystemBytes; - lastSample.rxTotalBytes += rxDiff; - lastSample.txTotalBytes += txDiff; - - if (DEBUG) { - debug("Update: " + JSON.stringify(lastSample)); - } - let req = aLastSampleCursor.update(lastSample); - } - }, - - _saveStats: function _saveStats(aTxn, aStore, aNetworkStats) { - if (DEBUG) { - debug("_saveStats: " + JSON.stringify(aNetworkStats)); - } - - if (Array.isArray(aNetworkStats)) { - let len = aNetworkStats.length - 1; - for (let i = 0; i <= len; i++) { - aStore.put(aNetworkStats[i]); - } - } else { - aStore.put(aNetworkStats); - } - }, - - _removeOldStats: function _removeOldStats(aTxn, aStore, aAppId, aIsInBrowser, - aServiceType, aNetwork, aDate) { - // Callback function to remove old items when new ones are added. - let filterDate = aDate - (SAMPLE_RATE * VALUES_MAX_LENGTH - 1); - let lowerFilter = [aAppId, aIsInBrowser, aServiceType, aNetwork, 0]; - let upperFilter = [aAppId, aIsInBrowser, aServiceType, aNetwork, filterDate]; - let range = IDBKeyRange.bound(lowerFilter, upperFilter, false, false); - let lastSample = null; - let self = this; - - aStore.openCursor(range).onsuccess = function(event) { - var cursor = event.target.result; - if (cursor) { - lastSample = cursor.value; - cursor.delete(); - cursor.continue(); - return; - } - - // If all samples for a network are removed, an empty sample - // has to be saved to keep the totalBytes in order to compute - // future samples because system counters are not set to 0. - // Thus, if there are no samples left, the last sample removed - // will be saved again after setting its bytes to 0. - let request = aStore.index("network").openCursor(aNetwork); - request.onsuccess = function onsuccess(event) { - let cursor = event.target.result; - if (!cursor && lastSample != null) { - let timestamp = new Date(); - timestamp = self.normalizeDate(timestamp); - lastSample.timestamp = timestamp; - lastSample.rxBytes = 0; - lastSample.txBytes = 0; - self._saveStats(aTxn, aStore, lastSample); - } - }; - }; - }, - - clearInterfaceStats: function clearInterfaceStats(aNetwork, aResultCb) { - let network = [aNetwork.network.id, aNetwork.network.type]; - let self = this; - - // Clear and save an empty sample to keep sync with system counters - this.dbNewTxn(STATS_STORE_NAME, "readwrite", function(aTxn, aStore) { - let sample = null; - let request = aStore.index("network").openCursor(network, "prev"); - request.onsuccess = function onsuccess(event) { - let cursor = event.target.result; - if (cursor) { - if (!sample && cursor.value.appId == 0) { - sample = cursor.value; - } - - cursor.delete(); - cursor.continue(); - return; - } - - if (sample) { - let timestamp = new Date(); - timestamp = self.normalizeDate(timestamp); - sample.timestamp = timestamp; - sample.appId = 0; - sample.isInBrowser = 0; - sample.serviceType = ""; - sample.rxBytes = 0; - sample.txBytes = 0; - sample.rxTotalBytes = 0; - sample.txTotalBytes = 0; - - self._saveStats(aTxn, aStore, sample); - } - }; - }, this._resetAlarms.bind(this, aNetwork.networkId, aResultCb)); - }, - - clearStats: function clearStats(aNetworks, aResultCb) { - let index = 0; - let stats = []; - let self = this; - - let callback = function(aError, aResult) { - index++; - - if (!aError && index < aNetworks.length) { - self.clearInterfaceStats(aNetworks[index], callback); - return; - } - - aResultCb(aError, aResult); - }; - - if (!aNetworks[index]) { - aResultCb(null, true); - return; - } - this.clearInterfaceStats(aNetworks[index], callback); - }, - - getCurrentStats: function getCurrentStats(aNetwork, aDate, aResultCb) { - if (DEBUG) { - debug("Get current stats for " + JSON.stringify(aNetwork) + " since " + aDate); - } - - let network = [aNetwork.id, aNetwork.type]; - if (aDate) { - this._getCurrentStatsFromDate(network, aDate, aResultCb); - return; - } - - this._getCurrentStats(network, aResultCb); - }, - - _getCurrentStats: function _getCurrentStats(aNetwork, aResultCb) { - this.dbNewTxn(STATS_STORE_NAME, "readonly", function(txn, store) { - let request = null; - let upperFilter = [0, 1, "", aNetwork, Date.now()]; - let range = IDBKeyRange.upperBound(upperFilter, false); - let result = { rxBytes: 0, txBytes: 0, - rxTotalBytes: 0, txTotalBytes: 0 }; - - request = store.openCursor(range, "prev"); - - request.onsuccess = function onsuccess(event) { - let cursor = event.target.result; - if (cursor) { - result.rxBytes = result.rxTotalBytes = cursor.value.rxTotalBytes; - result.txBytes = result.txTotalBytes = cursor.value.txTotalBytes; - } - - txn.result = result; - }; - }.bind(this), aResultCb); - }, - - _getCurrentStatsFromDate: function _getCurrentStatsFromDate(aNetwork, aDate, aResultCb) { - aDate = new Date(aDate); - this.dbNewTxn(STATS_STORE_NAME, "readonly", function(txn, store) { - let request = null; - let start = this.normalizeDate(aDate); - let upperFilter = [0, 1, "", aNetwork, Date.now()]; - let range = IDBKeyRange.upperBound(upperFilter, false); - let result = { rxBytes: 0, txBytes: 0, - rxTotalBytes: 0, txTotalBytes: 0 }; - - request = store.openCursor(range, "prev"); - - request.onsuccess = function onsuccess(event) { - let cursor = event.target.result; - if (cursor) { - result.rxBytes = result.rxTotalBytes = cursor.value.rxTotalBytes; - result.txBytes = result.txTotalBytes = cursor.value.txTotalBytes; - } - - let timestamp = cursor.value.timestamp; - let range = IDBKeyRange.lowerBound(lowerFilter, false); - request = store.openCursor(range); - - request.onsuccess = function onsuccess(event) { - let cursor = event.target.result; - if (cursor) { - if (cursor.value.timestamp == timestamp) { - // There is one sample only. - result.rxBytes = cursor.value.rxBytes; - result.txBytes = cursor.value.txBytes; - } else { - result.rxBytes -= cursor.value.rxTotalBytes; - result.txBytes -= cursor.value.txTotalBytes; - } - } - - txn.result = result; - }; - }; - }.bind(this), aResultCb); - }, - - find: function find(aResultCb, aAppId, aBrowsingTrafficOnly, aServiceType, - aNetwork, aStart, aEnd, aAppManifestURL) { - let offset = (new Date()).getTimezoneOffset() * 60 * 1000; - let start = this.normalizeDate(aStart); - let end = this.normalizeDate(aEnd); - - if (DEBUG) { - debug("Find samples for appId: " + aAppId + - " browsingTrafficOnly: " + aBrowsingTrafficOnly + - " serviceType: " + aServiceType + - " network: " + JSON.stringify(aNetwork) + " from " + start + - " until " + end); - debug("Start time: " + new Date(start)); - debug("End time: " + new Date(end)); - } - - // Find samples of browsing traffic (isInBrowser = 1) first since they are - // needed no matter browsingTrafficOnly is true or false. - // We have to make two queries to database because we cannot filter correct - // records by a single query that sets ranges for two keys (isInBrowser and - // timestamp). We think it is because the keyPath contains an array - // (network) so such query does not work. - this.dbNewTxn(STATS_STORE_NAME, "readonly", function(aTxn, aStore) { - let network = [aNetwork.id, aNetwork.type]; - let lowerFilter = [aAppId, 1, aServiceType, network, start]; - let upperFilter = [aAppId, 1, aServiceType, network, end]; - let range = IDBKeyRange.bound(lowerFilter, upperFilter, false, false); - - let data = []; - - if (!aTxn.result) { - aTxn.result = {}; - } - aTxn.result.appManifestURL = aAppManifestURL; - aTxn.result.browsingTrafficOnly = aBrowsingTrafficOnly; - aTxn.result.serviceType = aServiceType; - aTxn.result.network = aNetwork; - aTxn.result.start = aStart; - aTxn.result.end = aEnd; - - let request = aStore.openCursor(range).onsuccess = function(event) { - var cursor = event.target.result; - if (cursor){ - // We use rxTotalBytes/txTotalBytes instead of rxBytes/txBytes for - // the first (oldest) sample. The rx/txTotalBytes fields record - // accumulative usage amount, which means even if old samples were - // expired and removed from the Database, we can still obtain the - // correct network usage. - if (data.length == 0) { - data.push({ rxBytes: cursor.value.rxTotalBytes, - txBytes: cursor.value.txTotalBytes, - date: new Date(cursor.value.timestamp + offset) }); - } else { - data.push({ rxBytes: cursor.value.rxBytes, - txBytes: cursor.value.txBytes, - date: new Date(cursor.value.timestamp + offset) }); - } - cursor.continue(); - return; - } - - if (aBrowsingTrafficOnly) { - this.fillResultSamples(start + offset, end + offset, data); - aTxn.result.data = data; - return; - } - - // Find samples of app traffic (isInBrowser = 0) as well if - // browsingTrafficOnly is false. - lowerFilter = [aAppId, 0, aServiceType, network, start]; - upperFilter = [aAppId, 0, aServiceType, network, end]; - range = IDBKeyRange.bound(lowerFilter, upperFilter, false, false); - request = aStore.openCursor(range).onsuccess = function(event) { - cursor = event.target.result; - if (cursor) { - var date = new Date(cursor.value.timestamp + offset); - var foundData = data.find(function (element, index, array) { - if (element.date.getTime() !== date.getTime()) { - return false; - } - return element; - }, date); - - if (foundData) { - foundData.rxBytes += cursor.value.rxBytes; - foundData.txBytes += cursor.value.txBytes; - } else { - // We use rxTotalBytes/txTotalBytes instead of rxBytes/txBytes - // for the first (oldest) sample. The rx/txTotalBytes fields - // record accumulative usage amount, which means even if old - // samples were expired and removed from the Database, we can - // still obtain the correct network usage. - if (data.length == 0) { - data.push({ rxBytes: cursor.value.rxTotalBytes, - txBytes: cursor.value.txTotalBytes, - date: new Date(cursor.value.timestamp + offset) }); - } else { - data.push({ rxBytes: cursor.value.rxBytes, - txBytes: cursor.value.txBytes, - date: new Date(cursor.value.timestamp + offset) }); - } - } - cursor.continue(); - return; - } - this.fillResultSamples(start + offset, end + offset, data); - aTxn.result.data = data; - }.bind(this); // openCursor(range).onsuccess() callback - }.bind(this); // openCursor(range).onsuccess() callback - }.bind(this), aResultCb); - }, - - /* - * Fill data array (samples from database) with empty samples to match - * requested start / end dates. - */ - fillResultSamples: function fillResultSamples(aStart, aEnd, aData) { - if (aData.length == 0) { - aData.push({ rxBytes: undefined, - txBytes: undefined, - date: new Date(aStart) }); - } - - while (aStart < aData[0].date.getTime()) { - aData.unshift({ rxBytes: undefined, - txBytes: undefined, - date: new Date(aData[0].date.getTime() - SAMPLE_RATE) }); - } - - while (aEnd > aData[aData.length - 1].date.getTime()) { - aData.push({ rxBytes: undefined, - txBytes: undefined, - date: new Date(aData[aData.length - 1].date.getTime() + SAMPLE_RATE) }); - } - }, - - getAvailableNetworks: function getAvailableNetworks(aResultCb) { - this.dbNewTxn(STATS_STORE_NAME, "readonly", function(aTxn, aStore) { - if (!aTxn.result) { - aTxn.result = []; - } - - let request = aStore.index("network").openKeyCursor(null, "nextunique"); - request.onsuccess = function onsuccess(event) { - let cursor = event.target.result; - if (cursor) { - aTxn.result.push({ id: cursor.key[0], - type: cursor.key[1] }); - cursor.continue(); - return; - } - }; - }, aResultCb); - }, - - isNetworkAvailable: function isNetworkAvailable(aNetwork, aResultCb) { - this.dbNewTxn(STATS_STORE_NAME, "readonly", function(aTxn, aStore) { - if (!aTxn.result) { - aTxn.result = false; - } - - let network = [aNetwork.id, aNetwork.type]; - let request = aStore.index("network").openKeyCursor(IDBKeyRange.only(network)); - request.onsuccess = function onsuccess(event) { - if (event.target.result) { - aTxn.result = true; - } - }; - }, aResultCb); - }, - - getAvailableServiceTypes: function getAvailableServiceTypes(aResultCb) { - this.dbNewTxn(STATS_STORE_NAME, "readonly", function(aTxn, aStore) { - if (!aTxn.result) { - aTxn.result = []; - } - - let request = aStore.index("serviceType").openKeyCursor(null, "nextunique"); - request.onsuccess = function onsuccess(event) { - let cursor = event.target.result; - if (cursor && cursor.key != "") { - aTxn.result.push({ serviceType: cursor.key }); - cursor.continue(); - return; - } - }; - }, aResultCb); - }, - - get sampleRate () { - return SAMPLE_RATE; - }, - - get maxStorageSamples () { - return VALUES_MAX_LENGTH; - }, - - logAllRecords: function logAllRecords(aResultCb) { - this.dbNewTxn(STATS_STORE_NAME, "readonly", function(aTxn, aStore) { - aStore.mozGetAll().onsuccess = function onsuccess(event) { - aTxn.result = event.target.result; - }; - }, aResultCb); - }, - - alarmToRecord: function alarmToRecord(aAlarm) { - let record = { networkId: aAlarm.networkId, - absoluteThreshold: aAlarm.absoluteThreshold, - relativeThreshold: aAlarm.relativeThreshold, - startTime: aAlarm.startTime, - data: aAlarm.data, - manifestURL: aAlarm.manifestURL, - pageURL: aAlarm.pageURL }; - - if (aAlarm.id) { - record.id = aAlarm.id; - } - - return record; - }, - - recordToAlarm: function recordToalarm(aRecord) { - let alarm = { networkId: aRecord.networkId, - absoluteThreshold: aRecord.absoluteThreshold, - relativeThreshold: aRecord.relativeThreshold, - startTime: aRecord.startTime, - data: aRecord.data, - manifestURL: aRecord.manifestURL, - pageURL: aRecord.pageURL }; - - if (aRecord.id) { - alarm.id = aRecord.id; - } - - return alarm; - }, - - addAlarm: function addAlarm(aAlarm, aResultCb) { - this.dbNewTxn(ALARMS_STORE_NAME, "readwrite", function(txn, store) { - if (DEBUG) { - debug("Going to add " + JSON.stringify(aAlarm)); - } - - let record = this.alarmToRecord(aAlarm); - store.put(record).onsuccess = function setResult(aEvent) { - txn.result = aEvent.target.result; - if (DEBUG) { - debug("Request successful. New record ID: " + txn.result); - } - }; - }.bind(this), aResultCb); - }, - - getFirstAlarm: function getFirstAlarm(aNetworkId, aResultCb) { - let self = this; - - this.dbNewTxn(ALARMS_STORE_NAME, "readonly", function(txn, store) { - if (DEBUG) { - debug("Get first alarm for network " + aNetworkId); - } - - let lowerFilter = [aNetworkId, 0]; - let upperFilter = [aNetworkId, ""]; - let range = IDBKeyRange.bound(lowerFilter, upperFilter); - - store.index("alarm").openCursor(range).onsuccess = function onsuccess(event) { - let cursor = event.target.result; - txn.result = null; - if (cursor) { - txn.result = self.recordToAlarm(cursor.value); - } - }; - }, aResultCb); - }, - - removeAlarm: function removeAlarm(aAlarmId, aManifestURL, aResultCb) { - this.dbNewTxn(ALARMS_STORE_NAME, "readwrite", function(txn, store) { - if (DEBUG) { - debug("Remove alarm " + aAlarmId); - } - - store.get(aAlarmId).onsuccess = function onsuccess(event) { - let record = event.target.result; - txn.result = false; - if (!record || (aManifestURL && record.manifestURL != aManifestURL)) { - return; - } - - store.delete(aAlarmId); - txn.result = true; - } - }, aResultCb); - }, - - removeAlarms: function removeAlarms(aManifestURL, aResultCb) { - this.dbNewTxn(ALARMS_STORE_NAME, "readwrite", function(txn, store) { - if (DEBUG) { - debug("Remove alarms of " + aManifestURL); - } - - store.index("manifestURL").openCursor(aManifestURL) - .onsuccess = function onsuccess(event) { - let cursor = event.target.result; - if (cursor) { - cursor.delete(); - cursor.continue(); - } - } - }, aResultCb); - }, - - updateAlarm: function updateAlarm(aAlarm, aResultCb) { - let self = this; - this.dbNewTxn(ALARMS_STORE_NAME, "readwrite", function(txn, store) { - if (DEBUG) { - debug("Update alarm " + aAlarm.id); - } - - let record = self.alarmToRecord(aAlarm); - store.openCursor(record.id).onsuccess = function onsuccess(event) { - let cursor = event.target.result; - txn.result = false; - if (cursor) { - cursor.update(record); - txn.result = true; - } - } - }, aResultCb); - }, - - getAlarms: function getAlarms(aNetworkId, aManifestURL, aResultCb) { - let self = this; - this.dbNewTxn(ALARMS_STORE_NAME, "readonly", function(txn, store) { - if (DEBUG) { - debug("Get alarms for " + aManifestURL); - } - - txn.result = []; - store.index("manifestURL").openCursor(aManifestURL) - .onsuccess = function onsuccess(event) { - let cursor = event.target.result; - if (!cursor) { - return; - } - - if (!aNetworkId || cursor.value.networkId == aNetworkId) { - txn.result.push(self.recordToAlarm(cursor.value)); - } - - cursor.continue(); - } - }, aResultCb); - }, - - _resetAlarms: function _resetAlarms(aNetworkId, aResultCb) { - this.dbNewTxn(ALARMS_STORE_NAME, "readwrite", function(txn, store) { - if (DEBUG) { - debug("Reset alarms for network " + aNetworkId); - } - - let lowerFilter = [aNetworkId, 0]; - let upperFilter = [aNetworkId, ""]; - let range = IDBKeyRange.bound(lowerFilter, upperFilter); - - store.index("alarm").openCursor(range).onsuccess = function onsuccess(event) { - let cursor = event.target.result; - if (cursor) { - if (cursor.value.startTime) { - cursor.value.relativeThreshold = cursor.value.threshold; - cursor.update(cursor.value); - } - cursor.continue(); - return; - } - }; - }, aResultCb); - } -}; diff --git a/dom/network/NetworkStatsManager.js b/dom/network/NetworkStatsManager.js deleted file mode 100644 index b963aba2b..000000000 --- a/dom/network/NetworkStatsManager.js +++ /dev/null @@ -1,388 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -"use strict"; - -const DEBUG = false; -function debug(s) { dump("-*- NetworkStatsManager: " + s + "\n"); } - -const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components; - -Cu.import("resource://gre/modules/XPCOMUtils.jsm"); -Cu.import("resource://gre/modules/Services.jsm"); -Cu.import("resource://gre/modules/DOMRequestHelper.jsm"); - -// Ensure NetworkStatsService and NetworkStatsDB are loaded in the parent process -// to receive messages from the child processes. -var appInfo = Cc["@mozilla.org/xre/app-info;1"]; -var isParentProcess = !appInfo || appInfo.getService(Ci.nsIXULRuntime) - .processType == Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT; -if (isParentProcess) { - Cu.import("resource://gre/modules/NetworkStatsService.jsm"); -} - -XPCOMUtils.defineLazyServiceGetter(this, "cpmm", - "@mozilla.org/childprocessmessagemanager;1", - "nsISyncMessageSender"); - -// NetworkStatsData -const nsIClassInfo = Ci.nsIClassInfo; -const NETWORKSTATSDATA_CID = Components.ID("{3b16fe17-5583-483a-b486-b64a3243221c}"); - -function NetworkStatsData(aWindow, aData) { - this.rxBytes = aData.rxBytes; - this.txBytes = aData.txBytes; - this.date = new aWindow.Date(aData.date.getTime()); -} - -NetworkStatsData.prototype = { - classID : NETWORKSTATSDATA_CID, - - QueryInterface : XPCOMUtils.generateQI([]) -}; - -// NetworkStatsInterface -const NETWORKSTATSINTERFACE_CONTRACTID = "@mozilla.org/networkstatsinterface;1"; -const NETWORKSTATSINTERFACE_CID = Components.ID("{f540615b-d803-43ff-8200-2a9d145a5645}"); - -function NetworkStatsInterface() { - if (DEBUG) { - debug("NetworkStatsInterface Constructor"); - } -} - -NetworkStatsInterface.prototype = { - __init: function(aNetwork) { - this.type = aNetwork.type; - this.id = aNetwork.id; - }, - - classID : NETWORKSTATSINTERFACE_CID, - - contractID: NETWORKSTATSINTERFACE_CONTRACTID, - QueryInterface : XPCOMUtils.generateQI([]) -} - -// NetworkStats -const NETWORKSTATS_CID = Components.ID("{28904f59-8497-4ac0-904f-2af14b7fd3de}"); - -function NetworkStats(aWindow, aStats) { - if (DEBUG) { - debug("NetworkStats Constructor"); - } - this.appManifestURL = aStats.appManifestURL || null; - this.browsingTrafficOnly = aStats.browsingTrafficOnly || false; - this.serviceType = aStats.serviceType || null; - this.network = new aWindow.MozNetworkStatsInterface(aStats.network); - this.start = aStats.start ? new aWindow.Date(aStats.start.getTime()) : null; - this.end = aStats.end ? new aWindow.Date(aStats.end.getTime()) : null; - - let samples = this.data = new aWindow.Array(); - for (let i = 0; i < aStats.data.length; i++) { - samples.push(aWindow.MozNetworkStatsData._create( - aWindow, new NetworkStatsData(aWindow, aStats.data[i]))); - } -} - -NetworkStats.prototype = { - classID : NETWORKSTATS_CID, - - QueryInterface : XPCOMUtils.generateQI() -} - -// NetworkStatsAlarm -const NETWORKSTATSALARM_CID = Components.ID("{a93ea13e-409c-4189-9b1e-95fff220be55}"); - -function NetworkStatsAlarm(aWindow, aAlarm) { - this.alarmId = aAlarm.id; - this.network = new aWindow.MozNetworkStatsInterface(aAlarm.network); - this.threshold = aAlarm.threshold; - this.data = aAlarm.data; -} - -NetworkStatsAlarm.prototype = { - classID : NETWORKSTATSALARM_CID, - - QueryInterface : XPCOMUtils.generateQI([]) -}; - -// NetworkStatsManager - -const NETWORKSTATSMANAGER_CONTRACTID = "@mozilla.org/networkStatsManager;1"; -const NETWORKSTATSMANAGER_CID = Components.ID("{ceb874cd-cc1a-4e65-b404-cc2d3e42425f}"); - -function NetworkStatsManager() { - if (DEBUG) { - debug("Constructor"); - } -} - -NetworkStatsManager.prototype = { - __proto__: DOMRequestIpcHelper.prototype, - - getSamples: function getSamples(aNetwork, aStart, aEnd, aOptions) { - if (aStart > aEnd) { - throw Components.results.NS_ERROR_INVALID_ARG; - } - - // appManifestURL is used to query network statistics by app; - // serviceType is used to query network statistics by system service. - // It is illegal to specify both of them at the same time. - if (aOptions.appManifestURL && aOptions.serviceType) { - throw Components.results.NS_ERROR_NOT_IMPLEMENTED; - } - // browsingTrafficOnly is meaningful only when querying by app. - if (!aOptions.appManifestURL && aOptions.browsingTrafficOnly) { - throw Components.results.NS_ERROR_NOT_IMPLEMENTED; - } - - let appManifestURL = aOptions.appManifestURL; - let serviceType = aOptions.serviceType; - let browsingTrafficOnly = aOptions.browsingTrafficOnly; - - // TODO Bug 929410 Date object cannot correctly pass through cpmm/ppmm IPC - // This is just a work-around by passing timestamp numbers. - aStart = aStart.getTime(); - aEnd = aEnd.getTime(); - - let request = this.createRequest(); - cpmm.sendAsyncMessage("NetworkStats:Get", - { network: aNetwork.toJSON(), - start: aStart, - end: aEnd, - appManifestURL: appManifestURL, - browsingTrafficOnly: browsingTrafficOnly, - serviceType: serviceType, - id: this.getRequestId(request) }); - return request; - }, - - clearStats: function clearStats(aNetwork) { - let request = this.createRequest(); - cpmm.sendAsyncMessage("NetworkStats:Clear", - { network: aNetwork.toJSON(), - id: this.getRequestId(request) }); - return request; - }, - - clearAllStats: function clearAllStats() { - let request = this.createRequest(); - cpmm.sendAsyncMessage("NetworkStats:ClearAll", - {id: this.getRequestId(request)}); - return request; - }, - - addAlarm: function addAlarm(aNetwork, aThreshold, aOptions) { - let request = this.createRequest(); - cpmm.sendAsyncMessage("NetworkStats:SetAlarm", - {id: this.getRequestId(request), - data: {network: aNetwork.toJSON(), - threshold: aThreshold, - startTime: aOptions.startTime, - data: aOptions.data, - manifestURL: this.manifestURL, - pageURL: this.pageURL}}); - return request; - }, - - getAllAlarms: function getAllAlarms(aNetwork) { - let network = null; - if (aNetwork) { - network = aNetwork.toJSON(); - } - - let request = this.createRequest(); - cpmm.sendAsyncMessage("NetworkStats:GetAlarms", - {id: this.getRequestId(request), - data: {network: network, - manifestURL: this.manifestURL}}); - return request; - }, - - removeAlarms: function removeAlarms(aAlarmId) { - if (aAlarmId == 0) { - aAlarmId = -1; - } - - let request = this.createRequest(); - cpmm.sendAsyncMessage("NetworkStats:RemoveAlarms", - {id: this.getRequestId(request), - data: {alarmId: aAlarmId, - manifestURL: this.manifestURL}}); - - return request; - }, - - getAvailableNetworks: function getAvailableNetworks() { - let request = this.createRequest(); - cpmm.sendAsyncMessage("NetworkStats:GetAvailableNetworks", - { id: this.getRequestId(request) }); - return request; - }, - - getAvailableServiceTypes: function getAvailableServiceTypes() { - let request = this.createRequest(); - cpmm.sendAsyncMessage("NetworkStats:GetAvailableServiceTypes", - { id: this.getRequestId(request) }); - return request; - }, - - get sampleRate() { - return cpmm.sendSyncMessage("NetworkStats:SampleRate")[0]; - }, - - get maxStorageAge() { - return cpmm.sendSyncMessage("NetworkStats:MaxStorageAge")[0]; - }, - - receiveMessage: function(aMessage) { - if (DEBUG) { - debug("NetworkStatsmanager::receiveMessage: " + aMessage.name); - } - - let msg = aMessage.json; - let req = this.takeRequest(msg.id); - if (!req) { - if (DEBUG) { - debug("No request stored with id " + msg.id); - } - return; - } - - switch (aMessage.name) { - case "NetworkStats:Get:Return": - if (msg.error) { - Services.DOMRequest.fireError(req, msg.error); - return; - } - - let result = this._window.MozNetworkStats._create( - this._window, new NetworkStats(this._window, msg.result)); - if (DEBUG) { - debug("result: " + JSON.stringify(result)); - } - Services.DOMRequest.fireSuccess(req, result); - break; - - case "NetworkStats:GetAvailableNetworks:Return": - if (msg.error) { - Services.DOMRequest.fireError(req, msg.error); - return; - } - - let networks = new this._window.Array(); - for (let i = 0; i < msg.result.length; i++) { - let network = new this._window.MozNetworkStatsInterface(msg.result[i]); - networks.push(network); - } - - Services.DOMRequest.fireSuccess(req, networks); - break; - - case "NetworkStats:GetAvailableServiceTypes:Return": - if (msg.error) { - Services.DOMRequest.fireError(req, msg.error); - return; - } - - let serviceTypes = new this._window.Array(); - for (let i = 0; i < msg.result.length; i++) { - serviceTypes.push(msg.result[i]); - } - - Services.DOMRequest.fireSuccess(req, serviceTypes); - break; - - case "NetworkStats:Clear:Return": - case "NetworkStats:ClearAll:Return": - if (msg.error) { - Services.DOMRequest.fireError(req, msg.error); - return; - } - - Services.DOMRequest.fireSuccess(req, true); - break; - - case "NetworkStats:SetAlarm:Return": - case "NetworkStats:RemoveAlarms:Return": - if (msg.error) { - Services.DOMRequest.fireError(req, msg.error); - return; - } - - Services.DOMRequest.fireSuccess(req, msg.result); - break; - - case "NetworkStats:GetAlarms:Return": - if (msg.error) { - Services.DOMRequest.fireError(req, msg.error); - return; - } - - let alarms = new this._window.Array(); - for (let i = 0; i < msg.result.length; i++) { - // The WebIDL type of data is any, so we should manually clone it - // into the content window. - if ("data" in msg.result[i]) { - msg.result[i].data = Cu.cloneInto(msg.result[i].data, this._window); - } - let alarm = new NetworkStatsAlarm(this._window, msg.result[i]); - alarms.push(this._window.MozNetworkStatsAlarm._create(this._window, alarm)); - } - - Services.DOMRequest.fireSuccess(req, alarms); - break; - - default: - if (DEBUG) { - debug("Wrong message: " + aMessage.name); - } - } - }, - - init: function(aWindow) { - let principal = aWindow.document.nodePrincipal; - - this.initDOMRequestHelper(aWindow, ["NetworkStats:Get:Return", - "NetworkStats:GetAvailableNetworks:Return", - "NetworkStats:GetAvailableServiceTypes:Return", - "NetworkStats:Clear:Return", - "NetworkStats:ClearAll:Return", - "NetworkStats:SetAlarm:Return", - "NetworkStats:GetAlarms:Return", - "NetworkStats:RemoveAlarms:Return"]); - - // Init app properties. - let appsService = Cc["@mozilla.org/AppsService;1"] - .getService(Ci.nsIAppsService); - - this.manifestURL = appsService.getManifestURLByLocalId(principal.appId); - - let isApp = !!this.manifestURL.length; - if (isApp) { - this.pageURL = principal.URI.spec; - } - - this.window = aWindow; - }, - - // Called from DOMRequestIpcHelper - uninit: function uninit() { - if (DEBUG) { - debug("uninit call"); - } - }, - - classID : NETWORKSTATSMANAGER_CID, - contractID : NETWORKSTATSMANAGER_CONTRACTID, - QueryInterface : XPCOMUtils.generateQI([Ci.nsIDOMGlobalPropertyInitializer, - Ci.nsISupportsWeakReference, - Ci.nsIObserver]), -} - -this.NSGetFactory = XPCOMUtils.generateNSGetFactory([NetworkStatsAlarm, - NetworkStatsData, - NetworkStatsInterface, - NetworkStats, - NetworkStatsManager]); diff --git a/dom/network/NetworkStatsManager.manifest b/dom/network/NetworkStatsManager.manifest deleted file mode 100644 index 8e8700910..000000000 --- a/dom/network/NetworkStatsManager.manifest +++ /dev/null @@ -1,14 +0,0 @@ -component {3b16fe17-5583-483a-b486-b64a3243221c} NetworkStatsManager.js -contract @mozilla.org/networkStatsdata;1 {3b16fe17-5583-483a-b486-b64a3243221c} - -component {28904f59-8497-4ac0-904f-2af14b7fd3de} NetworkStatsManager.js -contract @mozilla.org/networkStats;1 {28904f59-8497-4ac0-904f-2af14b7fd3de} - -component {f540615b-d803-43ff-8200-2a9d145a5645} NetworkStatsManager.js -contract @mozilla.org/networkstatsinterface;1 {f540615b-d803-43ff-8200-2a9d145a5645} - -component {a93ea13e-409c-4189-9b1e-95fff220be55} NetworkStatsManager.js -contract @mozilla.org/networkstatsalarm;1 {a93ea13e-409c-4189-9b1e-95fff220be55} - -component {ceb874cd-cc1a-4e65-b404-cc2d3e42425f} NetworkStatsManager.js -contract @mozilla.org/networkStatsManager;1 {ceb874cd-cc1a-4e65-b404-cc2d3e42425f} diff --git a/dom/network/NetworkStatsService.jsm b/dom/network/NetworkStatsService.jsm deleted file mode 100644 index 4b6d69498..000000000 --- a/dom/network/NetworkStatsService.jsm +++ /dev/null @@ -1,1171 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -"use strict"; - -const DEBUG = false; -function debug(s) { - if (DEBUG) { - dump("-*- NetworkStatsService: " + s + "\n"); - } -} - -const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components; - -this.EXPORTED_SYMBOLS = ["NetworkStatsService"]; - -Cu.import("resource://gre/modules/XPCOMUtils.jsm"); -Cu.import("resource://gre/modules/Services.jsm"); -Cu.import("resource://gre/modules/NetworkStatsDB.jsm"); -Cu.import("resource://gre/modules/Timer.jsm"); - -const NET_NETWORKSTATSSERVICE_CONTRACTID = "@mozilla.org/network/netstatsservice;1"; -const NET_NETWORKSTATSSERVICE_CID = Components.ID("{18725604-e9ac-488a-8aa0-2471e7f6c0a4}"); - -const TOPIC_BANDWIDTH_CONTROL = "netd-bandwidth-control" - -const TOPIC_CONNECTION_STATE_CHANGED = "network-connection-state-changed"; -const NET_TYPE_WIFI = Ci.nsINetworkInfo.NETWORK_TYPE_WIFI; -const NET_TYPE_MOBILE = Ci.nsINetworkInfo.NETWORK_TYPE_MOBILE; - -// Networks have different status that NetworkStats API needs to be aware of. -// Network is present and ready, so NetworkManager provides the whole info. -const NETWORK_STATUS_READY = 0; -// Network is present but hasn't established a connection yet (e.g. SIM that has not -// enabled 3G since boot). -const NETWORK_STATUS_STANDBY = 1; -// Network is not present, but stored in database by the previous connections. -const NETWORK_STATUS_AWAY = 2; - -// The maximum traffic amount can be saved in the |cachedStats|. -const MAX_CACHED_TRAFFIC = 500 * 1000 * 1000; // 500 MB - -const QUEUE_TYPE_UPDATE_STATS = 0; -const QUEUE_TYPE_UPDATE_CACHE = 1; -const QUEUE_TYPE_WRITE_CACHE = 2; - -XPCOMUtils.defineLazyServiceGetter(this, "ppmm", - "@mozilla.org/parentprocessmessagemanager;1", - "nsIMessageListenerManager"); - -XPCOMUtils.defineLazyServiceGetter(this, "gRil", - "@mozilla.org/ril;1", - "nsIRadioInterfaceLayer"); - -XPCOMUtils.defineLazyServiceGetter(this, "networkService", - "@mozilla.org/network/service;1", - "nsINetworkService"); - -XPCOMUtils.defineLazyServiceGetter(this, "appsService", - "@mozilla.org/AppsService;1", - "nsIAppsService"); - -XPCOMUtils.defineLazyServiceGetter(this, "gSettingsService", - "@mozilla.org/settingsService;1", - "nsISettingsService"); - -XPCOMUtils.defineLazyServiceGetter(this, "messenger", - "@mozilla.org/system-message-internal;1", - "nsISystemMessagesInternal"); - -XPCOMUtils.defineLazyServiceGetter(this, "gIccService", - "@mozilla.org/icc/iccservice;1", - "nsIIccService"); - -this.NetworkStatsService = { - init: function() { - debug("Service started"); - - Services.obs.addObserver(this, "xpcom-shutdown", false); - Services.obs.addObserver(this, TOPIC_CONNECTION_STATE_CHANGED, false); - Services.obs.addObserver(this, TOPIC_BANDWIDTH_CONTROL, false); - Services.obs.addObserver(this, "profile-after-change", false); - - this.timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); - - // Object to store network interfaces, each network interface is composed - // by a network object (network type and network Id) and a interfaceName - // that contains the name of the physical interface (wlan0, rmnet0, etc.). - // The network type can be 0 for wifi or 1 for mobile. On the other hand, - // the network id is '0' for wifi or the iccid for mobile (SIM). - // Each networkInterface is placed in the _networks object by the index of - // 'networkId + networkType'. - // - // _networks object allows to map available network interfaces at low level - // (wlan0, rmnet0, etc.) to a network. It's not mandatory to have a - // networkInterface per network but can't exist a networkInterface not - // being mapped to a network. - - this._networks = Object.create(null); - - // There is no way to know a priori if wifi connection is available, - // just when the wifi driver is loaded, but it is unloaded when - // wifi is switched off. So wifi connection is hardcoded - let netId = this.getNetworkId('0', NET_TYPE_WIFI); - this._networks[netId] = { network: { id: '0', - type: NET_TYPE_WIFI }, - interfaceName: null, - status: NETWORK_STATUS_STANDBY }; - - this.messages = ["NetworkStats:Get", - "NetworkStats:Clear", - "NetworkStats:ClearAll", - "NetworkStats:SetAlarm", - "NetworkStats:GetAlarms", - "NetworkStats:RemoveAlarms", - "NetworkStats:GetAvailableNetworks", - "NetworkStats:GetAvailableServiceTypes", - "NetworkStats:SampleRate", - "NetworkStats:MaxStorageAge"]; - - this.messages.forEach(function(aMsgName) { - ppmm.addMessageListener(aMsgName, this); - }, this); - - this._db = new NetworkStatsDB(); - - // Stats for all interfaces are updated periodically - this.timer.initWithCallback(this, this._db.sampleRate, - Ci.nsITimer.TYPE_REPEATING_PRECISE_CAN_SKIP); - - // Stats not from netd are firstly stored in the cached. - this.cachedStats = Object.create(null); - this.cachedStatsDate = new Date(); - - this.updateQueue = []; - this.isQueueRunning = false; - - this._currentAlarms = {}; - this.initAlarms(); - }, - - receiveMessage: function(aMessage) { - if (!aMessage.target.assertPermission("networkstats-manage")) { - return; - } - - debug("receiveMessage " + aMessage.name); - - let mm = aMessage.target; - let msg = aMessage.json; - - switch (aMessage.name) { - case "NetworkStats:Get": - this.getSamples(mm, msg); - break; - case "NetworkStats:Clear": - this.clearInterfaceStats(mm, msg); - break; - case "NetworkStats:ClearAll": - this.clearDB(mm, msg); - break; - case "NetworkStats:SetAlarm": - this.setAlarm(mm, msg); - break; - case "NetworkStats:GetAlarms": - this.getAlarms(mm, msg); - break; - case "NetworkStats:RemoveAlarms": - this.removeAlarms(mm, msg); - break; - case "NetworkStats:GetAvailableNetworks": - this.getAvailableNetworks(mm, msg); - break; - case "NetworkStats:GetAvailableServiceTypes": - this.getAvailableServiceTypes(mm, msg); - break; - case "NetworkStats:SampleRate": - // This message is sync. - return this._db.sampleRate; - case "NetworkStats:MaxStorageAge": - // This message is sync. - return this._db.maxStorageSamples * this._db.sampleRate; - } - }, - - observe: function observe(aSubject, aTopic, aData) { - switch (aTopic) { - case TOPIC_CONNECTION_STATE_CHANGED: - - // If new interface is registered (notified from NetworkService), - // the stats are updated for the new interface without waiting to - // complete the updating period. - - let networkInfo = aSubject.QueryInterface(Ci.nsINetworkInfo); - debug("Network " + networkInfo.name + " of type " + networkInfo.type + " status change"); - - let netId = this.convertNetworkInfo(networkInfo); - if (!netId) { - break; - } - - this._updateCurrentAlarm(netId); - - debug("NetId: " + netId); - this.updateStats(netId); - break; - - case TOPIC_BANDWIDTH_CONTROL: - debug("Bandwidth message from netd: " + JSON.stringify(aData)); - - let interfaceName = aData.substring(aData.lastIndexOf(" ") + 1); - for (let networkId in this._networks) { - if (interfaceName == this._networks[networkId].interfaceName) { - let currentAlarm = this._currentAlarms[networkId]; - if (Object.getOwnPropertyNames(currentAlarm).length !== 0) { - this._fireAlarm(currentAlarm.alarm); - } - break; - } - } - break; - - case "xpcom-shutdown": - debug("Service shutdown"); - - this.messages.forEach(function(aMsgName) { - ppmm.removeMessageListener(aMsgName, this); - }, this); - - Services.obs.removeObserver(this, "xpcom-shutdown"); - Services.obs.removeObserver(this, "profile-after-change"); - Services.obs.removeObserver(this, TOPIC_CONNECTION_STATE_CHANGED); - Services.obs.removeObserver(this, TOPIC_BANDWIDTH_CONTROL); - - this.timer.cancel(); - this.timer = null; - - // Update stats before shutdown - this.updateAllStats(); - break; - } - }, - - /* - * nsITimerCallback - * Timer triggers the update of all stats - */ - notify: function(aTimer) { - this.updateAllStats(); - }, - - /* - * nsINetworkStatsService - */ - getRilNetworks: function() { - let networks = {}; - let numRadioInterfaces = gRil.numRadioInterfaces; - for (let i = 0; i < numRadioInterfaces; i++) { - let icc = gIccService.getIccByServiceId(i); - let radioInterface = gRil.getRadioInterface(i); - if (icc && icc.iccInfo) { - let netId = this.getNetworkId(icc.iccInfo.iccid, - NET_TYPE_MOBILE); - networks[netId] = { id : icc.iccInfo.iccid, - type: NET_TYPE_MOBILE }; - } - } - return networks; - }, - - convertNetworkInfo: function(aNetworkInfo) { - if (aNetworkInfo.type != NET_TYPE_MOBILE && - aNetworkInfo.type != NET_TYPE_WIFI) { - return null; - } - - let id = '0'; - if (aNetworkInfo.type == NET_TYPE_MOBILE) { - if (!(aNetworkInfo instanceof Ci.nsIRilNetworkInfo)) { - debug("Error! Mobile network should be an nsIRilNetworkInfo!"); - return null; - } - - let rilNetwork = aNetworkInfo.QueryInterface(Ci.nsIRilNetworkInfo); - id = rilNetwork.iccId; - } - - let netId = this.getNetworkId(id, aNetworkInfo.type); - - if (!this._networks[netId]) { - this._networks[netId] = Object.create(null); - this._networks[netId].network = { id: id, - type: aNetworkInfo.type }; - } - - this._networks[netId].status = NETWORK_STATUS_READY; - this._networks[netId].interfaceName = aNetworkInfo.name; - return netId; - }, - - getNetworkId: function getNetworkId(aIccId, aNetworkType) { - return aIccId + '' + aNetworkType; - }, - - /* Function to ensure that one network is valid. The network is valid if its status is - * NETWORK_STATUS_READY, NETWORK_STATUS_STANDBY or NETWORK_STATUS_AWAY. - * - * The result is |netId| or null in case of a non-valid network - * aCallback is signatured as |function(netId)|. - */ - validateNetwork: function validateNetwork(aNetwork, aCallback) { - let netId = this.getNetworkId(aNetwork.id, aNetwork.type); - - if (this._networks[netId]) { - aCallback(netId); - return; - } - - // Check if network is valid (RIL entry) but has not established a connection yet. - // If so add to networks list with empty interfaceName. - let rilNetworks = this.getRilNetworks(); - if (rilNetworks[netId]) { - this._networks[netId] = Object.create(null); - this._networks[netId].network = rilNetworks[netId]; - this._networks[netId].status = NETWORK_STATUS_STANDBY; - this._currentAlarms[netId] = Object.create(null); - aCallback(netId); - return; - } - - // Check if network is available in the DB. - this._db.isNetworkAvailable(aNetwork, function(aError, aResult) { - if (aResult) { - this._networks[netId] = Object.create(null); - this._networks[netId].network = aNetwork; - this._networks[netId].status = NETWORK_STATUS_AWAY; - this._currentAlarms[netId] = Object.create(null); - aCallback(netId); - return; - } - - aCallback(null); - }.bind(this)); - }, - - getAvailableNetworks: function getAvailableNetworks(mm, msg) { - let self = this; - let rilNetworks = this.getRilNetworks(); - this._db.getAvailableNetworks(function onGetNetworks(aError, aResult) { - - // Also return the networks that are valid but have not - // established connections yet. - for (let netId in rilNetworks) { - let found = false; - for (let i = 0; i < aResult.length; i++) { - if (netId == self.getNetworkId(aResult[i].id, aResult[i].type)) { - found = true; - break; - } - } - if (!found) { - aResult.push(rilNetworks[netId]); - } - } - - mm.sendAsyncMessage("NetworkStats:GetAvailableNetworks:Return", - { id: msg.id, error: aError, result: aResult }); - }); - }, - - getAvailableServiceTypes: function getAvailableServiceTypes(mm, msg) { - this._db.getAvailableServiceTypes(function onGetServiceTypes(aError, aResult) { - mm.sendAsyncMessage("NetworkStats:GetAvailableServiceTypes:Return", - { id: msg.id, error: aError, result: aResult }); - }); - }, - - initAlarms: function initAlarms() { - debug("Init usage alarms"); - let self = this; - - for (let netId in this._networks) { - this._currentAlarms[netId] = Object.create(null); - - this._db.getFirstAlarm(netId, function getResult(error, result) { - if (!error && result) { - self._setAlarm(result, function onSet(error, success) { - if (error == "InvalidStateError") { - self._fireAlarm(result); - } - }); - } - }); - } - }, - - /* - * Function called from manager to get stats from database. - * In order to return updated stats, first is performed a call to - * updateAllStats function, which will get last stats from netd - * and update the database. - * Then, depending on the request (stats per appId or total stats) - * it retrieve them from database and return to the manager. - */ - getSamples: function getSamples(mm, msg) { - let network = msg.network; - let netId = this.getNetworkId(network.id, network.type); - - let appId = 0; - let appManifestURL = msg.appManifestURL; - if (appManifestURL) { - appId = appsService.getAppLocalIdByManifestURL(appManifestURL); - - if (!appId) { - mm.sendAsyncMessage("NetworkStats:Get:Return", - { id: msg.id, - error: "Invalid appManifestURL", result: null }); - return; - } - } - - let browsingTrafficOnly = msg.browsingTrafficOnly || false; - let serviceType = msg.serviceType || ""; - - let start = new Date(msg.start); - let end = new Date(msg.end); - - let callback = (function (aError, aResult) { - this._db.find(function onStatsFound(aError, aResult) { - mm.sendAsyncMessage("NetworkStats:Get:Return", - { id: msg.id, error: aError, result: aResult }); - }, appId, browsingTrafficOnly, serviceType, network, start, end, appManifestURL); - }).bind(this); - - this.validateNetwork(network, function onValidateNetwork(aNetId) { - if (!aNetId) { - mm.sendAsyncMessage("NetworkStats:Get:Return", - { id: msg.id, error: "Invalid connectionType", result: null }); - return; - } - - // If network is currently active we need to update the cached stats first before - // retrieving stats from the DB. - if (this._networks[aNetId].status == NETWORK_STATUS_READY) { - debug("getstats for network " + network.id + " of type " + network.type); - debug("appId: " + appId + " from appManifestURL: " + appManifestURL); - debug("browsingTrafficOnly: " + browsingTrafficOnly); - debug("serviceType: " + serviceType); - - if (appId || serviceType) { - this.updateCachedStats(callback); - return; - } - - this.updateStats(aNetId, function onStatsUpdated(aResult, aMessage) { - this.updateCachedStats(callback); - }.bind(this)); - return; - } - - // Network not active, so no need to update - this._db.find(function onStatsFound(aError, aResult) { - mm.sendAsyncMessage("NetworkStats:Get:Return", - { id: msg.id, error: aError, result: aResult }); - }, appId, browsingTrafficOnly, serviceType, network, start, end, appManifestURL); - }.bind(this)); - }, - - clearInterfaceStats: function clearInterfaceStats(mm, msg) { - let self = this; - let network = msg.network; - - debug("clear stats for network " + network.id + " of type " + network.type); - - this.validateNetwork(network, function onValidateNetwork(aNetId) { - if (!aNetId) { - mm.sendAsyncMessage("NetworkStats:Clear:Return", - { id: msg.id, error: "Invalid connectionType", result: null }); - return; - } - - network = {network: network, networkId: aNetId}; - self.updateStats(aNetId, function onUpdate(aResult, aMessage) { - if (!aResult) { - mm.sendAsyncMessage("NetworkStats:Clear:Return", - { id: msg.id, error: aMessage, result: null }); - return; - } - - self._db.clearInterfaceStats(network, function onDBCleared(aError, aResult) { - self._updateCurrentAlarm(aNetId); - mm.sendAsyncMessage("NetworkStats:Clear:Return", - { id: msg.id, error: aError, result: aResult }); - }); - }); - }); - }, - - clearDB: function clearDB(mm, msg) { - let self = this; - this._db.getAvailableNetworks(function onGetNetworks(aError, aResult) { - if (aError) { - mm.sendAsyncMessage("NetworkStats:ClearAll:Return", - { id: msg.id, error: aError, result: aResult }); - return; - } - - let networks = aResult; - networks.forEach(function(network, index) { - networks[index] = {network: network, networkId: self.getNetworkId(network.id, network.type)}; - }, self); - - self.updateAllStats(function onUpdate(aResult, aMessage){ - if (!aResult) { - mm.sendAsyncMessage("NetworkStats:ClearAll:Return", - { id: msg.id, error: aMessage, result: null }); - return; - } - - self._db.clearStats(networks, function onDBCleared(aError, aResult) { - networks.forEach(function(network, index) { - self._updateCurrentAlarm(network.networkId); - }, self); - mm.sendAsyncMessage("NetworkStats:ClearAll:Return", - { id: msg.id, error: aError, result: aResult }); - }); - }); - }); - }, - - updateAllStats: function updateAllStats(aCallback) { - let elements = []; - let lastElement = null; - let callback = (function (success, message) { - this.updateCachedStats(aCallback); - }).bind(this); - - // For each connectionType create an object containning the type - // and the 'queueIndex', the 'queueIndex' is an integer representing - // the index of a connection type in the global queue array. So, if - // the connection type is already in the queue it is not appended again, - // else it is pushed in 'elements' array, which later will be pushed to - // the queue array. - for (let netId in this._networks) { - if (this._networks[netId].status != NETWORK_STATUS_READY) { - continue; - } - - lastElement = { netId: netId, - queueIndex: this.updateQueueIndex(netId) }; - - if (lastElement.queueIndex == -1) { - elements.push({ netId: lastElement.netId, - callbacks: [], - queueType: QUEUE_TYPE_UPDATE_STATS }); - } - } - - if (!lastElement) { - // No elements need to be updated, probably because status is different than - // NETWORK_STATUS_READY. - if (aCallback) { - aCallback(true, "OK"); - } - return; - } - - if (elements.length > 0) { - // If length of elements is greater than 0, callback is set to - // the last element. - elements[elements.length - 1].callbacks.push(callback); - this.updateQueue = this.updateQueue.concat(elements); - } else { - // Else, it means that all connection types are already in the queue to - // be updated, so callback for this request is added to - // the element in the main queue with the index of the last 'lastElement'. - // But before is checked that element is still in the queue because it can - // be processed while generating 'elements' array. - let element = this.updateQueue[lastElement.queueIndex]; - if (aCallback && - (!element || element.netId != lastElement.netId)) { - aCallback(); - return; - } - - this.updateQueue[lastElement.queueIndex].callbacks.push(callback); - } - - // Call the function that process the elements of the queue. - this.processQueue(); - - if (DEBUG) { - this.logAllRecords(); - } - }, - - updateStats: function updateStats(aNetId, aCallback) { - // Check if the connection is in the main queue, push a new element - // if it is not being processed or add a callback if it is. - let index = this.updateQueueIndex(aNetId); - if (index == -1) { - this.updateQueue.push({ netId: aNetId, - callbacks: [aCallback], - queueType: QUEUE_TYPE_UPDATE_STATS }); - } else { - this.updateQueue[index].callbacks.push(aCallback); - return; - } - - // Call the function that process the elements of the queue. - this.processQueue(); - }, - - /* - * Find if a connection is in the main queue array and return its - * index, if it is not in the array return -1. - */ - updateQueueIndex: function updateQueueIndex(aNetId) { - return this.updateQueue.map(function(e) { return e.netId; }).indexOf(aNetId); - }, - - /* - * Function responsible of process all requests in the queue. - */ - processQueue: function processQueue(aResult, aMessage) { - // If aResult is not undefined, the caller of the function is the result - // of processing an element, so remove that element and call the callbacks - // it has. - let self = this; - - if (aResult != undefined) { - let item = this.updateQueue.shift(); - for (let callback of item.callbacks) { - if (callback) { - callback(aResult, aMessage); - } - } - } else { - // The caller is a function that has pushed new elements to the queue, - // if isQueueRunning is false it means there is no processing currently - // being done, so start. - if (this.isQueueRunning) { - return; - } else { - this.isQueueRunning = true; - } - } - - // Check length to determine if queue is empty and stop processing. - if (this.updateQueue.length < 1) { - this.isQueueRunning = false; - return; - } - - // Process the next item as soon as possible. - setTimeout(function () { - self.run(self.updateQueue[0]); - }, 0); - }, - - run: function run(item) { - switch (item.queueType) { - case QUEUE_TYPE_UPDATE_STATS: - this.update(item.netId, this.processQueue.bind(this)); - break; - case QUEUE_TYPE_UPDATE_CACHE: - this.updateCache(this.processQueue.bind(this)); - break; - case QUEUE_TYPE_WRITE_CACHE: - this.writeCache(item.stats, this.processQueue.bind(this)); - break; - } - }, - - update: function update(aNetId, aCallback) { - // Check if connection type is valid. - if (!this._networks[aNetId]) { - if (aCallback) { - aCallback(false, "Invalid network " + aNetId); - } - return; - } - - let interfaceName = this._networks[aNetId].interfaceName; - debug("Update stats for " + interfaceName); - - // Request stats to NetworkService, which will get stats from netd, passing - // 'networkStatsAvailable' as a callback. - if (interfaceName) { - networkService.getNetworkInterfaceStats(interfaceName, - this.networkStatsAvailable.bind(this, aCallback, aNetId)); - return; - } - - if (aCallback) { - aCallback(true, "ok"); - } - }, - - /* - * Callback of request stats. Store stats in database. - */ - networkStatsAvailable: function networkStatsAvailable(aCallback, aNetId, - aResult, aRxBytes, - aTxBytes, aTimestamp) { - if (!aResult) { - if (aCallback) { - aCallback(false, "Netd IPC error"); - } - return; - } - - let stats = { appId: 0, - isInBrowser: false, - serviceType: "", - networkId: this._networks[aNetId].network.id, - networkType: this._networks[aNetId].network.type, - date: new Date(aTimestamp), - rxBytes: aTxBytes, - txBytes: aRxBytes, - isAccumulative: true }; - - debug("Update stats for: " + JSON.stringify(stats)); - - this._db.saveStats(stats, function onSavedStats(aError, aResult) { - if (aCallback) { - if (aError) { - aCallback(false, aError); - return; - } - - aCallback(true, "OK"); - } - }); - }, - - /* - * Function responsible for receiving stats which are not from netd. - */ - saveStats: function saveStats(aAppId, aIsInIsolatedMozBrowser, aServiceType, - aNetworkInfo, aTimeStamp, aRxBytes, aTxBytes, - aIsAccumulative, aCallback) { - let netId = this.convertNetworkInfo(aNetworkInfo); - if (!netId) { - if (aCallback) { - aCallback(false, "Invalid network type"); - } - return; - } - - // Check if |aConnectionType|, |aAppId| and |aServiceType| are valid. - // There are two invalid cases for the combination of |aAppId| and - // |aServiceType|: - // a. Both |aAppId| is non-zero and |aServiceType| is non-empty. - // b. Both |aAppId| is zero and |aServiceType| is empty. - if (!this._networks[netId] || (aAppId && aServiceType) || - (!aAppId && !aServiceType)) { - debug("Invalid network interface, appId or serviceType"); - return; - } - - let stats = { appId: aAppId, - isInBrowser: aIsInIsolatedMozBrowser, - serviceType: aServiceType, - networkId: this._networks[netId].network.id, - networkType: this._networks[netId].network.type, - date: new Date(aTimeStamp), - rxBytes: aRxBytes, - txBytes: aTxBytes, - isAccumulative: aIsAccumulative }; - - this.updateQueue.push({ stats: stats, - callbacks: [aCallback], - queueType: QUEUE_TYPE_WRITE_CACHE }); - - this.processQueue(); - }, - - /* - * - */ - writeCache: function writeCache(aStats, aCallback) { - debug("saveStats: " + aStats.appId + " " + aStats.isInBrowser + " " + - aStats.serviceType + " " + aStats.networkId + " " + - aStats.networkType + " " + aStats.date + " " + - aStats.rxBytes + " " + aStats.txBytes); - - // Generate an unique key from |appId|, |isInBrowser|, |serviceType| and - // |netId|, which is used to retrieve data in |cachedStats|. - let netId = this.getNetworkId(aStats.networkId, aStats.networkType); - let key = aStats.appId + "" + aStats.isInBrowser + "" + - aStats.serviceType + "" + netId; - - // |cachedStats| only keeps the data with the same date. - // If the incoming date is different from |cachedStatsDate|, - // both |cachedStats| and |cachedStatsDate| will get updated. - let diff = (this._db.normalizeDate(aStats.date) - - this._db.normalizeDate(this.cachedStatsDate)) / - this._db.sampleRate; - if (diff != 0) { - this.updateCache(function onUpdated(success, message) { - this.cachedStatsDate = aStats.date; - this.cachedStats[key] = aStats; - - if (aCallback) { - aCallback(true, "ok"); - } - }.bind(this)); - return; - } - - // Try to find the matched row in the cached by |appId| and |connectionType|. - // If not found, save the incoming data into the cached. - let cachedStats = this.cachedStats[key]; - if (!cachedStats) { - this.cachedStats[key] = aStats; - if (aCallback) { - aCallback(true, "ok"); - } - return; - } - - // Find matched row, accumulate the traffic amount. - cachedStats.rxBytes += aStats.rxBytes; - cachedStats.txBytes += aStats.txBytes; - - // If new rxBytes or txBytes exceeds MAX_CACHED_TRAFFIC - // the corresponding row will be saved to indexedDB. - // Then, the row will be removed from the cached. - if (cachedStats.rxBytes > MAX_CACHED_TRAFFIC || - cachedStats.txBytes > MAX_CACHED_TRAFFIC) { - this._db.saveStats(cachedStats, function (error, result) { - debug("Application stats inserted in indexedDB"); - if (aCallback) { - aCallback(true, "ok"); - } - }); - delete this.cachedStats[key]; - return; - } - - if (aCallback) { - aCallback(true, "ok"); - } - }, - - updateCachedStats: function updateCachedStats(aCallback) { - this.updateQueue.push({ callbacks: [aCallback], - queueType: QUEUE_TYPE_UPDATE_CACHE }); - - this.processQueue(); - }, - - updateCache: function updateCache(aCallback) { - debug("updateCache: " + this.cachedStatsDate); - - let stats = Object.keys(this.cachedStats); - if (stats.length == 0) { - // |cachedStats| is empty, no need to update. - if (aCallback) { - aCallback(true, "no need to update"); - } - return; - } - - let index = 0; - this._db.saveStats(this.cachedStats[stats[index]], - function onSavedStats(error, result) { - debug("Application stats inserted in indexedDB"); - - // Clean up the |cachedStats| after updating. - if (index == stats.length - 1) { - this.cachedStats = Object.create(null); - - if (aCallback) { - aCallback(true, "ok"); - } - return; - } - - // Update is not finished, keep updating. - index += 1; - this._db.saveStats(this.cachedStats[stats[index]], - onSavedStats.bind(this, error, result)); - }.bind(this)); - }, - - get maxCachedTraffic () { - return MAX_CACHED_TRAFFIC; - }, - - logAllRecords: function logAllRecords() { - this._db.logAllRecords(function onResult(aError, aResult) { - if (aError) { - debug("Error: " + aError); - return; - } - - debug("===== LOG ====="); - debug("There are " + aResult.length + " items"); - debug(JSON.stringify(aResult)); - }); - }, - - getAlarms: function getAlarms(mm, msg) { - let self = this; - let network = msg.data.network; - let manifestURL = msg.data.manifestURL; - - if (network) { - this.validateNetwork(network, function onValidateNetwork(aNetId) { - if (!aNetId) { - mm.sendAsyncMessage("NetworkStats:GetAlarms:Return", - { id: msg.id, error: "InvalidInterface", result: null }); - return; - } - - self._getAlarms(mm, msg, aNetId, manifestURL); - }); - return; - } - - this._getAlarms(mm, msg, null, manifestURL); - }, - - _getAlarms: function _getAlarms(mm, msg, aNetId, aManifestURL) { - let self = this; - this._db.getAlarms(aNetId, aManifestURL, function onCompleted(error, result) { - if (error) { - mm.sendAsyncMessage("NetworkStats:GetAlarms:Return", - { id: msg.id, error: error, result: result }); - return; - } - - let alarms = [] - // NetworkStatsManager must return the network instead of the networkId. - for (let i = 0; i < result.length; i++) { - let alarm = result[i]; - alarms.push({ id: alarm.id, - network: self._networks[alarm.networkId].network, - threshold: alarm.absoluteThreshold, - data: alarm.data }); - } - - mm.sendAsyncMessage("NetworkStats:GetAlarms:Return", - { id: msg.id, error: null, result: alarms }); - }); - }, - - removeAlarms: function removeAlarms(mm, msg) { - let alarmId = msg.data.alarmId; - let manifestURL = msg.data.manifestURL; - - let self = this; - let callback = function onRemove(error, result) { - if (error) { - mm.sendAsyncMessage("NetworkStats:RemoveAlarms:Return", - { id: msg.id, error: error, result: result }); - return; - } - - for (let i in self._currentAlarms) { - let currentAlarm = self._currentAlarms[i].alarm; - if (currentAlarm && ((alarmId == currentAlarm.id) || - (alarmId == -1 && currentAlarm.manifestURL == manifestURL))) { - - self._updateCurrentAlarm(currentAlarm.networkId); - } - } - - mm.sendAsyncMessage("NetworkStats:RemoveAlarms:Return", - { id: msg.id, error: error, result: true }); - }; - - if (alarmId == -1) { - this._db.removeAlarms(manifestURL, callback); - } else { - this._db.removeAlarm(alarmId, manifestURL, callback); - } - }, - - /* - * Function called from manager to set an alarm. - */ - setAlarm: function setAlarm(mm, msg) { - let options = msg.data; - let network = options.network; - let threshold = options.threshold; - - debug("Set alarm at " + threshold + " for " + JSON.stringify(network)); - - if (threshold < 0) { - mm.sendAsyncMessage("NetworkStats:SetAlarm:Return", - { id: msg.id, error: "InvalidThresholdValue", result: null }); - return; - } - - let self = this; - this.validateNetwork(network, function onValidateNetwork(aNetId) { - if (!aNetId) { - mm.sendAsyncMessage("NetworkStats:SetAlarm:Return", - { id: msg.id, error: "InvalidiConnectionType", result: null }); - return; - } - - let newAlarm = { - id: null, - networkId: aNetId, - absoluteThreshold: threshold, - relativeThreshold: null, - startTime: options.startTime, - data: options.data, - pageURL: options.pageURL, - manifestURL: options.manifestURL - }; - - self._getAlarmQuota(newAlarm, function onUpdate(error, quota) { - if (error) { - mm.sendAsyncMessage("NetworkStats:SetAlarm:Return", - { id: msg.id, error: error, result: null }); - return; - } - - self._db.addAlarm(newAlarm, function addSuccessCb(error, newId) { - if (error) { - mm.sendAsyncMessage("NetworkStats:SetAlarm:Return", - { id: msg.id, error: error, result: null }); - return; - } - - newAlarm.id = newId; - self._setAlarm(newAlarm, function onSet(error, success) { - mm.sendAsyncMessage("NetworkStats:SetAlarm:Return", - { id: msg.id, error: error, result: newId }); - - if (error == "InvalidStateError") { - self._fireAlarm(newAlarm); - } - }); - }); - }); - }); - }, - - _setAlarm: function _setAlarm(aAlarm, aCallback) { - let currentAlarm = this._currentAlarms[aAlarm.networkId]; - if ((Object.getOwnPropertyNames(currentAlarm).length !== 0 && - aAlarm.relativeThreshold > currentAlarm.alarm.relativeThreshold) || - this._networks[aAlarm.networkId].status != NETWORK_STATUS_READY) { - aCallback(null, true); - return; - } - - let self = this; - - this._getAlarmQuota(aAlarm, function onUpdate(aError, aQuota) { - if (aError) { - aCallback(aError, null); - return; - } - - let callback = function onAlarmSet(aError) { - if (aError) { - debug("Set alarm error: " + aError); - aCallback("netdError", null); - return; - } - - self._currentAlarms[aAlarm.networkId].alarm = aAlarm; - - aCallback(null, true); - }; - - debug("Set alarm " + JSON.stringify(aAlarm)); - let interfaceName = self._networks[aAlarm.networkId].interfaceName; - if (interfaceName) { - networkService.setNetworkInterfaceAlarm(interfaceName, - aQuota, - callback); - return; - } - - aCallback(null, true); - }); - }, - - _getAlarmQuota: function _getAlarmQuota(aAlarm, aCallback) { - let self = this; - this.updateStats(aAlarm.networkId, function onStatsUpdated(aResult, aMessage) { - self._db.getCurrentStats(self._networks[aAlarm.networkId].network, - aAlarm.startTime, - function onStatsFound(error, result) { - if (error) { - debug("Error getting stats for " + - JSON.stringify(self._networks[aAlarm.networkId]) + ": " + error); - aCallback(error, result); - return; - } - - let quota = aAlarm.absoluteThreshold - result.rxBytes - result.txBytes; - - // Alarm set to a threshold lower than current rx/tx bytes. - if (quota <= 0) { - aCallback("InvalidStateError", null); - return; - } - - aAlarm.relativeThreshold = aAlarm.startTime - ? result.rxTotalBytes + result.txTotalBytes + quota - : aAlarm.absoluteThreshold; - - aCallback(null, quota); - }); - }); - }, - - _fireAlarm: function _fireAlarm(aAlarm) { - debug("Fire alarm"); - - let self = this; - this._db.removeAlarm(aAlarm.id, null, function onRemove(aError, aResult){ - if (!aError && !aResult) { - return; - } - - self._fireSystemMessage(aAlarm); - self._updateCurrentAlarm(aAlarm.networkId); - }); - }, - - _updateCurrentAlarm: function _updateCurrentAlarm(aNetworkId) { - this._currentAlarms[aNetworkId] = Object.create(null); - - let self = this; - this._db.getFirstAlarm(aNetworkId, function onGet(error, result){ - if (error) { - debug("Error getting the first alarm"); - return; - } - - if (!result) { - let interfaceName = self._networks[aNetworkId].interfaceName; - networkService.setNetworkInterfaceAlarm(interfaceName, -1, - function onComplete(){}); - return; - } - - self._setAlarm(result, function onSet(error, success){ - if (error == "InvalidStateError") { - self._fireAlarm(result); - return; - } - }); - }); - }, - - _fireSystemMessage: function _fireSystemMessage(aAlarm) { - debug("Fire system message: " + JSON.stringify(aAlarm)); - - let manifestURI = Services.io.newURI(aAlarm.manifestURL, null, null); - let pageURI = Services.io.newURI(aAlarm.pageURL, null, null); - - let alarm = { "id": aAlarm.id, - "threshold": aAlarm.absoluteThreshold, - "data": aAlarm.data }; - messenger.sendMessage("networkstats-alarm", alarm, pageURI, manifestURI); - } -}; - -NetworkStatsService.init(); diff --git a/dom/network/NetworkStatsServiceProxy.js b/dom/network/NetworkStatsServiceProxy.js deleted file mode 100644 index f3df4344d..000000000 --- a/dom/network/NetworkStatsServiceProxy.js +++ /dev/null @@ -1,90 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -"use strict"; - -const DEBUG = false; -function debug(s) { dump("-*- NetworkStatsServiceProxy: " + s + "\n"); } - -const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components; - -this.EXPORTED_SYMBOLS = ["NetworkStatsServiceProxy"]; - -Cu.import("resource://gre/modules/XPCOMUtils.jsm"); -Cu.import("resource://gre/modules/NetworkStatsService.jsm"); - -const NETWORKSTATSSERVICEPROXY_CONTRACTID = "@mozilla.org/networkstatsServiceProxy;1"; -const NETWORKSTATSSERVICEPROXY_CID = Components.ID("98fd8f69-784e-4626-aa59-56d6436a3c24"); -const nsINetworkStatsServiceProxy = Ci.nsINetworkStatsServiceProxy; - -function NetworkStatsServiceProxy() { - if (DEBUG) { - debug("Proxy started"); - } -} - -NetworkStatsServiceProxy.prototype = { - /* - * Function called in the protocol layer (HTTP, FTP, WebSocket ...etc) - * to pass the per-app stats to NetworkStatsService. - */ - saveAppStats: function saveAppStats(aAppId, aIsInIsolatedMozBrowser, aNetworkInfo, aTimeStamp, - aRxBytes, aTxBytes, aIsAccumulative, - aCallback) { - if (!aNetworkInfo) { - if (DEBUG) { - debug("|aNetworkInfo| is not specified. Failed to save stats. Returning."); - } - return; - } - - if (DEBUG) { - debug("saveAppStats: " + aAppId + " " + aIsInIsolatedMozBrowser + " " + - aNetworkInfo.type + " " + aTimeStamp + " " + - aRxBytes + " " + aTxBytes + " " + aIsAccumulative); - } - - if (aCallback) { - aCallback = aCallback.notify; - } - - NetworkStatsService.saveStats(aAppId, aIsInIsolatedMozBrowser, "", aNetworkInfo, - aTimeStamp, aRxBytes, aTxBytes, - aIsAccumulative, aCallback); - }, - - /* - * Function called in the points of different system services - * to pass the per-service stats to NetworkStatsService. - */ - saveServiceStats: function saveServiceStats(aServiceType, aNetworkInfo, - aTimeStamp, aRxBytes, aTxBytes, - aIsAccumulative, aCallback) { - if (!aNetworkInfo) { - if (DEBUG) { - debug("|aNetworkInfo| is not specified. Failed to save stats. Returning."); - } - return; - } - - if (DEBUG) { - debug("saveServiceStats: " + aServiceType + " " + aNetworkInfo.type + " " + - aTimeStamp + " " + aRxBytes + " " + aTxBytes + " " + - aIsAccumulative); - } - - if (aCallback) { - aCallback = aCallback.notify; - } - - NetworkStatsService.saveStats(0, false, aServiceType , aNetworkInfo, aTimeStamp, - aRxBytes, aTxBytes, aIsAccumulative, - aCallback); - }, - - classID : NETWORKSTATSSERVICEPROXY_CID, - QueryInterface : XPCOMUtils.generateQI([nsINetworkStatsServiceProxy]), -} - -this.NSGetFactory = XPCOMUtils.generateNSGetFactory([NetworkStatsServiceProxy]); diff --git a/dom/network/NetworkStatsServiceProxy.manifest b/dom/network/NetworkStatsServiceProxy.manifest deleted file mode 100644 index 24f09f088..000000000 --- a/dom/network/NetworkStatsServiceProxy.manifest +++ /dev/null @@ -1,2 +0,0 @@ -component {98fd8f69-784e-4626-aa59-56d6436a3c24} NetworkStatsServiceProxy.js -contract @mozilla.org/networkstatsServiceProxy;1 {98fd8f69-784e-4626-aa59-56d6436a3c24} diff --git a/dom/network/interfaces/moz.build b/dom/network/interfaces/moz.build index add687542..ad2e56bd6 100644 --- a/dom/network/interfaces/moz.build +++ b/dom/network/interfaces/moz.build @@ -10,10 +10,4 @@ XPIDL_SOURCES += [ 'nsIUDPSocketChild.idl', ] -if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk': - XPIDL_SOURCES += [ - 'nsIEthernetManager.idl', - 'nsINetworkStatsServiceProxy.idl', - ] - XPIDL_MODULE = 'dom_network' diff --git a/dom/network/interfaces/nsIEthernetManager.idl b/dom/network/interfaces/nsIEthernetManager.idl deleted file mode 100644 index 2b92dc88f..000000000 --- a/dom/network/interfaces/nsIEthernetManager.idl +++ /dev/null @@ -1,137 +0,0 @@ -/* 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/. */ - -#include "nsISupports.idl" - -[scriptable, function, uuid(2a3ad56c-edc0-439f-8aae-900b331ddf49)] -interface nsIEthernetManagerCallback : nsISupports -{ - /** - * Callback function used to report the success of different operations. - * - * @param success - * Boolean value indicates the success of an operation. - * @prarm message - * Message reported in the end of operation. - */ - void notify(in boolean success, in DOMString message); -}; - -[scriptable, function, uuid(1746e7dd-92d4-43fa-8ef4-bc13d0b60353)] -interface nsIEthernetManagerScanCallback : nsISupports -{ - /** - * Callback function used to report the result of scan function. - * - * @param list - * List of available ethernet interfaces. - */ - void notify(in jsval list); -}; - -/** - * An internal idl provides control to ethernet interfaces. - */ -[scriptable, uuid(81750c87-bb3b-4724-b955-834eafa53fd1)] -interface nsIEthernetManager : nsISupports -{ - /** - * List of exisiting interface name. - */ - readonly attribute jsval interfaceList; - - /** - * Scan available ethernet interfaces on device. - * - * @param callback - * Callback function. - */ - void scan(in nsIEthernetManagerScanCallback callback); - - /** - * Add a new interface to the interface list. - * - * @param ifname - * Interface name. Should be the form of "eth*". - * @param callback - * Callback function. - */ - void addInterface(in DOMString ifname, - in nsIEthernetManagerCallback callback); - - /** - * Remove an existing interface from the interface list. - * - * @param ifname - * Interface name. - * @param Callback - * Callback function. - */ - void removeInterface(in DOMString ifname, - in nsIEthernetManagerCallback callback); - - /** - * Update a conifg of an existing interface in the interface list. - * - * @param ifname - * Interface name. - * @param config - * .ip: IP address. - * .prefixLength: Mask length. - * .gateway: Gateway. - * .dnses: DNS addresses. - * .httpProxyHost: HTTP proxy host. - * .httpProxyPort: HTTP proxy port. - * .ipMode: IP mode, can be 'dhcp' or 'static'. - * @param callback - * Callback function. - */ - void updateInterfaceConfig(in DOMString ifname, - in jsval config, - in nsIEthernetManagerCallback callback); - - /** - * Enable networking of an existing interface in the interface list. - * - * @param ifname - * Interface name. - * @param callback - * Callback function. - */ - void enable(in DOMString ifname, - in nsIEthernetManagerCallback callback); - - /** - * Disable networking of an existing interface in the interface list. - * - * @param ifname - * Interface name. - * @param callback - * Callback function. - */ - void disable(in DOMString ifname, - in nsIEthernetManagerCallback callback); - - /** - * Make an existing interface connect to network. - * - * @param ifname - * Interface name. - * @param callback - * Callback function. - */ - void connect(in DOMString ifname, - in nsIEthernetManagerCallback callback); - - /** - * Disconnect a connected interface in the interface list. - * - * @param ifname - * Interface name. - * @param callback - * Callback function. - */ - void disconnect(in DOMString ifname, - in nsIEthernetManagerCallback callback); -}; diff --git a/dom/network/interfaces/nsINetworkStatsServiceProxy.idl b/dom/network/interfaces/nsINetworkStatsServiceProxy.idl deleted file mode 100644 index cd6765c68..000000000 --- a/dom/network/interfaces/nsINetworkStatsServiceProxy.idl +++ /dev/null @@ -1,64 +0,0 @@ -/* 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/. */ - -#include "nsISupports.idl" - -interface nsINetworkInfo; - -[scriptable, function, uuid(5f821529-1d80-4ab5-a933-4e1b3585b6bc)] -interface nsINetworkStatsServiceProxyCallback : nsISupports -{ - /* - * @param aResult callback result with boolean value - * @param aMessage message - */ - void notify(in boolean aResult, in jsval aMessage); -}; - -[scriptable, uuid(f4f3e901-e102-499d-9d37-dc9951f52df7)] -interface nsINetworkStatsServiceProxy : nsISupports -{ - /* - * An interface used to record per-app traffic data. - * @param aAppId app id - * @param aIsInIsolatedMozBrowser - * true if the frame is an isolated mozbrowser element. <iframe - * mozbrowser mozapp> and <xul:browser> are not considered to be - * mozbrowser elements. <iframe mozbrowser noisolation> does not count - * as isolated since isolation is disabled. Isolation can only be - * disabled if the containing document is chrome. - * @param aNetworkInterface network - * @param aTimeStamp time stamp - * @param aRxBytes received data amount - * @param aTxBytes transmitted data amount - * @param aIsAccumulative is stats accumulative - * @param aCallback an optional callback - */ - void saveAppStats(in unsigned long aAppId, - in boolean aIsInIsolatedMozBrowser, - in nsINetworkInfo aNetworkInfo, - in unsigned long long aTimeStamp, - in unsigned long long aRxBytes, - in unsigned long long aTxBytes, - in boolean aIsAccumulative, - [optional] in nsINetworkStatsServiceProxyCallback aCallback); - - /* - * An interface used to record per-system service traffic data. - * @param aServiceType system service type - * @param aNetworkInterface network - * @param aTimeStamp time stamp - * @param aRxBytes received data amount - * @param aTxBytes transmitted data amount - * @param aIsAccumulative is stats accumulative - * @param aCallback an optional callback - */ - void saveServiceStats(in string aServiceType, - in nsINetworkInfo aNetworkInfo, - in unsigned long long aTimeStamp, - in unsigned long long aRxBytes, - in unsigned long long aTxBytes, - in boolean aIsAccumulative, - [optional] in nsINetworkStatsServiceProxyCallback aCallback); -}; diff --git a/dom/network/moz.build b/dom/network/moz.build index 63e5c75c0..ffb90d116 100644 --- a/dom/network/moz.build +++ b/dom/network/moz.build @@ -40,28 +40,6 @@ UNIFIED_SOURCES += [ 'UDPSocketParent.cpp', ] -if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk': - EXTRA_JS_MODULES += [ - 'NetworkStatsDB.jsm', - 'NetworkStatsService.jsm', - ] - -if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk': - EXTRA_COMPONENTS += [ - 'EthernetManager.js', - 'EthernetManager.manifest', - 'NetworkStatsManager.js', - 'NetworkStatsManager.manifest', - 'NetworkStatsServiceProxy.js', - 'NetworkStatsServiceProxy.manifest', - ] - EXPORTS.mozilla.dom.network += [ - 'NetUtils.h', - ] - UNIFIED_SOURCES += [ - 'NetUtils.cpp', - ] - IPDL_SOURCES += [ 'PTCPServerSocket.ipdl', 'PTCPSocket.ipdl', diff --git a/dom/permission/tests/mochitest.ini b/dom/permission/tests/mochitest.ini index 58fd048ca..2d4208e1f 100644 --- a/dom/permission/tests/mochitest.ini +++ b/dom/permission/tests/mochitest.ini @@ -7,7 +7,6 @@ support-files = [test_browser.html] skip-if = true [test_idle.html] -# skip-if = (toolkit == 'gonk' && debug) #debug-only failure skip-if = true [test_permissions.html] skip-if = true diff --git a/dom/speakermanager/SpeakerManager.cpp b/dom/speakermanager/SpeakerManager.cpp deleted file mode 100644 index 2b30fa72c..000000000 --- a/dom/speakermanager/SpeakerManager.cpp +++ /dev/null @@ -1,217 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -#include "SpeakerManager.h" - -#include "mozilla/Services.h" - -#include "mozilla/dom/Event.h" - -#include "AudioChannelService.h" -#include "nsIDocShell.h" -#include "nsIDOMClassInfo.h" -#include "nsIDOMEventListener.h" -#include "nsIInterfaceRequestorUtils.h" -#include "nsIPermissionManager.h" -#include "SpeakerManagerService.h" - -namespace mozilla { -namespace dom { - -NS_IMPL_QUERY_INTERFACE_INHERITED(SpeakerManager, DOMEventTargetHelper, - nsIDOMEventListener) -NS_IMPL_ADDREF_INHERITED(SpeakerManager, DOMEventTargetHelper) -NS_IMPL_RELEASE_INHERITED(SpeakerManager, DOMEventTargetHelper) - -SpeakerManager::SpeakerManager() - : mForcespeaker(false) - , mVisible(false) -{ - SpeakerManagerService *service = - SpeakerManagerService::GetOrCreateSpeakerManagerService(); - MOZ_ASSERT(service); - service->RegisterSpeakerManager(this); -} - -SpeakerManager::~SpeakerManager() -{ - SpeakerManagerService *service = SpeakerManagerService::GetOrCreateSpeakerManagerService(); - MOZ_ASSERT(service); - - service->UnRegisterSpeakerManager(this); - nsCOMPtr<EventTarget> target = do_QueryInterface(GetOwner()); - NS_ENSURE_TRUE_VOID(target); - - target->RemoveSystemEventListener(NS_LITERAL_STRING("visibilitychange"), - this, - /* useCapture = */ true); -} - -bool -SpeakerManager::Speakerforced() -{ - // If a background app calls forcespeaker=true that doesn't change anything. - // 'speakerforced' remains false everywhere. - if (mForcespeaker && !mVisible) { - return false; - } - SpeakerManagerService *service = SpeakerManagerService::GetOrCreateSpeakerManagerService(); - MOZ_ASSERT(service); - return service->GetSpeakerStatus(); - -} - -bool -SpeakerManager::Forcespeaker() -{ - return mForcespeaker; -} - -void -SpeakerManager::SetForcespeaker(bool aEnable) -{ - SpeakerManagerService *service = SpeakerManagerService::GetOrCreateSpeakerManagerService(); - MOZ_ASSERT(service); - - service->ForceSpeaker(aEnable, mVisible); - mForcespeaker = aEnable; -} - -void -SpeakerManager::DispatchSimpleEvent(const nsAString& aStr) -{ - MOZ_ASSERT(NS_IsMainThread(), "Not running on main thread"); - nsresult rv = CheckInnerWindowCorrectness(); - if (NS_FAILED(rv)) { - return; - } - - RefPtr<Event> event = NS_NewDOMEvent(this, nullptr, nullptr); - event->InitEvent(aStr, false, false); - event->SetTrusted(true); - - rv = DispatchDOMEvent(nullptr, event, nullptr, nullptr); - if (NS_FAILED(rv)) { - NS_ERROR("Failed to dispatch the event!!!"); - return; - } -} - -void -SpeakerManager::Init(nsPIDOMWindowInner* aWindow) -{ - BindToOwner(aWindow); - - nsCOMPtr<nsIDocShell> docshell = GetOwner()->GetDocShell(); - NS_ENSURE_TRUE_VOID(docshell); - docshell->GetIsActive(&mVisible); - - nsCOMPtr<nsIDOMEventTarget> target = do_QueryInterface(GetOwner()); - NS_ENSURE_TRUE_VOID(target); - - target->AddSystemEventListener(NS_LITERAL_STRING("visibilitychange"), - this, - /* useCapture = */ true, - /* wantsUntrusted = */ false); -} - -nsPIDOMWindowInner* -SpeakerManager::GetParentObject() const -{ - return GetOwner(); -} - -/* static */ already_AddRefed<SpeakerManager> -SpeakerManager::Constructor(const GlobalObject& aGlobal, ErrorResult& aRv) -{ - nsCOMPtr<nsIScriptGlobalObject> sgo = do_QueryInterface(aGlobal.GetAsSupports()); - if (!sgo) { - aRv.Throw(NS_ERROR_FAILURE); - return nullptr; - } - - nsCOMPtr<nsPIDOMWindowInner> ownerWindow = do_QueryInterface(aGlobal.GetAsSupports()); - if (!ownerWindow) { - aRv.Throw(NS_ERROR_FAILURE); - return nullptr; - } - - nsCOMPtr<nsIPermissionManager> permMgr = services::GetPermissionManager(); - NS_ENSURE_TRUE(permMgr, nullptr); - - uint32_t permission = nsIPermissionManager::DENY_ACTION; - nsresult rv = - permMgr->TestPermissionFromWindow(ownerWindow, "speaker-control", - &permission); - NS_ENSURE_SUCCESS(rv, nullptr); - - if (permission != nsIPermissionManager::ALLOW_ACTION) { - aRv.Throw(NS_ERROR_DOM_SECURITY_ERR); - return nullptr; - } - - RefPtr<SpeakerManager> object = new SpeakerManager(); - object->Init(ownerWindow); - return object.forget(); -} - -JSObject* -SpeakerManager::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) -{ - return MozSpeakerManagerBinding::Wrap(aCx, this, aGivenProto); -} - -NS_IMETHODIMP -SpeakerManager::HandleEvent(nsIDOMEvent* aEvent) -{ - nsAutoString type; - aEvent->GetType(type); - - if (!type.EqualsLiteral("visibilitychange")) { - return NS_ERROR_FAILURE; - } - - nsCOMPtr<nsIDocShell> docshell = do_GetInterface(GetOwner()); - NS_ENSURE_TRUE(docshell, NS_ERROR_FAILURE); - docshell->GetIsActive(&mVisible); - - // If an app that has called forcespeaker=true is switched - // from the background to the foreground 'speakerforced' - // switches to true in all apps. I.e. the app doesn't have to - // call forcespeaker=true again when it comes into foreground. - SpeakerManagerService *service = - SpeakerManagerService::GetOrCreateSpeakerManagerService(); - MOZ_ASSERT(service); - - if (mVisible && mForcespeaker) { - service->ForceSpeaker(mForcespeaker, mVisible); - } - // If an application that has called forcespeaker=true, but no audio is - // currently playing in the app itself, if application switch to - // the background, we switch 'speakerforced' to false. - if (!mVisible && mForcespeaker) { - RefPtr<AudioChannelService> audioChannelService = - AudioChannelService::GetOrCreate(); - if (audioChannelService && !audioChannelService->AnyAudioChannelIsActive()) { - service->ForceSpeaker(false, mVisible); - } - } - return NS_OK; -} - -void -SpeakerManager::SetAudioChannelActive(bool isActive) -{ - if (mForcespeaker) { - SpeakerManagerService *service = - SpeakerManagerService::GetOrCreateSpeakerManagerService(); - MOZ_ASSERT(service); - service->ForceSpeaker(isActive, mVisible); - } -} - -} // namespace dom -} // namespace mozilla diff --git a/dom/speakermanager/SpeakerManager.h b/dom/speakermanager/SpeakerManager.h deleted file mode 100644 index bf084dfd9..000000000 --- a/dom/speakermanager/SpeakerManager.h +++ /dev/null @@ -1,66 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -#ifndef mozilla_dom_SpeakerManager_h -#define mozilla_dom_SpeakerManager_h - -#include "mozilla/DOMEventTargetHelper.h" -#include "mozilla/dom/MozSpeakerManagerBinding.h" - -namespace mozilla { -namespace dom { -/* This class is used for UA to control devices's speaker status. - * After UA set the speaker status, the UA should handle the - * forcespeakerchange event and change the speaker status in UI. - * The device's speaker status would set back to normal when UA close the application. - */ -class SpeakerManager final - : public DOMEventTargetHelper - , public nsIDOMEventListener -{ - friend class SpeakerManagerService; - friend class SpeakerManagerServiceChild; - - NS_DECL_ISUPPORTS_INHERITED - NS_DECL_NSIDOMEVENTLISTENER - -public: - void Init(nsPIDOMWindowInner* aWindow); - - nsPIDOMWindowInner* GetParentObject() const; - - virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override; - /** - * WebIDL Interface - */ - // Get this api's force speaker setting. - bool Forcespeaker(); - // Force acoustic sound go through speaker. Don't force to speaker if application - // stay in the background and re-force when application - // go to foreground - void SetForcespeaker(bool aEnable); - // Get the device's speaker forced setting. - bool Speakerforced(); - - void SetAudioChannelActive(bool aIsActive); - IMPL_EVENT_HANDLER(speakerforcedchange) - - static already_AddRefed<SpeakerManager> - Constructor(const GlobalObject& aGlobal, ErrorResult& aRv); - -protected: - SpeakerManager(); - ~SpeakerManager(); - void DispatchSimpleEvent(const nsAString& aStr); - // This api's force speaker setting - bool mForcespeaker; - bool mVisible; -}; - -} // namespace dom -} // namespace mozilla - -#endif // mozilla_dom_SpeakerManager_h diff --git a/dom/speakermanager/SpeakerManagerService.cpp b/dom/speakermanager/SpeakerManagerService.cpp deleted file mode 100644 index a444f7163..000000000 --- a/dom/speakermanager/SpeakerManagerService.cpp +++ /dev/null @@ -1,224 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -#include "SpeakerManagerService.h" -#include "SpeakerManagerServiceChild.h" -#include "mozilla/Services.h" -#include "mozilla/StaticPtr.h" -#include "mozilla/Unused.h" -#include "mozilla/dom/ContentParent.h" -#include "nsIPropertyBag2.h" -#include "nsThreadUtils.h" -#include "nsServiceManagerUtils.h" -#include "AudioChannelService.h" -#include <cutils/properties.h> - -#define NS_AUDIOMANAGER_CONTRACTID "@mozilla.org/telephony/audiomanager;1" -#include "nsIAudioManager.h" - -using namespace mozilla; -using namespace mozilla::dom; - -StaticRefPtr<SpeakerManagerService> gSpeakerManagerService; - -// static -SpeakerManagerService* -SpeakerManagerService::GetOrCreateSpeakerManagerService() -{ - MOZ_ASSERT(NS_IsMainThread()); - - if (!XRE_IsParentProcess()) { - return SpeakerManagerServiceChild::GetOrCreateSpeakerManagerService(); - } - - // If we already exist, exit early - if (gSpeakerManagerService) { - return gSpeakerManagerService; - } - - // Create new instance, register, return - RefPtr<SpeakerManagerService> service = new SpeakerManagerService(); - - gSpeakerManagerService = service; - - return gSpeakerManagerService; -} - -SpeakerManagerService* -SpeakerManagerService::GetSpeakerManagerService() -{ - MOZ_ASSERT(NS_IsMainThread()); - - if (!XRE_IsParentProcess()) { - return SpeakerManagerServiceChild::GetSpeakerManagerService(); - } - - return gSpeakerManagerService; -} - -void -SpeakerManagerService::Shutdown() -{ - if (!XRE_IsParentProcess()) { - return SpeakerManagerServiceChild::Shutdown(); - } - - if (gSpeakerManagerService) { - gSpeakerManagerService = nullptr; - } -} - -NS_IMPL_ISUPPORTS(SpeakerManagerService, nsIObserver) - -void -SpeakerManagerService::ForceSpeaker(bool aEnable, uint64_t aChildId) -{ - TurnOnSpeaker(aEnable); - if (aEnable) { - mSpeakerStatusSet.Put(aChildId); - } - Notify(); - return; -} - -void -SpeakerManagerService::ForceSpeaker(bool aEnable, bool aVisible) -{ - // b2g main process without oop - TurnOnSpeaker(aEnable && aVisible); - mVisible = aVisible; - mOrgSpeakerStatus = aEnable; - Notify(); -} - -void -SpeakerManagerService::TurnOnSpeaker(bool aOn) -{ - nsCOMPtr<nsIAudioManager> audioManager = do_GetService(NS_AUDIOMANAGER_CONTRACTID); - NS_ENSURE_TRUE_VOID(audioManager); - int32_t phoneState; - audioManager->GetPhoneState(&phoneState); - int32_t forceuse = (phoneState == nsIAudioManager::PHONE_STATE_IN_CALL || - phoneState == nsIAudioManager::PHONE_STATE_IN_COMMUNICATION) - ? nsIAudioManager::USE_COMMUNICATION : nsIAudioManager::USE_MEDIA; - if (aOn) { - audioManager->SetForceForUse(forceuse, nsIAudioManager::FORCE_SPEAKER); - } else { - audioManager->SetForceForUse(forceuse, nsIAudioManager::FORCE_NONE); - } -} - -bool -SpeakerManagerService::GetSpeakerStatus() -{ - char propQemu[PROPERTY_VALUE_MAX]; - property_get("ro.kernel.qemu", propQemu, ""); - if (!strncmp(propQemu, "1", 1)) { - return mOrgSpeakerStatus; - } - nsCOMPtr<nsIAudioManager> audioManager = do_GetService(NS_AUDIOMANAGER_CONTRACTID); - NS_ENSURE_TRUE(audioManager, false); - int32_t usage; - audioManager->GetForceForUse(nsIAudioManager::USE_MEDIA, &usage); - return usage == nsIAudioManager::FORCE_SPEAKER; -} - -void -SpeakerManagerService::Notify() -{ - // Parent Notify to all the child processes. - nsTArray<ContentParent*> children; - ContentParent::GetAll(children); - for (uint32_t i = 0; i < children.Length(); i++) { - Unused << children[i]->SendSpeakerManagerNotify(); - } - - for (uint32_t i = 0; i < mRegisteredSpeakerManagers.Length(); i++) { - mRegisteredSpeakerManagers[i]-> - DispatchSimpleEvent(NS_LITERAL_STRING("speakerforcedchange")); - } -} - -void -SpeakerManagerService::SetAudioChannelActive(bool aIsActive) -{ - if (!aIsActive && !mVisible) { - ForceSpeaker(!mOrgSpeakerStatus, mVisible); - } -} - -NS_IMETHODIMP -SpeakerManagerService::Observe(nsISupports* aSubject, - const char* aTopic, - const char16_t* aData) -{ - if (!strcmp(aTopic, "ipc:content-shutdown")) { - nsCOMPtr<nsIPropertyBag2> props = do_QueryInterface(aSubject); - if (!props) { - NS_WARNING("ipc:content-shutdown message without property bag as subject"); - return NS_OK; - } - - uint64_t childID = 0; - nsresult rv = props->GetPropertyAsUint64(NS_LITERAL_STRING("childID"), - &childID); - if (NS_SUCCEEDED(rv)) { - // If the audio has paused by audiochannel, - // the enable flag should be false and don't need to handle. - if (mSpeakerStatusSet.Contains(childID)) { - TurnOnSpeaker(false); - mSpeakerStatusSet.Remove(childID); - } - if (mOrgSpeakerStatus) { - TurnOnSpeaker(!mOrgSpeakerStatus); - mOrgSpeakerStatus = false; - } - } else { - NS_WARNING("ipc:content-shutdown message without childID property"); - } - } else if (!strcmp(aTopic, "xpcom-will-shutdown")) { - // Note that we need to do this before xpcom-shutdown, since the - // AudioChannelService cannot be used past that point. - RefPtr<AudioChannelService> audioChannelService = - AudioChannelService::GetOrCreate(); - if (audioChannelService) { - audioChannelService->UnregisterSpeakerManager(this); - } - - nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService(); - if (obs) { - obs->RemoveObserver(this, "ipc:content-shutdown"); - obs->RemoveObserver(this, "xpcom-will-shutdown"); - } - - Shutdown(); - } - return NS_OK; -} - -SpeakerManagerService::SpeakerManagerService() - : mOrgSpeakerStatus(false), - mVisible(false) -{ - MOZ_COUNT_CTOR(SpeakerManagerService); - if (XRE_IsParentProcess()) { - nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService(); - if (obs) { - obs->AddObserver(this, "ipc:content-shutdown", false); - obs->AddObserver(this, "xpcom-will-shutdown", false); - } - } - RefPtr<AudioChannelService> audioChannelService = - AudioChannelService::GetOrCreate(); - if (audioChannelService) { - audioChannelService->RegisterSpeakerManager(this); - } -} - -SpeakerManagerService::~SpeakerManagerService() -{ - MOZ_COUNT_DTOR(SpeakerManagerService); -} diff --git a/dom/speakermanager/SpeakerManagerService.h b/dom/speakermanager/SpeakerManagerService.h deleted file mode 100644 index 5f3506ae2..000000000 --- a/dom/speakermanager/SpeakerManagerService.h +++ /dev/null @@ -1,79 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -#ifndef mozilla_dom_SpeakerManagerService_h__ -#define mozilla_dom_SpeakerManagerService_h__ - -#include "nsIObserver.h" -#include "nsTArray.h" -#include "SpeakerManager.h" -#include "nsIAudioManager.h" -#include "nsCheapSets.h" -#include "nsHashKeys.h" - -namespace mozilla { -namespace dom { - -class SpeakerManagerService : public nsIObserver -{ -public: - NS_DECL_ISUPPORTS - NS_DECL_NSIOBSERVER - /* - * Return null or instance which has been created. - */ - static SpeakerManagerService* GetSpeakerManagerService(); - /* - * Return SpeakerManagerService instance. - * If SpeakerManagerService is not exist, create and return new one. - */ - static SpeakerManagerService* GetOrCreateSpeakerManagerService(); - virtual void ForceSpeaker(bool aEnable, bool aVisible); - virtual bool GetSpeakerStatus(); - virtual void SetAudioChannelActive(bool aIsActive); - // Called by child - void ForceSpeaker(bool enable, uint64_t aChildid); - // Register the SpeakerManager to service for notify the speakerforcedchange event - void RegisterSpeakerManager(SpeakerManager* aSpeakerManager) - { - mRegisteredSpeakerManagers.AppendElement(aSpeakerManager); - } - void UnRegisterSpeakerManager(SpeakerManager* aSpeakerManager) - { - mRegisteredSpeakerManagers.RemoveElement(aSpeakerManager); - } - -protected: - SpeakerManagerService(); - - virtual ~SpeakerManagerService(); - // Notify to UA if device speaker status changed - virtual void Notify(); - - void TurnOnSpeaker(bool aEnable); - - /** - * Shutdown the singleton. - */ - static void Shutdown(); - - nsTArray<RefPtr<SpeakerManager> > mRegisteredSpeakerManagers; - // Set for remember all the child speaker status - nsCheapSet<nsUint64HashKey> mSpeakerStatusSet; - // The Speaker status assign by UA - bool mOrgSpeakerStatus; - - bool mVisible; - // This is needed for IPC communication between - // SpeakerManagerServiceChild and this class. - friend class ContentParent; - friend class ContentChild; -}; - -} // namespace dom -} // namespace mozilla - -#endif diff --git a/dom/speakermanager/SpeakerManagerServiceChild.cpp b/dom/speakermanager/SpeakerManagerServiceChild.cpp deleted file mode 100644 index 6c1e30b78..000000000 --- a/dom/speakermanager/SpeakerManagerServiceChild.cpp +++ /dev/null @@ -1,121 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -#include "SpeakerManagerServiceChild.h" -#include "mozilla/Services.h" -#include "mozilla/StaticPtr.h" -#include "mozilla/Unused.h" -#include "mozilla/dom/ContentChild.h" -#include "mozilla/dom/ContentParent.h" -#include "nsIObserverService.h" -#include "nsThreadUtils.h" -#include "AudioChannelService.h" -#include <cutils/properties.h> - -using namespace mozilla; -using namespace mozilla::dom; - -StaticRefPtr<SpeakerManagerServiceChild> gSpeakerManagerServiceChild; - -// static -SpeakerManagerService* -SpeakerManagerServiceChild::GetOrCreateSpeakerManagerService() -{ - MOZ_ASSERT(NS_IsMainThread()); - - // If we already exist, exit early - if (gSpeakerManagerServiceChild) { - return gSpeakerManagerServiceChild; - } - - // Create new instance, register, return - RefPtr<SpeakerManagerServiceChild> service = new SpeakerManagerServiceChild(); - - gSpeakerManagerServiceChild = service; - - return gSpeakerManagerServiceChild; -} - -// static -SpeakerManagerService* -SpeakerManagerServiceChild::GetSpeakerManagerService() -{ - MOZ_ASSERT(NS_IsMainThread()); - - return gSpeakerManagerServiceChild; -} - -void -SpeakerManagerServiceChild::ForceSpeaker(bool aEnable, bool aVisible) -{ - mVisible = aVisible; - mOrgSpeakerStatus = aEnable; - ContentChild *cc = ContentChild::GetSingleton(); - if (cc) { - cc->SendSpeakerManagerForceSpeaker(aEnable && aVisible); - } -} - -bool -SpeakerManagerServiceChild::GetSpeakerStatus() -{ - ContentChild *cc = ContentChild::GetSingleton(); - bool status = false; - if (cc) { - cc->SendSpeakerManagerGetSpeakerStatus(&status); - } - char propQemu[PROPERTY_VALUE_MAX]; - property_get("ro.kernel.qemu", propQemu, ""); - if (!strncmp(propQemu, "1", 1)) { - return mOrgSpeakerStatus; - } - return status; -} - -void -SpeakerManagerServiceChild::Shutdown() -{ - if (gSpeakerManagerServiceChild) { - gSpeakerManagerServiceChild = nullptr; - } -} - -void -SpeakerManagerServiceChild::SetAudioChannelActive(bool aIsActive) -{ - // Content process and switch to background with no audio and speaker forced. - // Then disable speaker - for (uint32_t i = 0; i < mRegisteredSpeakerManagers.Length(); i++) { - mRegisteredSpeakerManagers[i]->SetAudioChannelActive(aIsActive); - } -} - -SpeakerManagerServiceChild::SpeakerManagerServiceChild() -{ - MOZ_ASSERT(NS_IsMainThread()); - RefPtr<AudioChannelService> audioChannelService = AudioChannelService::GetOrCreate(); - if (audioChannelService) { - audioChannelService->RegisterSpeakerManager(this); - } - MOZ_COUNT_CTOR(SpeakerManagerServiceChild); -} - -SpeakerManagerServiceChild::~SpeakerManagerServiceChild() -{ - RefPtr<AudioChannelService> audioChannelService = AudioChannelService::GetOrCreate(); - if (audioChannelService) { - audioChannelService->UnregisterSpeakerManager(this); - } - MOZ_COUNT_DTOR(SpeakerManagerServiceChild); -} - -void -SpeakerManagerServiceChild::Notify() -{ - for (uint32_t i = 0; i < mRegisteredSpeakerManagers.Length(); i++) { - mRegisteredSpeakerManagers[i]->DispatchSimpleEvent(NS_LITERAL_STRING("speakerforcedchange")); - } -} diff --git a/dom/speakermanager/SpeakerManagerServiceChild.h b/dom/speakermanager/SpeakerManagerServiceChild.h deleted file mode 100644 index 5eb1c6afa..000000000 --- a/dom/speakermanager/SpeakerManagerServiceChild.h +++ /dev/null @@ -1,44 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -#ifndef mozilla_dom_SpeakerManagerServicechild_h__ -#define mozilla_dom_SpeakerManagerServicechild_h__ - -#include "nsISupports.h" -#include "SpeakerManagerService.h" - -namespace mozilla { -namespace dom { -/* This class is used to do the IPC to enable/disable speaker status - Also handle the application speaker competition problem -*/ -class SpeakerManagerServiceChild : public SpeakerManagerService -{ -public: - /* - * Return null or instance which has been created. - */ - static SpeakerManagerService* GetSpeakerManagerService(); - /* - * Return SpeakerManagerServiceChild instance. - * If SpeakerManagerServiceChild is not exist, create and return new one. - */ - static SpeakerManagerService* GetOrCreateSpeakerManagerService(); - static void Shutdown(); - virtual void ForceSpeaker(bool aEnable, bool aVisible) override; - virtual bool GetSpeakerStatus() override; - virtual void SetAudioChannelActive(bool aIsActive) override; - virtual void Notify() override; -protected: - SpeakerManagerServiceChild(); - virtual ~SpeakerManagerServiceChild(); -}; - -} // namespace dom -} // namespace mozilla - -#endif - diff --git a/dom/speakermanager/moz.build b/dom/speakermanager/moz.build deleted file mode 100644 index 22ed849fb..000000000 --- a/dom/speakermanager/moz.build +++ /dev/null @@ -1,23 +0,0 @@ -# -*- Mode: python; 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 += ['tests/mochitest.ini'] - -EXPORTS += [ - 'SpeakerManager.h', - 'SpeakerManagerService.h', - 'SpeakerManagerServiceChild.h', -] - -UNIFIED_SOURCES += [ - 'SpeakerManager.cpp', - 'SpeakerManagerService.cpp', - 'SpeakerManagerServiceChild.cpp', -] - -include('/ipc/chromium/chromium-config.mozbuild') - -FINAL_LIBRARY = 'xul' diff --git a/dom/speakermanager/tests/mochitest.ini b/dom/speakermanager/tests/mochitest.ini deleted file mode 100644 index bb272adc0..000000000 --- a/dom/speakermanager/tests/mochitest.ini +++ /dev/null @@ -1,3 +0,0 @@ -[DEFAULT] - -[test_speakermanager.html] diff --git a/dom/speakermanager/tests/test_speakermanager.html b/dom/speakermanager/tests/test_speakermanager.html deleted file mode 100644 index 509df5e84..000000000 --- a/dom/speakermanager/tests/test_speakermanager.html +++ /dev/null @@ -1,53 +0,0 @@ -<!DOCTYPE HTML> -<html> -<head> - <meta charset="utf-8"> - <title>Test MozSpeakerManager API</title> - <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> - <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> -</head> -<body> -<p id="display"></p> -<div id="content" style="display: none"></div> -<pre id="test"> - <script type="application/javascript"> - - "use strict"; - - function testObject() { - var mgr = new MozSpeakerManager(); - var spkforced = false; - mgr.onspeakerforcedchange = function() { - if (spkforced) { - is(mgr.speakerforced, true, 'speaker should be true'); - spkforced = false; - mgr.forcespeaker = false; - } else { - is(mgr.speakerforced, false, 'speaker should be false'); - SimpleTest.finish(); - } - } - spkforced = true; - mgr.forcespeaker = true; - } - - function startTests() { - // Currently applicable only on FxOS - if (navigator.userAgent.indexOf("Mobile") != -1 && - navigator.appVersion.indexOf("Android") == -1) { - testObject(); - } else { - ok(true, "MozSpeakerManager on Firefox OS only."); - SimpleTest.finish(); - } - } - - SimpleTest.waitForExplicitFinish(); - SpecialPowers.pushPermissions( - [{ "type": "speaker-control", "allow": 1, "context": document }], - startTests); - - </script> -</pre> -</body> -</html> diff --git a/dom/tethering/TetheringManager.js b/dom/tethering/TetheringManager.js deleted file mode 100644 index 1e3d3a0ea..000000000 --- a/dom/tethering/TetheringManager.js +++ /dev/null @@ -1,92 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -"use strict"; - -const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components; - -Cu.import("resource://gre/modules/XPCOMUtils.jsm"); -Cu.import("resource://gre/modules/Services.jsm"); -Cu.import("resource://gre/modules/DOMRequestHelper.jsm"); - -XPCOMUtils.defineLazyServiceGetter(this, "cpmm", - "@mozilla.org/childprocessmessagemanager;1", - "nsIMessageSender"); - -const DEBUG = false; - -const TETHERING_TYPE_WIFI = "wifi"; -const TETHERING_TYPE_BLUETOOTH = "bt"; -const TETHERING_TYPE_USB = "usb"; - -function TetheringManager() { -} - -TetheringManager.prototype = { - __proto__: DOMRequestIpcHelper.prototype, - - classDescription: "TetheringManager", - classID: Components.ID("{bd8a831c-d8ec-4f00-8803-606e50781097}"), - contractID: "@mozilla.org/dom/tetheringmanager;1", - - QueryInterface: XPCOMUtils.generateQI([Ci.nsIDOMGlobalPropertyInitializer, - Ci.nsISupportsWeakReference, - Ci.nsIObserver]), - - init: function(aWindow) { - const messages = ["WifiManager:setWifiTethering:Return:OK", - "WifiManager:setWifiTethering:Return:NO"]; - this.initDOMRequestHelper(aWindow, messages); - }, - - // TODO : aMessage format may be different after supporting bt/usb. - // for now, use wifi format first. - receiveMessage: function(aMessage) { - let data = aMessage.data.data; - - let resolver = this.takePromiseResolver(data.resolverId); - if (!resolver) { - return; - } - - switch (aMessage.name) { - case "WifiManager:setWifiTethering:Return:OK": - resolver.resolve(data); - break; - case "WifiManager:setWifiTethering:Return:NO": - resolver.reject(data.reason); - break; - } - }, - - setTetheringEnabled: function setTetheringEnabled(aEnabled, aType, aConfig) { - let self = this; - switch (aType) { - case TETHERING_TYPE_WIFI: - return this.createPromiseWithId(function(aResolverId) { - let data = { resolverId: aResolverId, enabled: aEnabled, config: aConfig }; - cpmm.sendAsyncMessage("WifiManager:setWifiTethering", { data: data}); - }); - case TETHERING_TYPE_BLUETOOTH: - case TETHERING_TYPE_USB: - default: - debug("tethering type(" + aType + ") doesn't support"); - return this.createPromiseWithId(function(aResolverId) { - self.takePromiseResolver(aResolverId).reject(); - }); - } - }, -}; - -this.NSGetFactory = - XPCOMUtils.generateNSGetFactory([TetheringManager]); - -var debug; -if (DEBUG) { - debug = function (s) { - dump("-*- TetheringManager component: " + s + "\n"); - }; -} else { - debug = function (s) {}; -} diff --git a/dom/tethering/TetheringManager.manifest b/dom/tethering/TetheringManager.manifest deleted file mode 100644 index 6ef01c69d..000000000 --- a/dom/tethering/TetheringManager.manifest +++ /dev/null @@ -1,4 +0,0 @@ -#TetheringManager.js -component {bd8a831c-d8ec-4f00-8803-606e50781097} TetheringManager.js -contract @mozilla.org/tetheringmanager;1 {bd8a831c-d8ec-4f00-8803-606e50781097} - diff --git a/dom/tethering/moz.build b/dom/tethering/moz.build deleted file mode 100644 index 4f68aca2d..000000000 --- a/dom/tethering/moz.build +++ /dev/null @@ -1,12 +0,0 @@ -# -*- Mode: python; 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/. - -EXTRA_COMPONENTS += [ - 'TetheringManager.js', - 'TetheringManager.manifest', -] - -FINAL_LIBRARY = 'xul' diff --git a/dom/tethering/tests/marionette/head.js b/dom/tethering/tests/marionette/head.js deleted file mode 100644 index c6b6abe26..000000000 --- a/dom/tethering/tests/marionette/head.js +++ /dev/null @@ -1,768 +0,0 @@ -/* 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/. */ - -const TYPE_WIFI = "wifi"; -const TYPE_BLUETOOTH = "bt"; -const TYPE_USB = "usb"; - -/** - * General tethering setting. - */ -const TETHERING_SETTING_IP = "192.168.1.1"; -const TETHERING_SETTNG_PREFIX = "24"; -const TETHERING_SETTING_START_IP = "192.168.1.10"; -const TETHERING_SETTING_END_IP = "192.168.1.30"; -const TETHERING_SETTING_DNS1 = "8.8.8.8"; -const TETHERING_SETTING_DNS2 = "8.8.4.4"; - -const TETHERING_NETWORK_ADDR = "192.168.1.0/24"; - -/** - * Wifi tethering setting. - */ -const TETHERING_SETTING_SSID = "FirefoxHotSpot"; -const TETHERING_SETTING_SECURITY = "open"; -const TETHERING_SETTING_KEY = "1234567890"; - -const SETTINGS_RIL_DATA_ENABLED = 'ril.data.enabled'; -const SETTINGS_KEY_DATA_APN_SETTINGS = "ril.data.apnSettings"; - -// Emulate Promise.jsm semantics. -Promise.defer = function() { return new Deferred(); } -function Deferred() { - this.promise = new Promise(function(resolve, reject) { - this.resolve = resolve; - this.reject = reject; - }.bind(this)); - Object.freeze(this); -} - -var gTestSuite = (function() { - let suite = {}; - - let tetheringManager; - let pendingEmulatorShellCount = 0; - - /** - * A wrapper function of "is". - * - * Calls the marionette function "is" as well as throws an exception - * if the givens values are not equal. - * - * @param value1 - * Any type of value to compare. - * - * @param value2 - * Any type of value to compare. - * - * @param message - * Debug message for this check. - * - */ - function isOrThrow(value1, value2, message) { - is(value1, value2, message); - if (value1 !== value2) { - throw message; - } - } - - /** - * Send emulator shell command with safe guard. - * - * We should only call |finish()| after all emulator command transactions - * end, so here comes with the pending counter. Resolve when the emulator - * gives positive response, and reject otherwise. - * - * Fulfill params: - * result -- an array of emulator response lines. - * Reject params: - * result -- an array of emulator response lines. - * - * @param aCommand - * A string command to be passed to emulator through its telnet console. - * - * @return A deferred promise. - */ - function runEmulatorShellSafe(aCommand) { - let deferred = Promise.defer(); - - ++pendingEmulatorShellCount; - runEmulatorShell(aCommand, function(aResult) { - --pendingEmulatorShellCount; - - ok(true, "Emulator shell response: " + JSON.stringify(aResult)); - if (Array.isArray(aResult)) { - deferred.resolve(aResult); - } else { - deferred.reject(aResult); - } - }); - - return deferred.promise; - } - - /** - * Wait for timeout. - * - * Resolve when the given duration elapsed. Never reject. - * - * Fulfill params: (none) - * - * @param aTimeoutMs - * The duration after which the timeout event should occurs. - * - * @return A deferred promise. - */ - function waitForTimeout(aTimeoutMs) { - let deferred = Promise.defer(); - - setTimeout(function() { - deferred.resolve(); - }, aTimeoutMs); - - return deferred.promise; - } - - /** - * Get mozSettings value specified by @aKey. - * - * Resolve if that mozSettings value is retrieved successfully, reject - * otherwise. - * - * Fulfill params: - * The corresponding mozSettings value of the key. - * Reject params: (none) - * - * @param aKey - * A string. - * - * @return A deferred promise. - */ - function getSettings(aKey) { - let request = navigator.mozSettings.createLock().get(aKey); - - return wrapDomRequestAsPromise(request) - .then(function resolve(aEvent) { - ok(true, "getSettings(" + aKey + ") - success"); - return aEvent.target.result[aKey]; - }, function reject(aEvent) { - ok(false, "getSettings(" + aKey + ") - error"); - throw aEvent.target.error; - }); - } - - /** - * Set mozSettings values. - * - * Resolve if that mozSettings value is set successfully, reject otherwise. - * - * Fulfill params: (none) - * Reject params: (none) - * - * @param aSettings - * An object of format |{key1: value1, key2: value2, ...}|. - * @return A deferred promise. - */ - function setSettings(aSettings) { - let lock = window.navigator.mozSettings.createLock(); - let request = lock.set(aSettings); - let deferred = Promise.defer(); - lock.onsettingstransactionsuccess = function () { - ok(true, "setSettings(" + JSON.stringify(aSettings) + ")"); - deferred.resolve(); - }; - lock.onsettingstransactionfailure = function (aEvent) { - ok(false, "setSettings(" + JSON.stringify(aSettings) + ")"); - deferred.reject(); - throw aEvent.target.error; - }; - return deferred.promise; - } - - /** - * Set mozSettings value with only one key. - * - * Resolve if that mozSettings value is set successfully, reject otherwise. - * - * Fulfill params: (none) - * Reject params: (none) - * - * @param aKey - * A string key. - * @param aValue - * An object value. - * @param aAllowError [optional] - * A boolean value. If set to true, an error response won't be treated - * as test failure. Default: false. - * - * @return A deferred promise. - */ - function setSettings1(aKey, aValue, aAllowError) { - let settings = {}; - settings[aKey] = aValue; - return setSettings(settings, aAllowError); - } - - /** - * Convenient MozSettings getter for SETTINGS_KEY_DATA_APN_SETTINGS. - */ - function getDataApnSettings(aAllowError) { - return getSettings(SETTINGS_KEY_DATA_APN_SETTINGS, aAllowError); - } - - /** - * Convenient MozSettings setter for SETTINGS_KEY_DATA_APN_SETTINGS. - */ - function setDataApnSettings(aApnSettings, aAllowError) { - return setSettings1(SETTINGS_KEY_DATA_APN_SETTINGS, aApnSettings, aAllowError); - } - - /** - * Set 'ro.tethering.dun_required' system property to 1. Note that this is a - * 'ro' property, it can only be set once. - */ - function setTetheringDunRequired() { - return runEmulatorShellSafe(['setprop', 'ro.tethering.dun_required', '1']); - } - - /** - * Wrap DOMRequest onsuccess/onerror events to Promise resolve/reject. - * - * Fulfill params: A DOMEvent. - * Reject params: A DOMEvent. - * - * @param aRequest - * A DOMRequest instance. - * - * @return A deferred promise. - */ - function wrapDomRequestAsPromise(aRequest) { - let deffered = Promise.defer(); - - ok(aRequest instanceof DOMRequest, - "aRequest is instanceof" + aRequest.constructor); - - aRequest.onsuccess = function(aEvent) { - deffered.resolve(aEvent); - }; - aRequest.onerror = function(aEvent) { - deffered.reject(aEvent); - }; - - return deffered.promise; - } - - /** - * Wait for one named MozMobileConnection event. - * - * Resolve if that named event occurs. Never reject. - * - * Fulfill params: the DOMEvent passed. - * - * @param aEventName - * A string event name. - * - * @return A deferred promise. - */ - function waitForMobileConnectionEventOnce(aEventName, aServiceId) { - aServiceId = aServiceId || 0; - - let deferred = Promise.defer(); - let mobileconnection = navigator.mozMobileConnections[aServiceId]; - - mobileconnection.addEventListener(aEventName, function onevent(aEvent) { - mobileconnection.removeEventListener(aEventName, onevent); - - ok(true, "Mobile connection event '" + aEventName + "' got."); - deferred.resolve(aEvent); - }); - - return deferred.promise; - } - - /** - * Wait for RIL data being connected. - * - * This function will check |MozMobileConnection.data.connected| on - * every 'datachange' event. Resolve when |MozMobileConnection.data.connected| - * becomes the expected state. Never reject. - * - * Fulfill params: (none) - * Reject params: (none) - * - * @param aConnected - * Boolean that indicates the desired data state. - * - * @param aServiceId [optional] - * A numeric DSDS service id. Default: 0. - * - * @return A deferred promise. - */ - function waitForRilDataConnected(aConnected, aServiceId) { - aServiceId = aServiceId || 0; - - return waitForMobileConnectionEventOnce('datachange', aServiceId) - .then(function () { - let mobileconnection = navigator.mozMobileConnections[aServiceId]; - if (mobileconnection.data.connected !== aConnected) { - return waitForRilDataConnected(aConnected, aServiceId); - } - }); - } - - /** - * Verify everything about routing when the wifi tethering is either on or off. - * - * We use two unix commands to verify the routing: 'netcfg' and 'ip route'. - * For now the following two things will be checked: - * 1) The default route interface should be 'rmnet0'. - * 2) wlan0 is up and its ip is set to a private subnet. - * - * We also verify iptables output as netd's NatController will execute - * $ iptables -t nat -A POSTROUTING -o rmnet0 -j MASQUERADE - * - * For tethering through dun, we use 'ip rule' to find the secondary routing - * table and look for default route on that table. - * - * Resolve when the verification is successful and reject otherwise. - * - * Fulfill params: (none) - * Reject params: String that indicates the reason of rejection. - * - * @return A deferred promise. - */ - function verifyTetheringRouting(aEnabled, aIsDun) { - let netcfgResult = {}; - let ipRouteResult = {}; - let ipSecondaryRouteResult = {}; - - // Execute 'netcfg' and parse to |netcfgResult|, each key of which is the - // interface name and value is { ip(string) }. - function exeAndParseNetcfg() { - return runEmulatorShellSafe(['netcfg']) - .then(function (aLines) { - // Sample output: - // - // lo UP 127.0.0.1/8 0x00000049 00:00:00:00:00:00 - // eth0 UP 10.0.2.15/24 0x00001043 52:54:00:12:34:56 - // rmnet1 DOWN 0.0.0.0/0 0x00001002 52:54:00:12:34:58 - // rmnet2 DOWN 0.0.0.0/0 0x00001002 52:54:00:12:34:59 - // rmnet3 DOWN 0.0.0.0/0 0x00001002 52:54:00:12:34:5a - // wlan0 UP 192.168.1.1/24 0x00001043 52:54:00:12:34:5b - // sit0 DOWN 0.0.0.0/0 0x00000080 00:00:00:00:00:00 - // rmnet0 UP 10.0.2.100/24 0x00001043 52:54:00:12:34:57 - // - aLines.forEach(function (aLine) { - let tokens = aLine.split(/\s+/); - if (tokens.length < 5) { - return; - } - let ifname = tokens[0]; - let ip = (tokens[2].split('/'))[0]; - netcfgResult[ifname] = { ip: ip }; - }); - }); - } - - // Execute 'ip route' and parse to |ipRouteResult|, each key of which is the - // interface name and value is { src(string), default(boolean) }. - function exeAndParseIpRoute() { - return runEmulatorShellSafe(['ip', 'route']) - .then(function (aLines) { - // Sample output: - // - // 10.0.2.4 via 10.0.2.2 dev rmnet0 - // 10.0.2.3 via 10.0.2.2 dev rmnet0 - // 192.168.1.0/24 dev wlan0 proto kernel scope link src 192.168.1.1 - // 10.0.2.0/24 dev eth0 proto kernel scope link src 10.0.2.15 - // 10.0.2.0/24 dev rmnet0 proto kernel scope link src 10.0.2.100 - // default via 10.0.2.2 dev rmnet0 - // default via 10.0.2.2 dev eth0 metric 2 - // - - // Parse source ip for each interface. - aLines.forEach(function (aLine) { - let tokens = aLine.trim().split(/\s+/); - let srcIndex = tokens.indexOf('src'); - if (srcIndex < 0 || srcIndex + 1 >= tokens.length) { - return; - } - let ifname = tokens[2]; - let src = tokens[srcIndex + 1]; - ipRouteResult[ifname] = { src: src, default: false }; - }); - - // Parse default interfaces. - aLines.forEach(function (aLine) { - let tokens = aLine.split(/\s+/); - if (tokens.length < 2) { - return; - } - if ('default' === tokens[0]) { - let ifnameIndex = tokens.indexOf('dev'); - if (ifnameIndex < 0 || ifnameIndex + 1 >= tokens.length) { - return; - } - let ifname = tokens[ifnameIndex + 1]; - if (ipRouteResult[ifname]) { - ipRouteResult[ifname].default = true; - } - return; - } - }); - - }); - - } - - // Find MASQUERADE in POSTROUTING section. 'MASQUERADE' should be found - // when tethering is enabled. 'MASQUERADE' shouldn't be found when tethering - // is disabled. - function verifyIptables() { - return runEmulatorShellSafe(['iptables', '-t', 'nat', '-L', 'POSTROUTING']) - .then(function(aLines) { - // $ iptables -t nat -L POSTROUTING - // - // Sample output (tethering on): - // - // Chain POSTROUTING (policy ACCEPT) - // target prot opt source destination - // MASQUERADE all -- anywhere anywhere - // - let found = (function find_MASQUERADE() { - // Skip first two lines. - for (let i = 2; i < aLines.length; i++) { - if (-1 !== aLines[i].indexOf('MASQUERADE')) { - return true; - } - } - return false; - })(); - - if ((aEnabled && !found) || (!aEnabled && found)) { - throw 'MASQUERADE' + (found ? '' : ' not') + ' found while tethering is ' + - (aEnabled ? 'enabled' : 'disabled'); - } - }); - } - - // Execute 'ip rule show', there must be one rule for tethering network - // address to lookup for a secondary routing table, return that table id. - function verifyIpRule() { - if (!aIsDun) { - return; - } - - return runEmulatorShellSafe(['ip', 'rule', 'show']) - .then(function (aLines) { - // Sample output: - // - // 0: from all lookup local - // 32765: from 192.168.1.0/24 lookup 60 - // 32766: from all lookup main - // 32767: from all lookup default - // - let tableId = (function findTableId() { - for (let i = 0; i < aLines.length; i++) { - let tokens = aLines[i].split(/\s+/); - if (-1 != tokens.indexOf(TETHERING_NETWORK_ADDR)) { - let lookupIndex = tokens.indexOf('lookup'); - if (lookupIndex < 0 || lookupIndex + 1 >= tokens.length) { - return; - } - return tokens[lookupIndex + 1]; - } - } - return; - })(); - - if ((aEnabled && !tableId) || (!aEnabled && tableId)) { - throw 'Secondary table' + (tableId ? '' : ' not') + ' found while tethering is ' + - (aEnabled ? 'enabled' : 'disabled'); - } - - return tableId; - }); - } - - // Given the table id, use 'ip rule show table <table id>' to find the - // default route on that secondary routing table. - function execAndParseSecondaryTable(aTableId) { - if (!aIsDun || !aEnabled) { - return; - } - - return runEmulatorShellSafe(['ip', 'route', 'show', 'table', aTableId]) - .then(function (aLines) { - // We only look for default route in secondary table. - aLines.forEach(function (aLine) { - let tokens = aLine.split(/\s+/); - if (tokens.length < 2) { - return; - } - if ('default' === tokens[0]) { - let ifnameIndex = tokens.indexOf('dev'); - if (ifnameIndex < 0 || ifnameIndex + 1 >= tokens.length) { - return; - } - let ifname = tokens[ifnameIndex + 1]; - ipSecondaryRouteResult[ifname] = { default: true }; - return; - } - }); - }); - } - - function verifyDefaultRouteAndIp(aExpectedWifiTetheringIp) { - log(JSON.stringify(ipRouteResult)); - log(JSON.stringify(ipSecondaryRouteResult)); - log(JSON.stringify(netcfgResult)); - - if (aEnabled) { - isOrThrow(ipRouteResult['rmnet0'].src, netcfgResult['rmnet0'].ip, 'rmnet0.ip'); - isOrThrow(ipRouteResult['rmnet0'].default, true, 'rmnet0.default'); - - isOrThrow(ipRouteResult['wlan0'].src, netcfgResult['wlan0'].ip, 'wlan0.ip'); - isOrThrow(ipRouteResult['wlan0'].src, aExpectedWifiTetheringIp, 'expected ip'); - isOrThrow(ipRouteResult['wlan0'].default, false, 'wlan0.default'); - - if (aIsDun) { - isOrThrow(ipRouteResult['rmnet1'].src, netcfgResult['rmnet1'].ip, 'rmnet1.ip'); - isOrThrow(ipRouteResult['rmnet1'].default, false, 'rmnet1.default'); - // Dun's network default route is set on secondary routing table. - isOrThrow(ipSecondaryRouteResult['rmnet1'].default, true, 'secondary rmnet1.default'); - } - } - } - - return verifyIptables() - .then(verifyIpRule) - .then(tableId => execAndParseSecondaryTable(tableId)) - .then(exeAndParseNetcfg) - .then(exeAndParseIpRoute) - .then(() => verifyDefaultRouteAndIp(TETHERING_SETTING_IP)); - } - - /** - * Request to enable/disable wifi tethering. - * - * Enable/disable wifi tethering by using setTetheringEnabled API - * Resolve when the routing is verified to set up successfully in 20 seconds. The polling - * period is 1 second. - * - * Fulfill params: (none) - * Reject params: The error message. - * - * @param aEnabled - * Boolean that indicates to enable or disable wifi tethering. - * @param aIsDun - * Boolean that indicates whether dun is required. - * - * @return A deferred promise. - */ - function setWifiTetheringEnabled(aEnabled, aIsDun) { - let RETRY_INTERVAL_MS = 1000; - let retryCnt = 20; - - let config = { - "ip" : TETHERING_SETTING_IP, - "prefix" : TETHERING_SETTNG_PREFIX, - "startIp" : TETHERING_SETTING_START_IP, - "endIp" : TETHERING_SETTING_END_IP, - "dns1" : TETHERING_SETTING_DNS1, - "dns2" : TETHERING_SETTING_DNS2, - "wifiConfig": { - "ssid" : TETHERING_SETTING_SSID, - "security" : TETHERING_SETTING_SECURITY - } - }; - - return tetheringManager.setTetheringEnabled(aEnabled, TYPE_WIFI, config) - .then(function waitForRoutingVerified() { - return verifyTetheringRouting(aEnabled, aIsDun) - .then(null, function onreject(aReason) { - - log('verifyTetheringRouting rejected due to ' + aReason + - ' (' + retryCnt + ')'); - - if (!retryCnt--) { - throw aReason; - } - - return waitForTimeout(RETRY_INTERVAL_MS).then(waitForRoutingVerified); - }); - }); - } - - /** - * Ensure wifi is enabled/disabled. - * - * Issue a wifi enable/disable request if wifi is not in the desired state; - * return a resolved promise otherwise. - * - * Fulfill params: (none) - * Reject params: (none) - * - * @return a resolved promise or deferred promise. - */ - function ensureWifiEnabled(aEnabled) { - let wifiManager = window.navigator.mozWifiManager; - if (wifiManager.enabled === aEnabled) { - return Promise.resolve(); - } - let request = wifiManager.setWifiEnabled(aEnabled); - return wrapDomRequestAsPromise(request) - } - - /** - * Ensure tethering manager exists. - * - * Check navigator property |mozTetheringManager| to ensure we could access - * tethering related function. - * - * Fulfill params: (none) - * Reject params: (none) - * - * @return A deferred promise. - */ - function ensureTetheringManager() { - let deferred = Promise.defer(); - - tetheringManager = window.navigator.mozTetheringManager; - - if (tetheringManager instanceof MozTetheringManager) { - deferred.resolve(); - } else { - log("navigator.mozTetheringManager is unavailable"); - deferred.reject(); - } - - return deferred.promise; - } - - /** - * Add required permissions for tethering. Never reject. - * - * The permissions required for wifi testing are 'wifi-manage' and 'settings-write'. - * Never reject. - * - * Fulfill params: (none) - * - * @return A deferred promise. - */ - function acquirePermission() { - let deferred = Promise.defer(); - - let permissions = [{ 'type': 'wifi-manage', 'allow': 1, 'context': window.document }, - { 'type': 'settings-write', 'allow': 1, 'context': window.document }, - { 'type': 'settings-read', 'allow': 1, 'context': window.document }, - { 'type': 'settings-api-write', 'allow': 1, 'context': window.document }, - { 'type': 'settings-api-read', 'allow': 1, 'context': window.document }, - { 'type': 'mobileconnection', 'allow': 1, 'context': window.document }]; - - SpecialPowers.pushPermissions(permissions, function() { - deferred.resolve(); - }); - - return deferred.promise; - } - - /** - * Common test routine. - * - * Start a test with the given test case chain. The test environment will be - * settled down before the test. After the test, all the affected things will - * be restored. - * - * Fulfill params: (none) - * Reject params: (none) - * - * @param aTestCaseChain - * The test case entry point, which can be a function or a promise. - * - * @return A deferred promise. - */ - suite.startTest = function(aTestCaseChain) { - function setUp() { - return ensureTetheringManager() - .then(acquirePermission); - } - - function tearDown() { - waitFor(finish, function() { - return pendingEmulatorShellCount === 0; - }); - } - - return setUp() - .then(aTestCaseChain) - .then(function onresolve() { - tearDown(); - }, function onreject(aReason) { - ok(false, 'Promise rejects during test' + (aReason ? '(' + aReason + ')' : '')); - tearDown(); - }); - }; - - //--------------------------------------------------- - // Public test suite functions - //--------------------------------------------------- - suite.ensureWifiEnabled = ensureWifiEnabled; - suite.setWifiTetheringEnabled = setWifiTetheringEnabled; - suite.getDataApnSettings = getDataApnSettings; - suite.setDataApnSettings = setDataApnSettings; - suite.setTetheringDunRequired = setTetheringDunRequired; - - - /** - * The common test routine for wifi tethering. - * - * Set 'ril.data.enabled' to true - * before testing and restore it afterward. It will also verify 'ril.data.enabled' - * and 'tethering.wifi.enabled' to be false in the beginning. Note that this routine - * will NOT change the state of 'tethering.wifi.enabled' so the user should enable - * than disable on his/her own. This routine will only check if tethering is turned - * off after testing. - * - * Fulfill params: (none) - * Reject params: (none) - * - * @param aTestCaseChain - * The test case entry point, which can be a function or a promise. - * - * @return A deferred promise. - */ - suite.startTetheringTest = function(aTestCaseChain) { - let oriDataEnabled; - function verifyInitialState() { - return getSettings(SETTINGS_RIL_DATA_ENABLED) - .then(enabled => initTetheringTestEnvironment(enabled)); - } - - function initTetheringTestEnvironment(aEnabled) { - oriDataEnabled = aEnabled; - if (aEnabled) { - return Promise.resolve(); - } else { - return Promise.all([waitForRilDataConnected(true), - setSettings1(SETTINGS_RIL_DATA_ENABLED, true)]); - } - } - - function restoreToInitialState() { - return setSettings1(SETTINGS_RIL_DATA_ENABLED, oriDataEnabled); - } - - return suite.startTest(function() { - return verifyInitialState() - .then(aTestCaseChain) - .then(restoreToInitialState, function onreject(aReason) { - return restoreToInitialState() - .then(() => { throw aReason; }); // Re-throw the orignal reject reason. - }); - }); - }; - - return suite; -})(); diff --git a/dom/tethering/tests/marionette/manifest.ini b/dom/tethering/tests/marionette/manifest.ini deleted file mode 100644 index 89065724f..000000000 --- a/dom/tethering/tests/marionette/manifest.ini +++ /dev/null @@ -1,7 +0,0 @@ -[DEFAULT] -run-if = buildapp == 'b2g' - -[test_wifi_tethering_enabled.js] -; The following test must be the last tethering test ran, as it sets the -; 'ro.tethering.dun_required' property. -[test_wifi_tethering_dun.js] diff --git a/dom/tethering/tests/marionette/test_wifi_tethering_dun.js b/dom/tethering/tests/marionette/test_wifi_tethering_dun.js deleted file mode 100644 index 3d93cf8d3..000000000 --- a/dom/tethering/tests/marionette/test_wifi_tethering_dun.js +++ /dev/null @@ -1,37 +0,0 @@ -/* 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/. */ - -MARIONETTE_TIMEOUT = 60000; -MARIONETTE_HEAD_JS = 'head.js'; - -gTestSuite.startTest(function() { - let origApnSettings; - return gTestSuite.getDataApnSettings() - .then(value => { - origApnSettings = value; - }) - .then(() => { - // Set dun apn settings. - let apnSettings = [[ { "carrier": "T-Mobile US", - "apn": "epc1.tmobile.com", - "mmsc": "http://mms.msg.eng.t-mobile.com/mms/wapenc", - "types": ["default","supl","mms"] }, - { "carrier": "T-Mobile US", - "apn": "epc2.tmobile.com", - "types": ["dun"] } ]]; - return gTestSuite.setDataApnSettings(apnSettings); - }) - .then(() => gTestSuite.setTetheringDunRequired()) - .then(() => gTestSuite.startTetheringTest(function() { - return gTestSuite.ensureWifiEnabled(false) - .then(() => gTestSuite.setWifiTetheringEnabled(true, true)) - .then(() => gTestSuite.setWifiTetheringEnabled(false, true)); - })) - // Restore apn settings. - .then(() => { - if (origApnSettings) { - return gTestSuite.setDataApnSettings(origApnSettings); - } - }); -});
\ No newline at end of file diff --git a/dom/tethering/tests/marionette/test_wifi_tethering_enabled.js b/dom/tethering/tests/marionette/test_wifi_tethering_enabled.js deleted file mode 100644 index 936219ec5..000000000 --- a/dom/tethering/tests/marionette/test_wifi_tethering_enabled.js +++ /dev/null @@ -1,12 +0,0 @@ -/* 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/. */ - -MARIONETTE_TIMEOUT = 60000; -MARIONETTE_HEAD_JS = 'head.js'; - -gTestSuite.startTetheringTest(function() { - return gTestSuite.ensureWifiEnabled(false) - .then(() => gTestSuite.setWifiTetheringEnabled(true)) - .then(() => gTestSuite.setWifiTetheringEnabled(false)); -}); diff --git a/dom/webidl/MozNetworkStats.webidl b/dom/webidl/MozNetworkStats.webidl deleted file mode 100644 index dc8635b87..000000000 --- a/dom/webidl/MozNetworkStats.webidl +++ /dev/null @@ -1,73 +0,0 @@ -/* 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/. */ - -/** - * Provide the detailed options for specifying different kinds of data filtering - * in getSamples function. - */ -dictionary NetworkStatsGetOptions -{ - /** - * App manifest URL is used to filter network stats by app, while service type - * is used to filter stats by system service. - * Note that, these two options cannot be specified at the same time for now; - * others, an NS_ERROR_NOT_IMPLMENTED exception will be thrown. - */ - DOMString? appManifestURL = null; - DOMString serviceType = ""; - /** - * If it is set as true, only the browsing traffic, which is generated from - * the mozbrowser iframe element within an app, is returned in result. - * If it is set as false or not set, the total traffic, which is generated - * from both the mozapp and mozbrowser iframe elements, is returned. - */ - boolean browsingTrafficOnly = false; -}; - -dictionary NetworkStatsAlarmOptions -{ - Date startTime; - Date data; -}; - -[JSImplementation="@mozilla.org/networkstats;1", - ChromeOnly, - Pref="dom.mozNetworkStats.enabled"] -interface MozNetworkStats { - /** - * App manifest URL of an application for specifying the per-app stats of the - * specified app. - */ - readonly attribute DOMString appManifestURL; - - /** - * True if this stats is the browsing traffic of an app (the traffic generated - * by a mozbrowser iframe element). - * Otherwise this stats represents the total traffic of an app. - */ - readonly attribute boolean browsingTrafficOnly; - - /** - * Service type is used to retrieve the corresponding "system-only" stats. - * E.g., "Tethering", "OTA", etc. - */ - readonly attribute DOMString serviceType; - - /** - * Network the returned data belongs to. - */ - readonly attribute MozNetworkStatsInterface network; - - /** - * Stats for a network. - */ - [Cached, Pure] - readonly attribute sequence<MozNetworkStatsData> data; - - /** - * Dates - */ - readonly attribute object start; - readonly attribute object end; -}; diff --git a/dom/webidl/MozNetworkStatsAlarm.webidl b/dom/webidl/MozNetworkStatsAlarm.webidl deleted file mode 100644 index e8bc01998..000000000 --- a/dom/webidl/MozNetworkStatsAlarm.webidl +++ /dev/null @@ -1,13 +0,0 @@ -/* 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/. */ - -[JSImplementation="@mozilla.org/networkstatsalarm;1", - ChromeOnly, - Pref="dom.mozNetworkStats.enabled"] -interface MozNetworkStatsAlarm { - readonly attribute unsigned long alarmId; - readonly attribute MozNetworkStatsInterface network; - readonly attribute long long threshold; - readonly attribute any data; -}; diff --git a/dom/webidl/MozNetworkStatsData.webidl b/dom/webidl/MozNetworkStatsData.webidl deleted file mode 100644 index 60d1e0d36..000000000 --- a/dom/webidl/MozNetworkStatsData.webidl +++ /dev/null @@ -1,12 +0,0 @@ -/* 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/. */ - -[JSImplementation="@mozilla.org/networkStatsdata;1", - ChromeOnly, - Pref="dom.mozNetworkStats.enabled"] -interface MozNetworkStatsData { - readonly attribute unsigned long rxBytes; // Received bytes. - readonly attribute unsigned long txBytes; // Sent bytes. - readonly attribute Date date; // Date. -}; diff --git a/dom/webidl/MozNetworkStatsInterface.webidl b/dom/webidl/MozNetworkStatsInterface.webidl deleted file mode 100644 index 82acfad6b..000000000 --- a/dom/webidl/MozNetworkStatsInterface.webidl +++ /dev/null @@ -1,26 +0,0 @@ -/* 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/. */ - -dictionary NetworkInterface { - long type; - DOMString id; -}; - -/** - * Represents a data interface for which the manager is recording statistics. - */ -[Constructor(optional NetworkInterface networkinterface), - JSImplementation="@mozilla.org/networkstatsinterface;1", - ChromeOnly, - Pref="dom.mozNetworkStats.enabled"] -interface MozNetworkStatsInterface { - readonly attribute long type; - - /** - * Id value is '0' for wifi or the iccid for mobile (SIM). - */ - readonly attribute DOMString id; - - jsonifier; -}; diff --git a/dom/webidl/MozNetworkStatsManager.webidl b/dom/webidl/MozNetworkStatsManager.webidl deleted file mode 100644 index 2c0e374d7..000000000 --- a/dom/webidl/MozNetworkStatsManager.webidl +++ /dev/null @@ -1,96 +0,0 @@ -/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. - */ - -[NavigatorProperty="mozNetworkStats", - JSImplementation="@mozilla.org/networkStatsManager;1", - ChromeOnly, - Pref="dom.mozNetworkStats.enabled"] -interface MozNetworkStatsManager { - /** - * Constants for known interface types. - */ - const long WIFI = 0; - const long MOBILE = 1; - - /** - * Find samples between two dates start and end, both included. - * - * If options is provided, per-app or per-system service usage will be - * retrieved; otherwise the target will be overall system usage. - * - * If success, the request result will be an MozNetworkStats object. - */ - DOMRequest getSamples(MozNetworkStatsInterface network, - Date start, - Date end, - optional NetworkStatsGetOptions options); - - /** - * Install an alarm on a network. The network must be in the return of - * getAvailableNetworks() otherwise an "InvalidNetwork" exception will - * be raised. - * - * When total data usage reaches threshold bytes, a "networkstats-alarm" - * system message is sent to the application, where the optional parameter - * |data| must be a cloneable object. - * - * If success, the |result| field of the DOMRequest keeps the alarm Id. - */ - DOMRequest addAlarm(MozNetworkStatsInterface network, - long long threshold, - optional NetworkStatsAlarmOptions options); - - /** - * Obtain all alarms for those networks returned by getAvailableNetworks(). - * If a network is provided, only retrieves the alarms for that network. - * The network must be one of those returned by getAvailebleNetworks() or an - * "InvalidNetwork" exception will be raised. - * - * Each alarm object has the same fields as that in the system message: - * - alarmId - * - network - * - threshold - * - data - */ - DOMRequest getAllAlarms(optional MozNetworkStatsInterface network); - - /** - * Remove all network alarms. If an |alarmId| is provided, then only that - * alarm is removed. - */ - DOMRequest removeAlarms(optional unsigned long alarmId = 0); - - /** - * Remove all stats related with the provided network from DB. - */ - DOMRequest clearStats(MozNetworkStatsInterface network); - - /** - * Remove all stats in the database. - */ - DOMRequest clearAllStats(); - - /** - * Return available networks that used to be saved in the database. - */ - DOMRequest getAvailableNetworks(); // array of MozNetworkStatsInterface. - - /** - * Return available service types that used to be saved in the database. - */ - DOMRequest getAvailableServiceTypes(); // array of string. - - /** - * Minimum time in milliseconds between samples stored in the database. - */ - readonly attribute long sampleRate; - - /** - * Time in milliseconds recorded by the API until present time. All samples - * older than maxStorageAge from now are deleted. - */ - readonly attribute long long maxStorageAge; -}; diff --git a/dom/webidl/MozSpeakerManager.webidl b/dom/webidl/MozSpeakerManager.webidl deleted file mode 100644 index 56ecf866f..000000000 --- a/dom/webidl/MozSpeakerManager.webidl +++ /dev/null @@ -1,18 +0,0 @@ -/* 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/. - */ - -/* - * Allow application can control acoustic sound output through speaker. - * Reference https://wiki.mozilla.org/WebAPI/SpeakerManager - */ -[Constructor()] -interface MozSpeakerManager : EventTarget { - /* query the speaker status */ - readonly attribute boolean speakerforced; - /* force device device's acoustic sound output through speaker */ - attribute boolean forcespeaker; - /* this event will be fired when device's speaker forced status change */ - attribute EventHandler onspeakerforcedchange; -}; diff --git a/dom/webidl/MozWifiCapabilities.webidl b/dom/webidl/MozWifiCapabilities.webidl deleted file mode 100644 index 3acf5fd55..000000000 --- a/dom/webidl/MozWifiCapabilities.webidl +++ /dev/null @@ -1,46 +0,0 @@ -/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=2 et sw=2 tw=80: */ -/* 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/. - */ - -/* - * The capabilities of Wifi. These are guaranteed not to change over the - * lifetime of that particular instance. - */ -enum WifiSecurityMethod { - "OPEN", - "WEP", - "WPA-PSK", - "WPA-EAP" -}; - -enum WifiWpaMethod { - "SIM", - "PEAP", - "TTLS", - "TLS" -}; - -enum WifiWpaPhase2Method { - "MSCHAPV2", - "GTC" -}; - -enum WifiWpaCertificate { - "SERVER", - "USER" -}; - -[JSImplementation="@mozilla.org/mozwificapabilities;1", - Func="Navigator::HasWifiManagerSupport"] -interface MozWifiCapabilities { - [Constant, Cached] readonly attribute sequence<WifiSecurityMethod> security; - [Constant, Cached] readonly attribute sequence<WifiWpaMethod> eapMethod; - [Constant, Cached] readonly attribute sequence<WifiWpaPhase2Method> eapPhase2; - [Constant, Cached] readonly attribute sequence<WifiWpaCertificate> certificate; - - jsonifier; -}; - diff --git a/dom/webidl/MozWifiConnectionInfoEvent.webidl b/dom/webidl/MozWifiConnectionInfoEvent.webidl deleted file mode 100644 index cfba1aa3e..000000000 --- a/dom/webidl/MozWifiConnectionInfoEvent.webidl +++ /dev/null @@ -1,43 +0,0 @@ -/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. - */ - -[Constructor(DOMString type, optional MozWifiConnectionInfoEventInit eventInitDict)] -interface MozWifiConnectionInfoEvent : Event -{ - /** - * Network object with an SSID field. - */ - readonly attribute any network; - - /** - * Strength of the signal to network, in dBm between -55 and -100 dBm. - */ - readonly attribute short signalStrength; - - /** - * Relative signal strength between 0 and 100. - */ - readonly attribute short relSignalStrength; - - /** - * Link speed in Mb/s. - */ - readonly attribute long linkSpeed; - - /** - * IP address in the dotted quad format. - */ - readonly attribute DOMString? ipAddress; -}; - -dictionary MozWifiConnectionInfoEventInit : EventInit -{ - any network = null; - short signalStrength = 0; - short relSignalStrength = 0; - long linkSpeed = 0; - DOMString ipAddress = ""; -}; diff --git a/dom/webidl/MozWifiManager.webidl b/dom/webidl/MozWifiManager.webidl deleted file mode 100644 index dd5aa5932..000000000 --- a/dom/webidl/MozWifiManager.webidl +++ /dev/null @@ -1,347 +0,0 @@ -/* 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/. */ - -enum WifiWPSMethod { - "pbc", - "pin", - "cancel" -}; - -enum ConnectionStatus { - "connecting", - "authenticating", - "associated", - "connected", - "disconnected", - "wps-timedout", - "wps-failed", - "wps-overlapped", - "connectingfailed" -}; - -dictionary WifiWPSInfo { - WifiWPSMethod method; - DOMString? pin; - DOMString? bssid; -}; - -dictionary NetworkProperties { - DOMString ssid; - long mode; - long frequency; - sequence<DOMString>? security; - sequence<DOMString>? capabilities; - boolean known; - boolean connected; - boolean hidden; - DOMString bssid; - DOMString signalStrength; - long relSignalStrength; - DOMString psk; - DOMString wep; - DOMString wep_key0; - DOMString wep_key1; - DOMString wep_key2; - DOMString wep_key3; - long wep_tx_keyidx; - long priority; - long scan_ssid; - DOMString keyManagement; - DOMString identity; - DOMString password; - DOMString auth_alg; - DOMString phase1; - DOMString phase2; - DOMString eap; - DOMString pin; - boolean dontConnect; - DOMString serverCertificate; - DOMString subjectMatch; - DOMString userCertificate; -}; - -[Constructor(optional NetworkProperties properties), - JSImplementation="@mozilla.org/mozwifinetwork;1", - Func="Navigator::HasWifiManagerSupport"] -interface MozWifiNetwork { - readonly attribute DOMString ssid; - readonly attribute long mode; - readonly attribute long frequency; - [Constant, Cached] readonly attribute sequence<DOMString>? security; - [Constant, Cached] readonly attribute sequence<DOMString>? capabilities; - readonly attribute boolean known; - readonly attribute boolean connected; - readonly attribute boolean hidden; - - attribute DOMString? bssid; - attribute DOMString? signalStrength; - attribute long? relSignalStrength; - attribute DOMString? psk; - attribute DOMString? wep; - attribute DOMString? wep_key0; - attribute DOMString? wep_key1; - attribute DOMString? wep_key2; - attribute DOMString? wep_key3; - attribute long? wep_tx_keyidx; - attribute long? priority; - attribute long? scan_ssid; - attribute DOMString? keyManagement; - attribute DOMString? identity; - attribute DOMString? password; - attribute DOMString? auth_alg; - attribute DOMString? phase1; - attribute DOMString? phase2; - attribute DOMString? eap; - attribute DOMString? pin; - attribute boolean? dontConnect; - attribute DOMString? serverCertificate; - attribute DOMString? subjectMatch; - attribute DOMString? userCertificate; -}; - -[JSImplementation="@mozilla.org/mozwificonnection;1", - ChromeOnly] -interface MozWifiConnection { - readonly attribute ConnectionStatus status; - readonly attribute MozWifiNetwork? network; -}; - -[JSImplementation="@mozilla.org/mozwificonnectioninfo;1", - ChromeOnly] -interface MozWifiConnectionInfo { - readonly attribute short signalStrength; - readonly attribute short relSignalStrength; - readonly attribute long linkSpeed; - readonly attribute DOMString? ipAddress; -}; - -dictionary IPConfiguration { - boolean enabled; - DOMString ipaddr; - DOMString proxy; - short maskLength; - DOMString gateway; - DOMString dns1; - DOMString dns2; -}; - -[JSImplementation="@mozilla.org/wifimanager;1", - NavigatorProperty="mozWifiManager", - Func="Navigator::HasWifiManagerSupport", - UnsafeInPrerendering] -interface MozWifiManager : EventTarget { - /** - * Turn on/off wifi functionality. - * @param enable true for enable, false for disable. - * onsuccess: Wifi enable/disable successfully, including no status change. - * onerror: Wifi enable/disable failed or prohibited. - */ - DOMRequest setWifiEnabled(boolean enabled); - - /** - * Returns the list of currently available networks. - * onsuccess: We have obtained the current list of networks. request.value - * is an object whose property names are SSIDs and values are - * network objects. - * onerror: We were unable to obtain a list of property names. - */ - DOMRequest getNetworks(); - - /** - * Returns the list of networks known to the system that will be - * automatically connected to if they're in range. - * onsuccess: request.value is an object whose property names are - * SSIDs and values are network objects. - * onerror: We were unable to obtain a list of known networks. - */ - DOMRequest getKnownNetworks(); - - /** - * Takes one of the networks returned from getNetworks and tries to - * connect to it. - * @param network A network object with information about the network, - * such as the SSID, key management desired, etc. - * onsuccess: We have started attempting to associate with the network. - * request.value is true. - * onerror: We were unable to select the network. This most likely means a - * configuration error. - */ - DOMRequest associate(MozWifiNetwork network); - - /** - * Given a network, removes it from the list of networks that we'll - * automatically connect to. In order to re-connect to the network, it is - * necessary to call associate on it. - * @param network A network object with the SSID of the network to remove. - * onsuccess: We have removed this network. If we were previously - * connected to it, we have started reconnecting to the next - * network in the list. - * onerror: We were unable to remove the network. - */ - DOMRequest forget(MozWifiNetwork network); - - /** - * Wi-Fi Protected Setup functionality. - * @param detail WPS detail which has 'method' and 'pin' field. - * The possible method field values are: - * - pbc: The Push Button Configuration. - * - pin: The PIN configuration. - * - cancel: Request to cancel WPS in progress. - * If method field is 'pin', 'pin' field can exist and has - * a PIN number. - * If method field is 'pin', 'bssid' field can exist and has - * a opposite BSSID. - * onsuccess: We have successfully started/canceled wps. - * onerror: We have failed to start/cancel wps. - */ - DOMRequest wps(optional WifiWPSInfo detail); - - /** - * Turn on/off wifi power saving mode. - * @param enabled true or false. - * onsuccess: We have successfully turn on/off wifi power saving mode. - * onerror: We have failed to turn on/off wifi power saving mode. - */ - DOMRequest setPowerSavingMode(boolean enabled); - - /** - * Given a network, configure using static IP instead of running DHCP - * @param network A network object with the SSID of the network to set static ip. - * @param info info should have following field: - * - enabled True to enable static IP, false to use DHCP - * - ipaddr configured static IP address - * - proxy configured proxy server address - * - maskLength configured mask length - * - gateway configured gateway address - * - dns1 configured first DNS server address - * - dns2 configured seconf DNS server address - * onsuccess: We have successfully configure the static ip mode. - * onerror: We have failed to configure the static ip mode. - */ - DOMRequest setStaticIpMode(MozWifiNetwork network, optional IPConfiguration info); - - /** - * Given a network, configure http proxy when using wifi. - * @param network A network object with the SSID of the network to set http proxy. - * @param info info should have following field: - * - httpProxyHost ip address of http proxy. - * - httpProxyPort port of http proxy, set 0 to use default port 8080. - * set info to null to clear http proxy. - * onsuccess: We have successfully configure http proxy. - * onerror: We have failed to configure http proxy. - */ - DOMRequest setHttpProxy(MozWifiNetwork network, any info); - - /** - * Import a certificate file, only support CA certificate now. - * @param certBlob A Blob object containing raw data of certificate to be imported. - * Supported format: binary/base64 encoded DER certificates. - * (.der/.crt/.cer/.pem) - * Cause error if importing certificates already imported. - * @param certPassword Password of certificate. - * @param certNickname User assigned nickname for imported certificate. - * Nickname must be unique, it causes error on redundant nickname. - * onsuccess: We have successfully imported certificate. request.result is an - * object, containing information of imported CA: - * { - * nickname: Nickname of imported CA, String. - * usage: Supported usage of imported CA, Array of String, - * includes: "ServerCert". - * } - * onerror: We have failed to import certificate. - */ - DOMRequest importCert(Blob certBlob, - DOMString certPassword, - DOMString certNickname); - - /** - * Get list of imported WIFI certificates. - * onsuccess: We have successfully gotten imported certificate list. - * request.result is an object using nickname as key, array of usage - * string as value. - * request.result[USAGE] = [CA_NICKNAME1, CA_NICKNAME2, ...] - * USAGE string includes: "ServerCert". - * onerror: We have failed to list certificate. - */ - DOMRequest getImportedCerts(); - - /** - * Delete an imported certificate. - * @param certNickname Nickname of imported to be deleted. - * onsuccess: We have successfully deleted certificate. - * onerror: We have failed to delete certificate. - */ - DOMRequest deleteCert(DOMString certNickname); - - /** - * Returns whether or not wifi is currently enabled. - */ - readonly attribute boolean enabled; - - /** - * Returns the MAC address of the wifi adapter. - */ - readonly attribute DOMString macAddress; - - /** - * An non-null object containing the following information: - * - status ("disconnected", "connecting", "associated", "connected") - * - network - * - * Note that the object returned is read only. Any changes required must - * be done by calling other APIs. - */ - readonly attribute MozWifiConnection connection; - - /** - * A connectionInformation object with the same information found in an - * MozWifiConnectionInfoEvent (but without the network). - * If we are not currently connected to a network, this will be null. - */ - readonly attribute MozWifiConnectionInfo? connectionInformation; - - /** - * Capabilities of Wifi. - */ - readonly attribute MozWifiCapabilities? capabilities; - - /** - * State notification listeners. These all take an - * MozWifiStatusChangeEvent with the new status and a network (which may be - * null). - * - * The possible statuses are: - * - connecting: Fires when we start the process of connecting to a - * network. - * - associated: Fires when we have connected to an access point but do - * not yet have an IP address. - * - connected: Fires once we are fully connected to an access point and - * can access the internet. - * - disconnected: Fires when we either fail to connect to an access - * point (transition: associated -> disconnected) or - * when we were connected to a network but have - * disconnected for any reason (transition: connected -> - * disconnected). - */ - attribute EventHandler onstatuschange; - - /** - * An event listener that is called with information about the signal - * strength and link speed every 5 seconds. - */ - attribute EventHandler onconnectioninfoupdate; - - /** - * These two events fire when the wifi system is brought online or taken - * offline. - */ - attribute EventHandler onenabled; - attribute EventHandler ondisabled; - - /** - * An event listener that is called with information about the number - * of wifi stations connected to wifi hotspot every 5 seconds. - */ - attribute EventHandler onstationinfoupdate; -}; diff --git a/dom/webidl/MozWifiP2pManager.webidl b/dom/webidl/MozWifiP2pManager.webidl deleted file mode 100644 index 58ac1f7be..000000000 --- a/dom/webidl/MozWifiP2pManager.webidl +++ /dev/null @@ -1,147 +0,0 @@ -/* 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/. */ - -enum WPSMethod { - "pbc", - "keypad", - "display" -}; - -dictionary WPSInfo { - WPSMethod method; - DOMString pin; -}; - -[JSImplementation="@mozilla.org/wifip2pgroupowner;1", - Func="Navigator::HasWifiManagerSupport"] -interface MozWifiP2pGroupOwner { - readonly attribute DOMString groupName; - readonly attribute DOMString macAddress; - readonly attribute DOMString ipAddress; - readonly attribute DOMString passphrase; - readonly attribute DOMString ssid; - readonly attribute any wpsCapabilities; - readonly attribute unsigned long freq; - readonly attribute boolean isLocal; -}; - -[JSImplementation="@mozilla.org/wifip2pmanager;1", - NavigatorProperty="mozWifiP2pManager", - Func="Navigator::HasWifiManagerSupport"] -interface MozWifiP2pManager : EventTarget -{ - /** - * Enable/Disable wifi direct scan. - * - * onsuccess: Succeeded in starting/stopping wifi direct scan. - * onerror: Failed to start/stop wifi direct scan. - * - */ - DOMRequest setScanEnabled(boolean enabled); - - /** - * Connect to a peer with given configuration. - * - * @param address The peer MAC address we are going to connect. - * @param wpsMethod The WPS method we want to use. - * @param goIntent Number from 0 ~ 15 to indicate how much we want to be - * the group owner. - * - * onsuccess: Succeeded in issueing a 'connect' request. It doesn't mean we - * have connected to the peer. - * - * onerror: Failed to issue a 'connect' request, probably due to an - * invalid peer address, unsupported wps method or any - * preliminary error. - * - **/ - DOMRequest connect(DOMString address, WPSMethod wpsMethod, optional byte goIntent); - - /** - * Disconnect with a peer. - * - * @param address The mac address of the peer. - * - * onsuccess: Succeeded to issue a 'disconnect' request. It doesn't mean we - * have disconnected with the peer. - * - * onerror: Failed to issue a 'disconnect' request, probably due to the - * invalid peer address or any preliminary error. - * - */ - DOMRequest disconnect(DOMString address); - - /** - * Get peer list - * - * onsuccess: Command success, req.result contains an array of peer objects. - * onerror: Command failed. - * - * Peer object format: - * .address MAC address of the peer (string) - * .name the peer's device name (string) - * .isGroupOwner if the peer is the group owner (boolean) - * .wpsCapabilities array of the supported |WPSMethod| - * .connectionStatus one of { "disconnected", "connecting", "connected", "disconnecting" } - * - */ - DOMRequest getPeerList(); - - /** - * Set pairing confirmation result. - * - * @param accepted Boolean to indicate whether we accepted the request or not. - * @param pin The user input pin number if the wps method is keypad. - * - * onsuccess: Command succeeded. - * onerror: Command failed. - * - */ - DOMRequest setPairingConfirmation(boolean accepted, optional DOMString pin); - - /** - * Set device name. - * - * @param devieName The new device name we are going to set. - * - * onsuccess: Command succeeded. - * onerror: Command failed. - * - */ - DOMRequest setDeviceName(DOMString deviceName); - - /** - * Returns if Wifi Direct is enabled. - * - */ - readonly attribute boolean enabled; - - /** - * The current group owner, null if none. - */ - readonly attribute MozWifiP2pGroupOwner? groupOwner; - - /** - * An event listener that is called whenever the Wifi Direct peer list is - * updated. Use getPeerList() to get the up-to-date peer list. - */ - attribute EventHandler onpeerinfoupdate; - - /** - * An event listener that is called whenever Wifi Direct status changed. - * The address of the changed peer will be stored in event.peerList. - * See MozWifiP2pStatusChangeEvent.webidl. - */ - attribute EventHandler onstatuschange; - - /** - * An event listener that is called whenever Wifi Direct is enabled. - */ - attribute EventHandler onenabled; - - /** - * An event listener that is called whenever Wifi Direct is disabled. - */ - attribute EventHandler ondisabled; -}; diff --git a/dom/webidl/MozWifiP2pStatusChangeEvent.webidl b/dom/webidl/MozWifiP2pStatusChangeEvent.webidl deleted file mode 100644 index be96e2786..000000000 --- a/dom/webidl/MozWifiP2pStatusChangeEvent.webidl +++ /dev/null @@ -1,20 +0,0 @@ -/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. - */ - -[Constructor(DOMString type, optional MozWifiP2pStatusChangeEventInit eventInitDict), - Func="Navigator::HasWifiManagerSupport"] -interface MozWifiP2pStatusChangeEvent : Event -{ - /** - * The mac address of the peer whose status has just changed. - */ - readonly attribute DOMString peerAddress; -}; - -dictionary MozWifiP2pStatusChangeEventInit : EventInit -{ - DOMString peerAddress = ""; -}; diff --git a/dom/webidl/MozWifiStationInfoEvent.webidl b/dom/webidl/MozWifiStationInfoEvent.webidl deleted file mode 100644 index ff3f5ac6a..000000000 --- a/dom/webidl/MozWifiStationInfoEvent.webidl +++ /dev/null @@ -1,19 +0,0 @@ -/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. - */ - -[Constructor(DOMString type, optional MozWifiStationInfoEventInit eventInitDict)] -interface MozWifiStationInfoEvent : Event -{ - /** - * The number of wifi stations connected to wifi hotspot. - */ - readonly attribute short station; -}; - -dictionary MozWifiStationInfoEventInit : EventInit -{ - short station = 0; -}; diff --git a/dom/webidl/MozWifiStatusChangeEvent.webidl b/dom/webidl/MozWifiStatusChangeEvent.webidl deleted file mode 100644 index 20d16e4d9..000000000 --- a/dom/webidl/MozWifiStatusChangeEvent.webidl +++ /dev/null @@ -1,27 +0,0 @@ -/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. - */ - -[Constructor(DOMString type, optional MozWifiStatusChangeEventInit eventInitDict)] -interface MozWifiStatusChangeEvent : Event -{ - /** - * Network object with a SSID field describing the network affected by - * this change. This might be null. - */ - readonly attribute any network; - - /** - * String describing the current status of the wifi manager. See above for - * the possible values. - */ - readonly attribute DOMString? status; -}; - -dictionary MozWifiStatusChangeEventInit : EventInit -{ - any network = null; - DOMString status = ""; -}; diff --git a/dom/webidl/moz.build b/dom/webidl/moz.build index b246b410c..4c2567a1c 100644 --- a/dom/webidl/moz.build +++ b/dom/webidl/moz.build @@ -677,22 +677,9 @@ if CONFIG['MOZ_SECUREELEMENT']: 'SecureElementManager.webidl', ] -if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk': - WEBIDL_FILES += [ - 'MozNetworkStats.webidl', - 'MozNetworkStatsAlarm.webidl', - 'MozNetworkStatsData.webidl', - 'MozNetworkStatsInterface.webidl', - 'MozNetworkStatsManager.webidl', - 'MozSpeakerManager.webidl', - 'MozWifiCapabilities.webidl', - 'MozWifiManager.webidl', - 'MozWifiP2pManager.webidl', - ] -else: - WEBIDL_FILES += [ - 'InstallTrigger.webidl', - ] +WEBIDL_FILES += [ + 'InstallTrigger.webidl', +] GENERATED_EVENTS_WEBIDL_FILES = [ 'AnimationPlaybackEvent.webidl', @@ -761,14 +748,6 @@ if CONFIG['MOZ_GAMEPAD']: 'GamepadEvent.webidl', ] -if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk': - GENERATED_EVENTS_WEBIDL_FILES += [ - 'MozWifiConnectionInfoEvent.webidl', - 'MozWifiP2pStatusChangeEvent.webidl', - 'MozWifiStationInfoEvent.webidl', - 'MozWifiStatusChangeEvent.webidl', - ] - if CONFIG['MOZ_BUILD_APP'] in ['xulrunner'] or CONFIG['MOZ_PHOENIX'] or CONFIG['MOZ_SUITE']: WEBIDL_FILES += [ 'BrowserFeedWriter.webidl', diff --git a/dom/wifi/DOMWifiManager.js b/dom/wifi/DOMWifiManager.js deleted file mode 100644 index 8bedfc398..000000000 --- a/dom/wifi/DOMWifiManager.js +++ /dev/null @@ -1,543 +0,0 @@ -/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ -/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -"use strict"; - -const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components; - -Cu.import("resource://gre/modules/XPCOMUtils.jsm"); -Cu.import("resource://gre/modules/Services.jsm"); -Cu.import("resource://gre/modules/DOMRequestHelper.jsm"); - -const DEBUG = false; // set to false to suppress debug messages - -const DOMWIFIMANAGER_CONTRACTID = "@mozilla.org/wifimanager;1"; -const DOMWIFIMANAGER_CID = Components.ID("{c9b5f09e-25d2-40ca-aef4-c4d13d93c706}"); - -function MozWifiNetwork() { -} - -MozWifiNetwork.prototype = { - - init: function(aWindow) { - this._window = aWindow; - }, - - __init: function(obj) { - for (let key in obj) { - this[key] = obj[key]; - } - }, - - classID: Components.ID("{c01fd751-43c0-460a-8b64-abf652ec7220}"), - contractID: "@mozilla.org/mozwifinetwork;1", - QueryInterface: XPCOMUtils.generateQI([Ci.nsISupports, - Ci.nsIDOMGlobalPropertyInitializer]) -}; - -function MozWifiConnection(obj) { - this.status = obj.status; - this.network = obj.network; -} - -MozWifiConnection.prototype = { - classID: Components.ID("{23579da4-201b-4319-bd42-9b7f337343ac}"), - contractID: "@mozilla.org/mozwificonnection;1", - QueryInterface: XPCOMUtils.generateQI([Ci.nsISupports]) -}; - -function MozWifiConnectionInfo(obj) { - this.signalStrength = obj.signalStrength; - this.relSignalStrength = obj.relSignalStrength; - this.linkSpeed = obj.linkSpeed; - this.ipAddress = obj.ipAddress; -} - -MozWifiConnectionInfo.prototype = { - classID: Components.ID("{83670352-6ed4-4c35-8de9-402296a1959c}"), - contractID: "@mozilla.org/mozwificonnectioninfo;1", - QueryInterface: XPCOMUtils.generateQI([Ci.nsISupports]) -} - -function MozWifiCapabilities(obj) { - this.security = obj.security; - this.eapMethod = obj.eapMethod; - this.eapPhase2 = obj.eapPhase2; - this.certificate = obj.certificate; -} - -MozWifiCapabilities.prototype = { - classID: Components.ID("08c88ece-8092-481b-863b-5515a52e411a"), - contractID: "@mozilla.org/mozwificapabilities;1", - QueryInterface: XPCOMUtils.generateQI([Ci.nsISupports]) -} - -function DOMWifiManager() { - this.defineEventHandlerGetterSetter("onstatuschange"); - this.defineEventHandlerGetterSetter("onconnectioninfoupdate"); - this.defineEventHandlerGetterSetter("onenabled"); - this.defineEventHandlerGetterSetter("ondisabled"); - this.defineEventHandlerGetterSetter("onstationinfoupdate"); -} - -DOMWifiManager.prototype = { - __proto__: DOMRequestIpcHelper.prototype, - classDescription: "DOMWifiManager", - classID: DOMWIFIMANAGER_CID, - contractID: DOMWIFIMANAGER_CONTRACTID, - QueryInterface: XPCOMUtils.generateQI([Ci.nsIDOMGlobalPropertyInitializer, - Ci.nsISupportsWeakReference, - Ci.nsIObserver]), - - // nsIDOMGlobalPropertyInitializer implementation - init: function(aWindow) { - // Maintain this state for synchronous APIs. - this._currentNetwork = null; - this._connectionStatus = "disconnected"; - this._enabled = false; - this._lastConnectionInfo = null; - this._capabilities = null; - this._stationNumber = 0; - - const messages = ["WifiManager:getNetworks:Return:OK", "WifiManager:getNetworks:Return:NO", - "WifiManager:getKnownNetworks:Return:OK", "WifiManager:getKnownNetworks:Return:NO", - "WifiManager:associate:Return:OK", "WifiManager:associate:Return:NO", - "WifiManager:forget:Return:OK", "WifiManager:forget:Return:NO", - "WifiManager:wps:Return:OK", "WifiManager:wps:Return:NO", - "WifiManager:setPowerSavingMode:Return:OK", "WifiManager:setPowerSavingMode:Return:NO", - "WifiManager:setHttpProxy:Return:OK", "WifiManager:setHttpProxy:Return:NO", - "WifiManager:setStaticIpMode:Return:OK", "WifiManager:setStaticIpMode:Return:NO", - "WifiManager:importCert:Return:OK", "WifiManager:importCert:Return:NO", - "WifiManager:getImportedCerts:Return:OK", "WifiManager:getImportedCerts:Return:NO", - "WifiManager:deleteCert:Return:OK", "WifiManager:deleteCert:Return:NO", - "WifiManager:setWifiEnabled:Return:OK", "WifiManager:setWifiEnabled:Return:NO", - "WifiManager:wifiDown", "WifiManager:wifiUp", - "WifiManager:onconnecting", "WifiManager:onassociate", - "WifiManager:onconnect", "WifiManager:ondisconnect", - "WifiManager:onwpstimeout", "WifiManager:onwpsfail", - "WifiManager:onwpsoverlap", "WifiManager:connectioninfoupdate", - "WifiManager:onauthenticating", "WifiManager:onconnectingfailed", - "WifiManager:stationinfoupdate"]; - this.initDOMRequestHelper(aWindow, messages); - this._mm = Cc["@mozilla.org/childprocessmessagemanager;1"].getService(Ci.nsISyncMessageSender); - - var state = this._mm.sendSyncMessage("WifiManager:getState")[0]; - if (state) { - this._currentNetwork = this._convertWifiNetwork(state.network); - this._lastConnectionInfo = this._convertConnectionInfo(state.connectionInfo); - this._enabled = state.enabled; - this._connectionStatus = state.status; - this._macAddress = state.macAddress; - this._capabilities = this._convertWifiCapabilities(state.capabilities); - } else { - this._currentNetwork = null; - this._lastConnectionInfo = null; - this._enabled = false; - this._connectionStatus = "disconnected"; - this._macAddress = ""; - } - }, - - _convertWifiNetworkToJSON: function(aNetwork) { - let json = {}; - - for (let key in aNetwork) { - // In WifiWorker.js there are lots of check using "key in network". - // So if the value of any property of WifiNetwork is undefined, do not clone it. - if (aNetwork[key] != undefined) { - json[key] = aNetwork[key]; - } - } - return json; - }, - - _convertWifiNetwork: function(aNetwork) { - let network = aNetwork ? new this._window.MozWifiNetwork(aNetwork) : null; - return network; - }, - - _convertWifiNetworks: function(aNetworks) { - let networks = new this._window.Array(); - for (let i in aNetworks) { - networks.push(this._convertWifiNetwork(aNetworks[i])); - } - return networks; - }, - - _convertConnection: function(aConn) { - let conn = aConn ? new MozWifiConnection(aConn) : null; - return conn; - }, - - _convertConnectionInfo: function(aInfo) { - let info = aInfo ? new MozWifiConnectionInfo(aInfo) : null; - return info; - }, - - _convertWifiCapabilities: function(aCapabilities) { - let capabilities = aCapabilities ? - new MozWifiCapabilities(aCapabilities) : null; - return capabilities; - }, - - _sendMessageForRequest: function(name, data, request) { - let id = this.getRequestId(request); - this._mm.sendAsyncMessage(name, { data: data, rid: id, mid: this._id }); - }, - - receiveMessage: function(aMessage) { - let msg = aMessage.json; - if (msg.mid && msg.mid != this._id) - return; - - let request; - if (msg.rid) { - request = this.takeRequest(msg.rid); - if (!request) { - return; - } - } - - switch (aMessage.name) { - case "WifiManager:setWifiEnabled:Return:OK": - Services.DOMRequest.fireSuccess(request, msg.data); - break; - - case "WifiManager:setWifiEnabled:Return:NO": - Services.DOMRequest.fireError(request, "Unable to enable/disable Wifi"); - break; - - case "WifiManager:getNetworks:Return:OK": - Services.DOMRequest.fireSuccess(request, this._convertWifiNetworks(msg.data)); - break; - - case "WifiManager:getNetworks:Return:NO": - Services.DOMRequest.fireError(request, "Unable to scan for networks"); - break; - - case "WifiManager:getKnownNetworks:Return:OK": - Services.DOMRequest.fireSuccess(request, this._convertWifiNetworks(msg.data)); - break; - - case "WifiManager:getKnownNetworks:Return:NO": - Services.DOMRequest.fireError(request, "Unable to get known networks"); - break; - - case "WifiManager:associate:Return:OK": - Services.DOMRequest.fireSuccess(request, true); - break; - - case "WifiManager:associate:Return:NO": - Services.DOMRequest.fireError(request, "Unable to add the network"); - break; - - case "WifiManager:forget:Return:OK": - Services.DOMRequest.fireSuccess(request, true); - break; - - case "WifiManager:forget:Return:NO": - Services.DOMRequest.fireError(request, msg.data); - break; - - case "WifiManager:wps:Return:OK": - Services.DOMRequest.fireSuccess(request, msg.data); - break; - - case "WifiManager:wps:Return:NO": - Services.DOMRequest.fireError(request, msg.data); - break; - - case "WifiManager:setPowerSavingMode:Return:OK": - Services.DOMRequest.fireSuccess(request, msg.data); - break; - - case "WifiManager:setPowerSavingMode:Return:NO": - Services.DOMRequest.fireError(request, msg.data); - break; - - case "WifiManager:setHttpProxy:Return:OK": - Services.DOMRequest.fireSuccess(request, msg.data); - break; - - case "WifiManager:setHttpProxy:Return:NO": - Services.DOMRequest.fireError(request, msg.data); - break; - - case "WifiManager:setStaticIpMode:Return:OK": - Services.DOMRequest.fireSuccess(request, msg.data); - break; - - case "WifiManager:setStaticIpMode:Return:NO": - Services.DOMRequest.fireError(request, msg.data); - break; - - case "WifiManager:importCert:Return:OK": - Services.DOMRequest.fireSuccess(request, Cu.cloneInto(msg.data, this._window)); - break; - - case "WifiManager:importCert:Return:NO": - Services.DOMRequest.fireError(request, msg.data); - break; - - case "WifiManager:getImportedCerts:Return:OK": - Services.DOMRequest.fireSuccess(request, Cu.cloneInto(msg.data, this._window)); - break; - - case "WifiManager:getImportedCerts:Return:NO": - Services.DOMRequest.fireError(request, msg.data); - break; - - case "WifiManager:deleteCert:Return:OK": - Services.DOMRequest.fireSuccess(request, msg.data); - break; - - case "WifiManager:deleteCert:Return:NO": - Services.DOMRequest.fireError(request, msg.data); - break; - - case "WifiManager:wifiDown": - this._enabled = false; - this._currentNetwork = null; - this._fireEnabledOrDisabled(false); - break; - - case "WifiManager:wifiUp": - this._enabled = true; - this._macAddress = msg.macAddress; - this._fireEnabledOrDisabled(true); - break; - - case "WifiManager:onconnecting": - this._currentNetwork = this._convertWifiNetwork(msg.network); - this._connectionStatus = "connecting"; - this._fireStatusChangeEvent(msg.network); - break; - - case "WifiManager:onassociate": - this._currentNetwork = this._convertWifiNetwork(msg.network); - this._connectionStatus = "associated"; - this._fireStatusChangeEvent(msg.network); - break; - - case "WifiManager:onconnect": - this._currentNetwork = this._convertWifiNetwork(msg.network); - this._connectionStatus = "connected"; - this._fireStatusChangeEvent(msg.network); - break; - - case "WifiManager:ondisconnect": - this._currentNetwork = null; - this._connectionStatus = "disconnected"; - this._lastConnectionInfo = null; - this._fireStatusChangeEvent(msg.network); - break; - - case "WifiManager:onwpstimeout": - this._currentNetwork = null; - this._connectionStatus = "wps-timedout"; - this._lastConnectionInfo = null; - this._fireStatusChangeEvent(msg.network); - break; - - case "WifiManager:onwpsfail": - this._currentNetwork = null; - this._connectionStatus = "wps-failed"; - this._lastConnectionInfo = null; - this._fireStatusChangeEvent(msg.network); - break; - - case "WifiManager:onwpsoverlap": - this._currentNetwork = null; - this._connectionStatus = "wps-overlapped"; - this._lastConnectionInfo = null; - this._fireStatusChangeEvent(msg.network); - break; - - case "WifiManager:connectioninfoupdate": - this._lastConnectionInfo = this._convertConnectionInfo(msg); - this._fireConnectionInfoUpdate(msg); - break; - case "WifiManager:onconnectingfailed": - this._currentNetwork = null; - this._connectionStatus = "connectingfailed"; - this._lastConnectionInfo = null; - this._fireStatusChangeEvent(msg.network); - break; - case "WifiManager:onauthenticating": - this._currentNetwork = this._convertWifiNetwork(msg.network); - this._connectionStatus = "authenticating"; - this._fireStatusChangeEvent(msg.network); - break; - case "WifiManager:stationinfoupdate": - this._stationNumber = msg.station; - this._fireStationInfoUpdate(msg); - break; - } - }, - - _fireStatusChangeEvent: function StatusChangeEvent(aNetwork) { - var event = new this._window.MozWifiStatusChangeEvent("statuschange", - { network: this._convertWifiNetwork(aNetwork), - status: this._connectionStatus - }); - this.__DOM_IMPL__.dispatchEvent(event); - }, - - _fireConnectionInfoUpdate: function onConnectionInfoUpdate(info) { - var evt = new this._window.MozWifiConnectionInfoEvent("connectioninfoupdate", - { network: this._currentNetwork, - signalStrength: info.signalStrength, - relSignalStrength: info.relSignalStrength, - linkSpeed: info.linkSpeed, - ipAddress: info.ipAddress, - }); - this.__DOM_IMPL__.dispatchEvent(evt); - }, - - _fireEnabledOrDisabled: function enabledDisabled(enabled) { - var evt = new this._window.Event(enabled ? "enabled" : "disabled"); - this.__DOM_IMPL__.dispatchEvent(evt); - }, - - _fireStationInfoUpdate: function onStationInfoUpdate(info) { - var evt = new this._window.MozWifiStationInfoEvent("stationinfoupdate", - { station: this._stationNumber} - ); - this.__DOM_IMPL__.dispatchEvent(evt); - }, - - setWifiEnabled: function setWifiEnabled(enabled) { - var request = this.createRequest(); - this._sendMessageForRequest("WifiManager:setWifiEnabled", enabled, request); - return request; - }, - - getNetworks: function getNetworks() { - var request = this.createRequest(); - this._sendMessageForRequest("WifiManager:getNetworks", null, request); - return request; - }, - - getKnownNetworks: function getKnownNetworks() { - var request = this.createRequest(); - this._sendMessageForRequest("WifiManager:getKnownNetworks", null, request); - return request; - }, - - associate: function associate(network) { - var request = this.createRequest(); - this._sendMessageForRequest("WifiManager:associate", - this._convertWifiNetworkToJSON(network), request); - return request; - }, - - forget: function forget(network) { - var request = this.createRequest(); - this._sendMessageForRequest("WifiManager:forget", - this._convertWifiNetworkToJSON(network), request); - return request; - }, - - wps: function wps(detail) { - var request = this.createRequest(); - this._sendMessageForRequest("WifiManager:wps", detail, request); - return request; - }, - - setPowerSavingMode: function setPowerSavingMode(enabled) { - var request = this.createRequest(); - this._sendMessageForRequest("WifiManager:setPowerSavingMode", enabled, request); - return request; - }, - - setHttpProxy: function setHttpProxy(network, info) { - var request = this.createRequest(); - this._sendMessageForRequest("WifiManager:setHttpProxy", - { network: this._convertWifiNetworkToJSON(network), info:info}, request); - return request; - }, - - setStaticIpMode: function setStaticIpMode(network, info) { - var request = this.createRequest(); - this._sendMessageForRequest("WifiManager:setStaticIpMode", - { network: this._convertWifiNetworkToJSON(network), info: info}, request); - return request; - }, - - importCert: function nsIDOMWifiManager_importCert(certBlob, certPassword, certNickname) { - var request = this.createRequest(); - this._sendMessageForRequest("WifiManager:importCert", - { - certBlob: certBlob, - certPassword: certPassword, - certNickname: certNickname - }, request); - return request; - }, - - getImportedCerts: function nsIDOMWifiManager_getImportedCerts() { - var request = this.createRequest(); - this._sendMessageForRequest("WifiManager:getImportedCerts", null, request); - return request; - }, - - deleteCert: function nsIDOMWifiManager_deleteCert(certNickname) { - var request = this.createRequest(); - this._sendMessageForRequest("WifiManager:deleteCert", - { - certNickname: certNickname - }, request); - return request; - }, - - get enabled() { - return this._enabled; - }, - - get macAddress() { - return this._macAddress; - }, - - get connection() { - let _connection = this._convertConnection({ status: this._connectionStatus, - network: this._currentNetwork, - }); - return _connection; - }, - - get connectionInformation() { - return this._lastConnectionInfo; - }, - - get capabilities() { - return this._capabilities; - }, - - defineEventHandlerGetterSetter: function(name) { - Object.defineProperty(this, name, { - get: function() { - return this.__DOM_IMPL__.getEventHandler(name); - }, - set: function(handler) { - this.__DOM_IMPL__.setEventHandler(name, handler); - } - }); - }, -}; - -this.NSGetFactory = XPCOMUtils.generateNSGetFactory([ - DOMWifiManager, MozWifiNetwork, MozWifiConnection, MozWifiCapabilities, - MozWifiConnectionInfo -]); - -var debug; -if (DEBUG) { - debug = function (s) { - dump("-*- DOMWifiManager component: " + s + "\n"); - }; -} else { - debug = function (s) {}; -} diff --git a/dom/wifi/DOMWifiManager.manifest b/dom/wifi/DOMWifiManager.manifest deleted file mode 100644 index 3ba83c1b2..000000000 --- a/dom/wifi/DOMWifiManager.manifest +++ /dev/null @@ -1,18 +0,0 @@ -# DOMWifiManager.js -component {c9b5f09e-25d2-40ca-aef4-c4d13d93c706} DOMWifiManager.js -contract @mozilla.org/wifimanager;1 {c9b5f09e-25d2-40ca-aef4-c4d13d93c706} - -component {c01fd751-43c0-460a-8b64-abf652ec7220} DOMWifiManager.js -contract @mozilla.org/mozwifinetwork;1 {c01fd751-43c0-460a-8b64-abf652ec7220} - -component {23579da4-201b-4319-bd42-9b7f337343ac} DOMWifiManager.js -contract @mozilla.org/mozwificonnection;1 {23579da4-201b-4319-bd42-9b7f337343ac} - -component {83670352-6ed4-4c35-8de9-402296a1959c} DOMWifiManager.js -contract @mozilla.org/mozwificonnectioninfo;1 {83670352-6ed4-4c35-8de9-402296a1959c} - -component {ad5c5295-85fb-4460-8e0c-e130d3f029ab} DOMWifiManager.js -contract @mozilla.org/mozwificertificateinfo;1 {ad5c5295-85fb-4460-8e0c-e130d3f029ab} - -component {08c88ece-8092-481b-863b-5515a52e411a} DOMWifiManager.js -contract @mozilla.org/mozwificapabilities;1 {08c88ece-8092-481b-863b-5515a52e411a} diff --git a/dom/wifi/DOMWifiP2pManager.js b/dom/wifi/DOMWifiP2pManager.js deleted file mode 100644 index 3a5637521..000000000 --- a/dom/wifi/DOMWifiP2pManager.js +++ /dev/null @@ -1,328 +0,0 @@ -/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ -/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -"use strict"; - -const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components; - -Cu.import("resource://gre/modules/XPCOMUtils.jsm"); -Cu.import("resource://gre/modules/Services.jsm"); -Cu.import("resource://gre/modules/DOMRequestHelper.jsm"); - -const DEBUG = false; - -// interface MozWifiP2pGroupOwner implementation. - -function MozWifiP2pGroupOwner(aGo) { - this.groupName = aGo.groupName; - this.macAddress = aGo.macAddress; - this.ipAddress = aGo.ipAddress; - this.passphrase = aGo.passphrase; - this.ssid = aGo.ssid; - this.wpsCapabilities = aGo.wpsCapabilities; - this.freq = aGo.freq; - this.isLocal = aGo.isLocal; -} - -MozWifiP2pGroupOwner.prototype = { - classID: Components.ID("{a9b81450-349d-11e3-aa6e-0800200c9a66}"), - contractID: "@mozilla.org/wifip2pgroupowner;1", - QueryInterface: XPCOMUtils.generateQI([Ci.nsISupports]) -}; - -// interface MozWifiP2pManager implementation. - -const MOZ_WIFIP2PMANAGER_CONTRACTID = "@mozilla.org/wifip2pmanager;1"; -const MOZ_WIFIP2PMANAGER_CID = Components.ID("{8d9125a0-3498-11e3-aa6e-0800200c9a66}"); - -function MozWifiP2pManager() { - this.defineEventHandlerGetterSetter("onstatuschange"); - this.defineEventHandlerGetterSetter("onpeerinfoupdate"); - this.defineEventHandlerGetterSetter("onenabled"); - this.defineEventHandlerGetterSetter("ondisabled"); - - this.currentPeer = null; - this.enabled = false; - this.groupOwner = null; -} - -// For smaller, read-only APIs, we expose any property that doesn't begin with -// an underscore. -function exposeReadOnly(obj) { - let exposedProps = {}; - for (let i in obj) { - if (i[0] === "_") { - continue; - } - exposedProps[i] = "r"; - } - - obj.__exposedProps__ = exposedProps; - return obj; -} - -function debug(msg) { - if (DEBUG) { - dump('-------------- MozWifiP2pManager: ' + msg); - } -} - -MozWifiP2pManager.prototype = { - __proto__: DOMRequestIpcHelper.prototype, - - classID: MOZ_WIFIP2PMANAGER_CID, - contractID: MOZ_WIFIP2PMANAGER_CONTRACTID, - QueryInterface: XPCOMUtils.generateQI([Ci.nsIDOMGlobalPropertyInitializer, - Ci.nsISupportsWeakReference, - Ci.nsIObserver, - Ci.nsISupports]), - - // - // nsIDOMGlobalPropertyInitializer implementation. - // - - init: function(aWindow) { - const messages = ["WifiP2pManager:setScanEnabled:Return:OK", - "WifiP2pManager:setScanEnabled:Return:NO", - "WifiP2pManager:getPeerList:Return:OK", - "WifiP2pManager:getPeerList:Return:NO", - "WifiP2pManager:connect:Return:OK", - "WifiP2pManager:connect:Return:NO", - "WifiP2pManager:disconnect:Return:OK", - "WifiP2pManager:disconnect:Return:NO", - "WifiP2pManager:setPairingConfirmation:Return", - "WifiP2pManager:setDeviceName:Return:OK", - "WifiP2pManager:setDeviceName:Return:NO", - - "WifiP2pManager:p2pDown", - "WifiP2pManager:p2pUp", - "WifiP2pManager:onconnecting", - "WifiP2pManager:onconnected", - "WifiP2pManager:ondisconnected", - "WifiP2pManager:ongroupnstop", - "WifiP2pManager:onconnectingfailed", - "WifiP2pManager:onwpstimeout", - "WifiP2pManager:onwpsfail", - "WifiP2pManager:onpeerinfoupdate", - ]; - - this.initDOMRequestHelper(aWindow, messages); - this._mm = Cc["@mozilla.org/childprocessmessagemanager;1"].getService(Ci.nsISyncMessageSender); - - // Notify the internal a new DOM mananger is created. - let state = this._mm.sendSyncMessage("WifiP2pManager:getState")[0]; - if (state) { - debug('State: ' + JSON.stringify(state)); - this.enabled = state.enabled; - this.currentPeer = state.currentPeer; - if (state.groupOwner) { - this.groupOwner = new MozWifiP2pGroupOwner(state.groupOwner); - } - } else { - debug('Failed to get state'); - } - }, - - uninit: function() { - }, - - _sendMessageForRequest: function(name, data, request) { - let id = this.getRequestId(request); - this._mm.sendAsyncMessage(name, { data: data, rid: id, mid: this._id }); - }, - - receiveMessage: function(aMessage) { - let msg = aMessage.json; - if (msg.mid && msg.mid !== this._id) { - return; - } - - let request; - switch (aMessage.name) { - case "WifiP2pManager:setScanEnabled:Return:OK": - request = this.takeRequest(msg.rid); - Services.DOMRequest.fireSuccess(request, exposeReadOnly(msg.data)); - break; - - case "WifiP2pManager:setScanEnabled:Return:NO": - request = this.takeRequest(msg.rid); - Services.DOMRequest.fireError(request, "Unable to enable/disable Wifi P2P peer discovery."); - break; - - case "WifiP2pManager:getPeerList:Return:OK": - request = this.takeRequest(msg.rid); - Services.DOMRequest.fireSuccess(request, Cu.cloneInto(msg.data, this._window)); - break; - - case "WifiP2pManager:getPeerList:Return:NO": - request = this.takeRequest(msg.rid); - Services.DOMRequest.fireError(request, "Unable to disable Wifi P2P peer discovery."); - break; - - case "WifiP2pManager:connect:Return:OK": - request = this.takeRequest(msg.rid); - Services.DOMRequest.fireSuccess(request, exposeReadOnly(msg.data)); - break; - - case "WifiP2pManager:connect:Return:NO": - request = this.takeRequest(msg.rid); - Services.DOMRequest.fireError(request, "Unable to connect to Wifi P2P peer."); - break; - - case "WifiP2pManager:disconnect:Return:OK": - request = this.takeRequest(msg.rid); - Services.DOMRequest.fireSuccess(request, exposeReadOnly(msg.data)); - break; - - case "WifiP2pManager:disconnect:Return:NO": - request = this.takeRequest(msg.rid); - Services.DOMRequest.fireError(request, "Unable to disconnect to Wifi P2P peer."); - break; - - case "WifiP2pManager:setDeviceName:Return:OK": - request = this.takeRequest(msg.rid); - Services.DOMRequest.fireSuccess(request, exposeReadOnly(msg.data)); - break; - - case "WifiP2pManager:setDeviceName:Return:NO": - request = this.takeRequest(msg.rid); - Services.DOMRequest.fireError(request, "Unable to set device name."); - break; - - case "WifiP2pManager:p2pDown": - this.enabled = false; - this.currentPeer = null; - this._fireEnabledOrDisabled(false); - break; - - case "WifiP2pManager:p2pUp": - this.enabled = true; - this._fireEnabledOrDisabled(true); - break; - - case "WifiP2pManager:onconnecting": - debug('onconnecting with peer: ' + JSON.stringify(msg.peer)); - this.currentPeer = msg.peer; - this._fireStatusChangeEvent(msg.peer.address); - break; - - case "WifiP2pManager:onconnected": - debug('onconnected with peer: ' + JSON.stringify(msg.peer)); - this.currentPeer = msg.peer; - this.groupOwner = new MozWifiP2pGroupOwner(msg.groupOwner); - this._fireStatusChangeEvent(msg.peer.address); - break; - - case "WifiP2pManager:ondisconnected": - debug('ondisconnected with peer: ' + JSON.stringify(msg.peer)); - this.currentPeer = null; - this.groupOwner = null; - this._fireStatusChangeEvent(msg.peer.address); - break; - - case "WifiP2pManager:onconnectingfailed": - this._fireStatusChangeEvent(null); - break; - - case "WifiP2pManager:onwpstimeout": - this._fireStatusChangeEvent(null); - break; - - case "WifiP2pManager:onwpsfail": - this._fireStatusChangeEvent(null); - break; - - case "WifiP2pManager:onpeerinfoupdate": - this._firePeerInfoUpdateEvent(); - break; - } - }, - - _firePeerInfoUpdateEvent: function PeerInfoUpdate() { - let evt = new this._window.Event("peerinfoupdate"); - this.__DOM_IMPL__.dispatchEvent(evt); - }, - - _fireStatusChangeEvent: function WifiP2pStatusChange(peerAddress) { - let evt = new this._window.MozWifiP2pStatusChangeEvent("statuschange", - { peerAddress: peerAddress }); - this.__DOM_IMPL__.dispatchEvent(evt); - }, - - _fireEnabledOrDisabled: function enabledDisabled(enabled) { - let evt = new this._window.Event(enabled ? "enabled" : "disabled"); - this.__DOM_IMPL__.dispatchEvent(evt); - }, - - // - // WifiP2pManager.webidl implementation. - // - - enableScan: function () { - let request = this.createRequest(); - this._sendMessageForRequest("WifiP2pManager:enableScan", null, request); - return request; - }, - - disableScan: function () { - let request = this.createRequest(); - this._sendMessageForRequest("WifiP2pManager:disableScan", null, request); - return request; - }, - - setScanEnabled: function(enabled) { - let request = this.createRequest(); - this._sendMessageForRequest("WifiP2pManager:setScanEnabled", enabled, request); - return request; - }, - - connect: function (address, wpsMethod, goIntent) { - let request = this.createRequest(); - let connectionInfo = { address: address, wpsMethod: wpsMethod, goIntent: goIntent }; - this._sendMessageForRequest("WifiP2pManager:connect", connectionInfo, request); - return request; - }, - - disconnect: function (address) { - let request = this.createRequest(); - this._sendMessageForRequest("WifiP2pManager:disconnect", address, request); - return request; - }, - - getPeerList: function () { - let request = this.createRequest(); - this._sendMessageForRequest("WifiP2pManager:getPeerList", null, request); - return request; - }, - - setPairingConfirmation: function (accepted, pin) { - let request = this.createRequest(); - let result = { accepted: accepted, pin: pin }; - this._sendMessageForRequest("WifiP2pManager:setPairingConfirmation", result, request); - return request; - }, - - setDeviceName: function(newDeviceName) { - let request = this.createRequest(); - this._sendMessageForRequest("WifiP2pManager:setDeviceName", newDeviceName, request); - return request; - }, - - // Helpers. - defineEventHandlerGetterSetter: function(event) { - Object.defineProperty(this, event, { - get: function() { - return this.__DOM_IMPL__.getEventHandler(event); - }, - - set: function(handler) { - this.__DOM_IMPL__.setEventHandler(event, handler); - } - }); - }, -}; - -this.NSGetFactory = XPCOMUtils.generateNSGetFactory([MozWifiP2pManager, MozWifiP2pGroupOwner]); diff --git a/dom/wifi/DOMWifiP2pManager.manifest b/dom/wifi/DOMWifiP2pManager.manifest deleted file mode 100644 index bc80efa48..000000000 --- a/dom/wifi/DOMWifiP2pManager.manifest +++ /dev/null @@ -1,6 +0,0 @@ -# DOMWifiP2pManager.js -component {8d9125a0-3498-11e3-aa6e-0800200c9a66} DOMWifiP2pManager.js -contract @mozilla.org/wifip2pmanager;1 {8d9125a0-3498-11e3-aa6e-0800200c9a66} - -component {a9b81450-349d-11e3-aa6e-0800200c9a66} DOMWifiP2pManager.js -contract @mozilla.org/wifip2pgroupowner;1 {a9b81450-349d-11e3-aa6e-0800200c9a66}
\ No newline at end of file diff --git a/dom/wifi/StateMachine.jsm b/dom/wifi/StateMachine.jsm deleted file mode 100644 index 94b876f82..000000000 --- a/dom/wifi/StateMachine.jsm +++ /dev/null @@ -1,205 +0,0 @@ -/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ -/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -"use strict"; - -const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components; - -Cu.import("resource://gre/modules/Services.jsm"); - -this.EXPORTED_SYMBOLS = ["StateMachine"]; - -const DEBUG = false; - -this.StateMachine = function(aDebugTag) { - function debug(aMsg) { - dump('-------------- StateMachine:' + aDebugTag + ': ' + aMsg); - } - - var sm = {}; - - var _initialState; - var _curState; - var _prevState; - var _paused; - var _eventQueue = []; - var _deferredEventQueue = []; - var _defaultEventHandler; - - // Public interfaces. - - sm.setDefaultEventHandler = function(aDefaultEventHandler) { - _defaultEventHandler = aDefaultEventHandler; - }; - - sm.start = function(aInitialState) { - _initialState = aInitialState; - sm.gotoState(_initialState); - }; - - sm.sendEvent = function (aEvent) { - if (!_initialState) { - if (DEBUG) { - debug('StateMachine is not running. Call StateMachine.start() first.'); - } - return; - } - _eventQueue.push(aEvent); - asyncCall(handleFirstEvent); - }; - - sm.getPreviousState = function() { - return _prevState; - }; - - sm.getCurrentState = function() { - return _curState; - }; - - // State object maker. - // @param aName string for this state's name. - // @param aDelegate object: - // .handleEvent: required. - // .enter: called before entering this state (optional). - // .exit: called before exiting this state (optional). - sm.makeState = function (aName, aDelegate) { - if (!aDelegate.handleEvent) { - throw "handleEvent is a required delegate function."; - } - var nop = function() {}; - return { - name: aName, - enter: (aDelegate.enter || nop), - exit: (aDelegate.exit || nop), - handleEvent: aDelegate.handleEvent - }; - }; - - sm.deferEvent = function (aEvent) { - // The definition of a 'deferred event' is: - // We are not able to handle this event now but after receiving - // certain event or entering a new state, we might be able to handle - // it. For example, we couldn't handle CONNECT_EVENT in the - // diconnecting state. But once we finish doing "disconnecting", we - // could then handle CONNECT_EVENT! - // - // So, the deferred event may be handled in the following cases: - // 1. Once we entered a new state. - // 2. Once we handled a regular event. - if (DEBUG) { - debug('Deferring event: ' + JSON.stringify(aEvent)); - } - _deferredEventQueue.push(aEvent); - }; - - // Goto the new state. If the current state is null, the exit - // function won't be called. - sm.gotoState = function (aNewState) { - if (_curState) { - if (DEBUG) { - debug("exiting state: " + _curState.name); - } - _curState.exit(); - } - - _prevState = _curState; - _curState = aNewState; - - if (DEBUG) { - debug("entering state: " + _curState.name); - } - _curState.enter(); - - // We are in the new state now. We got a chance to handle the - // deferred events. - handleDeferredEvents(); - - sm.resume(); - }; - - // No incoming event will be handled after you call pause(). - // (But they will be queued.) - sm.pause = function() { - _paused = true; - }; - - // Continue to handle incoming events. - sm.resume = function() { - _paused = false; - asyncCall(handleFirstEvent); - }; - - //---------------------------------------------------------- - // Private stuff - //---------------------------------------------------------- - - function asyncCall(f) { - Services.tm.currentThread.dispatch(f, Ci.nsIThread.DISPATCH_NORMAL); - } - - function handleFirstEvent() { - var hadDeferredEvents; - - if (0 === _eventQueue.length) { - return; - } - - if (_paused) { - return; // The state machine is paused now. - } - - hadDeferredEvents = _deferredEventQueue.length > 0; - - handleOneEvent(_eventQueue.shift()); // The handler may defer this event. - - // We've handled one event. If we had deferred events before, now is - // a good chance to handle them. - if (hadDeferredEvents) { - handleDeferredEvents(); - } - - // Continue to handle the next regular event. - handleFirstEvent(); - } - - function handleDeferredEvents() { - if (_deferredEventQueue.length && DEBUG) { - debug('Handle deferred events: ' + _deferredEventQueue.length); - } - for (let i = 0; i < _deferredEventQueue.length; i++) { - handleOneEvent(_deferredEventQueue.shift()); - } - } - - function handleOneEvent(aEvent) - { - if (DEBUG) { - debug('Handling event: ' + JSON.stringify(aEvent)); - } - - var handled = _curState.handleEvent(aEvent); - - if (undefined === handled) { - throw "handleEvent returns undefined: " + _curState.name; - } - if (!handled) { - // Event is not handled in the current state. Try handleEventCommon(). - handled = (_defaultEventHandler ? _defaultEventHandler(aEvent) : handled); - } - if (undefined === handled) { - throw "handleEventCommon returns undefined: " + _curState.name; - } - if (!handled) { - if (DEBUG) { - debug('!!!!!!!!! FIXME !!!!!!!!! Event not handled: ' + JSON.stringify(aEvent)); - } - } - - return handled; - } - - return sm; -}; diff --git a/dom/wifi/WifiCertService.cpp b/dom/wifi/WifiCertService.cpp deleted file mode 100644 index 85e0d2f5b..000000000 --- a/dom/wifi/WifiCertService.cpp +++ /dev/null @@ -1,536 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -#include "WifiCertService.h" - -#include "mozilla/ClearOnShutdown.h" -#include "mozilla/EndianUtils.h" -#include "mozilla/ModuleUtils.h" -#include "mozilla/RefPtr.h" -#include "mozilla/dom/File.h" -#include "mozilla/dom/ToJSValue.h" -#include "cert.h" -#include "certdb.h" -#include "CryptoTask.h" -#include "nsIDOMBlob.h" -#include "nsIWifiService.h" -#include "nsNetUtil.h" -#include "nsIInputStream.h" -#include "nsServiceManagerUtils.h" -#include "nsXULAppAPI.h" -#include "ScopedNSSTypes.h" - -#define NS_WIFICERTSERVICE_CID \ - { 0x83585afd, 0x0e11, 0x43aa, {0x83, 0x46, 0xf3, 0x4d, 0x97, 0x5e, 0x46, 0x77} } - -using namespace mozilla; -using namespace mozilla::dom; - -namespace mozilla { - -// The singleton Wifi Cert service, to be used on the main thread. -StaticRefPtr<WifiCertService> gWifiCertService; - -class ImportCertTask final: public CryptoTask -{ -public: - ImportCertTask(int32_t aId, Blob* aCertBlob, - const nsAString& aCertPassword, - const nsAString& aCertNickname) - : mBlob(aCertBlob) - , mPassword(aCertPassword) - { - MOZ_ASSERT(NS_IsMainThread()); - - mResult.mId = aId; - mResult.mStatus = 0; - mResult.mUsageFlag = 0; - mResult.mNickname = aCertNickname; - } - -private: - virtual void ReleaseNSSResources() {} - - virtual nsresult CalculateResult() override - { - MOZ_ASSERT(!NS_IsMainThread()); - - // read data from blob. - nsCString blobBuf; - nsresult rv = ReadBlob(blobBuf); - if (NS_FAILED(rv)) { - return rv; - } - - char* buf; - uint32_t size = blobBuf.GetMutableData(&buf); - if (size == 0) { - return NS_ERROR_OUT_OF_MEMORY; - } - - // Try import as DER format first. - rv = ImportDERBlob(buf, size); - if (NS_SUCCEEDED(rv)) { - return rv; - } - - // Try import as PKCS#12 format. - return ImportPKCS12Blob(buf, size, mPassword); - } - - virtual void CallCallback(nsresult rv) - { - if (NS_FAILED(rv)) { - mResult.mStatus = -1; - } - gWifiCertService->DispatchResult(mResult); - } - - nsresult ImportDERBlob(char* buf, uint32_t size) - { - // Create certificate object. - ScopedCERTCertificate cert(CERT_DecodeCertFromPackage(buf, size)); - if (!cert) { - return MapSECStatus(SECFailure); - } - - // Import certificate. - return ImportCert(cert); - } - - static SECItem* - HandleNicknameCollision(SECItem* aOldNickname, PRBool* aCancel, void* aWincx) - { - const char* dummyName = "Imported User Cert"; - const size_t dummyNameLen = strlen(dummyName); - SECItem* newNick = ::SECITEM_AllocItem(nullptr, nullptr, dummyNameLen + 1); - if (!newNick) { - return nullptr; - } - - newNick->type = siAsciiString; - // Dummy name, will be renamed later. - memcpy(newNick->data, dummyName, dummyNameLen + 1); - newNick->len = dummyNameLen; - - return newNick; - } - - static SECStatus - HandleNicknameUpdate(const CERTCertificate *aCert, - const SECItem *default_nickname, - SECItem **new_nickname, - void *arg) - { - WifiCertServiceResultOptions *result = (WifiCertServiceResultOptions *)arg; - - nsCString userNickname; - CopyUTF16toUTF8(result->mNickname, userNickname); - - nsCString fullNickname; - if (aCert->isRoot && (aCert->nsCertType & NS_CERT_TYPE_SSL_CA)) { - // Accept self-signed SSL CA as server certificate. - fullNickname.AssignLiteral("WIFI_SERVERCERT_"); - fullNickname += userNickname; - result->mUsageFlag |= nsIWifiCertService::WIFI_CERT_USAGE_FLAG_SERVER; - } else if (aCert->nsCertType & NS_CERT_TYPE_SSL_CLIENT) { - // User Certificate - fullNickname.AssignLiteral("WIFI_USERCERT_"); - fullNickname += userNickname; - result->mUsageFlag |= nsIWifiCertService::WIFI_CERT_USAGE_FLAG_USER; - } - char* nickname; - uint32_t length = fullNickname.GetMutableData(&nickname); - - SECItem* newNick = ::SECITEM_AllocItem(nullptr, nullptr, length + 1); - if (!newNick) { - return SECFailure; - } - - newNick->type = siAsciiString; - memcpy(newNick->data, nickname, length + 1); - newNick->len = length; - - *new_nickname = newNick; - return SECSuccess; - } - - nsresult ImportPKCS12Blob(char* buf, uint32_t size, const nsAString& aPassword) - { - nsString password(aPassword); - - // password is null-terminated wide-char string. - // passwordItem is required to be big-endian form of password, stored in char - // array, including the null-termination. - uint32_t length = password.Length() + 1; - ScopedSECItem passwordItem( - ::SECITEM_AllocItem(nullptr, nullptr, length * sizeof(nsString::char_type))); - - if (!passwordItem) { - return NS_ERROR_FAILURE; - } - - mozilla::NativeEndian::copyAndSwapToBigEndian(passwordItem->data, - password.BeginReading(), - length); - // Create a decoder. - ScopedSEC_PKCS12DecoderContext p12dcx(SEC_PKCS12DecoderStart( - passwordItem, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, - nullptr)); - - if (!p12dcx) { - return NS_ERROR_FAILURE; - } - - // Assign data to decorder. - SECStatus srv = SEC_PKCS12DecoderUpdate(p12dcx, - reinterpret_cast<unsigned char*>(buf), - size); - if (srv != SECSuccess) { - return MapSECStatus(srv); - } - - // Verify certificates. - srv = SEC_PKCS12DecoderVerify(p12dcx); - if (srv != SECSuccess) { - return MapSECStatus(srv); - } - - // Set certificate nickname and usage flag. - srv = SEC_PKCS12DecoderRenameCertNicknames(p12dcx, HandleNicknameUpdate, - &mResult); - - // Validate certificates. - srv = SEC_PKCS12DecoderValidateBags(p12dcx, HandleNicknameCollision); - if (srv != SECSuccess) { - return MapSECStatus(srv); - } - - // Initialize slot. - ScopedPK11SlotInfo slot(PK11_GetInternalKeySlot()); - if (!slot) { - return NS_ERROR_FAILURE; - } - if (PK11_NeedLogin(slot) && PK11_NeedUserInit(slot)) { - srv = PK11_InitPin(slot, "", ""); - if (srv != SECSuccess) { - return MapSECStatus(srv); - } - } - - // Import cert and key. - srv = SEC_PKCS12DecoderImportBags(p12dcx); - if (srv != SECSuccess) { - return MapSECStatus(srv); - } - - // User certificate must be imported from PKCS#12. - return (mResult.mUsageFlag & nsIWifiCertService::WIFI_CERT_USAGE_FLAG_USER) - ? NS_OK : NS_ERROR_FAILURE; - } - - nsresult ReadBlob(/*out*/ nsCString& aBuf) - { - NS_ENSURE_ARG_POINTER(mBlob); - - static const uint64_t MAX_FILE_SIZE = 16384; - - ErrorResult rv; - uint64_t size = mBlob->GetSize(rv); - if (NS_WARN_IF(rv.Failed())) { - return rv.StealNSResult(); - } - - if (size > MAX_FILE_SIZE) { - return NS_ERROR_FILE_TOO_BIG; - } - - nsCOMPtr<nsIInputStream> inputStream; - mBlob->GetInternalStream(getter_AddRefs(inputStream), rv); - if (NS_WARN_IF(rv.Failed())) { - return rv.StealNSResult(); - } - - rv = NS_ReadInputStreamToString(inputStream, aBuf, (uint32_t)size); - if (NS_WARN_IF(rv.Failed())) { - return rv.StealNSResult(); - } - - return NS_OK; - } - - nsresult ImportCert(CERTCertificate* aCert) - { - nsCString userNickname, fullNickname; - - CopyUTF16toUTF8(mResult.mNickname, userNickname); - // Determine certificate nickname by adding prefix according to its type. - if (aCert->isRoot && (aCert->nsCertType & NS_CERT_TYPE_SSL_CA)) { - // Accept self-signed SSL CA as server certificate. - fullNickname.AssignLiteral("WIFI_SERVERCERT_"); - fullNickname += userNickname; - mResult.mUsageFlag |= nsIWifiCertService::WIFI_CERT_USAGE_FLAG_SERVER; - } else if (aCert->nsCertType & NS_CERT_TYPE_SSL_CLIENT) { - // User Certificate - fullNickname.AssignLiteral("WIFI_USERCERT_"); - fullNickname += userNickname; - mResult.mUsageFlag |= nsIWifiCertService::WIFI_CERT_USAGE_FLAG_USER; - } else { - return NS_ERROR_ABORT; - } - - char* nickname; - uint32_t length; - length = fullNickname.GetMutableData(&nickname); - if (length == 0) { - return NS_ERROR_UNEXPECTED; - } - - // Import certificate, duplicated nickname will cause error. - SECStatus srv = CERT_AddTempCertToPerm(aCert, nickname, nullptr); - if (srv != SECSuccess) { - return MapSECStatus(srv); - } - - return NS_OK; - } - - RefPtr<Blob> mBlob; - nsString mPassword; - WifiCertServiceResultOptions mResult; -}; - -class DeleteCertTask final: public CryptoTask -{ -public: - DeleteCertTask(int32_t aId, const nsAString& aCertNickname) - { - MOZ_ASSERT(NS_IsMainThread()); - - mResult.mId = aId; - mResult.mStatus = 0; - mResult.mUsageFlag = 0; - mResult.mNickname = aCertNickname; - } - -private: - virtual void ReleaseNSSResources() {} - - virtual nsresult CalculateResult() override - { - MOZ_ASSERT(!NS_IsMainThread()); - - nsCString userNickname; - CopyUTF16toUTF8(mResult.mNickname, userNickname); - - // Delete server certificate. - nsCString serverCertName("WIFI_SERVERCERT_", 16); - serverCertName += userNickname; - nsresult rv = deleteCert(serverCertName); - if (NS_FAILED(rv)) { - return rv; - } - - // Delete user certificate and private key. - nsCString userCertName("WIFI_USERCERT_", 14); - userCertName += userNickname; - rv = deleteCert(userCertName); - if (NS_FAILED(rv)) { - return rv; - } - - return NS_OK; - } - - nsresult deleteCert(const nsCString &aCertNickname) - { - ScopedCERTCertificate cert( - CERT_FindCertByNickname(CERT_GetDefaultCertDB(), aCertNickname.get()) - ); - // Because we delete certificates in blind, so it's acceptable to delete - // a non-exist certificate. - if (!cert) { - return NS_OK; - } - - ScopedPK11SlotInfo slot( - PK11_KeyForCertExists(cert, nullptr, nullptr) - ); - - SECStatus srv; - if (slot) { - // Delete private key along with certificate. - srv = PK11_DeleteTokenCertAndKey(cert, nullptr); - } else { - srv = SEC_DeletePermCertificate(cert); - } - - if (srv != SECSuccess) { - return MapSECStatus(srv); - } - - return NS_OK; - } - - virtual void CallCallback(nsresult rv) - { - if (NS_FAILED(rv)) { - mResult.mStatus = -1; - } - gWifiCertService->DispatchResult(mResult); - } - - WifiCertServiceResultOptions mResult; -}; - -NS_IMPL_ISUPPORTS(WifiCertService, nsIWifiCertService) - -NS_IMETHODIMP -WifiCertService::Start(nsIWifiEventListener* aListener) -{ - MOZ_ASSERT(aListener); - - mListener = aListener; - - return NS_OK; -} - -NS_IMETHODIMP -WifiCertService::Shutdown() -{ - MOZ_ASSERT(NS_IsMainThread()); - - mListener = nullptr; - - return NS_OK; -} - -void -WifiCertService::DispatchResult(const WifiCertServiceResultOptions& aOptions) -{ - MOZ_ASSERT(NS_IsMainThread()); - - mozilla::AutoSafeJSContext cx; - JS::RootedValue val(cx); - nsCString dummyInterface; - - if (!ToJSValue(cx, aOptions, &val)) { - return; - } - - // Certll the listener with a JS value. - mListener->OnCommand(val, dummyInterface); -} - -WifiCertService::WifiCertService() -{ - MOZ_ASSERT(NS_IsMainThread()); - MOZ_ASSERT(!gWifiCertService); -} - -WifiCertService::~WifiCertService() -{ - MOZ_ASSERT(!gWifiCertService); - - nsNSSShutDownPreventionLock locker; - if (isAlreadyShutDown()) { - return; - } - shutdown(ShutdownCalledFrom::Object); -} - -already_AddRefed<WifiCertService> -WifiCertService::FactoryCreate() -{ - if (!XRE_IsParentProcess()) { - return nullptr; - } - - MOZ_ASSERT(NS_IsMainThread()); - - if (!gWifiCertService) { - gWifiCertService = new WifiCertService(); - ClearOnShutdown(&gWifiCertService); - } - - RefPtr<WifiCertService> service = gWifiCertService.get(); - return service.forget(); -} - -NS_IMETHODIMP -WifiCertService::ImportCert(int32_t aId, nsIDOMBlob* aCertBlob, - const nsAString& aCertPassword, - const nsAString& aCertNickname) -{ - RefPtr<Blob> blob = static_cast<Blob*>(aCertBlob); - RefPtr<CryptoTask> task = new ImportCertTask(aId, blob, aCertPassword, - aCertNickname); - return task->Dispatch("WifiImportCert"); -} - -NS_IMETHODIMP -WifiCertService::DeleteCert(int32_t aId, const nsAString& aCertNickname) -{ - RefPtr<CryptoTask> task = new DeleteCertTask(aId, aCertNickname); - return task->Dispatch("WifiDeleteCert"); -} - -NS_IMETHODIMP -WifiCertService::HasPrivateKey(const nsAString& aCertNickname, bool *aHasKey) -{ - *aHasKey = false; - - nsNSSShutDownPreventionLock locker; - if (isAlreadyShutDown()) { - return NS_ERROR_NOT_AVAILABLE; - } - - nsCString certNickname; - CopyUTF16toUTF8(aCertNickname, certNickname); - - ScopedCERTCertificate cert( - CERT_FindCertByNickname(CERT_GetDefaultCertDB(), certNickname.get()) - ); - if (!cert) { - return NS_OK; - } - - ScopedPK11SlotInfo slot( - PK11_KeyForCertExists(cert, nullptr, nullptr) - ); - if (slot) { - *aHasKey = true; - } - - return NS_OK; -} - -NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(WifiCertService, - WifiCertService::FactoryCreate) - -NS_DEFINE_NAMED_CID(NS_WIFICERTSERVICE_CID); - -static const mozilla::Module::CIDEntry kWifiCertServiceCIDs[] = { - { &kNS_WIFICERTSERVICE_CID, false, nullptr, WifiCertServiceConstructor }, - { nullptr } -}; - -static const mozilla::Module::ContractIDEntry kWifiCertServiceContracts[] = { - { "@mozilla.org/wifi/certservice;1", &kNS_WIFICERTSERVICE_CID }, - { nullptr } -}; - -static const mozilla::Module kWifiCertServiceModule = { - mozilla::Module::kVersion, - kWifiCertServiceCIDs, - kWifiCertServiceContracts, - nullptr -}; - -} // namespace mozilla - -NSMODULE_DEFN(WifiCertServiceModule) = &kWifiCertServiceModule; diff --git a/dom/wifi/WifiCertService.h b/dom/wifi/WifiCertService.h deleted file mode 100644 index f542bb0c8..000000000 --- a/dom/wifi/WifiCertService.h +++ /dev/null @@ -1,40 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -#ifndef WifiCertService_h -#define WifiCertService_h - -#include "nsIWifiCertService.h" -#include "nsCOMPtr.h" -#include "nsNSSShutDown.h" -#include "nsThread.h" -#include "mozilla/dom/WifiOptionsBinding.h" - -namespace mozilla { -namespace dom { - -class WifiCertService final : public nsIWifiCertService, - public nsNSSShutDownObject -{ -public: - NS_DECL_ISUPPORTS - NS_DECL_NSIWIFICERTSERVICE - - static already_AddRefed<WifiCertService> - FactoryCreate(); - void DispatchResult(const mozilla::dom::WifiCertServiceResultOptions& aOptions); - -private: - WifiCertService(); - ~WifiCertService(); - virtual void virtualDestroyNSSReference() {}; - nsCOMPtr<nsIWifiEventListener> mListener; -}; - -} // namespce dom -} // namespace mozilla - -#endif // WifiCertService_h diff --git a/dom/wifi/WifiCommand.jsm b/dom/wifi/WifiCommand.jsm deleted file mode 100644 index 93b0f1a1e..000000000 --- a/dom/wifi/WifiCommand.jsm +++ /dev/null @@ -1,594 +0,0 @@ -/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ -/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -"use strict"; - -this.EXPORTED_SYMBOLS = ["WifiCommand"]; - -const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components; - -Cu.import("resource://gre/modules/systemlibs.js"); - -const SUPP_PROP = "init.svc.wpa_supplicant"; -const WPA_SUPPLICANT = "wpa_supplicant"; -const DEBUG = false; - -this.WifiCommand = function(aControlMessage, aInterface, aSdkVersion) { - function debug(msg) { - if (DEBUG) { - dump('-------------- WifiCommand: ' + msg); - } - } - - var command = {}; - - //------------------------------------------------- - // Utilities. - //------------------------------------------------- - command.getSdkVersion = function() { - return aSdkVersion; - }; - - //------------------------------------------------- - // General commands. - //------------------------------------------------- - - command.loadDriver = function (callback) { - voidControlMessage("load_driver", function(status) { - callback(status); - }); - }; - - command.unloadDriver = function (callback) { - voidControlMessage("unload_driver", function(status) { - callback(status); - }); - }; - - command.startSupplicant = function (callback) { - voidControlMessage("start_supplicant", callback); - }; - - command.killSupplicant = function (callback) { - // It is interesting to note that this function does exactly what - // wifi_stop_supplicant does. Unforunately, on the Galaxy S2, Samsung - // changed that function in a way that means that it doesn't recognize - // wpa_supplicant as already running. Therefore, we have to roll our own - // version here. - stopProcess(SUPP_PROP, WPA_SUPPLICANT, callback); - }; - - command.terminateSupplicant = function (callback) { - doBooleanCommand("TERMINATE", "OK", callback); - }; - - command.stopSupplicant = function (callback) { - voidControlMessage("stop_supplicant", callback); - }; - - command.listNetworks = function (callback) { - doStringCommand("LIST_NETWORKS", callback); - }; - - command.addNetwork = function (callback) { - doIntCommand("ADD_NETWORK", callback); - }; - - command.setNetworkVariable = function (netId, name, value, callback) { - doBooleanCommand("SET_NETWORK " + netId + " " + name + " " + - value, "OK", callback); - }; - - command.getNetworkVariable = function (netId, name, callback) { - doStringCommand("GET_NETWORK " + netId + " " + name, callback); - }; - - command.removeNetwork = function (netId, callback) { - doBooleanCommand("REMOVE_NETWORK " + netId, "OK", callback); - }; - - command.enableNetwork = function (netId, disableOthers, callback) { - doBooleanCommand((disableOthers ? "SELECT_NETWORK " : "ENABLE_NETWORK ") + - netId, "OK", callback); - }; - - command.disableNetwork = function (netId, callback) { - doBooleanCommand("DISABLE_NETWORK " + netId, "OK", callback); - }; - - command.status = function (callback) { - doStringCommand("STATUS", callback); - }; - - command.ping = function (callback) { - doBooleanCommand("PING", "PONG", callback); - }; - - command.scanResults = function (callback) { - doStringCommand("SCAN_RESULTS", callback); - }; - - command.disconnect = function (callback) { - doBooleanCommand("DISCONNECT", "OK", callback); - }; - - command.reconnect = function (callback) { - doBooleanCommand("RECONNECT", "OK", callback); - }; - - command.reassociate = function (callback) { - doBooleanCommand("REASSOCIATE", "OK", callback); - }; - - command.setBackgroundScan = function (enable, callback) { - doBooleanCommand("SET pno " + (enable ? "1" : "0"), - "OK", - function(ok) { - callback(true, ok); - }); - }; - - command.doSetScanMode = function (setActive, callback) { - doBooleanCommand(setActive ? - "DRIVER SCAN-ACTIVE" : - "DRIVER SCAN-PASSIVE", "OK", callback); - }; - - command.scan = function (callback) { - doBooleanCommand("SCAN", "OK", callback); - }; - - command.setLogLevel = function (level, callback) { - doBooleanCommand("LOG_LEVEL " + level, "OK", callback); - }; - - command.getLogLevel = function (callback) { - doStringCommand("LOG_LEVEL", callback); - }; - - command.wpsPbc = function (callback, iface) { - let cmd = 'WPS_PBC'; - - // If the network interface is specified and we are based on JB, - // append the argument 'interface=[iface]' to the supplicant command. - // - // Note: The argument "interface" is only required for wifi p2p on JB. - // For other cases, the argument is useless and even leads error. - // Check the evil work here: - // http://androidxref.com/4.2.2_r1/xref/external/wpa_supplicant_8/wpa_supplicant/ctrl_iface_unix.c#172 - // - if (iface && isJellybean()) { - cmd += (' inferface=' + iface); - } - - doBooleanCommand(cmd, "OK", callback); - }; - - command.wpsPin = function (detail, callback) { - let cmd = 'WPS_PIN '; - - // See the comment above in wpsPbc(). - if (detail.iface && isJellybean()) { - cmd += ('inferface=' + iface + ' '); - } - - cmd += (detail.bssid === undefined ? "any" : detail.bssid); - cmd += (detail.pin === undefined ? "" : (" " + detail.pin)); - - doStringCommand(cmd, callback); - }; - - command.wpsCancel = function (callback) { - doBooleanCommand("WPS_CANCEL", "OK", callback); - }; - - command.startDriver = function (callback) { - doBooleanCommand("DRIVER START", "OK"); - }; - - command.stopDriver = function (callback) { - doBooleanCommand("DRIVER STOP", "OK"); - }; - - command.startPacketFiltering = function (callback) { - var commandChain = ["DRIVER RXFILTER-ADD 0", - "DRIVER RXFILTER-ADD 1", - "DRIVER RXFILTER-ADD 3", - "DRIVER RXFILTER-START"]; - - doBooleanCommandChain(commandChain, callback); - }; - - command.stopPacketFiltering = function (callback) { - var commandChain = ["DRIVER RXFILTER-STOP", - "DRIVER RXFILTER-REMOVE 3", - "DRIVER RXFILTER-REMOVE 1", - "DRIVER RXFILTER-REMOVE 0"]; - - doBooleanCommandChain(commandChain, callback); - }; - - command.doGetRssi = function (cmd, callback) { - doCommand(cmd, function(data) { - var rssi = -200; - - if (!data.status) { - // If we are associating, the reply is "OK". - var reply = data.reply; - if (reply !== "OK") { - // Format is: <SSID> rssi XX". SSID can contain spaces. - var offset = reply.lastIndexOf("rssi "); - if (offset !== -1) { - rssi = reply.substr(offset + 5) | 0; - } - } - } - callback(rssi); - }); - }; - - command.getRssi = function (callback) { - command.doGetRssi("DRIVER RSSI", callback); - }; - - command.getRssiApprox = function (callback) { - command.doGetRssi("DRIVER RSSI-APPROX", callback); - }; - - command.getLinkSpeed = function (callback) { - doStringCommand("DRIVER LINKSPEED", function(reply) { - if (reply) { - reply = reply.split(" ")[1] | 0; // Format: LinkSpeed XX - } - callback(reply); - }); - }; - - let infoKeys = [{regexp: /RSSI=/i, prop: 'rssi'}, - {regexp: /LINKSPEED=/i, prop: 'linkspeed'}]; - - command.getConnectionInfoICS = function (callback) { - doStringCommand("SIGNAL_POLL", function(reply) { - if (!reply) { - callback(null); - return; - } - - // Find any values matching |infoKeys|. This gets executed frequently - // enough that we want to avoid creating intermediate strings as much as - // possible. - let rval = {}; - for (let i = 0; i < infoKeys.length; i++) { - let re = infoKeys[i].regexp; - let iKeyStart = reply.search(re); - if (iKeyStart !== -1) { - let prop = infoKeys[i].prop; - let iValueStart = reply.indexOf('=', iKeyStart) + 1; - let iNewlineAfterValue = reply.indexOf('\n', iValueStart); - let iValueEnd = iNewlineAfterValue !== -1 - ? iNewlineAfterValue - : reply.length; - rval[prop] = reply.substring(iValueStart, iValueEnd) | 0; - } - } - - callback(rval); - }); - }; - - command.getMacAddress = function (callback) { - doStringCommand("DRIVER MACADDR", function(reply) { - if (reply) { - reply = reply.split(" ")[2]; // Format: Macaddr = XX.XX.XX.XX.XX.XX - } - callback(reply); - }); - }; - - command.connectToHostapd = function(callback) { - voidControlMessage("connect_to_hostapd", callback); - }; - - command.closeHostapdConnection = function(callback) { - voidControlMessage("close_hostapd_connection", callback); - }; - - command.hostapdCommand = function (callback, request) { - var msg = { cmd: "hostapd_command", - request: request, - iface: aInterface }; - - aControlMessage(msg, function(data) { - callback(data.status ? null : data.reply); - }); - }; - - command.hostapdGetStations = function (callback) { - var msg = { cmd: "hostapd_get_stations", - iface: aInterface }; - - aControlMessage(msg, function(data) { - callback(data.status); - }); - }; - - command.setPowerModeICS = function (mode, callback) { - doBooleanCommand("DRIVER POWERMODE " + (mode === "AUTO" ? 0 : 1), "OK", callback); - }; - - command.setPowerModeJB = function (mode, callback) { - doBooleanCommand("SET ps " + (mode === "AUTO" ? 1 : 0), "OK", callback); - }; - - command.getPowerMode = function (callback) { - doStringCommand("DRIVER GETPOWER", function(reply) { - if (reply) { - reply = (reply.split()[2]|0); // Format: powermode = XX - } - callback(reply); - }); - }; - - command.setNumAllowedChannels = function (numChannels, callback) { - doBooleanCommand("DRIVER SCAN-CHANNELS " + numChannels, "OK", callback); - }; - - command.getNumAllowedChannels = function (callback) { - doStringCommand("DRIVER SCAN-CHANNELS", function(reply) { - if (reply) { - reply = (reply.split()[2]|0); // Format: Scan-Channels = X - } - callback(reply); - }); - }; - - command.setBluetoothCoexistenceMode = function (mode, callback) { - doBooleanCommand("DRIVER BTCOEXMODE " + mode, "OK", callback); - }; - - command.setBluetoothCoexistenceScanMode = function (mode, callback) { - doBooleanCommand("DRIVER BTCOEXSCAN-" + (mode ? "START" : "STOP"), - "OK", callback); - }; - - command.saveConfig = function (callback) { - // Make sure we never write out a value for AP_SCAN other than 1. - doBooleanCommand("AP_SCAN 1", "OK", function(ok) { - doBooleanCommand("SAVE_CONFIG", "OK", callback); - }); - }; - - command.reloadConfig = function (callback) { - doBooleanCommand("RECONFIGURE", "OK", callback); - }; - - command.setScanResultHandling = function (mode, callback) { - doBooleanCommand("AP_SCAN " + mode, "OK", callback); - }; - - command.addToBlacklist = function (bssid, callback) { - doBooleanCommand("BLACKLIST " + bssid, "OK", callback); - }; - - command.clearBlacklist = function (callback) { - doBooleanCommand("BLACKLIST clear", "OK", callback); - }; - - command.setSuspendOptimizationsICS = function (enabled, callback) { - doBooleanCommand("DRIVER SETSUSPENDOPT " + (enabled ? 0 : 1), - "OK", callback); - }; - - command.setSuspendOptimizationsJB = function (enabled, callback) { - doBooleanCommand("DRIVER SETSUSPENDMODE " + (enabled ? 1 : 0), - "OK", callback); - }; - - command.connectToSupplicant = function(callback) { - voidControlMessage("connect_to_supplicant", callback); - }; - - command.closeSupplicantConnection = function(callback) { - voidControlMessage("close_supplicant_connection", callback); - }; - - command.getMacAddress = function(callback) { - doStringCommand("DRIVER MACADDR", function(reply) { - if (reply) { - reply = reply.split(" ")[2]; // Format: Macaddr = XX.XX.XX.XX.XX.XX - } - callback(reply); - }); - }; - - command.setDeviceName = function(deviceName, callback) { - doBooleanCommand("SET device_name " + deviceName, "OK", callback); - }; - - //------------------------------------------------- - // P2P commands. - //------------------------------------------------- - - command.p2pProvDiscovery = function(address, wpsMethod, callback) { - var command = "P2P_PROV_DISC " + address + " " + wpsMethod; - doBooleanCommand(command, "OK", callback); - }; - - command.p2pConnect = function(config, callback) { - var command = "P2P_CONNECT " + config.address + " " + config.wpsMethodWithPin + " "; - if (config.joinExistingGroup) { - command += "join"; - } else { - command += "go_intent=" + config.goIntent; - } - - debug('P2P connect command: ' + command); - doBooleanCommand(command, "OK", callback); - }; - - command.p2pGroupRemove = function(iface, callback) { - debug("groupRemove()"); - doBooleanCommand("P2P_GROUP_REMOVE " + iface, "OK", callback); - }; - - command.p2pEnable = function(detail, callback) { - var commandChain = ["SET device_name " + detail.deviceName, - "SET device_type " + detail.deviceType, - "SET config_methods " + detail.wpsMethods, - "P2P_SET conc_pref sta", - "P2P_FLUSH"]; - - doBooleanCommandChain(commandChain, callback); - }; - - command.p2pDisable = function(callback) { - doBooleanCommand("P2P_SET disabled 1", "OK", callback); - }; - - command.p2pEnableScan = function(timeout, callback) { - doBooleanCommand("P2P_FIND " + timeout, "OK", callback); - }; - - command.p2pDisableScan = function(callback) { - doBooleanCommand("P2P_STOP_FIND", "OK", callback); - }; - - command.p2pGetGroupCapab = function(address, callback) { - command.p2pPeer(address, function(reply) { - debug('p2p_peer reply: ' + reply); - if (!reply) { - callback(0); - return; - } - var capab = /group_capab=0x([0-9a-fA-F]+)/.exec(reply)[1]; - if (!capab) { - callback(0); - } else { - callback(parseInt(capab, 16)); - } - }); - }; - - command.p2pPeer = function(address, callback) { - doStringCommand("P2P_PEER " + address, callback); - }; - - command.p2pGroupAdd = function(netId, callback) { - doBooleanCommand("P2P_GROUP_ADD persistent=" + netId, callback); - }; - - command.p2pReinvoke = function(netId, address, callback) { - doBooleanCommand("P2P_INVITE persistent=" + netId + " peer=" + address, "OK", callback); - }; - - //---------------------------------------------------------- - // Private stuff. - //---------------------------------------------------------- - - function voidControlMessage(cmd, callback) { - aControlMessage({ cmd: cmd, iface: aInterface }, function (data) { - callback(data.status); - }); - } - - function doCommand(request, callback) { - var msg = { cmd: "command", - request: request, - iface: aInterface }; - - aControlMessage(msg, callback); - } - - function doIntCommand(request, callback) { - doCommand(request, function(data) { - callback(data.status ? -1 : (data.reply|0)); - }); - } - - function doBooleanCommand(request, expected, callback) { - doCommand(request, function(data) { - callback(data.status ? false : (data.reply === expected)); - }); - } - - function doStringCommand(request, callback) { - doCommand(request, function(data) { - callback(data.status ? null : data.reply); - }); - } - - function doBooleanCommandChain(commandChain, callback, i) { - if (undefined === i) { - i = 0; - } - - doBooleanCommand(commandChain[i], "OK", function(ok) { - if (!ok) { - return callback(false); - } - i++; - if (i === commandChain.length || !commandChain[i]) { - // Reach the end or empty command. - return callback(true); - } - doBooleanCommandChain(commandChain, callback, i); - }); - } - - //-------------------------------------------------- - // Helper functions. - //-------------------------------------------------- - - function stopProcess(service, process, callback) { - var count = 0; - var timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); - function tick() { - let result = libcutils.property_get(service); - if (result === null) { - callback(); - return; - } - if (result === "stopped" || ++count >= 5) { - // Either we succeeded or ran out of time. - timer = null; - callback(); - return; - } - - // Else it's still running, continue waiting. - timer.initWithCallback(tick, 1000, Ci.nsITimer.TYPE_ONE_SHOT); - } - - setProperty("ctl.stop", process, tick); - } - - // Wrapper around libcutils.property_set that returns true if setting the - // value was successful. - // Note that the callback is not called asynchronously. - function setProperty(key, value, callback) { - let ok = true; - try { - libcutils.property_set(key, value); - } catch(e) { - ok = false; - } - callback(ok); - } - - function isJellybean() { - // According to http://developer.android.com/guide/topics/manifest/uses-sdk-element.html - // ---------------------------------------------------- - // | Platform Version | API Level | VERSION_CODE | - // ---------------------------------------------------- - // | Android 4.1, 4.1.1 | 16 | JELLY_BEAN_MR2 | - // | Android 4.2, 4.2.2 | 17 | JELLY_BEAN_MR1 | - // | Android 4.3 | 18 | JELLY_BEAN | - // ---------------------------------------------------- - return aSdkVersion === 16 || aSdkVersion === 17 || aSdkVersion === 18; - } - - return command; -}; diff --git a/dom/wifi/WifiHotspotUtils.cpp b/dom/wifi/WifiHotspotUtils.cpp deleted file mode 100644 index 5fdb9b76e..000000000 --- a/dom/wifi/WifiHotspotUtils.cpp +++ /dev/null @@ -1,188 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -#include "WifiHotspotUtils.h" -#include <dlfcn.h> -#include <errno.h> -#include <string.h> -#include <dirent.h> -#include <stdlib.h> -#include <cutils/properties.h> - -#include "prinit.h" -#include "mozilla/Assertions.h" -#include "mozilla/Sprintf.h" -#include "nsDebug.h" -#include "nsPrintfCString.h" - -static void* sWifiHotspotUtilsLib; -static PRCallOnceType sInitWifiHotspotUtilsLib; -// Socket pair used to exit from a blocking read. -static struct wpa_ctrl* ctrl_conn; -static const char *ctrl_iface_dir = "/data/misc/wifi/hostapd"; -static char *ctrl_ifname = nullptr; - -DEFINE_DLFUNC(wpa_ctrl_open, struct wpa_ctrl*, const char*) -DEFINE_DLFUNC(wpa_ctrl_close, void, struct wpa_ctrl*) -DEFINE_DLFUNC(wpa_ctrl_attach, int32_t, struct wpa_ctrl*) -DEFINE_DLFUNC(wpa_ctrl_detach, int32_t, struct wpa_ctrl*) -DEFINE_DLFUNC(wpa_ctrl_request, int32_t, struct wpa_ctrl*, - const char*, size_t cmd_len, char *reply, - size_t *reply_len, void (*msg_cb)(char *msg, size_t len)) - - -static PRStatus -InitWifiHotspotUtilsLib() -{ - sWifiHotspotUtilsLib = dlopen("/system/lib/libwpa_client.so", RTLD_LAZY); - // We might fail to open the hardware lib. That's OK. - return PR_SUCCESS; -} - -static void* -GetWifiHotspotLibHandle() -{ - PR_CallOnce(&sInitWifiHotspotUtilsLib, InitWifiHotspotUtilsLib); - return sWifiHotspotUtilsLib; -} - -struct wpa_ctrl * -WifiHotspotUtils::openConnection(const char *ifname) -{ - if (!ifname) { - return nullptr; - } - - USE_DLFUNC(wpa_ctrl_open) - ctrl_conn = wpa_ctrl_open(nsPrintfCString("%s/%s", ctrl_iface_dir, ifname).get()); - return ctrl_conn; -} - -int32_t -WifiHotspotUtils::sendCommand(struct wpa_ctrl *ctrl, const char *cmd, - char *reply, size_t *reply_len) -{ - int32_t ret; - - if (!ctrl_conn) { - NS_WARNING(nsPrintfCString("Not connected to hostapd - \"%s\" command dropped.\n", cmd).get()); - return -1; - } - - USE_DLFUNC(wpa_ctrl_request) - ret = wpa_ctrl_request(ctrl, cmd, strlen(cmd), reply, reply_len, nullptr); - if (ret == -2) { - NS_WARNING(nsPrintfCString("'%s' command timed out.\n", cmd).get()); - return -2; - } else if (ret < 0 || strncmp(reply, "FAIL", 4) == 0) { - return -1; - } - - // Make the reply printable. - reply[*reply_len] = '\0'; - if (strncmp(cmd, "STA-FIRST", 9) == 0 || - strncmp(cmd, "STA-NEXT", 8) == 0) { - char *pos = reply; - - while (*pos && *pos != '\n') - pos++; - *pos = '\0'; - } - - return 0; -} - - -// static -void* -WifiHotspotUtils::GetSharedLibrary() -{ - void* wpaClientLib = GetWifiHotspotLibHandle(); - if (!wpaClientLib) { - NS_WARNING("No /system/lib/libwpa_client.so"); - } - return wpaClientLib; -} - -int32_t WifiHotspotUtils::do_wifi_connect_to_hostapd() -{ - struct dirent *dent; - - DIR *dir = opendir(ctrl_iface_dir); - if (dir) { - while ((dent = readdir(dir))) { - if (strcmp(dent->d_name, ".") == 0 || - strcmp(dent->d_name, "..") == 0) { - continue; - } - ctrl_ifname = strdup(dent->d_name); - break; - } - closedir(dir); - } - - ctrl_conn = openConnection(ctrl_ifname); - if (!ctrl_conn) { - NS_WARNING(nsPrintfCString("Unable to open connection to hostapd on \"%s\": %s", - ctrl_ifname, strerror(errno)).get()); - return -1; - } - - USE_DLFUNC(wpa_ctrl_attach) - if (wpa_ctrl_attach(ctrl_conn) != 0) { - USE_DLFUNC(wpa_ctrl_close) - wpa_ctrl_close(ctrl_conn); - ctrl_conn = nullptr; - return -1; - } - - return 0; -} - -int32_t WifiHotspotUtils::do_wifi_close_hostapd_connection() -{ - if (!ctrl_conn) { - NS_WARNING("Invalid ctrl_conn."); - return -1; - } - - USE_DLFUNC(wpa_ctrl_detach) - if (wpa_ctrl_detach(ctrl_conn) < 0) { - NS_WARNING("Failed to detach wpa_ctrl."); - } - - USE_DLFUNC(wpa_ctrl_close) - wpa_ctrl_close(ctrl_conn); - ctrl_conn = nullptr; - return 0; -} - -int32_t WifiHotspotUtils::do_wifi_hostapd_command(const char *command, - char *reply, - size_t *reply_len) -{ - return sendCommand(ctrl_conn, command, reply, reply_len); -} - -int32_t WifiHotspotUtils::do_wifi_hostapd_get_stations() -{ - char addr[32], cmd[64]; - int stations = 0; - size_t addrLen = sizeof(addr); - - if (sendCommand(ctrl_conn, "STA-FIRST", addr, &addrLen)) { - return 0; - } - stations++; - - SprintfLiteral(cmd, "STA-NEXT %s", addr); - while (sendCommand(ctrl_conn, cmd, addr, &addrLen) == 0) { - stations++; - SprintfLiteral(cmd, "STA-NEXT %s", addr); - } - - return stations; -} diff --git a/dom/wifi/WifiHotspotUtils.h b/dom/wifi/WifiHotspotUtils.h deleted file mode 100644 index 7afdec7da..000000000 --- a/dom/wifi/WifiHotspotUtils.h +++ /dev/null @@ -1,46 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/** - * Abstraction on top of the network support from libnetutils that we - * use to set up network connections. - */ - -#ifndef WifiHotspotUtils_h -#define WifiHotspotUtils_h - -// Forward declaration. -struct wpa_ctrl; - -class WifiHotspotUtils -{ -public: - static void* GetSharedLibrary(); - - int32_t do_wifi_connect_to_hostapd(); - int32_t do_wifi_close_hostapd_connection(); - int32_t do_wifi_hostapd_command(const char *command, - char *reply, - size_t *reply_len); - int32_t do_wifi_hostapd_get_stations(); - -private: - struct wpa_ctrl * openConnection(const char *ifname); - int32_t sendCommand(struct wpa_ctrl *ctrl, const char *cmd, - char *reply, size_t *reply_len); -}; - -// Defines a function type with the right arguments and return type. -#define DEFINE_DLFUNC(name, ret, args...) typedef ret (*FUNC##name)(args); - -// Set up a dlsymed function ready to use. -#define USE_DLFUNC(name) \ - FUNC##name name = (FUNC##name) dlsym(GetSharedLibrary(), #name); \ - if (!name) { \ - MOZ_CRASH("Symbol not found in shared library : " #name); \ - } - -#endif // WifiHotspotUtils_h diff --git a/dom/wifi/WifiNetUtil.jsm b/dom/wifi/WifiNetUtil.jsm deleted file mode 100644 index 2a1866515..000000000 --- a/dom/wifi/WifiNetUtil.jsm +++ /dev/null @@ -1,154 +0,0 @@ -/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ -/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -"use strict"; - -const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components; - -Cu.import("resource://gre/modules/XPCOMUtils.jsm"); -Cu.import("resource://gre/modules/systemlibs.js"); - -XPCOMUtils.defineLazyServiceGetter(this, "gNetworkService", - "@mozilla.org/network/service;1", - "nsINetworkService"); - -this.EXPORTED_SYMBOLS = ["WifiNetUtil"]; - -const DHCP_PROP = "init.svc.dhcpcd"; -const DHCP = "dhcpcd"; -const DEBUG = false; - -this.WifiNetUtil = function(controlMessage) { - function debug(msg) { - if (DEBUG) { - dump('-------------- NetUtil: ' + msg); - } - } - - var util = {}; - - util.runDhcp = function (ifname, gen, callback) { - util.stopDhcp(ifname, function() { - gNetworkService.dhcpRequest(ifname, function(success, dhcpInfo) { - util.runIpConfig(ifname, dhcpInfo, function(data) { - callback(data, gen); - }); - }); - }); - }; - - util.stopDhcp = function (ifname, callback) { - // This function does exactly what dhcp_stop does. Unforunately, if we call - // this function twice before the previous callback is returned. We may block - // our self waiting for the callback. It slows down the wifi startup procedure. - // Therefore, we have to roll our own version here. - let dhcpService = DHCP_PROP + "_" + ifname; - let suffix = (ifname.substr(0, 3) === "p2p") ? "p2p" : ifname; - let processName = DHCP + "_" + suffix; - - // The implementation of |dhcp_do_request| would wait until the - // |result_prop_name| (e.g. dhcp.wlan0.result) to be non-null - // or 30 second timeout. So we manually change the result property - // to 'ko' to avoid timeout. - // - // http://androidxref.com/4.4.4_r1/xref/system/core/libnetutils/dhcp_utils.c#234 - setProperty('dhcp.' + suffix + '.result', 'ko', function() { - stopProcess(dhcpService, processName, callback); - }); - }; - - util.startDhcpServer = function (config, callback) { - gNetworkService.setDhcpServer(true, config, function (error) { - callback(!error); - }); - }; - - util.stopDhcpServer = function (callback) { - gNetworkService.setDhcpServer(false, null, function (error) { - callback(!error); - }); - }; - - util.runIpConfig = function (name, data, callback) { - if (!data) { - debug("IP config failed to run"); - callback({ info: data }); - return; - } - - setProperty("net." + name + ".dns1", ipToString(data.dns1), - function(ok) { - if (!ok) { - debug("Unable to set net.<ifname>.dns1"); - return; - } - setProperty("net." + name + ".dns2", ipToString(data.dns2), - function(ok) { - if (!ok) { - debug("Unable to set net.<ifname>.dns2"); - return; - } - setProperty("net." + name + ".gw", ipToString(data.gateway), - function(ok) { - if (!ok) { - debug("Unable to set net.<ifname>.gw"); - return; - } - callback({ info: data }); - }); - }); - }); - }; - - //-------------------------------------------------- - // Helper functions. - //-------------------------------------------------- - - function stopProcess(service, process, callback) { - var count = 0; - var timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); - function tick() { - let result = libcutils.property_get(service); - if (result === null) { - callback(); - return; - } - if (result === "stopped" || ++count >= 5) { - // Either we succeeded or ran out of time. - timer = null; - callback(); - return; - } - - // Else it's still running, continue waiting. - timer.initWithCallback(tick, 1000, Ci.nsITimer.TYPE_ONE_SHOT); - } - - setProperty("ctl.stop", process, tick); - } - - // Wrapper around libcutils.property_set that returns true if setting the - // value was successful. - // Note that the callback is not called asynchronously. - function setProperty(key, value, callback) { - let ok = true; - try { - libcutils.property_set(key, value); - } catch(e) { - ok = false; - } - callback(ok); - } - - function ipToString(n) { - return String((n >> 0) & 0xFF) + "." + - ((n >> 8) & 0xFF) + "." + - ((n >> 16) & 0xFF) + "." + - ((n >> 24) & 0xFF); - } - - return util; -}; diff --git a/dom/wifi/WifiP2pManager.jsm b/dom/wifi/WifiP2pManager.jsm deleted file mode 100644 index c1b687438..000000000 --- a/dom/wifi/WifiP2pManager.jsm +++ /dev/null @@ -1,1649 +0,0 @@ -/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ -/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -"use strict"; - -const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components; - -Cu.import("resource://gre/modules/XPCOMUtils.jsm"); -Cu.import("resource://gre/modules/StateMachine.jsm"); -Cu.import("resource://gre/modules/Services.jsm"); -Cu.import("resource://gre/modules/systemlibs.js"); - -XPCOMUtils.defineLazyServiceGetter(this, "gSysMsgr", - "@mozilla.org/system-message-internal;1", - "nsISystemMessagesInternal"); - -XPCOMUtils.defineLazyServiceGetter(this, "gNetworkManager", - "@mozilla.org/network/manager;1", - "nsINetworkManager"); - -XPCOMUtils.defineLazyServiceGetter(this, "gNetworkService", - "@mozilla.org/network/service;1", - "nsINetworkService"); - -this.EXPORTED_SYMBOLS = ["WifiP2pManager"]; - -const EVENT_IGNORED = -1; -const EVENT_UNKNOWN = -2; - -// Events from supplicant for p2p. -const EVENT_P2P_DEVICE_FOUND = 0; -const EVENT_P2P_DEVICE_LOST = 1; -const EVENT_P2P_GROUP_STARTED = 2; -const EVENT_P2P_GROUP_REMOVED = 3; -const EVENT_P2P_PROV_DISC_PBC_REQ = 4; -const EVENT_P2P_PROV_DISC_PBC_RESP = 5; -const EVENT_P2P_PROV_DISC_SHOW_PIN = 6; -const EVENT_P2P_PROV_DISC_ENTER_PIN = 7; -const EVENT_P2P_GO_NEG_REQUEST = 8; -const EVENT_P2P_GO_NEG_SUCCESS = 9; -const EVENT_P2P_GO_NEG_FAILURE = 10; -const EVENT_P2P_GROUP_FORMATION_SUCCESS = 11; -const EVENT_P2P_GROUP_FORMATION_FAILURE = 12; -const EVENT_P2P_FIND_STOPPED = 13; -const EVENT_P2P_INVITATION_RESULT = 14; -const EVENT_P2P_INVITATION_RECEIVED = 15; -const EVENT_P2P_PROV_DISC_FAILURE = 16; - -// Events from supplicant but not p2p specific. -const EVENT_AP_STA_DISCONNECTED = 100; -const EVENT_AP_STA_CONNECTED = 101; - -// Events from DOM. -const EVENT_P2P_SET_PAIRING_CONFIRMATION = 1000; -const EVENT_P2P_CMD_CONNECT = 1001; -const EVENT_P2P_CMD_DISCONNECT = 1002; -const EVENT_P2P_CMD_ENABLE = 1003; -const EVENT_P2P_CMD_DISABLE = 1004; -const EVENT_P2P_CMD_ENABLE_SCAN = 1005; -const EVENT_P2P_CMD_DISABLE_SCAN = 1006; -const EVENT_P2P_CMD_BLOCK_SCAN = 1007; -const EVENT_P2P_CMD_UNBLOCK_SCAN = 1008; - -// Internal events. -const EVENT_TIMEOUT_PAIRING_CONFIRMATION = 10000; -const EVENT_TIMEOUT_NEG_REQ = 10001; -const EVENT_TIMEOUT_CONNECTING = 10002; -const EVENT_P2P_ENABLE_SUCCESS = 10003; -const EVENT_P2P_ENABLE_FAILED = 10004; -const EVENT_P2P_DISABLE_SUCCESS = 10005; - -// WPS method string. -const WPS_METHOD_PBC = "pbc"; -const WPS_METHOD_DISPLAY = "display"; -const WPS_METHOD_KEYPAD = "keypad"; - -// Role string. -const P2P_ROLE_GO = "GO"; -const P2P_ROLE_CLIENT = "client"; - -// System message for pairing request. -const PAIRING_REQUEST_SYS_MSG = "wifip2p-pairing-request"; - -// Configuration. -const P2P_INTERFACE_NAME = "p2p0"; -const DEFAULT_GO_INTENT = 15; -const DEFAULT_P2P_DEVICE_NAME = "FirefoxPhone"; -const P2P_SCAN_TIMEOUT_SEC = 120; -const DEFAULT_P2P_WPS_METHODS = "virtual_push_button physical_display keypad"; // For wpa_supplicant. -const DEFAULT_P2P_DEVICE_TYPE = "10-0050F204-5"; // For wpa_supplicant. - -const GO_NETWORK_INTERFACE = { - ip: "192.168.2.1", - maskLength: 24, - gateway: "192.168.2.1", - dns1: "0.0.0.0", - dns2: "0.0.0.0", - dhcpServer: "192.168.2.1" -}; - -const GO_DHCP_SERVER_IP_RANGE = { - startIp: "192.168.2.10", - endIp: "192.168.2.30" -}; - -var gDebug = false; - -// Device Capability bitmap -const DEVICE_CAPAB_SERVICE_DISCOVERY = 1; -const DEVICE_CAPAB_CLIENT_DISCOVERABILITY = 1<<1; -const DEVICE_CAPAB_CONCURRENT_OPER = 1<<2; -const DEVICE_CAPAB_INFRA_MANAGED = 1<<3; -const DEVICE_CAPAB_DEVICE_LIMIT = 1<<4; -const DEVICE_CAPAB_INVITATION_PROCEDURE = 1<<5; - -// Group Capability bitmap -const GROUP_CAPAB_GROUP_OWNER = 1; -const GROUP_CAPAB_PERSISTENT_GROUP = 1<<1; -const GROUP_CAPAB_GROUP_LIMIT = 1<<2; -const GROUP_CAPAB_INTRA_BSS_DIST = 1<<3; -const GROUP_CAPAB_CROSS_CONN = 1<<4; -const GROUP_CAPAB_PERSISTENT_RECONN = 1<<5; -const GROUP_CAPAB_GROUP_FORMATION = 1<<6; - -// Constants defined in wpa_supplicants. -const DEV_PW_REGISTRAR_SPECIFIED = 5; -const DEV_PW_USER_SPECIFIED = 1; -const DEV_PW_PUSHBUTTON = 4; - -this.WifiP2pManager = function (aP2pCommand, aNetUtil) { - function debug(aMsg) { - if (gDebug) { - dump('-------------- WifiP2pManager: ' + aMsg); - } - } - - let manager = {}; - - let _stateMachine = P2pStateMachine(aP2pCommand, aNetUtil); - - // Set debug flag to true or false. - // - // @param aDebug Boolean to indicate enabling or disabling the debug flag. - manager.setDebug = function(aDebug) { - gDebug = aDebug; - }; - - // Set observer of observing internal state machine events. - // - // @param aObserver Used to notify WifiWorker what's happening - // in the internal p2p state machine. - manager.setObserver = function(aObserver) { - _stateMachine.setObserver(aObserver); - }; - - // Handle wpa_supplicant events. - // - // @param aEventString string from wpa_supplicant. - manager.handleEvent = function(aEventString) { - let event = parseEventString(aEventString); - if (EVENT_UNKNOWN === event.id || EVENT_IGNORED === event.id) { - debug('Unknow or ignored event: ' + aEventString); - return false; - } - return _stateMachine.sendEvent(event); - }; - - // Set the confirmation of pairing request. - // - // @param aResult Object of confirmation result which contains: - // .accepted: user granted. - // .pin: pin code which is displaying or input by user. - // .wpsMethod: string of "pbc" or "display" or "keypad". - manager.setPairingConfirmation = function(aResult) { - let event = { - id: EVENT_P2P_SET_PAIRING_CONFIRMATION, - info: { - accepted: aResult.accepted, - pin: aResult.pin - } - }; - _stateMachine.sendEvent(event); - }; - - // Connect to a known peer. - // - // @param aAddress MAC address of the peer to connect. - // @param aWpsMethod String of "pbc" or "display" or "keypad". - // @param aGoIntent Number from 0 to 15. - // @param aCallback Callback |true| on attempting to connect. - // |false| on failed to connect. - manager.connect = function(aAddress, aWpsMethod, aGoIntent, aCallback) { - let event = { - id: EVENT_P2P_CMD_CONNECT, - info: { - wpsMethod: aWpsMethod, - address: aAddress, - goIntent: aGoIntent, - onDoConnect: aCallback - } - }; - _stateMachine.sendEvent(event); - }; - - // Disconnect with a known peer. - // - // @param aAddress The address the user desires to disconect. - // @param aCallback Callback |true| on "attempting" to disconnect. - // |false| on failed to disconnect. - manager.disconnect = function(aAddress, aCallback) { - let event = { - id: EVENT_P2P_CMD_DISCONNECT, - info: { - address: aAddress, - onDoDisconnect: aCallback - } - }; - _stateMachine.sendEvent(event); - }; - - // Enable/disable wifi p2p. - // - // @param aEnabled |true| to enable, |false| to disable. - // @param aCallbacks object for callbacks: - // .onEnabled - // .onDisabled - // .onSupplicantConnected - manager.setEnabled = function(aEnabled, aCallbacks) { - let event = { - id: (aEnabled ? EVENT_P2P_CMD_ENABLE : EVENT_P2P_CMD_DISABLE), - info: { - onEnabled: aCallbacks.onEnabled, - onDisabled: aCallbacks.onDisabled, - onSupplicantConnected: aCallbacks.onSupplicantConnected - } - }; - _stateMachine.sendEvent(event); - }; - - // Enable/disable the wifi p2p scan. - // - // @param aEnabled |true| to enable scan, |false| to disable scan. - // @param aCallback Callback |true| on success to enable/disable scan. - // |false| on failed to enable/disable scan. - manager.setScanEnabled = function(aEnabled, aCallback) { - let event = { - id: (aEnabled ? EVENT_P2P_CMD_ENABLE_SCAN : EVENT_P2P_CMD_DISABLE_SCAN), - info: { callback: aCallback } - }; - _stateMachine.sendEvent(event); - }; - - // Block wifi p2p scan. - manager.blockScan = function() { - _stateMachine.sendEvent({ id: EVENT_P2P_CMD_BLOCK_SCAN }); - }; - - // Un-block and do the pending scan if any. - manager.unblockScan = function() { - _stateMachine.sendEvent({ id: EVENT_P2P_CMD_UNBLOCK_SCAN }); - }; - - // Set the p2p device name. - manager.setDeviceName = function(newDeivceName, callback) { - aP2pCommand.setDeviceName(newDeivceName, callback); - }; - - // Parse wps_supplicant event string. - // - // @param aEventString The raw event string from wpa_supplicant. - // - // @return Object: - // .id: a number to represent an event. - // .info: the additional information carried by this event string. - function parseEventString(aEventString) { - if (isIgnoredEvent(aEventString)) { - return { id: EVENT_IGNORED }; - } - - let match = RegExp("p2p_dev_addr=([0-9a-fA-F:]+) " + - "pri_dev_type=([0-9a-zA-Z-]+) " + - "name='(.*)' " + - "config_methods=0x([0-9a-fA-F]+) " + - "dev_capab=0x([0-9a-fA-F]+) " + - "group_capab=0x([0-9a-fA-F]+) ").exec(aEventString + ' '); - - let tokens = aEventString.split(" "); - - let id = EVENT_UNKNOWN; - - // general info. - let info = {}; - - if (match) { - info = { - address: match[1] ? match[1] : null, - type: match[2] ? match[2] : null, - name: match[3] ? match[3] : null, - wpsFlag: match[4] ? parseInt(match[4], 16) : null, - devFlag: match[5] ? parseInt(match[5], 16) : null, - groupFlag: match[6] ? parseInt(match[6], 16) : null - }; - } - - if (0 === aEventString.indexOf("P2P-DEVICE-FOUND")) { - id = EVENT_P2P_DEVICE_FOUND; - info.wpsCapabilities = wpsFlagToCapabilities(info.wpsFlag); - info.isGroupOwner = isPeerGroupOwner(info.groupFlag); - } else if (0 === aEventString.indexOf("P2P-DEVICE-LOST")) { - // e.g. "P2P-DEVICE-LOST p2p_dev_addr=5e:0a:5b:15:1f:80". - id = EVENT_P2P_DEVICE_LOST; - info.address = /p2p_dev_addr=([0-9a-f:]+)/.exec(aEventString)[1]; - } else if (0 === aEventString.indexOf("P2P-GROUP-STARTED")) { - // e.g. "P2P-GROUP-STARTED wlan0-p2p-0 GO ssid="DIRECT-3F Testing - // passphrase="12345678" go_dev_addr=02:40:61:c2:f3:b7 [PERSISTENT]". - - id = EVENT_P2P_GROUP_STARTED; - let groupMatch = RegExp('ssid="(.*)" ' + - 'freq=([0-9]*) ' + - '(passphrase|psk)=([^ ]+) ' + - 'go_dev_addr=([0-9a-f:]+)').exec(aEventString); - info.ssid = groupMatch[1]; - info.freq = groupMatch[2]; - if ('passphrase' === groupMatch[3]) { - let s = groupMatch[4]; // e.g. "G7jHkkz9". - info.passphrase = s.substring(1, s.length-1); // Trim the double quote. - } else { // psk - info.psk = groupMatch[4]; - } - info.goAddress = groupMatch[5]; - info.ifname = tokens[1]; - info.role = tokens[2]; - } else if (0 === aEventString.indexOf("P2P-GROUP-REMOVED")) { - id = EVENT_P2P_GROUP_REMOVED; - // e.g. "P2P-GROUP-REMOVED wlan0-p2p-0 GO". - info.ifname = tokens[1]; - info.role = tokens[2]; - } else if (0 === aEventString.indexOf("P2P-PROV-DISC-PBC-REQ")) { - id = EVENT_P2P_PROV_DISC_PBC_REQ; - info.wpsMethod = WPS_METHOD_PBC; - } else if (0 === aEventString.indexOf("P2P-PROV-DISC-PBC-RESP")) { - id = EVENT_P2P_PROV_DISC_PBC_RESP; - // The address is different from the general pattern. - info.address = aEventString.split(" ")[1]; - info.wpsMethod = WPS_METHOD_PBC; - } else if (0 === aEventString.indexOf("P2P-PROV-DISC-SHOW-PIN")) { - id = EVENT_P2P_PROV_DISC_SHOW_PIN; - // Obtain peer address and pin from tokens. - info.address = tokens[1]; - info.pin = tokens[2]; - info.wpsMethod = WPS_METHOD_DISPLAY; - } else if (0 === aEventString.indexOf("P2P-PROV-DISC-ENTER-PIN")) { - id = EVENT_P2P_PROV_DISC_ENTER_PIN; - // Obtain peer address from tokens. - info.address = tokens[1]; - info.wpsMethod = WPS_METHOD_KEYPAD; - } else if (0 === aEventString.indexOf("P2P-GO-NEG-REQUEST")) { - id = EVENT_P2P_GO_NEG_REQUEST; - info.address = tokens[1]; - switch (parseInt(tokens[2].split("=")[1], 10)) { - case DEV_PW_REGISTRAR_SPECIFIED: // (5) Peer is display. - info.wpsMethod = WPS_METHOD_KEYPAD; - break; - case DEV_PW_USER_SPECIFIED: // (1) Peer is keypad. - info.wpsMethod = WPS_METHOD_DISPLAY; - break; - case DEV_PW_PUSHBUTTON: // (4) Peer is pbc. - info.wpsMethod = WPS_METHOD_PBC; - break; - default: - debug('Unknown wps method from event P2P-GO-NEG-REQUEST'); - break; - } - } else if (0 === aEventString.indexOf("P2P-GO-NEG-SUCCESS")) { - id = EVENT_P2P_GO_NEG_SUCCESS; - } else if (0 === aEventString.indexOf("P2P-GO-NEG-FAILURE")) { - id = EVENT_P2P_GO_NEG_FAILURE; - } else if (0 === aEventString.indexOf("P2P-GROUP-FORMATION-FAILURE")) { - id = EVENT_P2P_GROUP_FORMATION_FAILURE; - } else if (0 === aEventString.indexOf("P2P-GROUP-FORMATION-SUCCESS")) { - id = EVENT_P2P_GROUP_FORMATION_SUCCESS; - } else if (0 === aEventString.indexOf("P2P-FIND-STOPPED")) { - id = EVENT_P2P_FIND_STOPPED; - } else if (0 === aEventString.indexOf("P2P-INVITATION-RESULT")) { - id = EVENT_P2P_INVITATION_RESULT; - info.status = /status=([0-9]+)/.exec(aEventString)[1]; - } else if (0 === aEventString.indexOf("P2P-INVITATION-RECEIVED")) { - // e.g. "P2P-INVITATION-RECEIVED sa=32:85:a9:da:e6:1f persistent=7". - id = EVENT_P2P_INVITATION_RECEIVED; - info.address = /sa=([0-9a-f:]+)/.exec(aEventString)[1]; - info.netId = /persistent=([0-9]+)/.exec(aEventString)[1]; - } else if (0 === aEventString.indexOf("P2P-PROV-DISC-FAILURE")) { - id = EVENT_P2P_PROV_DISC_FAILURE; - } else { - // Not P2P event but we do receive it. Try to recognize it. - if (0 === aEventString.indexOf("AP-STA-DISCONNECTED")) { - id = EVENT_AP_STA_DISCONNECTED; - info.address = tokens[1]; - } else if (0 === aEventString.indexOf("AP-STA-CONNECTED")) { - id = EVENT_AP_STA_CONNECTED; - info.address = tokens[1]; - } else { - // Neither P2P event nor recognized supplicant event. - debug('Unknwon event string: ' + aEventString); - } - } - - let event = {id: id, info: info}; - debug('Event parsing result: ' + aEventString + ": " + JSON.stringify(event)); - - return event; - } - - function isIgnoredEvent(aEventString) { - const IGNORED_EVENTS = [ - "CTRL-EVENT-BSS-ADDED", - "CTRL-EVENT-BSS-REMOVED", - "CTRL-EVENT-SCAN-RESULTS", - "CTRL-EVENT-STATE-CHANGE", - "WPS-AP-AVAILABLE", - "WPS-ENROLLEE-SEEN" - ]; - for(let i = 0; i < IGNORED_EVENTS.length; i++) { - if (0 === aEventString.indexOf(IGNORED_EVENTS[i])) { - return true; - } - } - return false; - } - - function isPeerGroupOwner(aGroupFlag) { - return (aGroupFlag & GROUP_CAPAB_GROUP_OWNER) !== 0; - } - - // Convert flag to a wps capability array. - // - // @param aWpsFlag Number that represents the wps capabilities. - // @return Array of WPS flag. - function wpsFlagToCapabilities(aWpsFlag) { - let wpsCapabilities = []; - if (aWpsFlag & 0x8) { - wpsCapabilities.push(WPS_METHOD_DISPLAY); - } - if (aWpsFlag & 0x80) { - wpsCapabilities.push(WPS_METHOD_PBC); - } - if (aWpsFlag & 0x100) { - wpsCapabilities.push(WPS_METHOD_KEYPAD); - } - return wpsCapabilities; - } - - _stateMachine.start(); - return manager; -}; - -function P2pStateMachine(aP2pCommand, aNetUtil) { - function debug(aMsg) { - if (gDebug) { - dump('-------------- WifiP2pStateMachine: ' + aMsg); - } - } - - let p2pSm = {}; // The state machine to return. - - let _sm = StateMachine('WIFIP2P'); // The general purpose state machine. - - // Information we need to keep track across states. - let _observer; - - let _onEnabled; - let _onDisabled; - let _onSupplicantConnected; - let _savedConfig = {}; // Configuration used to do P2P_CONNECT. - let _groupInfo = {}; // The information of the group we have formed. - let _removedGroupInfo = {}; // Used to store the group info we are going to remove. - - let _scanBlocked = false; - let _scanPostponded = false; - - let _localDevice = { - address: "", - deviceName: DEFAULT_P2P_DEVICE_NAME + "_" + libcutils.property_get("ro.build.product"), - wpsCapabilities: [WPS_METHOD_PBC, WPS_METHOD_KEYPAD, WPS_METHOD_DISPLAY] - }; - - let _p2pNetworkInterface = { - QueryInterface: XPCOMUtils.generateQI([Ci.nsINetworkInterface]), - - info: { - QueryInterface: XPCOMUtils.generateQI([Ci.nsINetworkInfo]), - - state: Ci.nsINetworkInfo.NETWORK_STATE_DISCONNECTED, - type: Ci.nsINetworkInfo.NETWORK_TYPE_WIFI_P2P, - name: P2P_INTERFACE_NAME, - ips: [], - prefixLengths: [], - dnses: [], - gateways: [], - - getAddresses: function (ips, prefixLengths) { - ips.value = this.ips.slice(); - prefixLengths.value = this.prefixLengths.slice(); - - return this.ips.length; - }, - - getGateways: function (count) { - if (count) { - count.value = this.gateways.length; - } - return this.gateways.slice(); - }, - - getDnses: function (count) { - if (count) { - count.value = this.dnses.length; - } - return this.dnses.slice(); - } - }, - - httpProxyHost: null, - httpProxyPort: null, - - // help - registered: false - }; - - //--------------------------------------------------------- - // State machine APIs. - //--------------------------------------------------------- - - // Register the observer which is implemented in WifiP2pWorkerObserver.jsm. - // - // @param aObserver: - // .onEnabled - // .onDisbaled - // .onPeerFound - // .onPeerLost - // .onConnecting - // .onConnected - // .onDisconnected - // .onLocalDeviceChanged - p2pSm.setObserver = function(aObserver) { - _observer = aObserver; - }; - - p2pSm.start = function() { - _sm.start(stateDisabled); - }; - - p2pSm.sendEvent = function(aEvent) { - let willBeHandled = isInP2pManagedState(_sm.getCurrentState()); - _sm.sendEvent(aEvent); - return willBeHandled; - }; - - // Initialize internal state machine _sm. - _sm.setDefaultEventHandler(handleEventCommon); - - //---------------------------------------------------------- - // State definition. - //---------------------------------------------------------- - - // The initial state. - var stateDisabled = _sm.makeState("DISABLED", { - enter: function() { - _onEnabled = null; - _onSupplicantConnected = null; - _savedConfig = null; - _groupInfo = null; - _removedGroupInfo = null; - _scanBlocked = false; - _scanPostponded = false; - - unregisterP2pNetworkInteface(); - }, - - handleEvent: function(aEvent) { - switch (aEvent.id) { - case EVENT_P2P_CMD_ENABLE: - _onEnabled = aEvent.info.onEnabled; - _onSupplicantConnected = aEvent.info.onSupplicantConnected; - _sm.gotoState(stateEnabling); - break; - - default: - return false; - } // End of switch. - return true; - } - }); - - // The state where we are trying to enable wifi p2p. - var stateEnabling = _sm.makeState("ENABLING", { - enter: function() { - - function onFailure() - { - _onEnabled(false); - _observer.onDisabled(); - _sm.gotoState(stateDisabled); - } - - function onSuccess() - { - _onEnabled(true); - _observer.onEnabled(); - _sm.gotoState(stateInactive); - } - - _sm.pause(); - - // This function will only call back on success. - function connectToSupplicantIfNeeded(callback) { - if (aP2pCommand.getSdkVersion() >= 19) { - // No need to connect to supplicant on KK. Call back directly. - callback(); - return; - } - aP2pCommand.connectToSupplicant(function (status) { - if (0 !== status) { - debug('Failed to connect to p2p0'); - onFailure(); - return; - } - debug('wpa_supplicant p2p0 connected!'); - _onSupplicantConnected(); - callback(); - }); - } - - // Step 1: Connect to p2p0 if needed. - connectToSupplicantIfNeeded(function callback () { - let detail; - - // Step 2: Get MAC address. - if (!_localDevice.address) { - aP2pCommand.getMacAddress(function (address) { - if (!address) { - debug('Failed to get MAC address....'); - onFailure(); - return; - } - debug('Got mac address: ' + address); - _localDevice.address = address; - _observer.onLocalDeviceChanged(_localDevice); - }); - } - - // Step 3: Enable p2p with the device name and wps methods. - detail = { deviceName: _localDevice.deviceName, - deviceType: libcutils.property_get("ro.moz.wifi.p2p_device_type") || DEFAULT_P2P_DEVICE_TYPE, - wpsMethods: libcutils.property_get("ro.moz.wifi.p2p_wps_methods") || DEFAULT_P2P_WPS_METHODS }; - - aP2pCommand.p2pEnable(detail, function (success) { - if (!success) { - debug('Failed to enable p2p'); - onFailure(); - return; - } - - debug('P2P is enabled! Enabling net interface...'); - - // Step 4: Enable p2p0 net interface. wpa_supplicant may have - // already done it for us. - gNetworkService.enableInterface(P2P_INTERFACE_NAME, function (success) { - onSuccess(); - }); - }); - }); - }, - - handleEvent: function(aEvent) { - // We won't receive any event since all of them will be blocked. - return true; - } - }); - - // The state just after enabling wifi direct. - var stateInactive = _sm.makeState("INACTIVE", { - enter: function() { - registerP2pNetworkInteface(); - - if (_sm.getPreviousState() !== stateEnabling) { - _observer.onDisconnected(_savedConfig); - } - - _savedConfig = null; // Used to connect p2p peer. - _groupInfo = null; // The information of the formed group. - }, - - handleEvent: function(aEvent) { - switch (aEvent.id) { - // Receiving the following 3 states implies someone is trying to - // connect to me. - case EVENT_P2P_PROV_DISC_PBC_REQ: - case EVENT_P2P_PROV_DISC_SHOW_PIN: - case EVENT_P2P_PROV_DISC_ENTER_PIN: - debug('Someone is trying to connect to me: ' + JSON.stringify(aEvent.info)); - - _savedConfig = { - name: aEvent.info.name, - address: aEvent.info.address, - wpsMethod: aEvent.info.wpsMethod, - goIntent: DEFAULT_GO_INTENT, - pin: aEvent.info.pin // EVENT_P2P_PROV_DISC_SHOW_PIN only. - }; - - _sm.gotoState(stateWaitingForConfirmation); - break; - - // Connect to a peer. - case EVENT_P2P_CMD_CONNECT: - debug('Trying to connect to peer: ' + JSON.stringify(aEvent.info)); - - _savedConfig = { - address: aEvent.info.address, - wpsMethod: aEvent.info.wpsMethod, - goIntent: aEvent.info.goIntent - }; - - _sm.gotoState(stateProvisionDiscovery); - aEvent.info.onDoConnect(true); - break; - - case EVENT_P2P_INVITATION_RECEIVED: - _savedConfig = { - address: aEvent.info.address, - wpsMethod: WPS_METHOD_PBC, - goIntent: DEFAULT_GO_INTENT, - netId: aEvent.info.netId - }; - _sm.gotoState(stateWaitingForInvitationConfirmation); - break; - - case EVENT_P2P_GROUP_STARTED: - // Most likely the peer just reinvoked a peristen group and succeeeded. - - _savedConfig = { address: aEvent.info.goAddress }; - - _sm.pause(); - handleGroupStarted(aEvent.info, function (success) { - _sm.resume(); - }); - break; - - case EVENT_AP_STA_DISCONNECTED: - // We will hit this case when we used to be a group owner and - // requested to remove the group we owned. - break; - - default: - return false; - } // End of switch. - return true; - }, - }); - - // Waiting for user's confirmation. - var stateWaitingForConfirmation = _sm.makeState("WAITING_FOR_CONFIRMATION", { - timeoutTimer: null, - - enter: function() { - gSysMsgr.broadcastMessage(PAIRING_REQUEST_SYS_MSG, _savedConfig); - this.timeoutTimer = initTimeoutTimer(30000, EVENT_TIMEOUT_PAIRING_CONFIRMATION); - }, - - handleEvent: function(aEvent) { - switch (aEvent.id) { - case EVENT_P2P_SET_PAIRING_CONFIRMATION: - if (!aEvent.info.accepted) { - debug('User rejected this request'); - _sm.gotoState(stateInactive); // Reset to inactive state. - break; - } - - debug('User accepted this request'); - - // The only information we may have to grab from user. - _savedConfig.pin = aEvent.info.pin; - - // The case that user requested to form a group ealier on. - // Just go to connecting state and do p2p_connect. - if (_sm.getPreviousState() === stateProvisionDiscovery) { - _sm.gotoState(stateConnecting); - break; - } - - // Otherwise, wait for EVENT_P2P_GO_NEG_REQUEST. - _sm.gotoState(stateWaitingForNegReq); - break; - - case EVENT_TIMEOUT_PAIRING_CONFIRMATION: - debug('Confirmation timeout!'); - _sm.gotoState(stateInactive); - break; - - case EVENT_P2P_GO_NEG_REQUEST: - _sm.deferEvent(aEvent); - break; - - default: - return false; - } // End of switch. - - return true; - }, - - exit: function() { - this.timeoutTimer.cancel(); - this.timeoutTimer = null; - } - }); - - var stateWaitingForNegReq = _sm.makeState("WAITING_FOR_NEG_REQ", { - timeoutTimer: null, - - enter: function() { - debug('Wait for EVENT_P2P_GO_NEG_REQUEST'); - this.timeoutTimer = initTimeoutTimer(30000, EVENT_TIMEOUT_NEG_REQ); - }, - - handleEvent: function(aEvent) { - switch (aEvent.id) { - case EVENT_P2P_GO_NEG_REQUEST: - if (aEvent.info.wpsMethod !== _savedConfig.wpsMethod) { - debug('Unmatched wps method: ' + aEvent.info.wpsMethod + ", " + _savedConfig.wpsMetho); - } - _sm.gotoState(stateConnecting); - break; - - case EVENT_TIMEOUT_NEG_REQ: - debug("Waiting for NEG-REQ timeout"); - _sm.gotoState(stateInactive); - break; - - default: - return false; - } // End of switch. - return true; - }, - - exit: function() { - this.timeoutTimer.cancel(); - this.timeoutTimer = null; - } - }); - - // Waiting for user's confirmation for invitation. - var stateWaitingForInvitationConfirmation = _sm.makeState("WAITING_FOR_INV_CONFIRMATION", { - timeoutTimer: null, - - enter: function() { - gSysMsgr.broadcastMessage(PAIRING_REQUEST_SYS_MSG, _savedConfig); - this.timeoutTimer = initTimeoutTimer(30000, EVENT_TIMEOUT_PAIRING_CONFIRMATION); - }, - - handleEvent: function(aEvent) { - switch (aEvent.id) { - case EVENT_P2P_SET_PAIRING_CONFIRMATION: - if (!aEvent.info.accepted) { - debug('User rejected this request'); - _sm.gotoState(stateInactive); // Reset to inactive state. - break; - } - - debug('User accepted this request'); - _sm.pause(); - aP2pCommand.p2pGetGroupCapab(_savedConfig.address, function (gc) { - let isPeeGroupOwner = gc & GROUP_CAPAB_GROUP_OWNER; - _sm.gotoState(isPeeGroupOwner ? stateGroupAdding : stateReinvoking); - }); - - break; - - case EVENT_TIMEOUT_PAIRING_CONFIRMATION: - debug('Confirmation timeout!'); - _sm.gotoState(stateInactive); - break; - - default: - return false; - } // End of switch. - - return true; - }, - - exit: function() { - this.timeoutTimer.cancel(); - this.timeoutTimer = null; - } - }); - - var stateGroupAdding = _sm.makeState("GROUP_ADDING", { - timeoutTimer: null, - - enter: function() { - let self = this; - - _observer.onConnecting(_savedConfig); - - _sm.pause(); - aP2pCommand.p2pGroupAdd(_savedConfig.netId, function (success) { - if (!success) { - _sm.gotoState(stateInactive); - return; - } - // Waiting for EVENT_P2P_GROUP_STARTED. - self.timeoutTimer = initTimeoutTimer(60000, EVENT_TIMEOUT_CONNECTING); - _sm.resume(); - }); - }, - - handleEvent: function(aEvent) { - switch (aEvent.id) { - case EVENT_P2P_GROUP_STARTED: - _sm.pause(); - handleGroupStarted(aEvent.info, function (success) { - _sm.resume(); - }); - break; - - case EVENT_P2P_GO_NEG_FAILURE: - debug('Negotiation failure. Go back to inactive state'); - _sm.gotoState(stateInactive); - break; - - case EVENT_TIMEOUT_CONNECTING: - debug('Connecting timeout! Go back to inactive state'); - _sm.gotoState(stateInactive); - break; - - case EVENT_P2P_GROUP_FORMATION_SUCCESS: - case EVENT_P2P_GO_NEG_SUCCESS: - break; - - case EVENT_P2P_GROUP_FORMATION_FAILURE: - debug('Group formation failure'); - _sm.gotoState(stateInactive); - break; - - case EVENT_P2P_GROUP_REMOVED: - debug('Received P2P-GROUP-REMOVED due to previous failed handleGroupdStarted()'); - _removedGroupInfo = { - role: aEvent.info.role, - ifname: aEvent.info.ifname - }; - _sm.gotoState(stateDisconnecting); - break; - - default: - return false; - } // End of switch. - - return true; - }, - - exit: function() { - this.timeoutTimer.cancel(); - this.timeoutTimer = null; - } - }); - - var stateReinvoking = _sm.makeState("REINVOKING", { - timeoutTimer: null, - - enter: function() { - let self = this; - - _observer.onConnecting(_savedConfig); - _sm.pause(); - aP2pCommand.p2pReinvoke(_savedConfig.netId, _savedConfig.address, function(success) { - if (!success) { - _sm.gotoState(stateInactive); - return; - } - // Waiting for EVENT_P2P_GROUP_STARTED. - self.timeoutTimer = initTimeoutTimer(60000, EVENT_TIMEOUT_CONNECTING); - _sm.resume(); - }); - }, - - handleEvent: function(aEvent) { - switch (aEvent.id) { - case EVENT_P2P_GROUP_STARTED: - _sm.pause(); - handleGroupStarted(aEvent.info, function(success) { - _sm.resume(); - }); - break; - - case EVENT_P2P_GO_NEG_FAILURE: - debug('Negotiation failure. Go back to inactive state'); - _sm.gotoState(stateInactive); - break; - - case EVENT_TIMEOUT_CONNECTING: - debug('Connecting timeout! Go back to inactive state'); - _sm.gotoState(stateInactive); - break; - - case EVENT_P2P_GROUP_FORMATION_SUCCESS: - case EVENT_P2P_GO_NEG_SUCCESS: - break; - - case EVENT_P2P_GROUP_FORMATION_FAILURE: - debug('Group formation failure'); - _sm.gotoState(stateInactive); - break; - - case EVENT_P2P_GROUP_REMOVED: - debug('Received P2P-GROUP-REMOVED due to previous failed handleGroupdStarted()'); - _removedGroupInfo = { - role: aEvent.info.role, - ifname: aEvent.info.ifname - }; - _sm.gotoState(stateDisconnecting); - break; - - default: - return false; - } // End of switch. - - return true; - }, - - exit: function() { - this.timeoutTimer.cancel(); - } - }); - - var stateProvisionDiscovery = _sm.makeState("PROVISION_DISCOVERY", { - enter: function() { - function onDiscoveryCommandSent(success) { - if (!success) { - _sm.gotoState(stateInactive); - debug('Failed to send p2p_prov_disc. Go back to inactive state.'); - return; - } - - debug('p2p_prov_disc has been sent.'); - - _sm.resume(); - // Waiting for EVENT_P2P_PROV_DISC_PBC_RESP or - // EVENT_P2P_PROV_DISC_SHOW_PIN or - // EVENT_P2P_PROV_DISC_ENTER_PIN. - } - - _sm.pause(); - aP2pCommand.p2pProvDiscovery(_savedConfig.address, - toPeerWpsMethod(_savedConfig.wpsMethod), - onDiscoveryCommandSent); - }, - - handleEvent: function(aEvent) { - switch (aEvent.id) { - case EVENT_P2P_PROV_DISC_PBC_RESP: - _sm.gotoState(stateConnecting); // No need for local user grant. - break; - case EVENT_P2P_PROV_DISC_SHOW_PIN: - case EVENT_P2P_PROV_DISC_ENTER_PIN: - if (aEvent.info.wpsMethod !== _savedConfig.wpsMethod) { - debug('Unmatched wps method: ' + aEvent.info.wpsMethod + ":" + _savedConfig.wpsMethod); - } - if (EVENT_P2P_PROV_DISC_SHOW_PIN === aEvent.id) { - _savedConfig.pin = aEvent.info.pin; - } - _sm.gotoState(stateWaitingForConfirmation); - break; - - case EVENT_P2P_PROV_DISC_FAILURE: - _sm.gotoState(stateInactive); - break; - - default: - return false; - } // End of switch. - return true; - } - }); - - // We are going to connect to the peer. - // |_savedConfig| is supposed to have been filled properly. - var stateConnecting = _sm.makeState("CONNECTING", { - timeoutTimer: null, - - enter: function() { - let self = this; - - if (null === _savedConfig.goIntent) { - _savedConfig.goIntent = DEFAULT_GO_INTENT; - } - - _observer.onConnecting(_savedConfig); - - let wpsMethodWithPin; - if (WPS_METHOD_KEYPAD === _savedConfig.wpsMethod || - WPS_METHOD_DISPLAY === _savedConfig.wpsMethod) { - // e.g. '12345678 display or '12345678 keypad'. - wpsMethodWithPin = (_savedConfig.pin + ' ' + _savedConfig.wpsMethod); - } else { - // e.g. 'pbc'. - wpsMethodWithPin = _savedConfig.wpsMethod; - } - - _sm.pause(); - - aP2pCommand.p2pGetGroupCapab(_savedConfig.address, function(gc) { - debug('group capabilities of ' + _savedConfig.address + ': ' + gc); - - let isPeerGroupOwner = gc & GROUP_CAPAB_GROUP_OWNER; - let config = { address: _savedConfig.address, - wpsMethodWithPin: wpsMethodWithPin, - goIntent: _savedConfig.goIntent, - joinExistingGroup: isPeerGroupOwner }; - - aP2pCommand.p2pConnect(config, function (success) { - if (!success) { - debug('Failed to send p2p_connect'); - _sm.gotoState(stateInactive); - return; - } - debug('Waiting for EVENT_P2P_GROUP_STARTED.'); - self.timeoutTimer = initTimeoutTimer(60000, EVENT_TIMEOUT_CONNECTING); - _sm.resume(); - }); - }); - }, - - handleEvent: function(aEvent) { - switch (aEvent.id) { - case EVENT_P2P_GROUP_STARTED: - _sm.pause(); - handleGroupStarted(aEvent.info, function (success) { - _sm.resume(); - }); - break; - - case EVENT_P2P_GO_NEG_FAILURE: - debug('Negotiation failure. Go back to inactive state'); - _sm.gotoState(stateInactive); - break; - - case EVENT_TIMEOUT_CONNECTING: - debug('Connecting timeout! Go back to inactive state'); - _sm.gotoState(stateInactive); - break; - - case EVENT_P2P_GROUP_FORMATION_SUCCESS: - case EVENT_P2P_GO_NEG_SUCCESS: - break; - - case EVENT_P2P_GROUP_FORMATION_FAILURE: - debug('Group formation failure'); - _sm.gotoState(stateInactive); - break; - - case EVENT_P2P_GROUP_REMOVED: - debug('Received P2P-GROUP-REMOVED due to previous failed ' + - 'handleGroupdStarted()'); - _removedGroupInfo = { - role: aEvent.info.role, - ifname: aEvent.info.ifname - }; - _sm.gotoState(stateDisconnecting); - break; - - default: - return false; - } // End of switch. - - return true; - }, - - exit: function() { - this.timeoutTimer.cancel(); - } - }); - - var stateConnected = _sm.makeState("CONNECTED", { - groupOwner: null, - - enter: function() { - this.groupOwner = { - macAddress: _groupInfo.goAddress, - ipAddress: _groupInfo.networkInterface.info.gateways[0], - passphrase: _groupInfo.passphrase, - ssid: _groupInfo.ssid, - freq: _groupInfo.freq, - isLocal: _groupInfo.isGroupOwner - }; - - if (!_groupInfo.isGroupOwner) { - _observer.onConnected(this.groupOwner, _savedConfig); - } else { - // If I am a group owner, notify onConnected until EVENT_AP_STA_CONNECTED - // is received. - } - - _removedGroupInfo = null; - }, - - handleEvent: function(aEvent) { - switch (aEvent.id) { - case EVENT_AP_STA_CONNECTED: - if (_groupInfo.isGroupOwner) { - _observer.onConnected(this.groupOwner, _savedConfig); - } - break; - - case EVENT_P2P_GROUP_REMOVED: - _removedGroupInfo = { - role: aEvent.info.role, - ifname: aEvent.info.ifname - }; - _sm.gotoState(stateDisconnecting); - break; - - case EVENT_AP_STA_DISCONNECTED: - debug('Client disconnected: ' + aEvent.info.address); - - // Now we suppose it's the only client. Remove my group. - _sm.pause(); - aP2pCommand.p2pGroupRemove(_groupInfo.ifname, function (success) { - debug('Requested to remove p2p group. Wait for EVENT_P2P_GROUP_REMOVED.'); - _sm.resume(); - }); - break; - - case EVENT_P2P_CMD_DISCONNECT: - // Since we only support single connection, we can ignore - // the given peer address. - _sm.pause(); - aP2pCommand.p2pGroupRemove(_groupInfo.ifname, function(success) { - aEvent.info.onDoDisconnect(true); - _sm.resume(); - }); - - debug('Sent disconnect command. Wait for EVENT_P2P_GROUP_REMOVED.'); - break; - - case EVENT_P2P_PROV_DISC_PBC_REQ: - case EVENT_P2P_PROV_DISC_SHOW_PIN: - case EVENT_P2P_PROV_DISC_ENTER_PIN: - debug('Someone is trying to connect to me: ' + JSON.stringify(aEvent.info)); - - _savedConfig = { - name: aEvent.info.name, - address: aEvent.info.address, - wpsMethod: aEvent.info.wpsMethod, - pin: aEvent.info.pin - }; - - _sm.gotoState(stateWaitingForJoiningConfirmation); - break; - - default: - return false; - } // end of switch - return true; - } - }); - - var stateWaitingForJoiningConfirmation = _sm.makeState("WAITING_FOR_JOINING_CONFIRMATION", { - timeoutTimer: null, - - enter: function() { - gSysMsgr.broadcastMessage(PAIRING_REQUEST_SYS_MSG, _savedConfig); - this.timeoutTimer = initTimeoutTimer(30000, EVENT_TIMEOUT_PAIRING_CONFIRMATION); - }, - - handleEvent: function (aEvent) { - switch (aEvent.id) { - case EVENT_P2P_SET_PAIRING_CONFIRMATION: - if (!aEvent.info.accepted) { - debug('User rejected invitation!'); - _sm.gotoState(stateConnected); - break; - } - - let onWpsCommandSent = function(success) { - _observer.onConnecting(_savedConfig); - _sm.gotoState(stateConnected); - }; - - _sm.pause(); - if (WPS_METHOD_PBC === _savedConfig.wpsMethod) { - aP2pCommand.wpsPbc(onWpsCommandSent, _groupInfo.ifname); - } else { - let detail = { pin: _savedConfig.pin, iface: _groupInfo.ifname }; - aP2pCommand.wpsPin(detail, onWpsCommandSent); - } - break; - - case EVENT_TIMEOUT_PAIRING_CONFIRMATION: - debug('WAITING_FOR_JOINING_CONFIRMATION timeout!'); - _sm.gotoState(stateConnected); - break; - - default: - return false; - } // End of switch. - return true; - }, - - exit: function() { - this.timeoutTimer.cancel(); - this.timeoutTimer = null; - } - }); - - var stateDisconnecting = _sm.makeState("DISCONNECTING", { - enter: function() { - _sm.pause(); - handleGroupRemoved(_removedGroupInfo, function (success) { - if (!success) { - debug('Failed to handle group removed event. What can I do?'); - } - _sm.gotoState(stateInactive); - }); - }, - - handleEvent: function(aEvent) { - return false; // We will not receive any event in this state. - } - }); - - var stateDisabling = _sm.makeState("DISABLING", { - enter: function() { - _sm.pause(); - aNetUtil.stopDhcpServer(function (success) { // Stopping DHCP server is harmless. - debug('Stop DHCP server result: ' + success); - aP2pCommand.p2pDisable(function(success) { - debug('P2P function disabled'); - closeSupplicantConnectionIfNeeded(function() { - debug('Supplicant connection closed'); - gNetworkService.disableInterface(P2P_INTERFACE_NAME, function (success){ - debug('Disabled interface: ' + P2P_INTERFACE_NAME); - _onDisabled(true); - _observer.onDisabled(); - _sm.gotoState(stateDisabled); - }); - }); - }); - }); - - function closeSupplicantConnectionIfNeeded(callback) { - // No need to connect to supplicant on KK. Call back directly. - if (aP2pCommand.getSdkVersion() >= 19) { - callback(); - return; - } - aP2pCommand.closeSupplicantConnection(callback); - } - }, - - handleEvent: function(aEvent) { - return false; // We will not receive any event in this state. - } - }); - - //---------------------------------------------------------- - // Helper functions. - //---------------------------------------------------------- - - // Handle 'P2P_GROUP_STARTED' event. Note that this function - // will also do the state transitioning and error handling. - // - // @param aInfo Information carried by "P2P_GROUP_STARTED" event: - // .role: P2P_ROLE_GO or P2P_ROLE_CLIENT - // .ssid: - // .freq: - // .passphrase: Used to connect to GO for legacy device. - // .goAddress: - // .ifname: e.g. p2p-p2p0 - // - // @param aCallback Callback function. - function handleGroupStarted(aInfo, aCallback) { - debug('handleGroupStarted: ' + JSON.stringify(aInfo)); - - function onSuccess() - { - _sm.gotoState(stateConnected); - aCallback(true); - } - - function onFailure() - { - debug('Failed to handleGroupdStarted(). Remove the group...'); - aP2pCommand.p2pGroupRemove(aInfo.ifname, function (success) { - aCallback(false); - - if (success) { - return; // Stay in current state and wait for EVENT_P2P_GROUP_REMOVED. - } - - debug('p2pGroupRemove command error!'); - _sm.gotoState(stateInactive); - }); - } - - // Save this group information. - _groupInfo = aInfo; - _groupInfo.isGroupOwner = (P2P_ROLE_GO === aInfo.role); - - if (_groupInfo.isGroupOwner) { - debug('Group owner. Start DHCP server'); - let dhcpServerConfig = { ifname: aInfo.ifname, - startIp: GO_DHCP_SERVER_IP_RANGE.startIp, - endIp: GO_DHCP_SERVER_IP_RANGE.endIp, - serverIp: GO_NETWORK_INTERFACE.ip, - maskLength: GO_NETWORK_INTERFACE.maskLength }; - - aNetUtil.startDhcpServer(dhcpServerConfig, function (success) { - if (!success) { - debug('Failed to start DHCP server'); - onFailure(); - return; - } - - // Update p2p network interface. - _p2pNetworkInterface.info.state = Ci.nsINetworkInfo.NETWORK_STATE_CONNECTED; - _p2pNetworkInterface.info.ips = [GO_NETWORK_INTERFACE.ip]; - _p2pNetworkInterface.info.prefixLengths = [GO_NETWORK_INTERFACE.maskLength]; - _p2pNetworkInterface.info.gateways = [GO_NETWORK_INTERFACE.ip]; - handleP2pNetworkInterfaceStateChanged(); - - _groupInfo.networkInterface = _p2pNetworkInterface; - - debug('Everything is done. Happy p2p GO~'); - onSuccess(); - }); - - return; - } - - // We are the client. - - debug("Client. Request IP from DHCP server on interface: " + _groupInfo.ifname); - - aNetUtil.runDhcp(aInfo.ifname, 0, function(dhcpData) { - if(!dhcpData || !dhcpData.info) { - debug('Failed to run DHCP client'); - onFailure(); - return; - } - - // Save network interface. - debug("DHCP request success: " + JSON.stringify(dhcpData.info)); - - // Update p2p network interface. - let maskLength = - netHelpers.getMaskLength(netHelpers.stringToIP(dhcpData.info.mask_str)); - if (!maskLength) { - maskLength = 32; // max prefix for IPv4. - } - _p2pNetworkInterface.info.state = Ci.nsINetworkInfo.NETWORK_STATE_CONNECTED; - _p2pNetworkInterface.info.ips = [dhcpData.info.ipaddr_str]; - _p2pNetworkInterface.info.prefixLengths = [maskLength]; - if (typeof dhcpData.info.dns1_str == "string" && - dhcpData.info.dns1_str.length) { - _p2pNetworkInterface.info.dnses.push(dhcpData.info.dns1_str); - } - if (typeof dhcpData.info.dns2_str == "string" && - dhcpData.info.dns2_str.length) { - _p2pNetworkInterface.info.dnses.push(dhcpData.info.dns2_str); - } - _p2pNetworkInterface.info.gateways = [dhcpData.info.gateway_str]; - handleP2pNetworkInterfaceStateChanged(); - - _groupInfo.networkInterface = _p2pNetworkInterface; - - debug('Happy p2p client~'); - onSuccess(); - }); - } - - function resetP2pNetworkInterface() { - _p2pNetworkInterface.info.state = Ci.nsINetworkInfo.NETWORK_STATE_DISCONNECTED; - _p2pNetworkInterface.info.ips = []; - _p2pNetworkInterface.info.prefixLengths = []; - _p2pNetworkInterface.info.dnses = []; - _p2pNetworkInterface.info.gateways = []; - } - - function registerP2pNetworkInteface() { - if (!_p2pNetworkInterface.registered) { - resetP2pNetworkInterface(); - gNetworkManager.registerNetworkInterface(_p2pNetworkInterface); - _p2pNetworkInterface.registered = true; - } - } - - function unregisterP2pNetworkInteface() { - if (_p2pNetworkInterface.registered) { - resetP2pNetworkInterface(); - gNetworkManager.unregisterNetworkInterface(_p2pNetworkInterface); - _p2pNetworkInterface.registered = false; - } - } - - function handleP2pNetworkInterfaceStateChanged() { - gNetworkManager.updateNetworkInterface(_p2pNetworkInterface); - } - - // Handle 'P2P_GROUP_STARTED' event. - // - // @param aInfo information carried by "P2P_GROUP_REMOVED" event: - // .ifname - // .role: "GO" or "client". - // - // @param aCallback Callback function. - function handleGroupRemoved(aInfo, aCallback) { - if (!_groupInfo) { - debug('No group info. Why?'); - aCallback(true); - return; - } - if (_groupInfo.ifname !== aInfo.ifname || - _groupInfo.role !== aInfo.role) { - debug('Unmatched group info: ' + JSON.stringify(_groupInfo) + - ' v.s. ' + JSON.stringify(aInfo)); - } - - // Update p2p network interface. - _p2pNetworkInterface.info.state = Ci.nsINetworkInfo.NETWORK_STATE_DISCONNECTED; - handleP2pNetworkInterfaceStateChanged(); - - if (P2P_ROLE_GO === aInfo.role) { - aNetUtil.stopDhcpServer(function(success) { - debug('Stop DHCP server result: ' + success); - aCallback(true); - }); - } else { - aNetUtil.stopDhcp(aInfo.ifname, function() { - aCallback(true); - }); - } - } - - // Non state-specific event handler. - function handleEventCommon(aEvent) { - switch (aEvent.id) { - case EVENT_P2P_DEVICE_FOUND: - _observer.onPeerFound(aEvent.info); - break; - - case EVENT_P2P_DEVICE_LOST: - _observer.onPeerLost(aEvent.info); - break; - - case EVENT_P2P_CMD_DISABLE: - _onDisabled = aEvent.info.onDisabled; - _sm.gotoState(stateDisabling); - break; - - case EVENT_P2P_CMD_ENABLE_SCAN: - if (_scanBlocked) { - _scanPostponded = true; - aEvent.info.callback(true); - break; - } - aP2pCommand.p2pEnableScan(P2P_SCAN_TIMEOUT_SEC, aEvent.info.callback); - break; - - case EVENT_P2P_CMD_DISABLE_SCAN: - aP2pCommand.p2pDisableScan(aEvent.info.callback); - break; - - case EVENT_P2P_FIND_STOPPED: - break; - - case EVENT_P2P_CMD_BLOCK_SCAN: - _scanBlocked = true; - aP2pCommand.p2pDisableScan(function(success) {}); - break; - - case EVENT_P2P_CMD_UNBLOCK_SCAN: - _scanBlocked = false; - if (_scanPostponded) { - aP2pCommand.p2pEnableScan(P2P_SCAN_TIMEOUT_SEC, function(success) {}); - } - break; - - case EVENT_P2P_CMD_CONNECT: - case EVENT_P2P_CMD_DISCONNECT: - debug("The current state couldn't handle connect/disconnect request. Ignore it."); - break; - - default: - return false; - } // End of switch. - return true; - } - - function isInP2pManagedState(aState) { - let p2pManagedStates = [stateWaitingForConfirmation, - stateWaitingForNegReq, - stateProvisionDiscovery, - stateWaitingForInvitationConfirmation, - stateGroupAdding, - stateReinvoking, - stateConnecting, - stateConnected, - stateDisconnecting]; - - for (let i = 0; i < p2pManagedStates.length; i++) { - if (aState === p2pManagedStates[i]) { - return true; - } - } - - return false; - } - - function initTimeoutTimer(aTimeoutMs, aTimeoutEvent) { - let timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); - function onTimerFired() { - _sm.sendEvent({ id: aTimeoutEvent }); - timer = null; - } - timer.initWithCallback(onTimerFired.bind(this), aTimeoutMs, - Ci.nsITimer.TYPE_ONE_SHOT); - return timer; - } - - // Converts local WPS method to peer WPS method. - function toPeerWpsMethod(aLocalWpsMethod) { - switch (aLocalWpsMethod) { - case WPS_METHOD_DISPLAY: - return WPS_METHOD_KEYPAD; - case WPS_METHOD_KEYPAD: - return WPS_METHOD_DISPLAY; - case WPS_METHOD_PBC: - return WPS_METHOD_PBC; - default: - return WPS_METHOD_PBC; // Use "push button" as the default method. - } - } - - return p2pSm; -} - -this.WifiP2pManager.INTERFACE_NAME = P2P_INTERFACE_NAME; diff --git a/dom/wifi/WifiP2pWorkerObserver.jsm b/dom/wifi/WifiP2pWorkerObserver.jsm deleted file mode 100644 index d04e8db5e..000000000 --- a/dom/wifi/WifiP2pWorkerObserver.jsm +++ /dev/null @@ -1,319 +0,0 @@ -/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ -/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -"use strict"; - -const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components; - -const CONNECTION_STATUS_DISCONNECTED = "disconnected"; -const CONNECTION_STATUS_CONNECTING = "connecting"; -const CONNECTION_STATUS_CONNECTED = "connected"; -const CONNECTION_STATUS_DISCONNECTING = "disconnecting"; - -const DEBUG = false; - -this.EXPORTED_SYMBOLS = ["WifiP2pWorkerObserver"]; - -// WifiP2pWorkerObserver resides in WifiWorker to handle DOM message -// by either 1) returning internally maintained information or -// 2) delegating to aDomMsgResponder. It is also responsible -// for observing events from WifiP2pManager and dispatch to DOM. -// -// @param aDomMsgResponder handles DOM messages, including -// - setScanEnabled -// - connect -// - disconnect -// - setPairingConfirmation -// The instance is actually WifiP2pManager. -this.WifiP2pWorkerObserver = function(aDomMsgResponder) { - function debug(aMsg) { - if (DEBUG) { - dump('-------------- WifiP2pWorkerObserver: ' + aMsg); - } - } - - // Private member variables. - let _localDevice; - let _peerList = {}; // List of P2pDevice. - let _domManagers = []; - let _enabled = false; - let _groupOwner = null; - let _currentPeer = null; - - // Constructor of P2pDevice. It will be exposed to DOM. - // - // @param aPeer object representing a P2P device: - // .name: string for the device name. - // .address: Mac address. - // .isGroupOwner: boolean to indicate if this device is the group owner. - // .wpsCapabilities: array of string of {"pbc", "display", "keypad"}. - function P2pDevice(aPeer) { - this.address = aPeer.address; - this.name = (aPeer.name ? aPeer.name : aPeer.address); - this.isGroupOwner = aPeer.isGroupOwner; - this.wpsCapabilities = aPeer.wpsCapabilities; - this.connectionStatus = CONNECTION_STATUS_DISCONNECTED; - - // Since this object will be exposed to web, defined the exposed - // properties here. - this.__exposedProps__ = { - address: "r", - name: "r", - isGroupOwner: "r", - wpsCapabilities: "r", - connectionStatus: "r" - }; - } - - // Constructor of P2pGroupOwner. - // - // @param aGroupOwner: - // .macAddress - // .ipAddress - // .passphrase - // .ssid - // .freq - // .isLocal - function P2pGroupOwner(aGroupOwner) { - this.macAddress = aGroupOwner.macAddress; // The identifier to get further information. - this.ipAddress = aGroupOwner.ipAddress; - this.passphrase = aGroupOwner.passphrase; - this.ssid = aGroupOwner.ssid; // e.g. DIRECT-xy. - this.freq = aGroupOwner.freq; - this.isLocal = aGroupOwner.isLocal; - - let detail = _peerList[aGroupOwner.macAddress]; - if (detail) { - this.name = detail.name; - this.wpsCapabilities = detail.wpsCapabilities; - } else if (_localDevice.address === this.macAddress) { - this.name = _localDevice.name; - this.wpsCapabilities = _localDevice.wpsCapabilities; - } else { - debug("We don't know this group owner: " + aGroupOwner.macAddress); - this.name = aGroupOwner.macAddress; - this.wpsCapabilities = []; - } - } - - function fireEvent(aMessage, aData) { - debug('domManager: ' + JSON.stringify(_domManagers)); - _domManagers.forEach(function(manager) { - // Note: We should never have a dead message manager here because we - // observe our child message managers shutting down below. - manager.sendAsyncMessage("WifiP2pManager:" + aMessage, aData); - }); - } - - function addDomManager(aMsg) { - if (-1 === _domManagers.indexOf(aMsg.manager)) { - _domManagers.push(aMsg.manager); - } - } - - function returnMessage(aMessage, aSuccess, aData, aMsg) { - let rMsg = aMessage + ":Return:" + (aSuccess ? "OK" : "NO"); - aMsg.manager.sendAsyncMessage(rMsg, - { data: aData, rid: aMsg.rid, mid: aMsg.mid }); - } - - function handlePeerListUpdated() { - fireEvent("onpeerinfoupdate", {}); - } - - // Return a literal object as the constructed object. - return { - onLocalDeviceChanged: function(aDevice) { - _localDevice = aDevice; - debug('Local device updated to: ' + JSON.stringify(_localDevice)); - }, - - onEnabled: function() { - _peerList = []; - _enabled = true; - fireEvent("p2pUp", {}); - }, - - onDisbaled: function() { - _enabled = false; - fireEvent("p2pDown", {}); - }, - - onPeerFound: function(aPeer) { - let newFoundPeer = new P2pDevice(aPeer); - let origianlPeer = _peerList[aPeer.address]; - _peerList[aPeer.address] = newFoundPeer; - if (origianlPeer) { - newFoundPeer.connectionStatus = origianlPeer.connectionStatus; - } - handlePeerListUpdated(); - }, - - onPeerLost: function(aPeer) { - let lostPeer = _peerList[aPeer.address]; - if (!lostPeer) { - debug('Unknown peer lost: ' + aPeer.address); - return; - } - delete _peerList[aPeer.address]; - handlePeerListUpdated(); - }, - - onConnecting: function(aPeer) { - let peer = _peerList[aPeer.address]; - if (!peer) { - debug('Unknown peer connecting: ' + aPeer.address); - peer = new P2pDevice(aPeer); - _peerList[aPeer.address] = peer; - handlePeerListUpdated(); - } - peer.connectionStatus = CONNECTION_STATUS_CONNECTING; - - fireEvent('onconnecting', { peer: peer }); - }, - - onConnected: function(aGroupOwner, aPeer) { - let go = new P2pGroupOwner(aGroupOwner); - let peer = _peerList[aPeer.address]; - if (!peer) { - debug('Unknown peer connected: ' + aPeer.address); - peer = new P2pDevice(aPeer); - _peerList[aPeer.address] = peer; - handlePeerListUpdated(); - } - peer.connectionStatus = CONNECTION_STATUS_CONNECTED; - peer.isGroupOwner = (aPeer.address === aGroupOwner.address); - - _groupOwner = go; - _currentPeer = peer; - - fireEvent('onconnected', { groupOwner: go, peer: peer }); - }, - - onDisconnected: function(aPeer) { - let peer = _peerList[aPeer.address]; - if (!peer) { - debug('Unknown peer disconnected: ' + aPeer.address); - return; - } - - peer.connectionStatus = CONNECTION_STATUS_DISCONNECTED; - - _groupOwner = null; - _currentPeer = null; - - fireEvent('ondisconnected', { peer: peer }); - }, - - getObservedDOMMessages: function() { - return [ - "WifiP2pManager:getState", - "WifiP2pManager:getPeerList", - "WifiP2pManager:setScanEnabled", - "WifiP2pManager:connect", - "WifiP2pManager:disconnect", - "WifiP2pManager:setPairingConfirmation", - "WifiP2pManager:setDeviceName" - ]; - }, - - onDOMMessage: function(aMessage) { - let msg = aMessage.data || {}; - msg.manager = aMessage.target; - - if ("child-process-shutdown" === aMessage.name) { - let i; - if (-1 !== (i = _domManagers.indexOf(msg.manager))) { - _domManagers.splice(i, 1); - } - return; - } - - if (!aMessage.target.assertPermission("wifi-manage")) { - return; - } - - switch (aMessage.name) { - case "WifiP2pManager:getState": // A new DOM manager is created. - addDomManager(msg); - return { // Synchronous call. Simply return it. - enabled: _enabled, - groupOwner: _groupOwner, - currentPeer: _currentPeer - }; - - case "WifiP2pManager:setScanEnabled": - { - let enabled = msg.data; - - aDomMsgResponder.setScanEnabled(enabled, function(success) { - returnMessage(aMessage.name, success, (success ? true : "ERROR"), msg); - }); - } - break; - - case "WifiP2pManager:getPeerList": - { - // Convert the object to an array. - let peerArray = []; - for (let key in _peerList) { - if (_peerList.hasOwnProperty(key)) { - peerArray.push(_peerList[key]); - } - } - - returnMessage(aMessage.name, true, peerArray, msg); - } - break; - - case "WifiP2pManager:connect": - { - let peer = msg.data; - - let onDoConnect = function(success) { - returnMessage(aMessage.name, success, (success ? true : "ERROR"), msg); - }; - - aDomMsgResponder.connect(peer.address, peer.wpsMethod, - peer.goIntent, onDoConnect); - } - break; - - case "WifiP2pManager:disconnect": - { - let address = msg.data; - - aDomMsgResponder.disconnect(address, function(success) { - returnMessage(aMessage.name, success, (success ? true : "ERROR"), msg); - }); - } - break; - - case "WifiP2pManager:setPairingConfirmation": - { - let result = msg.data; - aDomMsgResponder.setPairingConfirmation(result); - returnMessage(aMessage.name, true, true, msg); - } - break; - - case "WifiP2pManager:setDeviceName": - { - let newDeviceName = msg.data; - aDomMsgResponder.setDeviceName(newDeviceName, function(success) { - returnMessage(aMessage.name, success, (success ? true : "ERROR"), msg); - }); - } - break; - - default: - if (0 === aMessage.name.indexOf("WifiP2pManager:")) { - debug("DOM WifiP2pManager message not handled: " + aMessage.name); - } - } // End of switch. - } - }; -}; diff --git a/dom/wifi/WifiProxyService.cpp b/dom/wifi/WifiProxyService.cpp deleted file mode 100644 index 0ff5097af..000000000 --- a/dom/wifi/WifiProxyService.cpp +++ /dev/null @@ -1,357 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -#include "WifiProxyService.h" -#include "nsServiceManagerUtils.h" -#include "mozilla/ModuleUtils.h" -#include "mozilla/ClearOnShutdown.h" -#include "mozilla/dom/ToJSValue.h" -#include "nsXULAppAPI.h" -#include "WifiUtils.h" - -#ifdef MOZ_TASK_TRACER -#include "GeckoTaskTracer.h" -using namespace mozilla::tasktracer; -#endif - -#define NS_WIFIPROXYSERVICE_CID \ - { 0xc6c9be7e, 0x744f, 0x4222, {0xb2, 0x03, 0xcd, 0x55, 0xdf, 0xc8, 0xbc, 0x12} } - -using namespace mozilla; -using namespace mozilla::dom; - -namespace mozilla { - -// The singleton Wifi service, to be used on the main thread. -static StaticRefPtr<WifiProxyService> gWifiProxyService; - -// The singleton supplicant class, that can be used on any thread. -static UniquePtr<WpaSupplicant> gWpaSupplicant; - -// Runnable used dispatch the WaitForEvent result on the main thread. -class WifiEventDispatcher : public Runnable -{ -public: - WifiEventDispatcher(const nsAString& aEvent, const nsACString& aInterface) - : mEvent(aEvent) - , mInterface(aInterface) - { - MOZ_ASSERT(!NS_IsMainThread()); - } - - NS_IMETHOD Run() override - { - MOZ_ASSERT(NS_IsMainThread()); - gWifiProxyService->DispatchWifiEvent(mEvent, mInterface); - return NS_OK; - } - -private: - nsString mEvent; - nsCString mInterface; -}; - -// Runnable used to call WaitForEvent on the event thread. -class EventRunnable : public Runnable -{ -public: - EventRunnable(const nsACString& aInterface) - : mInterface(aInterface) - { - MOZ_ASSERT(NS_IsMainThread()); - } - - NS_IMETHOD Run() override - { - MOZ_ASSERT(!NS_IsMainThread()); - nsAutoString event; - gWpaSupplicant->WaitForEvent(event, mInterface); - if (!event.IsEmpty()) { -#ifdef MOZ_TASK_TRACER - // Make wifi initialization events to be the source events of TaskTracer, - // and originate the rest correlation tasks from here. - AutoSourceEvent taskTracerEvent(SourceEventType::Wifi); - AddLabel("%s %s", mInterface.get(), NS_ConvertUTF16toUTF8(event).get()); -#endif - nsCOMPtr<nsIRunnable> runnable = new WifiEventDispatcher(event, mInterface); - NS_DispatchToMainThread(runnable); - } - return NS_OK; - } - -private: - nsCString mInterface; -}; - -// Runnable used dispatch the Command result on the main thread. -class WifiResultDispatcher : public Runnable -{ -public: - WifiResultDispatcher(WifiResultOptions& aResult, const nsACString& aInterface) - : mResult(aResult) - , mInterface(aInterface) - { - MOZ_ASSERT(!NS_IsMainThread()); - } - - NS_IMETHOD Run() override - { - MOZ_ASSERT(NS_IsMainThread()); - gWifiProxyService->DispatchWifiResult(mResult, mInterface); - return NS_OK; - } - -private: - WifiResultOptions mResult; - nsCString mInterface; -}; - -// Runnable used to call SendCommand on the control thread. -class ControlRunnable : public Runnable -{ -public: - ControlRunnable(CommandOptions aOptions, const nsACString& aInterface) - : mOptions(aOptions) - , mInterface(aInterface) - { - MOZ_ASSERT(NS_IsMainThread()); - } - - NS_IMETHOD Run() override - { - WifiResultOptions result; - if (gWpaSupplicant->ExecuteCommand(mOptions, result, mInterface)) { - nsCOMPtr<nsIRunnable> runnable = new WifiResultDispatcher(result, mInterface); - NS_DispatchToMainThread(runnable); - } - return NS_OK; - } -private: - CommandOptions mOptions; - nsCString mInterface; -}; - -NS_IMPL_ISUPPORTS(WifiProxyService, nsIWifiProxyService) - -WifiProxyService::WifiProxyService() -{ - MOZ_ASSERT(NS_IsMainThread()); - MOZ_ASSERT(!gWifiProxyService); -} - -WifiProxyService::~WifiProxyService() -{ - MOZ_ASSERT(!gWifiProxyService); -} - -already_AddRefed<WifiProxyService> -WifiProxyService::FactoryCreate() -{ - if (!XRE_IsParentProcess()) { - return nullptr; - } - - MOZ_ASSERT(NS_IsMainThread()); - - if (!gWifiProxyService) { - gWifiProxyService = new WifiProxyService(); - ClearOnShutdown(&gWifiProxyService); - - gWpaSupplicant = MakeUnique<WpaSupplicant>(); - ClearOnShutdown(&gWpaSupplicant); - } - - RefPtr<WifiProxyService> service = gWifiProxyService.get(); - return service.forget(); -} - -NS_IMETHODIMP -WifiProxyService::Start(nsIWifiEventListener* aListener, - const char ** aInterfaces, - uint32_t aNumOfInterfaces) -{ - MOZ_ASSERT(NS_IsMainThread()); - MOZ_ASSERT(aListener); - -#if ANDROID_VERSION >= 19 - // KK changes the way mux'ing/demux'ing different supplicant interfaces - // (e.g. wlan0/p2p0) from multi-sockets to single socket embedded with - // prefixed interface name (e.g. IFNAME=wlan0 xxxxxx). Therefore, we use - // the first given interface as the global interface for KK. - aNumOfInterfaces = 1; -#endif - - nsresult rv; - - // Since EventRunnable runs in the manner of blocking, we have to - // spin a thread for each interface. - // (See the WpaSupplicant::WaitForEvent) - mEventThreadList.SetLength(aNumOfInterfaces); - for (uint32_t i = 0; i < aNumOfInterfaces; i++) { - mEventThreadList[i].mInterface = aInterfaces[i]; - rv = NS_NewThread(getter_AddRefs(mEventThreadList[i].mThread)); - if (NS_FAILED(rv)) { - NS_WARNING("Can't create wifi event thread"); - Shutdown(); - return NS_ERROR_FAILURE; - } - } - - rv = NS_NewThread(getter_AddRefs(mControlThread)); - if (NS_FAILED(rv)) { - NS_WARNING("Can't create wifi control thread"); - Shutdown(); - return NS_ERROR_FAILURE; - } - - mListener = aListener; - - return NS_OK; -} - -NS_IMETHODIMP -WifiProxyService::Shutdown() -{ - MOZ_ASSERT(NS_IsMainThread()); - for (size_t i = 0; i < mEventThreadList.Length(); i++) { - if (mEventThreadList[i].mThread) { - mEventThreadList[i].mThread->Shutdown(); - mEventThreadList[i].mThread = nullptr; - } - } - - mEventThreadList.Clear(); - - if (mControlThread) { - mControlThread->Shutdown(); - mControlThread = nullptr; - } - - mListener = nullptr; - - return NS_OK; -} - -NS_IMETHODIMP -WifiProxyService::SendCommand(JS::Handle<JS::Value> aOptions, - const nsACString& aInterface, - JSContext* aCx) -{ - MOZ_ASSERT(NS_IsMainThread()); - WifiCommandOptions options; - - if (!options.Init(aCx, aOptions)) { - NS_WARNING("Bad dictionary passed to WifiProxyService::SendCommand"); - return NS_ERROR_FAILURE; - } - - if (!mControlThread) { - return NS_ERROR_FAILURE; - } - - // Dispatch the command to the control thread. - CommandOptions commandOptions(options); - nsCOMPtr<nsIRunnable> runnable = new ControlRunnable(commandOptions, aInterface); - mControlThread->Dispatch(runnable, nsIEventTarget::DISPATCH_NORMAL); - return NS_OK; -} - -NS_IMETHODIMP -WifiProxyService::WaitForEvent(const nsACString& aInterface) -{ - MOZ_ASSERT(NS_IsMainThread()); - -#if ANDROID_VERSION >= 19 - // We will only have one global interface for KK. - if (!mEventThreadList.IsEmpty()) { - nsCOMPtr<nsIRunnable> runnable = new EventRunnable(aInterface); - mEventThreadList[0].mThread->Dispatch(runnable, nsIEventTarget::DISPATCH_NORMAL); - return NS_OK; - } -#else - // Dispatch to the event thread which has the given interface name - for (size_t i = 0; i < mEventThreadList.Length(); i++) { - if (mEventThreadList[i].mInterface.Equals(aInterface)) { - nsCOMPtr<nsIRunnable> runnable = new EventRunnable(aInterface); - mEventThreadList[i].mThread->Dispatch(runnable, nsIEventTarget::DISPATCH_NORMAL); - return NS_OK; - } - } -#endif - - return NS_ERROR_FAILURE; -} - -void -WifiProxyService::DispatchWifiResult(const WifiResultOptions& aOptions, const nsACString& aInterface) -{ - MOZ_ASSERT(NS_IsMainThread()); - - mozilla::AutoSafeJSContext cx; - JS::Rooted<JS::Value> val(cx); - - if (!ToJSValue(cx, aOptions, &val)) { - return; - } - - if (mListener) { - // Call the listener with a JS value. - mListener->OnCommand(val, aInterface); - } -} - -void -WifiProxyService::DispatchWifiEvent(const nsAString& aEvent, const nsACString& aInterface) -{ - MOZ_ASSERT(NS_IsMainThread()); - -#if ANDROID_VERSION < 19 - mListener->OnWaitEvent(aEvent, aInterface); -#else - // The interface might be embedded in the event string such as - // "IFNAME=wlan0 CTRL-EVENT-BSS-ADDED 65 3c:94:d5:7c:11:8b". - // Parse the interface name from the event string and use p2p0 - // as the default interface if "IFNAME" is not found. - nsAutoString event; - nsAutoString embeddedInterface(NS_LITERAL_STRING("p2p0")); - if (StringBeginsWith(aEvent, NS_LITERAL_STRING("IFNAME"))) { - int32_t ifnameFrom = aEvent.FindChar('=') + 1; - int32_t ifnameTo = aEvent.FindChar(' ') - 1; - embeddedInterface = Substring(aEvent, ifnameFrom, ifnameTo - ifnameFrom + 1); - event = Substring(aEvent, aEvent.FindChar(' ') + 1); - } - else { - event = aEvent; - } - mListener->OnWaitEvent(event, NS_ConvertUTF16toUTF8(embeddedInterface)); -#endif -} - -NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(WifiProxyService, - WifiProxyService::FactoryCreate) - -NS_DEFINE_NAMED_CID(NS_WIFIPROXYSERVICE_CID); - -static const mozilla::Module::CIDEntry kWifiProxyServiceCIDs[] = { - { &kNS_WIFIPROXYSERVICE_CID, false, nullptr, WifiProxyServiceConstructor }, - { nullptr } -}; - -static const mozilla::Module::ContractIDEntry kWifiProxyServiceContracts[] = { - { "@mozilla.org/wifi/service;1", &kNS_WIFIPROXYSERVICE_CID }, - { nullptr } -}; - -static const mozilla::Module kWifiProxyServiceModule = { - mozilla::Module::kVersion, - kWifiProxyServiceCIDs, - kWifiProxyServiceContracts, - nullptr -}; - -} // namespace mozilla - -NSMODULE_DEFN(WifiProxyServiceModule) = &kWifiProxyServiceModule; diff --git a/dom/wifi/WifiProxyService.h b/dom/wifi/WifiProxyService.h deleted file mode 100644 index 406be47de..000000000 --- a/dom/wifi/WifiProxyService.h +++ /dev/null @@ -1,49 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -#ifndef WifiProxyService_h -#define WifiProxyService_h - -#include "nsIWifiService.h" -#include "nsCOMPtr.h" -#include "nsThread.h" -#include "mozilla/dom/WifiOptionsBinding.h" -#include "nsTArray.h" - -namespace mozilla { - -class WifiProxyService final : public nsIWifiProxyService -{ -private: - struct EventThreadListEntry - { - nsCOMPtr<nsIThread> mThread; - nsCString mInterface; - }; - -public: - NS_DECL_ISUPPORTS - NS_DECL_NSIWIFIPROXYSERVICE - - static already_AddRefed<WifiProxyService> - FactoryCreate(); - - void DispatchWifiEvent(const nsAString& aEvent, const nsACString& aInterface); - void DispatchWifiResult(const mozilla::dom::WifiResultOptions& aOptions, - const nsACString& aInterface); - -private: - WifiProxyService(); - ~WifiProxyService(); - - nsTArray<EventThreadListEntry> mEventThreadList; - nsCOMPtr<nsIThread> mControlThread; - nsCOMPtr<nsIWifiEventListener> mListener; -}; - -} // namespace mozilla - -#endif // WifiProxyService_h diff --git a/dom/wifi/WifiUtils.cpp b/dom/wifi/WifiUtils.cpp deleted file mode 100644 index 2526c9ea4..000000000 --- a/dom/wifi/WifiUtils.cpp +++ /dev/null @@ -1,521 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -#include "WifiUtils.h" -#include <dlfcn.h> -#include <errno.h> -#include <cutils/properties.h> -#include "prinit.h" -#include "mozilla/Sprintf.h" -#include "js/CharacterEncoding.h" - -using namespace mozilla::dom; - -#define BUFFER_SIZE 4096 -#define COMMAND_SIZE 256 - -// Intentionally not trying to dlclose() this handle. That's playing -// Russian roulette with security bugs. -static void* sWifiLib; -static PRCallOnceType sInitWifiLib; - -static PRStatus -InitWifiLib() -{ - sWifiLib = dlopen("/system/lib/libhardware_legacy.so", RTLD_LAZY); - // We might fail to open the hardware lib. That's OK. - return PR_SUCCESS; -} - -static void* -GetSharedLibrary() -{ - PR_CallOnce(&sInitWifiLib, InitWifiLib); - return sWifiLib; -} - -static bool -GetWifiP2pSupported() -{ - char propP2pSupported[PROPERTY_VALUE_MAX]; - property_get("ro.moz.wifi.p2p_supported", propP2pSupported, "0"); - return (0 == strcmp(propP2pSupported, "1")); -} - -static int -hex2num(char c) -{ - if (c >= '0' && c <= '9') - return c - '0'; - if (c >= 'a' && c <= 'f') - return c - 'a' + 10; - if (c >= 'A' && c <= 'F') - return c - 'A' + 10; - return -1; -} - -static int -hex2byte(const char* hex) -{ - int a, b; - a = hex2num(*hex++); - if (a < 0) - return -1; - b = hex2num(*hex++); - if (b < 0) - return -1; - return (a << 4) | b; -} - -// This function is equivalent to printf_decode() at src/utils/common.c in -// the supplicant. - -static uint32_t -convertToBytes(char* buf, uint32_t maxlen, const char* str) -{ - const char *pos = str; - uint32_t len = 0; - int val; - - while (*pos) { - if (len == maxlen) - break; - switch (*pos) { - case '\\': - pos++; - switch (*pos) { - case '\\': - buf[len++] = '\\'; - pos++; - break; - case '"': - buf[len++] = '"'; - pos++; - break; - case 'n': - buf[len++] = '\n'; - pos++; - break; - case 'r': - buf[len++] = '\r'; - pos++; - break; - case 't': - buf[len++] = '\t'; - pos++; - break; - case 'e': - buf[len++] = '\e'; - pos++; - break; - case 'x': - pos++; - val = hex2byte(pos); - if (val < 0) { - val = hex2num(*pos); - if (val < 0) - break; - buf[len++] = val; - pos++; - } else { - buf[len++] = val; - pos += 2; - } - break; - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - val = *pos++ - '0'; - if (*pos >= '0' && *pos <= '7') - val = val * 8 + (*pos++ - '0'); - if (*pos >= '0' && *pos <= '7') - val = val * 8 + (*pos++ - '0'); - buf[len++] = val; - break; - default: - break; - } - break; - default: - buf[len++] = *pos++; - break; - } - } - return len; -} - -// This is the same algorithm as in InflateUTF8StringToBuffer with Copy and -// while ignoring invalids. -// https://mxr.mozilla.org/mozilla-central/source/js/src/vm/CharacterEncoding.cpp#231 - -static const uint32_t REPLACE_UTF8 = 0xFFFD; - -static void -LossyConvertUTF8toUTF16(const char* aInput, uint32_t aLength, nsAString& aOut) -{ - JS::UTF8Chars src(aInput, aLength); - - char16_t dst[aLength]; // Allocating for worst case. - - // Count how many char16_t characters are needed in the inflated string. - // |i| is the index into |src|, and |j| is the the index into |dst|. - size_t srclen = src.length(); - uint32_t j = 0; - for (uint32_t i = 0; i < srclen; i++, j++) { - uint32_t v = uint32_t(src[i]); - if (v == uint32_t('\0') && i < srclen - 1) { - // If the leading byte is '\0' and it's not the last byte, - // just ignore it to prevent from being truncated. This could - // be caused by |convertToBytes| (e.g. \x00 would be converted to '\0') - j--; - continue; - } - if (!(v & 0x80)) { - // ASCII code unit. Simple copy. - dst[j] = char16_t(v); - } else { - // Non-ASCII code unit. Determine its length in bytes (n). - uint32_t n = 1; - while (v & (0x80 >> n)) - n++; - - #define INVALID(report, arg, n2) \ - do { \ - n = n2; \ - goto invalidMultiByteCodeUnit; \ - } while (0) - - // Check the leading byte. - if (n < 2 || n > 4) - INVALID(ReportInvalidCharacter, i, 1); - - // Check that |src| is large enough to hold an n-byte code unit. - if (i + n > srclen) - INVALID(ReportBufferTooSmall, /* dummy = */ 0, 1); - - // Check the second byte. From Unicode Standard v6.2, Table 3-7 - // Well-Formed UTF-8 Byte Sequences. - if ((v == 0xE0 && ((uint8_t)src[i + 1] & 0xE0) != 0xA0) || // E0 A0~BF - (v == 0xED && ((uint8_t)src[i + 1] & 0xE0) != 0x80) || // ED 80~9F - (v == 0xF0 && ((uint8_t)src[i + 1] & 0xF0) == 0x80) || // F0 90~BF - (v == 0xF4 && ((uint8_t)src[i + 1] & 0xF0) != 0x80)) // F4 80~8F - { - INVALID(ReportInvalidCharacter, i, 1); - } - - // Check the continuation bytes. - for (uint32_t m = 1; m < n; m++) - if ((src[i + m] & 0xC0) != 0x80) - INVALID(ReportInvalidCharacter, i, m); - - // Determine the code unit's length in char16_t units and act accordingly. - v = JS::Utf8ToOneUcs4Char((uint8_t *)&src[i], n); - if (v < 0x10000) { - // The n-byte UTF8 code unit will fit in a single char16_t. - dst[j] = char16_t(v); - } else { - v -= 0x10000; - if (v <= 0xFFFFF) { - // The n-byte UTF8 code unit will fit in two char16_t units. - dst[j] = char16_t((v >> 10) + 0xD800); - j++; - dst[j] = char16_t((v & 0x3FF) + 0xDC00); - } else { - // The n-byte UTF8 code unit won't fit in two char16_t units. - INVALID(ReportTooBigCharacter, v, 1); - } - } - - invalidMultiByteCodeUnit: - // Move i to the last byte of the multi-byte code unit; the loop - // header will do the final i++ to move to the start of the next - // code unit. - i += n - 1; - } - } - - dst[j] = 0; - aOut = dst; -} - -// Helper to check we have loaded the hardware shared library. -#define CHECK_HWLIB(ret) \ - void* hwLib = GetSharedLibrary(); \ - if (!hwLib) { \ - NS_WARNING("No /system/lib/libhardware_legacy.so"); \ - return ret; \ - } - -#define DEFAULT_IMPL(name, ret, args...) \ - DEFINE_DLFUNC(name, ret, args...) \ - ret do_##name(args) { \ - USE_DLFUNC(name) \ - return name(args); \ - } - -// ICS implementation. -class ICSWpaSupplicantImpl : public WpaSupplicantImpl -{ -public: - DEFAULT_IMPL(wifi_load_driver, int32_t, ) - DEFAULT_IMPL(wifi_unload_driver, int32_t, ) - - DEFINE_DLFUNC(wifi_wait_for_event, int32_t, char*, size_t) - int32_t do_wifi_wait_for_event(const char *iface, char *buf, size_t len) { - USE_DLFUNC(wifi_wait_for_event) - return wifi_wait_for_event(buf, len); - } - - DEFINE_DLFUNC(wifi_command, int32_t, const char*, char*, size_t*) - int32_t do_wifi_command(const char* iface, const char* cmd, char* buf, size_t* len) { - USE_DLFUNC(wifi_command) - return wifi_command(cmd, buf, len); - } - - DEFINE_DLFUNC(wifi_start_supplicant, int32_t, ) - int32_t do_wifi_start_supplicant(int32_t) { - USE_DLFUNC(wifi_start_supplicant) - return wifi_start_supplicant(); - } - - DEFINE_DLFUNC(wifi_stop_supplicant, int32_t) - int32_t do_wifi_stop_supplicant(int32_t) { - USE_DLFUNC(wifi_stop_supplicant) - return wifi_stop_supplicant(); - } - - DEFINE_DLFUNC(wifi_connect_to_supplicant, int32_t, ) - int32_t do_wifi_connect_to_supplicant(const char* iface) { - USE_DLFUNC(wifi_connect_to_supplicant) - return wifi_connect_to_supplicant(); - } - - DEFINE_DLFUNC(wifi_close_supplicant_connection, void, ) - void do_wifi_close_supplicant_connection(const char* iface) { - USE_DLFUNC(wifi_close_supplicant_connection) - return wifi_close_supplicant_connection(); - } -}; - -// JB implementation. -// We only redefine the methods that have a different signature than on ICS. -class JBWpaSupplicantImpl : public ICSWpaSupplicantImpl -{ -public: - DEFINE_DLFUNC(wifi_wait_for_event, int32_t, const char*, char*, size_t) - int32_t do_wifi_wait_for_event(const char* iface, char* buf, size_t len) { - USE_DLFUNC(wifi_wait_for_event) - return wifi_wait_for_event(iface, buf, len); - } - - DEFINE_DLFUNC(wifi_command, int32_t, const char*, const char*, char*, size_t*) - int32_t do_wifi_command(const char* iface, const char* cmd, char* buf, size_t* len) { - USE_DLFUNC(wifi_command) - return wifi_command(iface, cmd, buf, len); - } - - DEFINE_DLFUNC(wifi_start_supplicant, int32_t, int32_t) - int32_t do_wifi_start_supplicant(int32_t arg) { - USE_DLFUNC(wifi_start_supplicant) - return wifi_start_supplicant(arg); - } - - DEFINE_DLFUNC(wifi_stop_supplicant, int32_t, int32_t) - int32_t do_wifi_stop_supplicant(int32_t arg) { - USE_DLFUNC(wifi_stop_supplicant) - return wifi_stop_supplicant(arg); - } - - DEFINE_DLFUNC(wifi_connect_to_supplicant, int32_t, const char*) - int32_t do_wifi_connect_to_supplicant(const char* iface) { - USE_DLFUNC(wifi_connect_to_supplicant) - return wifi_connect_to_supplicant(iface); - } - - DEFINE_DLFUNC(wifi_close_supplicant_connection, void, const char*) - void do_wifi_close_supplicant_connection(const char* iface) { - USE_DLFUNC(wifi_close_supplicant_connection) - wifi_close_supplicant_connection(iface); - } -}; - -// KK implementation. -// We only redefine the methods that have a different signature than on ICS. -class KKWpaSupplicantImpl : public ICSWpaSupplicantImpl -{ -public: - DEFINE_DLFUNC(wifi_start_supplicant, int32_t, int32_t) - int32_t do_wifi_start_supplicant(int32_t arg) { - USE_DLFUNC(wifi_start_supplicant) - return wifi_start_supplicant(arg); - } - - DEFINE_DLFUNC(wifi_stop_supplicant, int32_t, int32_t) - int32_t do_wifi_stop_supplicant(int32_t arg) { - USE_DLFUNC(wifi_stop_supplicant) - return wifi_stop_supplicant(arg); - } - - DEFINE_DLFUNC(wifi_command, int32_t, const char*, char*, size_t*) - int32_t do_wifi_command(const char* iface, const char* cmd, char* buf, size_t* len) { - char command[COMMAND_SIZE]; - if (!strcmp(iface, "p2p0")) { - // Commands for p2p0 interface don't need prefix - SprintfLiteral(command, "%s", cmd); - } - else { - SprintfLiteral(command, "IFNAME=%s %s", iface, cmd); - } - USE_DLFUNC(wifi_command) - return wifi_command(command, buf, len); - } -}; - -// Concrete class to use to access the wpa supplicant. -WpaSupplicant::WpaSupplicant() -{ - char propVersion[PROPERTY_VALUE_MAX]; - property_get("ro.build.version.sdk", propVersion, "0"); - mSdkVersion = strtol(propVersion, nullptr, 10); - - if (mSdkVersion < 16) { - mImpl = MakeUnique<ICSWpaSupplicantImpl>(); - } else if (mSdkVersion < 19) { - mImpl = MakeUnique<JBWpaSupplicantImpl>(); - } else { - mImpl = MakeUnique<KKWpaSupplicantImpl>(); - } - mWifiHotspotUtils = MakeUnique<WifiHotspotUtils>(); -}; - -void WpaSupplicant::WaitForEvent(nsAString& aEvent, const nsCString& aInterface) -{ - CHECK_HWLIB() - - char buffer[BUFFER_SIZE]; - int32_t ret = mImpl->do_wifi_wait_for_event(aInterface.get(), buffer, BUFFER_SIZE); - CheckBuffer(buffer, ret, aEvent); -} - -#define GET_CHAR(prop) NS_ConvertUTF16toUTF8(aOptions.prop).get() - -/** - * Make a subnet mask. - */ -uint32_t WpaSupplicant::MakeMask(uint32_t len) { - uint32_t mask = 0; - for (uint32_t i = 0; i < len; ++i) { - mask |= (0x80000000 >> i); - } - return ntohl(mask); -} - -bool WpaSupplicant::ExecuteCommand(CommandOptions aOptions, - WifiResultOptions& aResult, - const nsCString& aInterface) -{ - CHECK_HWLIB(false) - - if (!mWifiHotspotUtils->GetSharedLibrary()) { - return false; - } - - // Always correlate the opaque ids. - aResult.mId = aOptions.mId; - - if (aOptions.mCmd.EqualsLiteral("command")) { - size_t len = BUFFER_SIZE - 1; - char buffer[BUFFER_SIZE]; - NS_ConvertUTF16toUTF8 request(aOptions.mRequest); - aResult.mStatus = mImpl->do_wifi_command(aInterface.get(), request.get(), buffer, &len); - nsString value; - if (aResult.mStatus == 0) { - if (buffer[len - 1] == '\n') { // remove trailing new lines. - len--; - } - buffer[len] = '\0'; - CheckBuffer(buffer, len, value); - } - aResult.mReply = value; - } else if (aOptions.mCmd.EqualsLiteral("close_supplicant_connection")) { - mImpl->do_wifi_close_supplicant_connection(aInterface.get()); - } else if (aOptions.mCmd.EqualsLiteral("load_driver")) { - aResult.mStatus = mImpl->do_wifi_load_driver(); - } else if (aOptions.mCmd.EqualsLiteral("unload_driver")) { - aResult.mStatus = mImpl->do_wifi_unload_driver(); - } else if (aOptions.mCmd.EqualsLiteral("start_supplicant")) { - aResult.mStatus = mImpl->do_wifi_start_supplicant(GetWifiP2pSupported() ? 1 : 0); - } else if (aOptions.mCmd.EqualsLiteral("stop_supplicant")) { - aResult.mStatus = mImpl->do_wifi_stop_supplicant(0); - } else if (aOptions.mCmd.EqualsLiteral("connect_to_supplicant")) { - aResult.mStatus = mImpl->do_wifi_connect_to_supplicant(aInterface.get()); - } else if (aOptions.mCmd.EqualsLiteral("hostapd_command")) { - size_t len = BUFFER_SIZE - 1; - char buffer[BUFFER_SIZE]; - NS_ConvertUTF16toUTF8 request(aOptions.mRequest); - aResult.mStatus = mWifiHotspotUtils->do_wifi_hostapd_command(request.get(), - buffer, - &len); - nsString value; - if (aResult.mStatus == 0) { - if (buffer[len - 1] == '\n') { // remove trailing new lines. - len--; - } - buffer[len] = '\0'; - CheckBuffer(buffer, len, value); - } - aResult.mReply = value; - } else if (aOptions.mCmd.EqualsLiteral("hostapd_get_stations")) { - aResult.mStatus = mWifiHotspotUtils->do_wifi_hostapd_get_stations(); - } else if (aOptions.mCmd.EqualsLiteral("connect_to_hostapd")) { - aResult.mStatus = mWifiHotspotUtils->do_wifi_connect_to_hostapd(); - } else if (aOptions.mCmd.EqualsLiteral("close_hostapd_connection")) { - aResult.mStatus = mWifiHotspotUtils->do_wifi_close_hostapd_connection(); - - } else { - NS_WARNING("WpaSupplicant::ExecuteCommand : Unknown command"); - printf_stderr("WpaSupplicant::ExecuteCommand : Unknown command: %s", - NS_ConvertUTF16toUTF8(aOptions.mCmd).get()); - return false; - } - - return true; -} - -// Checks the buffer and do the utf processing. -void -WpaSupplicant::CheckBuffer(char* buffer, int32_t length, - nsAString& aEvent) -{ - if (length <= 0 || length >= (BUFFER_SIZE - 1)) { - NS_WARNING("WpaSupplicant::CheckBuffer: Invalid buffer length"); - return; - } - - if (mSdkVersion < 18) { - buffer[length] = 0; - LossyConvertUTF8toUTF16(buffer, length, aEvent); - return; - } - - // After Android JB4.3, the SSIDs have been converted into printable form. - // In most of cases, SSIDs do not use unprintable characters, but IEEE 802.11 - // standard does not limit the used character set, so anything could be used - // in an SSID. Convert it to raw data form here. - char bytesBuffer[BUFFER_SIZE]; - uint32_t bytes = convertToBytes(bytesBuffer, length, buffer); - if (bytes <= 0 || bytes >= BUFFER_SIZE) { - NS_WARNING("WpaSupplicant::CheckBuffer: Invalid bytesbuffer length"); - return; - } - bytesBuffer[bytes] = 0; - LossyConvertUTF8toUTF16(bytesBuffer, bytes, aEvent); -} diff --git a/dom/wifi/WifiUtils.h b/dom/wifi/WifiUtils.h deleted file mode 100644 index a83ba9c15..000000000 --- a/dom/wifi/WifiUtils.h +++ /dev/null @@ -1,107 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -/** - * Abstraction on top of the wifi support from libhardware_legacy that we - * use to talk to the wpa_supplicant. - */ - -#ifndef WifiUtils_h -#define WifiUtils_h - -#include "nsString.h" -#include "mozilla/dom/WifiOptionsBinding.h" -#include "mozilla/UniquePtr.h" -#include "WifiHotspotUtils.h" - -// Needed to add a copy constructor to WifiCommandOptions. -struct CommandOptions -{ -public: - CommandOptions(const mozilla::dom::WifiCommandOptions& aOther) { - -#define COPY_OPT_FIELD(prop, defaultValue) \ - if (aOther.prop.WasPassed()) { \ - prop = aOther.prop.Value(); \ - } else { \ - prop = defaultValue; \ - } - -#define COPY_FIELD(prop) prop = aOther.prop; - COPY_FIELD(mId) - COPY_FIELD(mCmd) - COPY_OPT_FIELD(mRequest, EmptyString()) - -#undef COPY_OPT_FIELD -#undef COPY_FIELD - } - - // All the fields, not Optional<> anymore to get copy constructors. - nsString mCmd; - int32_t mId; - nsString mRequest; -}; - -// Abstract class that exposes libhardware_legacy functions we need for -// wifi management. -// We use the ICS signatures here since they are likely more future-proof. -class WpaSupplicantImpl -{ -public: - // Suppress warning from |UniquePtr| - virtual ~WpaSupplicantImpl() {} - - virtual int32_t - do_wifi_wait_for_event(const char *iface, char *buf, size_t len) = 0; // KK == ICS != JB - - virtual int32_t - do_wifi_command(const char* iface, const char* cmd, char* buff, size_t* len) = 0; // KK == ICS != JB - - virtual int32_t - do_wifi_load_driver() = 0; - - virtual int32_t - do_wifi_unload_driver() = 0; - - virtual int32_t - do_wifi_start_supplicant(int32_t) = 0; // ICS != JB == KK - - virtual int32_t - do_wifi_stop_supplicant(int32_t) = 0; //ICS != JB == KK - - virtual int32_t - do_wifi_connect_to_supplicant(const char* iface) = 0; // KK == ICS != JB - - virtual void - do_wifi_close_supplicant_connection(const char* iface) = 0; // KK == ICS != JB -}; - -// Concrete class to use to access the wpa supplicant. -class WpaSupplicant final -{ -public: - WpaSupplicant(); - - // Use nsCString as the type of aInterface to guarantee it's - // null-terminated so that we can pass it to c API without - // conversion - void WaitForEvent(nsAString& aEvent, const nsCString& aInterface); - bool ExecuteCommand(CommandOptions aOptions, - mozilla::dom::WifiResultOptions& result, - const nsCString& aInterface); - -private: - UniquePtr<WpaSupplicantImpl> mImpl; - UniquePtr<WifiHotspotUtils> mWifiHotspotUtils; - - uint32_t mSdkVersion; - -protected: - void CheckBuffer(char* buffer, int32_t length, nsAString& aEvent); - uint32_t MakeMask(uint32_t len); -}; - -#endif // WifiUtils_h diff --git a/dom/wifi/WifiWorker.h b/dom/wifi/WifiWorker.h deleted file mode 100644 index 2cd89c3e7..000000000 --- a/dom/wifi/WifiWorker.h +++ /dev/null @@ -1,9 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -#define NS_WIFIWORKER_CID \ -{ 0xA14E8977, 0xD259, 0x433A, \ - { 0xA8, 0x8D, 0x58, 0xDD, 0x44, 0x65, 0x7E, 0x5B } } diff --git a/dom/wifi/WifiWorker.js b/dom/wifi/WifiWorker.js deleted file mode 100644 index 243ba8b97..000000000 --- a/dom/wifi/WifiWorker.js +++ /dev/null @@ -1,3928 +0,0 @@ -/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ -/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -"use strict"; - -const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components; - -Cu.import("resource://gre/modules/XPCOMUtils.jsm"); -Cu.import("resource://gre/modules/Services.jsm"); -Cu.import("resource://gre/modules/systemlibs.js"); -Cu.import("resource://gre/modules/FileUtils.jsm"); -Cu.import("resource://gre/modules/WifiCommand.jsm"); -Cu.import("resource://gre/modules/WifiNetUtil.jsm"); -Cu.import("resource://gre/modules/WifiP2pManager.jsm"); -Cu.import("resource://gre/modules/WifiP2pWorkerObserver.jsm"); - -var DEBUG = false; // set to true to show debug messages. - -const WIFIWORKER_CONTRACTID = "@mozilla.org/wifi/worker;1"; -const WIFIWORKER_CID = Components.ID("{a14e8977-d259-433a-a88d-58dd44657e5b}"); - -const WIFIWORKER_WORKER = "resource://gre/modules/wifi_worker.js"; - -const kMozSettingsChangedObserverTopic = "mozsettings-changed"; - -const MAX_RETRIES_ON_AUTHENTICATION_FAILURE = 2; -const MAX_SUPPLICANT_LOOP_ITERATIONS = 4; -const MAX_RETRIES_ON_DHCP_FAILURE = 2; - -// Settings DB path for wifi -const SETTINGS_WIFI_ENABLED = "wifi.enabled"; -const SETTINGS_WIFI_DEBUG_ENABLED = "wifi.debugging.enabled"; -// Settings DB path for Wifi tethering. -const SETTINGS_WIFI_TETHERING_ENABLED = "tethering.wifi.enabled"; -const SETTINGS_WIFI_SSID = "tethering.wifi.ssid"; -const SETTINGS_WIFI_SECURITY_TYPE = "tethering.wifi.security.type"; -const SETTINGS_WIFI_SECURITY_PASSWORD = "tethering.wifi.security.password"; -const SETTINGS_WIFI_IP = "tethering.wifi.ip"; -const SETTINGS_WIFI_PREFIX = "tethering.wifi.prefix"; -const SETTINGS_WIFI_DHCPSERVER_STARTIP = "tethering.wifi.dhcpserver.startip"; -const SETTINGS_WIFI_DHCPSERVER_ENDIP = "tethering.wifi.dhcpserver.endip"; -const SETTINGS_WIFI_DNS1 = "tethering.wifi.dns1"; -const SETTINGS_WIFI_DNS2 = "tethering.wifi.dns2"; - -// Settings DB path for USB tethering. -const SETTINGS_USB_DHCPSERVER_STARTIP = "tethering.usb.dhcpserver.startip"; -const SETTINGS_USB_DHCPSERVER_ENDIP = "tethering.usb.dhcpserver.endip"; - -// Default value for WIFI tethering. -const DEFAULT_WIFI_IP = "192.168.1.1"; -const DEFAULT_WIFI_PREFIX = "24"; -const DEFAULT_WIFI_DHCPSERVER_STARTIP = "192.168.1.10"; -const DEFAULT_WIFI_DHCPSERVER_ENDIP = "192.168.1.30"; -const DEFAULT_WIFI_SSID = "FirefoxHotspot"; -const DEFAULT_WIFI_SECURITY_TYPE = "open"; -const DEFAULT_WIFI_SECURITY_PASSWORD = "1234567890"; -const DEFAULT_DNS1 = "8.8.8.8"; -const DEFAULT_DNS2 = "8.8.4.4"; - -// Default value for USB tethering. -const DEFAULT_USB_DHCPSERVER_STARTIP = "192.168.0.10"; -const DEFAULT_USB_DHCPSERVER_ENDIP = "192.168.0.30"; - -const WIFI_FIRMWARE_AP = "AP"; -const WIFI_FIRMWARE_STATION = "STA"; -const WIFI_SECURITY_TYPE_NONE = "open"; -const WIFI_SECURITY_TYPE_WPA_PSK = "wpa-psk"; -const WIFI_SECURITY_TYPE_WPA2_PSK = "wpa2-psk"; - -const NETWORK_INTERFACE_UP = "up"; -const NETWORK_INTERFACE_DOWN = "down"; - -const DEFAULT_WLAN_INTERFACE = "wlan0"; - -const DRIVER_READY_WAIT = 2000; - -const SUPP_PROP = "init.svc.wpa_supplicant"; -const WPA_SUPPLICANT = "wpa_supplicant"; -const DHCP_PROP = "init.svc.dhcpcd"; -const DHCP = "dhcpcd"; - -const MODE_ESS = 0; -const MODE_IBSS = 1; - -XPCOMUtils.defineLazyServiceGetter(this, "gNetworkManager", - "@mozilla.org/network/manager;1", - "nsINetworkManager"); - -XPCOMUtils.defineLazyServiceGetter(this, "gNetworkService", - "@mozilla.org/network/service;1", - "nsINetworkService"); - -XPCOMUtils.defineLazyServiceGetter(this, "gSettingsService", - "@mozilla.org/settingsService;1", - "nsISettingsService"); - -XPCOMUtils.defineLazyServiceGetter(this, "gTetheringService", - "@mozilla.org/tethering/service;1", - "nsITetheringService"); - -// A note about errors and error handling in this file: -// The libraries that we use in this file are intended for C code. For -// C code, it is natural to return -1 for errors and 0 for success. -// Therefore, the code that interacts directly with the worker uses this -// convention (note: command functions do get boolean results since the -// command always succeeds and we do a string/boolean check for the -// expected results). -var WifiManager = (function() { - var manager = {}; - - function getStartupPrefs() { - return { - sdkVersion: parseInt(libcutils.property_get("ro.build.version.sdk"), 10), - unloadDriverEnabled: libcutils.property_get("ro.moz.wifi.unloaddriver") === "1", - schedScanRecovery: libcutils.property_get("ro.moz.wifi.sched_scan_recover") === "false" ? false : true, - driverDelay: libcutils.property_get("ro.moz.wifi.driverDelay"), - p2pSupported: libcutils.property_get("ro.moz.wifi.p2p_supported") === "1", - eapSimSupported: libcutils.property_get("ro.moz.wifi.eapsim_supported") === "1", - ibssSupported: libcutils.property_get("ro.moz.wifi.ibss_supported", "true") === "true", - ifname: libcutils.property_get("wifi.interface") - }; - } - - let {sdkVersion, unloadDriverEnabled, schedScanRecovery, - driverDelay, p2pSupported, eapSimSupported, ibssSupported, ifname} = getStartupPrefs(); - - let capabilities = { - security: ["OPEN", "WEP", "WPA-PSK", "WPA-EAP"], - eapMethod: ["PEAP", "TTLS", "TLS"], - eapPhase2: ["MSCHAPV2"], - certificate: ["SERVER"], - mode: [MODE_ESS] - }; - if (eapSimSupported) { - capabilities.eapMethod.unshift("SIM"); - } - if (ibssSupported) { - capabilities.mode.push(MODE_IBSS); - } - - let wifiListener = { - onWaitEvent: function(event, iface) { - if (manager.ifname === iface && handleEvent(event)) { - waitForEvent(iface); - } else if (p2pSupported) { - // Please refer to - // http://androidxref.com/4.4.2_r1/xref/frameworks/base/wifi/java/android/net/wifi/WifiMonitor.java#519 - // for interface event mux/demux rules. In short words, both - // 'p2p0' and 'p2p-' should go to Wifi P2P state machine. - if (WifiP2pManager.INTERFACE_NAME === iface || -1 !== iface.indexOf('p2p-')) { - // If the connection is closed, wifi.c::wifi_wait_for_event() - // will still return 'CTRL-EVENT-TERMINATING - connection closed' - // rather than blocking. So when we see this special event string, - // just return immediately. - const TERMINATED_EVENT = 'CTRL-EVENT-TERMINATING - connection closed'; - if (-1 !== event.indexOf(TERMINATED_EVENT)) { - return; - } - p2pManager.handleEvent(event); - waitForEvent(iface); - } - } - }, - - onCommand: function(event, iface) { - onmessageresult(event, iface); - } - } - - manager.ifname = ifname; - manager.connectToSupplicant = false; - // Emulator build runs to here. - // The debug() should only be used after WifiManager. - if (!ifname) { - manager.ifname = DEFAULT_WLAN_INTERFACE; - } - manager.schedScanRecovery = schedScanRecovery; - manager.driverDelay = driverDelay ? parseInt(driverDelay, 10) : DRIVER_READY_WAIT; - - // Regular Wifi stuff. - var netUtil = WifiNetUtil(controlMessage); - var wifiCommand = WifiCommand(controlMessage, manager.ifname, sdkVersion); - - // Wifi P2P stuff - var p2pManager; - if (p2pSupported) { - let p2pCommand = WifiCommand(controlMessage, WifiP2pManager.INTERFACE_NAME, sdkVersion); - p2pManager = WifiP2pManager(p2pCommand, netUtil); - } - - let wifiService = Cc["@mozilla.org/wifi/service;1"]; - if (wifiService) { - wifiService = wifiService.getService(Ci.nsIWifiProxyService); - let interfaces = [manager.ifname]; - if (p2pSupported) { - interfaces.push(WifiP2pManager.INTERFACE_NAME); - } - wifiService.start(wifiListener, interfaces, interfaces.length); - } else { - debug("No wifi service component available!"); - } - - // Callbacks to invoke when a reply arrives from the wifi service. - var controlCallbacks = Object.create(null); - var idgen = 0; - - function controlMessage(obj, callback) { - var id = idgen++; - obj.id = id; - if (callback) { - controlCallbacks[id] = callback; - } - wifiService.sendCommand(obj, obj.iface); - } - - let onmessageresult = function(data, iface) { - var id = data.id; - var callback = controlCallbacks[id]; - if (callback) { - callback(data); - delete controlCallbacks[id]; - } - } - - // Polling the status worker - var recvErrors = 0; - - function waitForEvent(iface) { - wifiService.waitForEvent(iface); - } - - // Commands to the control worker. - - var driverLoaded = false; - - function loadDriver(callback) { - if (driverLoaded) { - callback(0); - return; - } - - wifiCommand.loadDriver(function (status) { - driverLoaded = (status >= 0); - callback(status) - }); - } - - function unloadDriver(type, callback) { - if (!unloadDriverEnabled) { - // Unloading drivers is generally unnecessary and - // can trigger bugs in some drivers. - // On properly written drivers, bringing the interface - // down powers down the interface. - if (type === WIFI_FIRMWARE_STATION) { - notify("supplicantlost", { success: true }); - } - callback(0); - return; - } - - wifiCommand.unloadDriver(function(status) { - driverLoaded = (status < 0); - if (type === WIFI_FIRMWARE_STATION) { - notify("supplicantlost", { success: true }); - } - callback(status); - }); - } - - // A note about background scanning: - // Normally, background scanning shouldn't be necessary as wpa_supplicant - // has the capability to automatically schedule its own scans at appropriate - // intervals. However, with some drivers, this appears to get stuck after - // three scans, so we enable the driver's background scanning to work around - // that when we're not connected to any network. This ensures that we'll - // automatically reconnect to networks if one falls out of range. - var reEnableBackgroundScan = false; - - // NB: This is part of the internal API. - manager.backgroundScanEnabled = false; - function setBackgroundScan(enable, callback) { - var doEnable = (enable === "ON"); - if (doEnable === manager.backgroundScanEnabled) { - callback(false, true); - return; - } - - manager.backgroundScanEnabled = doEnable; - wifiCommand.setBackgroundScan(manager.backgroundScanEnabled, callback); - } - - var scanModeActive = false; - - function scan(forceActive, callback) { - if (forceActive && !scanModeActive) { - // Note: we ignore errors from doSetScanMode. - wifiCommand.doSetScanMode(true, function(ignore) { - setBackgroundScan("OFF", function(turned, ignore) { - reEnableBackgroundScan = turned; - manager.handlePreWifiScan(); - wifiCommand.scan(function(ok) { - wifiCommand.doSetScanMode(false, function(ignore) { - // The result of scanCommand is the result of the actual SCAN - // request. - callback(ok); - }); - }); - }); - }); - return; - } - manager.handlePreWifiScan(); - wifiCommand.scan(callback); - } - - var debugEnabled = false; - - function syncDebug() { - if (debugEnabled !== DEBUG) { - let wanted = DEBUG; - wifiCommand.setLogLevel(wanted ? "DEBUG" : "INFO", function(ok) { - if (ok) - debugEnabled = wanted; - }); - if (p2pSupported && p2pManager) { - p2pManager.setDebug(DEBUG); - } - } - } - - function getDebugEnabled(callback) { - wifiCommand.getLogLevel(function(level) { - if (level === null) { - debug("Unable to get wpa_supplicant's log level"); - callback(false); - return; - } - - var lines = level.split("\n"); - for (let i = 0; i < lines.length; ++i) { - let match = /Current level: (.*)/.exec(lines[i]); - if (match) { - debugEnabled = match[1].toLowerCase() === "debug"; - callback(true); - return; - } - } - - // If we're here, we didn't get the current level. - callback(false); - }); - } - - function setScanMode(setActive, callback) { - scanModeActive = setActive; - wifiCommand.doSetScanMode(setActive, callback); - } - - var httpProxyConfig = Object.create(null); - - /** - * Given a network, configure http proxy when using wifi. - * @param network A network object to update http proxy - * @param info Info should have following field: - * - httpProxyHost ip address of http proxy. - * - httpProxyPort port of http proxy, set 0 to use default port 8080. - * @param callback callback function. - */ - function configureHttpProxy(network, info, callback) { - if (!network) - return; - - let networkKey = getNetworkKey(network); - - if (!info || info.httpProxyHost === "") { - delete httpProxyConfig[networkKey]; - } else { - httpProxyConfig[networkKey] = network; - httpProxyConfig[networkKey].httpProxyHost = info.httpProxyHost; - httpProxyConfig[networkKey].httpProxyPort = info.httpProxyPort; - } - - callback(true); - } - - function getHttpProxyNetwork(network) { - if (!network) - return null; - - let networkKey = getNetworkKey(network); - return httpProxyConfig[networkKey]; - } - - function setHttpProxy(network) { - if (!network) - return; - - // If we got here, arg network must be the currentNetwork, so we just update - // WifiNetworkInterface correspondingly and notify NetworkManager. - WifiNetworkInterface.httpProxyHost = network.httpProxyHost; - WifiNetworkInterface.httpProxyPort = network.httpProxyPort; - - if (WifiNetworkInterface.info.state == - Ci.nsINetworkInfo.NETWORK_STATE_CONNECTED) { - gNetworkManager.updateNetworkInterface(WifiNetworkInterface); - } - } - - var staticIpConfig = Object.create(null); - function setStaticIpMode(network, info, callback) { - let setNetworkKey = getNetworkKey(network); - let curNetworkKey = null; - let currentNetwork = Object.create(null); - currentNetwork.netId = manager.connectionInfo.id; - - manager.getNetworkConfiguration(currentNetwork, function () { - curNetworkKey = getNetworkKey(currentNetwork); - - // Add additional information to static ip configuration - // It is used to compatiable with information dhcp callback. - info.ipaddr = netHelpers.stringToIP(info.ipaddr_str); - info.gateway = netHelpers.stringToIP(info.gateway_str); - info.mask_str = netHelpers.ipToString(netHelpers.makeMask(info.maskLength)); - - // Optional - info.dns1 = netHelpers.stringToIP(info.dns1_str); - info.dns2 = netHelpers.stringToIP(info.dns2_str); - info.proxy = netHelpers.stringToIP(info.proxy_str); - - staticIpConfig[setNetworkKey] = info; - - // If the ssid of current connection is the same as configured ssid - // It means we need update current connection to use static IP address. - if (setNetworkKey == curNetworkKey) { - // Use configureInterface directly doesn't work, the network interface - // and routing table is changed but still cannot connect to network - // so the workaround here is disable interface the enable again to - // trigger network reconnect with static ip. - gNetworkService.disableInterface(manager.ifname, function (ok) { - gNetworkService.enableInterface(manager.ifname, function (ok) { - callback(ok); - }); - }); - return; - } - - callback(true); - }); - } - - var dhcpInfo = null; - - function runStaticIp(ifname, key) { - debug("Run static ip"); - - // Read static ip information from settings. - let staticIpInfo; - - if (!(key in staticIpConfig)) - return; - - staticIpInfo = staticIpConfig[key]; - - // Stop dhcpd when use static IP - if (dhcpInfo != null) { - netUtil.stopDhcp(manager.ifname, function() {}); - } - - // Set ip, mask length, gateway, dns to network interface - gNetworkService.configureInterface( { ifname: ifname, - ipaddr: staticIpInfo.ipaddr, - mask: staticIpInfo.maskLength, - gateway: staticIpInfo.gateway, - dns1: staticIpInfo.dns1, - dns2: staticIpInfo.dns2 }, function (data) { - netUtil.runIpConfig(ifname, staticIpInfo, function(data) { - dhcpInfo = data.info; - notify("networkconnected", data); - }); - }); - } - - var suppressEvents = false; - function notify(eventName, eventObject) { - if (suppressEvents) - return; - var handler = manager["on" + eventName]; - if (handler) { - if (!eventObject) - eventObject = ({}); - handler.call(eventObject); - } - } - - function notifyStateChange(fields) { - // If we're already in the COMPLETED state, we might receive events from - // the supplicant that tell us that we're re-authenticating or reminding - // us that we're associated to a network. In those cases, we don't need to - // do anything, so just ignore them. - if (manager.state === "COMPLETED" && - fields.state !== "DISCONNECTED" && - fields.state !== "INTERFACE_DISABLED" && - fields.state !== "INACTIVE" && - fields.state !== "SCANNING") { - return false; - } - - // Stop background scanning if we're trying to connect to a network. - if (manager.backgroundScanEnabled && - (fields.state === "ASSOCIATING" || - fields.state === "ASSOCIATED" || - fields.state === "FOUR_WAY_HANDSHAKE" || - fields.state === "GROUP_HANDSHAKE" || - fields.state === "COMPLETED")) { - setBackgroundScan("OFF", function() {}); - } - - fields.prevState = manager.state; - // Detect wpa_supplicant's loop iterations. - manager.supplicantLoopDetection(fields.prevState, fields.state); - notify("statechange", fields); - - // Don't update state when and after disabling. - if (manager.state === "DISABLING" || - manager.state === "UNINITIALIZED") { - return false; - } - - manager.state = fields.state; - return true; - } - - function parseStatus(status) { - if (status === null) { - debug("Unable to get wpa supplicant's status"); - return; - } - - var ssid; - var bssid; - var state; - var ip_address; - var id; - - var lines = status.split("\n"); - for (let i = 0; i < lines.length; ++i) { - let [key, value] = lines[i].split("="); - switch (key) { - case "wpa_state": - state = value; - break; - case "ssid": - ssid = value; - break; - case "bssid": - bssid = value; - break; - case "ip_address": - ip_address = value; - break; - case "id": - id = value; - break; - } - } - - if (bssid && ssid) { - manager.connectionInfo.bssid = bssid; - manager.connectionInfo.ssid = ssid; - manager.connectionInfo.id = id; - } - - if (ip_address) - dhcpInfo = { ip_address: ip_address }; - - notifyStateChange({ state: state, fromStatus: true }); - - // If we parse the status and the supplicant has already entered the - // COMPLETED state, then we need to set up DHCP right away. - if (state === "COMPLETED") - onconnected(); - } - - // try to connect to the supplicant - var connectTries = 0; - var retryTimer = null; - function connectCallback(ok) { - if (ok === 0) { - // Tell the event worker to start waiting for events. - retryTimer = null; - connectTries = 0; - recvErrors = 0; - manager.connectToSupplicant = true; - didConnectSupplicant(function(){}); - return; - } - if (connectTries++ < 5) { - // Try again in 1 seconds. - if (!retryTimer) - retryTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); - - retryTimer.initWithCallback(function(timer) { - wifiCommand.connectToSupplicant(connectCallback); - }, 1000, Ci.nsITimer.TYPE_ONE_SHOT); - return; - } - - retryTimer = null; - connectTries = 0; - notify("supplicantlost", { success: false }); - } - - manager.connectionDropped = function(callback) { - // Reset network interface when connection drop - gNetworkService.configureInterface( { ifname: manager.ifname, - ipaddr: 0, - mask: 0, - gateway: 0, - dns1: 0, - dns2: 0 }, function (data) { - }); - - // If we got disconnected, kill the DHCP client in preparation for - // reconnection. - gNetworkService.resetConnections(manager.ifname, function() { - netUtil.stopDhcp(manager.ifname, function() { - callback(); - }); - }); - } - - manager.start = function() { - debug("detected SDK version " + sdkVersion); - wifiCommand.connectToSupplicant(connectCallback); - } - - let dhcpRequestGen = 0; - - function onconnected() { - // For now we do our own DHCP. In the future, this should be handed - // off to the Network Manager. - let currentNetwork = Object.create(null); - currentNetwork.netId = manager.connectionInfo.id; - - manager.getNetworkConfiguration(currentNetwork, function (){ - let key = getNetworkKey(currentNetwork); - if (staticIpConfig && - (key in staticIpConfig) && - staticIpConfig[key].enabled) { - debug("Run static ip"); - runStaticIp(manager.ifname, key); - return; - } - netUtil.runDhcp(manager.ifname, dhcpRequestGen++, function(data, gen) { - dhcpInfo = data.info; - debug('dhcpRequestGen: ' + dhcpRequestGen + ', gen: ' + gen); - if (!dhcpInfo) { - if (gen + 1 < dhcpRequestGen) { - debug('Do not bother younger DHCP request.'); - return; - } - if (++manager.dhcpFailuresCount >= MAX_RETRIES_ON_DHCP_FAILURE) { - manager.dhcpFailuresCount = 0; - notify("disconnected", {connectionInfo: manager.connectionInfo}); - return; - } - // NB: We have to call disconnect first. Otherwise, we only reauth with - // the existing AP and don't retrigger DHCP. - manager.disconnect(function() { - manager.reassociate(function(){}); - }); - return; - } - - manager.dhcpFailuresCount = 0; - notify("networkconnected", data); - }); - }); - } - - var supplicantStatesMap = (sdkVersion >= 15) ? - ["DISCONNECTED", "INTERFACE_DISABLED", "INACTIVE", "SCANNING", - "AUTHENTICATING", "ASSOCIATING", "ASSOCIATED", "FOUR_WAY_HANDSHAKE", - "GROUP_HANDSHAKE", "COMPLETED"] - : - ["DISCONNECTED", "INACTIVE", "SCANNING", "ASSOCIATING", - "ASSOCIATED", "FOUR_WAY_HANDSHAKE", "GROUP_HANDSHAKE", - "COMPLETED", "DORMANT", "UNINITIALIZED"]; - - var driverEventMap = { STOPPED: "driverstopped", STARTED: "driverstarted", HANGED: "driverhung" }; - - manager.getNetworkId = function (ssid, callback) { - manager.getConfiguredNetworks(function(networks) { - if (!networks) { - debug("Unable to get configured networks"); - return callback(null); - } - for (let net in networks) { - let network = networks[net]; - // Trying to get netId from - // 1. network matching SSID if SSID is provided. - // 2. current network if no SSID is provided, it's not guaranteed that - // current network matches requested SSID. - if ((!ssid && network.status === "CURRENT") || - (ssid && network.ssid && ssid === dequote(network.ssid))) { - return callback(net); - } - } - callback(null); - }); - } - - function handleWpaEapEvents(event) { - if (event.indexOf("CTRL-EVENT-EAP-FAILURE") !== -1) { - if (event.indexOf("EAP authentication failed") !== -1) { - notify("passwordmaybeincorrect"); - if (manager.authenticationFailuresCount > MAX_RETRIES_ON_AUTHENTICATION_FAILURE) { - manager.authenticationFailuresCount = 0; - notify("disconnected", {connectionInfo: manager.connectionInfo}); - } - } - return true; - } - if (event.indexOf("CTRL-EVENT-EAP-TLS-CERT-ERROR") !== -1) { - // Cert Error - notify("passwordmaybeincorrect"); - if (manager.authenticationFailuresCount > MAX_RETRIES_ON_AUTHENTICATION_FAILURE) { - manager.authenticationFailuresCount = 0; - notify("disconnected", {connectionInfo: manager.connectionInfo}); - } - return true; - } - if (event.indexOf("CTRL-EVENT-EAP-STARTED") !== -1) { - notifyStateChange({ state: "AUTHENTICATING" }); - return true; - } - return true; - } - - // Handle events sent to us by the event worker. - function handleEvent(event) { - debug("Event coming in: " + event); - if (event.indexOf("CTRL-EVENT-") !== 0 && event.indexOf("WPS") !== 0) { - // Handle connection fail exception on WEP-128, while password length - // is not 5 nor 13 bytes. - if (event.indexOf("Association request to the driver failed") !== -1) { - notify("passwordmaybeincorrect"); - if (manager.authenticationFailuresCount > MAX_RETRIES_ON_AUTHENTICATION_FAILURE) { - manager.authenticationFailuresCount = 0; - notify("disconnected", {connectionInfo: manager.connectionInfo}); - } - return true; - } - - if (event.indexOf("WPA:") == 0 && - event.indexOf("pre-shared key may be incorrect") != -1) { - notify("passwordmaybeincorrect"); - } - - // This is ugly, but we need to grab the SSID here. BSSID is not guaranteed - // to be provided, so don't grab BSSID here. - var match = /Trying to associate with.*SSID[ =]'(.*)'/.exec(event); - if (match) { - debug("Matched: " + match[1] + "\n"); - manager.connectionInfo.ssid = match[1]; - } - return true; - } - - var space = event.indexOf(" "); - var eventData = event.substr(0, space + 1); - if (eventData.indexOf("CTRL-EVENT-STATE-CHANGE") === 0) { - // Parse the event data. - var fields = {}; - var tokens = event.substr(space + 1).split(" "); - for (var n = 0; n < tokens.length; ++n) { - var kv = tokens[n].split("="); - if (kv.length === 2) - fields[kv[0]] = kv[1]; - } - if (!("state" in fields)) - return true; - fields.state = supplicantStatesMap[fields.state]; - - // The BSSID field is only valid in the ASSOCIATING and ASSOCIATED - // states, except when we "reauth", except this seems to depend on the - // driver, so simply check to make sure that we don't have a null BSSID. - if (fields.BSSID !== "00:00:00:00:00:00") - manager.connectionInfo.bssid = fields.BSSID; - - if (notifyStateChange(fields) && fields.state === "COMPLETED") { - onconnected(); - } - return true; - } - if (eventData.indexOf("CTRL-EVENT-DRIVER-STATE") === 0) { - var handlerName = driverEventMap[eventData]; - if (handlerName) - notify(handlerName); - return true; - } - if (eventData.indexOf("CTRL-EVENT-TERMINATING") === 0) { - // As long the monitor socket is not closed and we haven't seen too many - // recv errors yet, we will keep going for a bit longer. - if (event.indexOf("connection closed") === -1 && - event.indexOf("recv error") !== -1 && ++recvErrors < 10) - return true; - - notifyStateChange({ state: "DISCONNECTED", BSSID: null, id: -1 }); - - // If the supplicant is terminated as commanded, the supplicant lost - // notification will be sent after driver unloaded. In such case, the - // manager state will be "DISABLING" or "UNINITIALIZED". - // So if supplicant terminated with incorrect manager state, implying - // unexpected condition, we should notify supplicant lost here. - if (manager.state !== "DISABLING" && manager.state !== "UNINITIALIZED") { - notify("supplicantlost", { success: true }); - } - - if (manager.stopSupplicantCallback) { - cancelWaitForTerminateEventTimer(); - // It's possible that the terminating event triggered by timer comes - // earlier than the event from wpa_supplicant. Since - // stopSupplicantCallback contains async. callbacks, swap it to local - // to prevent calling the callback twice. - let stopSupplicantCallback = manager.stopSupplicantCallback.bind(manager); - manager.stopSupplicantCallback = null; - stopSupplicantCallback(); - stopSupplicantCallback = null; - } - return false; - } - if (eventData.indexOf("CTRL-EVENT-DISCONNECTED") === 0) { - var token = event.split(" ")[1]; - var bssid = token.split("=")[1]; - if (manager.authenticationFailuresCount > MAX_RETRIES_ON_AUTHENTICATION_FAILURE) { - manager.authenticationFailuresCount = 0; - notify("disconnected", {connectionInfo: manager.connectionInfo}); - } - manager.connectionInfo.bssid = null; - manager.connectionInfo.ssid = null; - manager.connectionInfo.id = -1; - return true; - } - if (eventData.indexOf("CTRL-EVENT-CONNECTED") === 0) { - // Format: CTRL-EVENT-CONNECTED - Connection to 00:1e:58:ec:d5:6d completed (reauth) [id=1 id_str=] - var bssid = event.split(" ")[4]; - - var keyword = "id="; - var id = event.substr(event.indexOf(keyword) + keyword.length).split(" ")[0]; - // Read current BSSID here, it will always being provided. - manager.connectionInfo.id = id; - manager.connectionInfo.bssid = bssid; - return true; - } - if (eventData.indexOf("CTRL-EVENT-SCAN-RESULTS") === 0) { - debug("Notifying of scan results available"); - if (reEnableBackgroundScan) { - reEnableBackgroundScan = false; - setBackgroundScan("ON", function() {}); - } - manager.handlePostWifiScan(); - notify("scanresultsavailable"); - return true; - } - if (eventData.indexOf("CTRL-EVENT-EAP") === 0) { - return handleWpaEapEvents(event); - } - if (eventData.indexOf("CTRL-EVENT-ASSOC-REJECT") === 0) { - debug("CTRL-EVENT-ASSOC-REJECT: network error"); - notify("passwordmaybeincorrect"); - if (manager.authenticationFailuresCount > MAX_RETRIES_ON_AUTHENTICATION_FAILURE) { - manager.authenticationFailuresCount = 0; - debug("CTRL-EVENT-ASSOC-REJECT: disconnect network"); - notify("disconnected", {connectionInfo: manager.connectionInfo}); - } - return true; - } - if (eventData.indexOf("WPS-TIMEOUT") === 0) { - notifyStateChange({ state: "WPS_TIMEOUT", BSSID: null, id: -1 }); - return true; - } - if (eventData.indexOf("WPS-FAIL") === 0) { - notifyStateChange({ state: "WPS_FAIL", BSSID: null, id: -1 }); - return true; - } - if (eventData.indexOf("WPS-OVERLAP-DETECTED") === 0) { - notifyStateChange({ state: "WPS_OVERLAP_DETECTED", BSSID: null, id: -1 }); - return true; - } - // Unknown event. - return true; - } - - function setPowerSavingMode(enabled) { - let mode = enabled ? "AUTO" : "ACTIVE"; - // Some wifi drivers may not implement this command. Set power mode - // even if suspend optimization command failed. - manager.setSuspendOptimizations(enabled, function(ok) { - manager.setPowerMode(mode, function() {}); - }); - } - - function didConnectSupplicant(callback) { - waitForEvent(manager.ifname); - - // Load up the supplicant state. - getDebugEnabled(function(ok) { - syncDebug(); - }); - wifiCommand.status(function(status) { - parseStatus(status); - notify("supplicantconnection"); - callback(); - }); - // WPA supplicant already connected. - manager.setPowerSavingMode(true); - if (p2pSupported) { - manager.enableP2p(function(success) {}); - } - } - - function prepareForStartup(callback) { - let status = libcutils.property_get(DHCP_PROP + "_" + manager.ifname); - if (status !== "running") { - tryStopSupplicant(); - return; - } - manager.connectionDropped(function() { - tryStopSupplicant(); - }); - - // Ignore any errors and kill any currently-running supplicants. On some - // phones, stopSupplicant won't work for a supplicant that we didn't - // start, so we hand-roll it here. - function tryStopSupplicant () { - let status = libcutils.property_get(SUPP_PROP); - if (status !== "running") { - callback(); - return; - } - suppressEvents = true; - wifiCommand.killSupplicant(function() { - gNetworkService.disableInterface(manager.ifname, function (ok) { - suppressEvents = false; - callback(); - }); - }); - } - } - - // Initial state. - manager.state = "UNINITIALIZED"; - manager.tetheringState = "UNINITIALIZED"; - manager.supplicantStarted = false; - manager.connectionInfo = { ssid: null, bssid: null, id: -1 }; - manager.authenticationFailuresCount = 0; - manager.loopDetectionCount = 0; - manager.dhcpFailuresCount = 0; - manager.stopSupplicantCallback = null; - - manager.__defineGetter__("enabled", function() { - switch (manager.state) { - case "UNINITIALIZED": - case "INITIALIZING": - case "DISABLING": - return false; - default: - return true; - } - }); - - var waitForTerminateEventTimer = null; - function cancelWaitForTerminateEventTimer() { - if (waitForTerminateEventTimer) { - waitForTerminateEventTimer.cancel(); - waitForTerminateEventTimer = null; - } - }; - function createWaitForTerminateEventTimer(onTimeout) { - if (waitForTerminateEventTimer) { - return; - } - waitForTerminateEventTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); - waitForTerminateEventTimer.initWithCallback(onTimeout, - 4000, - Ci.nsITimer.TYPE_ONE_SHOT); - }; - - var waitForDriverReadyTimer = null; - function cancelWaitForDriverReadyTimer() { - if (waitForDriverReadyTimer) { - waitForDriverReadyTimer.cancel(); - waitForDriverReadyTimer = null; - } - }; - function createWaitForDriverReadyTimer(onTimeout) { - waitForDriverReadyTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); - waitForDriverReadyTimer.initWithCallback(onTimeout, - manager.driverDelay, - Ci.nsITimer.TYPE_ONE_SHOT); - }; - - // Public interface of the wifi service. - manager.setWifiEnabled = function(enabled, callback) { - if (enabled === manager.isWifiEnabled(manager.state)) { - callback("no change"); - return; - } - - if (enabled) { - manager.state = "INITIALIZING"; - // Register as network interface. - WifiNetworkInterface.info.name = manager.ifname; - if (!WifiNetworkInterface.registered) { - gNetworkManager.registerNetworkInterface(WifiNetworkInterface); - WifiNetworkInterface.registered = true; - } - WifiNetworkInterface.info.state = - Ci.nsINetworkInfo.NETWORK_STATE_DISCONNECTED; - WifiNetworkInterface.info.ips = []; - WifiNetworkInterface.info.prefixLengths = []; - WifiNetworkInterface.info.gateways = []; - WifiNetworkInterface.info.dnses = []; - gNetworkManager.updateNetworkInterface(WifiNetworkInterface); - - prepareForStartup(function() { - loadDriver(function (status) { - if (status < 0) { - callback(status); - manager.state = "UNINITIALIZED"; - return; - } - // This command is mandatory for Nexus 4. But some devices like - // Galaxy S2 don't support it. Continue to start wpa_supplicant - // even if we fail to set wifi operation mode to station. - gNetworkService.setWifiOperationMode(manager.ifname, - WIFI_FIRMWARE_STATION, - function (status) { - - function startSupplicantInternal() { - wifiCommand.startSupplicant(function (status) { - if (status < 0) { - unloadDriver(WIFI_FIRMWARE_STATION, function() { - callback(status); - }); - manager.state = "UNINITIALIZED"; - return; - } - - manager.supplicantStarted = true; - gNetworkService.enableInterface(manager.ifname, function (ok) { - callback(ok ? 0 : -1); - }); - }); - } - - function doStartSupplicant() { - cancelWaitForDriverReadyTimer(); - - if (!manager.connectToSupplicant) { - startSupplicantInternal(); - return; - } - wifiCommand.closeSupplicantConnection(function () { - manager.connectToSupplicant = false; - // closeSupplicantConnection() will trigger onsupplicantlost - // and set manager.state to "UNINITIALIZED", we have to - // restore it here. - manager.state = "INITIALIZING"; - startSupplicantInternal(); - }); - } - // Driver startup on certain platforms takes longer than it takes for us - // to return from loadDriver, so wait 2 seconds before starting - // the supplicant to give it a chance to start. - if (manager.driverDelay > 0) { - createWaitForDriverReadyTimer(doStartSupplicant); - } else { - doStartSupplicant(); - } - }); - }); - }); - } else { - manager.state = "DISABLING"; - // Note these following calls ignore errors. If we fail to kill the - // supplicant gracefully, then we need to continue telling it to die - // until it does. - let doDisableWifi = function() { - manager.stopSupplicantCallback = (function () { - wifiCommand.stopSupplicant(function (status) { - wifiCommand.closeSupplicantConnection(function() { - manager.connectToSupplicant = false; - manager.state = "UNINITIALIZED"; - gNetworkService.disableInterface(manager.ifname, function (ok) { - unloadDriver(WIFI_FIRMWARE_STATION, callback); - }); - }); - }); - }).bind(this); - - let terminateEventCallback = (function() { - handleEvent("CTRL-EVENT-TERMINATING"); - }).bind(this); - createWaitForTerminateEventTimer(terminateEventCallback); - - // We are going to terminate the connection between wpa_supplicant. - // Stop the polling timer immediately to prevent connection info update - // command blocking in control thread until socket timeout. - notify("stopconnectioninfotimer"); - - wifiCommand.terminateSupplicant(function (ok) { - manager.connectionDropped(function () { - }); - }); - } - - if (p2pSupported) { - p2pManager.setEnabled(false, { onDisabled: doDisableWifi }); - } else { - doDisableWifi(); - } - } - } - - var wifiHotspotStatusTimer = null; - function cancelWifiHotspotStatusTimer() { - if (wifiHotspotStatusTimer) { - wifiHotspotStatusTimer.cancel(); - wifiHotspotStatusTimer = null; - } - } - - function createWifiHotspotStatusTimer(onTimeout) { - wifiHotspotStatusTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); - wifiHotspotStatusTimer.init(onTimeout, 5000, Ci.nsITimer.TYPE_REPEATING_SLACK); - } - - // Get wifi interface and load wifi driver when enable Ap mode. - manager.setWifiApEnabled = function(enabled, configuration, callback) { - if (enabled === manager.isWifiTetheringEnabled(manager.tetheringState)) { - callback("no change"); - return; - } - - if (enabled) { - manager.tetheringState = "INITIALIZING"; - loadDriver(function (status) { - if (status < 0) { - callback(); - manager.tetheringState = "UNINITIALIZED"; - if (wifiHotspotStatusTimer) { - cancelWifiHotspotStatusTimer(); - wifiCommand.closeHostapdConnection(function(result) { - }); - } - return; - } - - function getWifiHotspotStatus() { - wifiCommand.hostapdGetStations(function(result) { - notify("stationinfoupdate", {station: result}); - }); - } - - function doStartWifiTethering() { - cancelWaitForDriverReadyTimer(); - WifiNetworkInterface.info.name = - libcutils.property_get("wifi.tethering.interface", manager.ifname); - gTetheringService.setWifiTethering(enabled, - WifiNetworkInterface.info.name, - configuration, function(result) { - if (result) { - manager.tetheringState = "UNINITIALIZED"; - } else { - manager.tetheringState = "COMPLETED"; - wifiCommand.connectToHostapd(function(result) { - if (result) { - return; - } - // Create a timer to track the connection status. - createWifiHotspotStatusTimer(getWifiHotspotStatus); - }); - } - // Pop out current request. - callback(); - // Should we fire a dom event if we fail to set wifi tethering ? - debug("Enable Wifi tethering result: " + (result ? result : "successfully")); - }); - } - - // Driver startup on certain platforms takes longer than it takes - // for us to return from loadDriver, so wait 2 seconds before - // turning on Wifi tethering. - createWaitForDriverReadyTimer(doStartWifiTethering); - }); - } else { - cancelWifiHotspotStatusTimer(); - gTetheringService.setWifiTethering(enabled, WifiNetworkInterface, - configuration, function(result) { - // Should we fire a dom event if we fail to set wifi tethering ? - debug("Disable Wifi tethering result: " + (result ? result : "successfully")); - // Unload wifi driver even if we fail to control wifi tethering. - unloadDriver(WIFI_FIRMWARE_AP, function(status) { - if (status < 0) { - debug("Fail to unload wifi driver"); - } - manager.tetheringState = "UNINITIALIZED"; - callback(); - }); - }); - } - } - - manager.disconnect = wifiCommand.disconnect; - manager.reconnect = wifiCommand.reconnect; - manager.reassociate = wifiCommand.reassociate; - - var networkConfigurationFields = [ - {name: "ssid", type: "string"}, - {name: "bssid", type: "string"}, - {name: "psk", type: "string"}, - {name: "wep_key0", type: "string"}, - {name: "wep_key1", type: "string"}, - {name: "wep_key2", type: "string"}, - {name: "wep_key3", type: "string"}, - {name: "wep_tx_keyidx", type: "integer"}, - {name: "priority", type: "integer"}, - {name: "key_mgmt", type: "string"}, - {name: "scan_ssid", type: "string"}, - {name: "disabled", type: "integer"}, - {name: "identity", type: "string"}, - {name: "password", type: "string"}, - {name: "auth_alg", type: "string"}, - {name: "phase1", type: "string"}, - {name: "phase2", type: "string"}, - {name: "eap", type: "string"}, - {name: "pin", type: "string"}, - {name: "pcsc", type: "string"}, - {name: "ca_cert", type: "string"}, - {name: "subject_match", type: "string"}, - {name: "client_cert", type: "string"}, - {name: "private_key", type: "stirng"}, - {name: "engine", type: "integer"}, - {name: "engine_id", type: "string"}, - {name: "key_id", type: "string"}, - {name: "frequency", type: "integer"}, - {name: "mode", type: "integer"} - ]; - // These fields are only handled in IBSS (aka ad-hoc) mode - var ibssNetworkConfigurationFields = [ - "frequency", "mode" - ]; - - manager.getNetworkConfiguration = function(config, callback) { - var netId = config.netId; - var done = 0; - for (var n = 0; n < networkConfigurationFields.length; ++n) { - let fieldName = networkConfigurationFields[n].name; - let fieldType = networkConfigurationFields[n].type; - wifiCommand.getNetworkVariable(netId, fieldName, function(value) { - if (value !== null) { - if (fieldType === "integer") { - config[fieldName] = parseInt(value, 10); - } else if ( fieldName == "ssid" && value[0] != '"' ) { - // SET_NETWORK will set a quoted ssid to wpa_supplicant. - // But if ssid contains non-ascii char, it will be converted into utf-8. - // For example: "Testçš„wifi" --> 54657374e79a8477696669 - // When GET_NETWORK receive a un-quoted utf-8 ssid, it must be decoded and quoted. - config[fieldName] = quote(decodeURIComponent(value.replace(/[0-9a-f]{2}/g, '%$&'))); - } else { - // value is string type by default. - config[fieldName] = value; - } - } - if (++done == networkConfigurationFields.length) - callback(config); - }); - } - } - manager.setNetworkConfiguration = function(config, callback) { - var netId = config.netId; - var done = 0; - var errors = 0; - - function hasValidProperty(name) { - return ((name in config) && - config[name] != null && - (["password", "wep_key0", "psk"].indexOf(name) === -1 || - config[name] !== '*')); - } - - function getModeFromConfig() { - /* we use the mode from the config, or ESS as default */ - return hasValidProperty("mode") ? config["mode"] : MODE_ESS; - } - - var mode = getModeFromConfig(); - - function validForMode(name, mode) { - /* all fields are valid for IBSS */ - return (mode == MODE_IBSS) || - /* IBSS fields are not valid for ESS */ - ((mode == MODE_ESS) && !(name in ibssNetworkConfigurationFields)); - } - - for (var n = 0; n < networkConfigurationFields.length; ++n) { - let fieldName = networkConfigurationFields[n].name; - if (!hasValidProperty(fieldName) || !validForMode(fieldName, mode)) { - ++done; - } else { - wifiCommand.setNetworkVariable(netId, fieldName, config[fieldName], function(ok) { - if (!ok) - ++errors; - if (++done == networkConfigurationFields.length) - callback(errors == 0); - }); - } - } - // If config didn't contain any of the fields we want, don't lose the error callback. - if (done == networkConfigurationFields.length) - callback(false); - } - manager.getConfiguredNetworks = function(callback) { - wifiCommand.listNetworks(function (reply) { - var networks = Object.create(null); - var lines = reply ? reply.split("\n") : 0; - if (lines.length <= 1) { - // We need to make sure we call the callback even if there are no - // configured networks. - callback(networks); - return; - } - - var done = 0; - var errors = 0; - for (var n = 1; n < lines.length; ++n) { - var result = lines[n].split("\t"); - var netId = parseInt(result[0], 10); - var config = networks[netId] = { netId: netId }; - switch (result[3]) { - case "[CURRENT]": - config.status = "CURRENT"; - break; - case "[DISABLED]": - config.status = "DISABLED"; - break; - default: - config.status = "ENABLED"; - break; - } - manager.getNetworkConfiguration(config, function (ok) { - if (!ok) - ++errors; - if (++done == lines.length - 1) { - if (errors) { - // If an error occured, delete the new netId. - wifiCommand.removeNetwork(netId, function() { - callback(null); - }); - } else { - callback(networks); - } - } - }); - } - }); - } - manager.addNetwork = function(config, callback) { - wifiCommand.addNetwork(function (netId) { - config.netId = netId; - manager.setNetworkConfiguration(config, function (ok) { - if (!ok) { - wifiCommand.removeNetwork(netId, function() { callback(false); }); - return; - } - - callback(ok); - }); - }); - } - manager.updateNetwork = function(config, callback) { - manager.setNetworkConfiguration(config, callback); - } - manager.removeNetwork = function(netId, callback) { - wifiCommand.removeNetwork(netId, callback); - } - - manager.saveConfig = function(callback) { - wifiCommand.saveConfig(callback); - } - manager.enableNetwork = function(netId, disableOthers, callback) { - if (p2pSupported) { - // We have to stop wifi direct scan before associating to an AP. - // Otherwise we will get a "REJECT" wpa supplicant event. - p2pManager.setScanEnabled(false, function(success) {}); - } - wifiCommand.enableNetwork(netId, disableOthers, callback); - } - manager.disableNetwork = function(netId, callback) { - wifiCommand.disableNetwork(netId, callback); - } - manager.getMacAddress = wifiCommand.getMacAddress; - manager.getScanResults = wifiCommand.scanResults; - manager.setScanMode = function(mode, callback) { - setScanMode(mode === "active", callback); // Use our own version. - } - manager.setBackgroundScan = setBackgroundScan; // Use our own version. - manager.scan = scan; // Use our own version. - manager.wpsPbc = wifiCommand.wpsPbc; - manager.wpsPin = wifiCommand.wpsPin; - manager.wpsCancel = wifiCommand.wpsCancel; - manager.setPowerMode = (sdkVersion >= 16) - ? wifiCommand.setPowerModeJB - : wifiCommand.setPowerModeICS; - manager.setPowerSavingMode = setPowerSavingMode; - manager.getHttpProxyNetwork = getHttpProxyNetwork; - manager.setHttpProxy = setHttpProxy; - manager.configureHttpProxy = configureHttpProxy; - manager.setSuspendOptimizations = (sdkVersion >= 16) - ? wifiCommand.setSuspendOptimizationsJB - : wifiCommand.setSuspendOptimizationsICS; - manager.setStaticIpMode = setStaticIpMode; - manager.getRssiApprox = wifiCommand.getRssiApprox; - manager.getLinkSpeed = wifiCommand.getLinkSpeed; - manager.getDhcpInfo = function() { return dhcpInfo; } - manager.getConnectionInfo = (sdkVersion >= 15) - ? wifiCommand.getConnectionInfoICS - : wifiCommand.getConnectionInfoGB; - - manager.ensureSupplicantDetached = aCallback => { - if (!manager.enabled) { - aCallback(); - return; - } - wifiCommand.closeSupplicantConnection(aCallback); - }; - - manager.isHandShakeState = function(state) { - switch (state) { - case "AUTHENTICATING": - case "ASSOCIATING": - case "ASSOCIATED": - case "FOUR_WAY_HANDSHAKE": - case "GROUP_HANDSHAKE": - return true; - case "DORMANT": - case "COMPLETED": - case "DISCONNECTED": - case "INTERFACE_DISABLED": - case "INACTIVE": - case "SCANNING": - case "UNINITIALIZED": - case "INVALID": - case "CONNECTED": - default: - return false; - } - } - - manager.isWifiEnabled = function(state) { - switch (state) { - case "UNINITIALIZED": - case "DISABLING": - return false; - default: - return true; - } - } - - manager.isWifiTetheringEnabled = function(state) { - switch (state) { - case "UNINITIALIZED": - return false; - default: - return true; - } - } - - manager.syncDebug = syncDebug; - manager.stateOrdinal = function(state) { - return supplicantStatesMap.indexOf(state); - } - manager.supplicantLoopDetection = function(prevState, state) { - var isPrevStateInHandShake = manager.isHandShakeState(prevState); - var isStateInHandShake = manager.isHandShakeState(state); - - if (isPrevStateInHandShake) { - if (isStateInHandShake) { - // Increase the count only if we are in the loop. - if (manager.stateOrdinal(state) > manager.stateOrdinal(prevState)) { - manager.loopDetectionCount++; - } - if (manager.loopDetectionCount > MAX_SUPPLICANT_LOOP_ITERATIONS) { - notify("disconnected", {connectionInfo: manager.connectionInfo}); - manager.loopDetectionCount = 0; - } - } - } else { - // From others state to HandShake state. Reset the count. - if (isStateInHandShake) { - manager.loopDetectionCount = 0; - } - } - } - - manager.handlePreWifiScan = function() { - if (p2pSupported) { - // Before doing regular wifi scan, we have to disable wifi direct - // scan first. Otherwise we will never get the scan result. - p2pManager.blockScan(); - } - }; - - manager.handlePostWifiScan = function() { - if (p2pSupported) { - // After regular wifi scanning, we should restore the restricted - // wifi direct scan. - p2pManager.unblockScan(); - } - }; - - // - // Public APIs for P2P. - // - - manager.p2pSupported = function() { - return p2pSupported; - }; - - manager.getP2pManager = function() { - return p2pManager; - }; - - manager.enableP2p = function(callback) { - p2pManager.setEnabled(true, { - onSupplicantConnected: function() { - waitForEvent(WifiP2pManager.INTERFACE_NAME); - }, - - onEnabled: function(success) { - callback(success); - } - }); - }; - - manager.getCapabilities = function() { - return capabilities; - } - - // Cert Services - let wifiCertService = Cc["@mozilla.org/wifi/certservice;1"]; - if (wifiCertService) { - wifiCertService = wifiCertService.getService(Ci.nsIWifiCertService); - wifiCertService.start(wifiListener); - } else { - debug("No wifi CA service component available"); - } - - manager.importCert = function(caInfo, callback) { - var id = idgen++; - if (callback) { - controlCallbacks[id] = callback; - } - - wifiCertService.importCert(id, caInfo.certBlob, caInfo.certPassword, - caInfo.certNickname); - } - - manager.deleteCert = function(caInfo, callback) { - var id = idgen++; - if (callback) { - controlCallbacks[id] = callback; - } - - wifiCertService.deleteCert(id, caInfo.certNickname); - } - - manager.sdkVersion = function() { - return sdkVersion; - } - - return manager; -})(); - -// Get unique key for a network, now the key is created by escape(SSID)+Security. -// So networks of same SSID but different security mode can be identified. -function getNetworkKey(network) -{ - var ssid = "", - encryption = "OPEN"; - - if ("security" in network) { - // manager network object, represents an AP - // object structure - // { - // .ssid : SSID of AP - // .security[] : "WPA-PSK" for WPA-PSK - // "WPA-EAP" for WPA-EAP - // "WEP" for WEP - // "" for OPEN - // other keys - // } - - var security = network.security; - ssid = network.ssid; - - for (let j = 0; j < security.length; j++) { - if (security[j] === "WPA-PSK") { - encryption = "WPA-PSK"; - break; - } else if (security[j] === "WPA-EAP") { - encryption = "WPA-EAP"; - break; - } else if (security[j] === "WEP") { - encryption = "WEP"; - break; - } - } - } else if ("key_mgmt" in network) { - // configure network object, represents a network - // object structure - // { - // .ssid : SSID of network, quoted - // .key_mgmt : Encryption type - // "WPA-PSK" for WPA-PSK - // "WPA-EAP" for WPA-EAP - // "NONE" for WEP/OPEN - // .auth_alg : Encryption algorithm(WEP mode only) - // "OPEN_SHARED" for WEP - // other keys - // } - var key_mgmt = network.key_mgmt, - auth_alg = network.auth_alg; - ssid = dequote(network.ssid); - - if (key_mgmt == "WPA-PSK") { - encryption = "WPA-PSK"; - } else if (key_mgmt.indexOf("WPA-EAP") != -1) { - encryption = "WPA-EAP"; - } else if (key_mgmt == "NONE" && auth_alg === "OPEN SHARED") { - encryption = "WEP"; - } - } - - // ssid here must be dequoted, and it's safer to esacpe it. - // encryption won't be empty and always be assigned one of the followings : - // "OPEN"/"WEP"/"WPA-PSK"/"WPA-EAP". - // So for a invalid network object, the returned key will be "OPEN". - return escape(ssid) + encryption; -} - -function getMode(flags) { - if (/\[IBSS/.test(flags)) - return MODE_IBSS; - - return MODE_ESS; -} - -function getKeyManagement(flags) { - var types = []; - if (!flags) - return types; - - if (/\[WPA2?-PSK/.test(flags)) - types.push("WPA-PSK"); - if (/\[WPA2?-EAP/.test(flags)) - types.push("WPA-EAP"); - if (/\[WEP/.test(flags)) - types.push("WEP"); - return types; -} - -function getCapabilities(flags) { - var types = []; - if (!flags) - return types; - - if (/\[WPS/.test(flags)) - types.push("WPS"); - return types; -} - -// These constants shamelessly ripped from WifiManager.java -// strength is the value returned by scan_results. It is nominally in dB. We -// transform it into a percentage for clients looking to simply show a -// relative indication of the strength of a network. -const MIN_RSSI = -100; -const MAX_RSSI = -55; - -function calculateSignal(strength) { - // Some wifi drivers represent their signal strengths as 8-bit integers, so - // in order to avoid negative numbers, they add 256 to the actual values. - // While we don't *know* that this is the case here, we make an educated - // guess. - if (strength > 0) - strength -= 256; - - if (strength <= MIN_RSSI) - return 0; - if (strength >= MAX_RSSI) - return 100; - return Math.floor(((strength - MIN_RSSI) / (MAX_RSSI - MIN_RSSI)) * 100); -} - -function Network(ssid, mode, frequency, security, password, capabilities) { - this.ssid = ssid; - this.mode = mode; - this.frequency = frequency; - this.security = security; - - if (typeof password !== "undefined") - this.password = password; - if (capabilities !== undefined) - this.capabilities = capabilities; - // TODO connected here as well? - - this.__exposedProps__ = Network.api; -} - -Network.api = { - ssid: "r", - mode: "r", - frequency: "r", - security: "r", - capabilities: "r", - known: "r", - - password: "rw", - keyManagement: "rw", - psk: "rw", - identity: "rw", - wep: "rw", - hidden: "rw", - eap: "rw", - pin: "rw", - phase1: "rw", - phase2: "rw", - serverCertificate: "rw", - userCertificate: "rw" -}; - -// Note: We never use ScanResult.prototype, so the fact that it's unrelated to -// Network.prototype is OK. -function ScanResult(ssid, bssid, frequency, flags, signal) { - Network.call(this, ssid, getMode(flags), frequency, - getKeyManagement(flags), undefined, getCapabilities(flags)); - this.bssid = bssid; - this.signalStrength = signal; - this.relSignalStrength = calculateSignal(Number(signal)); - - this.__exposedProps__ = ScanResult.api; -} - -// XXX This should probably live in the DOM-facing side, but it's hard to do -// there, so we stick this here. -ScanResult.api = { - bssid: "r", - signalStrength: "r", - relSignalStrength: "r", - connected: "r" -}; - -for (let i in Network.api) { - ScanResult.api[i] = Network.api[i]; -} - -function quote(s) { - return '"' + s + '"'; -} - -function dequote(s) { - if (s[0] != '"' || s[s.length - 1] != '"') - throw "Invalid argument, not a quoted string: " + s; - return s.substr(1, s.length - 2); -} - -function isWepHexKey(s) { - if (s.length != 10 && s.length != 26 && s.length != 58) - return false; - return !/[^a-fA-F0-9]/.test(s); -} - - -var WifiNetworkInterface = { - - QueryInterface: XPCOMUtils.generateQI([Ci.nsINetworkInterface]), - - registered: false, - - // nsINetworkInterface - - NETWORK_STATE_UNKNOWN: Ci.nsINetworkInfo.NETWORK_STATE_UNKNOWN, - NETWORK_STATE_CONNECTING: Ci.nsINetworkInfo.CONNECTING, - NETWORK_STATE_CONNECTED: Ci.nsINetworkInfo.CONNECTED, - NETWORK_STATE_DISCONNECTING: Ci.nsINetworkInfo.DISCONNECTING, - NETWORK_STATE_DISCONNECTED: Ci.nsINetworkInfo.DISCONNECTED, - - NETWORK_TYPE_WIFI: Ci.nsINetworkInfo.NETWORK_TYPE_WIFI, - NETWORK_TYPE_MOBILE: Ci.nsINetworkInfo.NETWORK_TYPE_MOBILE, - NETWORK_TYPE_MOBILE_MMS: Ci.nsINetworkInfo.NETWORK_TYPE_MOBILE_MMS, - NETWORK_TYPE_MOBILE_SUPL: Ci.nsINetworkInfo.NETWORK_TYPE_MOBILE_SUPL, - - info: { - QueryInterface: XPCOMUtils.generateQI([Ci.nsINetworkInfo]), - - state: Ci.nsINetworkInfo.NETWORK_STATE_UNKNOWN, - - type: Ci.nsINetworkInfo.NETWORK_TYPE_WIFI, - - name: null, - - ips: [], - - prefixLengths: [], - - dnses: [], - - gateways: [], - - getAddresses: function (ips, prefixLengths) { - ips.value = this.ips.slice(); - prefixLengths.value = this.prefixLengths.slice(); - - return this.ips.length; - }, - - getGateways: function (count) { - if (count) { - count.value = this.gateways.length; - } - return this.gateways.slice(); - }, - - getDnses: function (count) { - if (count) { - count.value = this.dnses.length; - } - return this.dnses.slice(); - } - }, - - httpProxyHost: null, - - httpProxyPort: null -}; - -function WifiScanResult() {} - -// TODO Make the difference between a DOM-based network object and our -// networks objects much clearer. -var netToDOM; -var netFromDOM; - -function WifiWorker() { - var self = this; - - this._mm = Cc["@mozilla.org/parentprocessmessagemanager;1"] - .getService(Ci.nsIMessageListenerManager); - const messages = ["WifiManager:getNetworks", "WifiManager:getKnownNetworks", - "WifiManager:associate", "WifiManager:forget", - "WifiManager:wps", "WifiManager:getState", - "WifiManager:setPowerSavingMode", - "WifiManager:setHttpProxy", - "WifiManager:setStaticIpMode", - "WifiManager:importCert", - "WifiManager:getImportedCerts", - "WifiManager:deleteCert", - "WifiManager:setWifiEnabled", - "WifiManager:setWifiTethering", - "child-process-shutdown"]; - - messages.forEach((function(msgName) { - this._mm.addMessageListener(msgName, this); - }).bind(this)); - - Services.obs.addObserver(this, kMozSettingsChangedObserverTopic, false); - Services.obs.addObserver(this, "xpcom-shutdown", false); - - this.wantScanResults = []; - - this._needToEnableNetworks = false; - this._highestPriority = -1; - - // Networks is a map from SSID -> a scan result. - this.networks = Object.create(null); - - // ConfiguredNetworks is a map from SSID -> our view of a network. It only - // lists networks known to the wpa_supplicant. The SSID field (and other - // fields) are quoted for ease of use with WifiManager commands. - // Note that we don't have to worry about escaping embedded quotes since in - // all cases, the supplicant will take the last quotation that we pass it as - // the end of the string. - this.configuredNetworks = Object.create(null); - this._addingNetworks = Object.create(null); - - this.currentNetwork = null; - this.ipAddress = ""; - this.macAddress = null; - - this._lastConnectionInfo = null; - this._connectionInfoTimer = null; - this._reconnectOnDisconnect = false; - - // Create p2pObserver and assign to p2pManager. - if (WifiManager.p2pSupported()) { - this._p2pObserver = WifiP2pWorkerObserver(WifiManager.getP2pManager()); - WifiManager.getP2pManager().setObserver(this._p2pObserver); - - // Add DOM message observerd by p2pObserver to the message listener as well. - this._p2pObserver.getObservedDOMMessages().forEach((function(msgName) { - this._mm.addMessageListener(msgName, this); - }).bind(this)); - } - - // Users of instances of nsITimer should keep a reference to the timer until - // it is no longer needed in order to assure the timer is fired. - this._callbackTimer = null; - - // XXX On some phones (Otoro and Unagi) the wifi driver doesn't play nicely - // with the automatic scans that wpa_supplicant does (it appears that the - // driver forgets that it's returned scan results and then refuses to try to - // rescan. In order to detect this case we start a timer when we enter the - // SCANNING state and reset it whenever we either get scan results or leave - // the SCANNING state. If the timer fires, we assume that we are stuck and - // forceably try to unstick the supplican, also turning on background - // scanning to avoid having to constantly poke the supplicant. - - // How long we wait is controlled by the SCAN_STUCK_WAIT constant. - const SCAN_STUCK_WAIT = 12000; - this._scanStuckTimer = null; - this._turnOnBackgroundScan = false; - - function startScanStuckTimer() { - if (WifiManager.schedScanRecovery) { - self._scanStuckTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); - self._scanStuckTimer.initWithCallback(scanIsStuck, SCAN_STUCK_WAIT, - Ci.nsITimer.TYPE_ONE_SHOT); - } - } - - function scanIsStuck() { - // Uh-oh, we've waited too long for scan results. Disconnect (which - // guarantees that we leave the SCANNING state and tells wpa_supplicant to - // wait for our next command) ensure that background scanning is on and - // then try again. - debug("Determined that scanning is stuck, turning on background scanning!"); - WifiManager.handlePostWifiScan(); - WifiManager.disconnect(function(ok) {}); - self._turnOnBackgroundScan = true; - } - - // A list of requests to turn wifi on or off. - this._stateRequests = []; - - // Given a connection status network, takes a network from - // self.configuredNetworks and prepares it for the DOM. - netToDOM = function(net) { - if (!net) { - return null; - } - var ssid = dequote(net.ssid); - var mode = net.mode; - var frequency = net.frequency; - var security = (net.key_mgmt === "NONE" && net.wep_key0) ? ["WEP"] : - (net.key_mgmt && net.key_mgmt !== "NONE") ? [net.key_mgmt.split(" ")[0]] : - []; - var password; - if (("psk" in net && net.psk) || - ("password" in net && net.password) || - ("wep_key0" in net && net.wep_key0)) { - password = "*"; - } - - var pub = new Network(ssid, mode, frequency, security, password); - if (net.identity) - pub.identity = dequote(net.identity); - if ("netId" in net) - pub.known = true; - if (net.scan_ssid === 1) - pub.hidden = true; - if ("ca_cert" in net && net.ca_cert && - net.ca_cert.indexOf("keystore://WIFI_SERVERCERT_" === 0)) { - pub.serverCertificate = net.ca_cert.substr(27); - } - if(net.subject_match) { - pub.subjectMatch = net.subject_match; - } - if ("client_cert" in net && net.client_cert && - net.client_cert.indexOf("keystore://WIFI_USERCERT_" === 0)) { - pub.userCertificate = net.client_cert.substr(25); - } - return pub; - }; - - netFromDOM = function(net, configured) { - // Takes a network from the DOM and makes it suitable for insertion into - // self.configuredNetworks (that is calling addNetwork will do the right - // thing). - // NB: Modifies net in place: safe since we don't share objects between - // the dom and the chrome code. - - // Things that are useful for the UI but not to us. - delete net.bssid; - delete net.signalStrength; - delete net.relSignalStrength; - delete net.security; - delete net.capabilities; - - if (!configured) - configured = {}; - - net.ssid = quote(net.ssid); - - let wep = false; - if ("keyManagement" in net) { - if (net.keyManagement === "WEP") { - wep = true; - net.keyManagement = "NONE"; - } else if (net.keyManagement === "WPA-EAP") { - net.keyManagement += " IEEE8021X"; - } - - configured.key_mgmt = net.key_mgmt = net.keyManagement; // WPA2-PSK, WPA-PSK, etc. - delete net.keyManagement; - } else { - configured.key_mgmt = net.key_mgmt = "NONE"; - } - - if (net.hidden) { - configured.scan_ssid = net.scan_ssid = 1; - delete net.hidden; - } - - function checkAssign(name, checkStar) { - if (name in net) { - let value = net[name]; - if (!value || (checkStar && value === '*')) { - if (name in configured) - net[name] = configured[name]; - else - delete net[name]; - } else { - configured[name] = net[name] = quote(value); - } - } - } - - checkAssign("psk", true); - checkAssign("identity", false); - checkAssign("password", true); - if (wep && net.wep && net.wep != '*') { - configured.wep_key0 = net.wep_key0 = isWepHexKey(net.wep) ? net.wep : quote(net.wep); - configured.auth_alg = net.auth_alg = "OPEN SHARED"; - } - - function hasValidProperty(name) { - return ((name in net) && net[name] != null); - } - - if (hasValidProperty("eap")) { - if (hasValidProperty("pin")) { - net.pin = quote(net.pin); - } - - if (hasValidProperty("phase1")) - net.phase1 = quote(net.phase1); - - if (hasValidProperty("phase2")) { - if (net.phase2 === "TLS") { - net.phase2 = quote("autheap=" + net.phase2); - } else { // PAP, MSCHAPV2, etc. - net.phase2 = quote("auth=" + net.phase2); - } - } - - if (hasValidProperty("serverCertificate")) - net.ca_cert = quote("keystore://WIFI_SERVERCERT_" + net.serverCertificate); - - if (hasValidProperty("subjectMatch")) - net.subject_match = quote(net.subjectMatch); - - if (hasValidProperty("userCertificate")) { - let userCertName = "WIFI_USERCERT_" + net.userCertificate; - net.client_cert = quote("keystore://" + userCertName); - - let wifiCertService = Cc["@mozilla.org/wifi/certservice;1"]. - getService(Ci.nsIWifiCertService); - if (wifiCertService.hasPrivateKey(userCertName)) { - if (WifiManager.sdkVersion() >= 19) { - // Use openssol engine instead of keystore protocol after Kitkat. - net.engine = 1; - net.engine_id = quote("keystore"); - net.key_id = quote("WIFI_USERKEY_" + net.userCertificate); - } else { - net.private_key = quote("keystore://WIFI_USERKEY_" + net.userCertificate); - } - } - } - } - - return net; - }; - - WifiManager.onsupplicantconnection = function() { - debug("Connected to supplicant"); - // Give it a state other than UNINITIALIZED, INITIALIZING or DISABLING - // defined in getter function of WifiManager.enabled. It implies that - // we are ready to accept dom request from applications. - WifiManager.state = "DISCONNECTED"; - self._reloadConfiguredNetworks(function(ok) { - // Prime this.networks. - if (!ok) - return; - - // The select network command we used in associate() disables others networks. - // Enable them here to make sure wpa_supplicant helps to connect to known - // network automatically. - self._enableAllNetworks(); - WifiManager.saveConfig(function() {}) - }); - - // Notify everybody, even if they didn't ask us to come up. - WifiManager.getMacAddress(function (mac) { - self.macAddress = mac; - debug("Got mac: " + mac); - self._fireEvent("wifiUp", { macAddress: mac }); - self.requestDone(); - }); - - if (WifiManager.state === "SCANNING") - startScanStuckTimer(); - }; - - WifiManager.onsupplicantlost = function() { - WifiManager.supplicantStarted = false; - WifiManager.state = "UNINITIALIZED"; - debug("Supplicant died!"); - - // Notify everybody, even if they didn't ask us to come up. - self._fireEvent("wifiDown", {}); - self.requestDone(); - }; - - WifiManager.onpasswordmaybeincorrect = function() { - WifiManager.authenticationFailuresCount++; - }; - - WifiManager.ondisconnected = function() { - // We may fail to establish the connection, re-enable the - // rest of our networks. - if (self._needToEnableNetworks) { - self._enableAllNetworks(); - self._needToEnableNetworks = false; - } - - let connectionInfo = this.connectionInfo; - WifiManager.getNetworkId(connectionInfo.ssid, function(netId) { - // Trying to get netId from current network. - if (!netId && - self.currentNetwork && self.currentNetwork.ssid && - dequote(self.currentNetwork.ssid) == connectionInfo.ssid && - typeof self.currentNetwork.netId !== "undefined") { - netId = self.currentNetwork.netId; - } - if (netId) { - WifiManager.disableNetwork(netId, function() {}); - } - }); - self._fireEvent("onconnectingfailed", {network: netToDOM(self.currentNetwork)}); - } - - WifiManager.onstatechange = function() { - debug("State change: " + this.prevState + " -> " + this.state); - - if (self._connectionInfoTimer && - this.state !== "CONNECTED" && - this.state !== "COMPLETED") { - self._stopConnectionInfoTimer(); - } - - if (this.state !== "SCANNING" && - self._scanStuckTimer) { - self._scanStuckTimer.cancel(); - self._scanStuckTimer = null; - } - - switch (this.state) { - case "DORMANT": - // The dormant state is a bad state to be in since we won't - // automatically connect. Try to knock us out of it. We only - // hit this state when we've failed to run DHCP, so trying - // again isn't the worst thing we can do. Eventually, we'll - // need to detect if we're looping in this state and bail out. - WifiManager.reconnect(function(){}); - break; - case "ASSOCIATING": - // id has not yet been filled in, so we can only report the ssid and - // bssid. mode and frequency are simply made up. - self.currentNetwork = - { bssid: WifiManager.connectionInfo.bssid, - ssid: quote(WifiManager.connectionInfo.ssid), - mode: MODE_ESS, - frequency: 0}; - WifiManager.getNetworkConfiguration(self.currentNetwork, function (){ - // Notify again because we get complete network information. - self._fireEvent("onconnecting", { network: netToDOM(self.currentNetwork) }); - }); - break; - case "ASSOCIATED": - // set to full power mode when ready to do 4 way handsharke. - WifiManager.setPowerSavingMode(false); - if (!self.currentNetwork) { - self.currentNetwork = - { bssid: WifiManager.connectionInfo.bssid, - ssid: quote(WifiManager.connectionInfo.ssid) }; - } - self.currentNetwork.netId = this.id; - WifiManager.getNetworkConfiguration(self.currentNetwork, function (){ - // Notify again because we get complete network information. - self._fireEvent("onconnecting", { network: netToDOM(self.currentNetwork) }); - }); - break; - case "COMPLETED": - // Now that we've successfully completed the connection, re-enable the - // rest of our networks. - // XXX Need to do this eventually if the user entered an incorrect - // password. For now, we require user interaction to break the loop and - // select a better network! - if (self._needToEnableNetworks) { - self._enableAllNetworks(); - self._needToEnableNetworks = false; - } - - var _oncompleted = function() { - // The full authentication process is completed, reset the count. - WifiManager.authenticationFailuresCount = 0; - WifiManager.loopDetectionCount = 0; - self._startConnectionInfoTimer(); - self._fireEvent("onassociate", { network: netToDOM(self.currentNetwork) }); - }; - - // We get the ASSOCIATED event when we've associated but not connected, so - // wait until the handshake is complete. - if (this.fromStatus || !self.currentNetwork) { - // In this case, we connected to an already-connected wpa_supplicant, - // because of that we need to gather information about the current - // network here. - self.currentNetwork = { bssid: WifiManager.connectionInfo.bssid, - ssid: quote(WifiManager.connectionInfo.ssid), - netId: WifiManager.connectionInfo.id }; - WifiManager.getNetworkConfiguration(self.currentNetwork, _oncompleted); - } else { - _oncompleted(); - } - break; - case "CONNECTED": - // wifi connection complete, turn on the power saving mode. - WifiManager.setPowerSavingMode(true); - // BSSID is read after connected, update it. - self.currentNetwork.bssid = WifiManager.connectionInfo.bssid; - break; - case "DISCONNECTED": - // wpa_supplicant may give us a "DISCONNECTED" event even if - // we are already in "DISCONNECTED" state. - if ((WifiNetworkInterface.info.state === - Ci.nsINetworkInfo.NETWORK_STATE_DISCONNECTED) && - (this.prevState === "INITIALIZING" || - this.prevState === "DISCONNECTED" || - this.prevState === "INTERFACE_DISABLED" || - this.prevState === "INACTIVE" || - this.prevState === "UNINITIALIZED")) { - // When in disconnected mode, need to turn on wifi power saving mode. - WifiManager.setPowerSavingMode(true); - return; - } - - self._fireEvent("ondisconnect", {network: netToDOM(self.currentNetwork)}); - - self.currentNetwork = null; - self.ipAddress = ""; - - if (self._turnOnBackgroundScan) { - self._turnOnBackgroundScan = false; - WifiManager.setBackgroundScan("ON", function(did_something, ok) { - WifiManager.reassociate(function() {}); - }); - } - - WifiManager.connectionDropped(function() { - // We've disconnected from a network because of a call to forgetNetwork. - // Reconnect to the next available network (if any). - if (self._reconnectOnDisconnect) { - self._reconnectOnDisconnect = false; - WifiManager.reconnect(function(){}); - } - }); - - WifiNetworkInterface.info.state = - Ci.nsINetworkInfo.NETWORK_STATE_DISCONNECTED; - - // Update network infterface first then clear properties. - gNetworkManager.updateNetworkInterface(WifiNetworkInterface); - WifiNetworkInterface.info.ips = []; - WifiNetworkInterface.info.prefixLengths = []; - WifiNetworkInterface.info.gateways = []; - WifiNetworkInterface.info.dnses = []; - - - break; - case "WPS_TIMEOUT": - self._fireEvent("onwpstimeout", {}); - break; - case "WPS_FAIL": - self._fireEvent("onwpsfail", {}); - break; - case "WPS_OVERLAP_DETECTED": - self._fireEvent("onwpsoverlap", {}); - break; - case "AUTHENTICATING": - self._fireEvent("onauthenticating", {network: netToDOM(self.currentNetwork)}); - break; - case "SCANNING": - // If we're already scanning in the background, we don't need to worry - // about getting stuck while scanning. - if (!WifiManager.backgroundScanEnabled && WifiManager.enabled) - startScanStuckTimer(); - break; - } - }; - - WifiManager.onnetworkconnected = function() { - if (!this.info || !this.info.ipaddr_str) { - debug("Network information is invalid."); - return; - } - - let maskLength = - netHelpers.getMaskLength(netHelpers.stringToIP(this.info.mask_str)); - if (!maskLength) { - maskLength = 32; // max prefix for IPv4. - } - - let netConnect = WifiManager.getHttpProxyNetwork(self.currentNetwork); - if (netConnect) { - WifiNetworkInterface.httpProxyHost = netConnect.httpProxyHost; - WifiNetworkInterface.httpProxyPort = netConnect.httpProxyPort; - } - - WifiNetworkInterface.info.state = - Ci.nsINetworkInfo.NETWORK_STATE_CONNECTED; - WifiNetworkInterface.info.ips = [this.info.ipaddr_str]; - WifiNetworkInterface.info.prefixLengths = [maskLength]; - WifiNetworkInterface.info.gateways = [this.info.gateway_str]; - if (typeof this.info.dns1_str == "string" && - this.info.dns1_str.length) { - WifiNetworkInterface.info.dnses.push(this.info.dns1_str); - } - if (typeof this.info.dns2_str == "string" && - this.info.dns2_str.length) { - WifiNetworkInterface.info.dnses.push(this.info.dns2_str); - } - gNetworkManager.updateNetworkInterface(WifiNetworkInterface); - - self.ipAddress = this.info.ipaddr_str; - - // We start the connection information timer when we associate, but - // don't have our IP address until here. Make sure that we fire a new - // connectionInformation event with the IP address the next time the - // timer fires. - self._lastConnectionInfo = null; - self._fireEvent("onconnect", { network: netToDOM(self.currentNetwork) }); - }; - - WifiManager.onscanresultsavailable = function() { - if (self._scanStuckTimer) { - // We got scan results! We must not be stuck for now, try again. - self._scanStuckTimer.cancel(); - self._scanStuckTimer.initWithCallback(scanIsStuck, SCAN_STUCK_WAIT, - Ci.nsITimer.TYPE_ONE_SHOT); - } - - if (self.wantScanResults.length === 0) { - debug("Scan results available, but we don't need them"); - return; - } - - debug("Scan results are available! Asking for them."); - WifiManager.getScanResults(function(r) { - // Failure. - if (!r) { - self.wantScanResults.forEach(function(callback) { callback(null) }); - self.wantScanResults = []; - return; - } - - let capabilities = WifiManager.getCapabilities(); - - // Now that we have scan results, there's no more need to continue - // scanning. Ignore any errors from this command. - WifiManager.setScanMode("inactive", function() {}); - let lines = r.split("\n"); - // NB: Skip the header line. - self.networksArray = []; - for (let i = 1; i < lines.length; ++i) { - // bssid / frequency / signal level / flags / ssid - var match = /([\S]+)\s+([\S]+)\s+([\S]+)\s+(\[[\S]+\])?\s(.*)/.exec(lines[i]); - - if (match && match[5]) { - let ssid = match[5], - bssid = match[1], - frequency = match[2], - signalLevel = match[3], - flags = match[4]; - - /* Skip networks with unknown or unsupported modes. */ - if (capabilities.mode.indexOf(getMode(flags)) == -1) - continue; - - // If this is the first time that we've seen this SSID in the scan - // results, add it to the list along with any other information. - // Also, we use the highest signal strength that we see. - let network = new ScanResult(ssid, bssid, frequency, flags, signalLevel); - - let networkKey = getNetworkKey(network); - let eapIndex = -1; - if (networkKey in self.configuredNetworks) { - let known = self.configuredNetworks[networkKey]; - network.known = true; - - if ("identity" in known && known.identity) - network.identity = dequote(known.identity); - - // Note: we don't hand out passwords here! The * marks that there - // is a password that we're hiding. - if (("psk" in known && known.psk) || - ("password" in known && known.password) || - ("wep_key0" in known && known.wep_key0)) { - network.password = "*"; - } - } - - self.networksArray.push(network); - if (network.bssid === WifiManager.connectionInfo.bssid) - network.connected = true; - - let signal = calculateSignal(Number(match[3])); - if (signal > network.relSignalStrength) - network.relSignalStrength = signal; - } else if (!match) { - debug("Match didn't find anything for: " + lines[i]); - } - } - - self.wantScanResults.forEach(function(callback) { callback(self.networksArray) }); - self.wantScanResults = []; - }); - }; - - WifiManager.onstationinfoupdate = function() { - self._fireEvent("stationinfoupdate", { station: this.station }); - }; - - WifiManager.onstopconnectioninfotimer = function() { - self._stopConnectionInfoTimer(); - }; - - // Read the 'wifi.enabled' setting in order to start with a known - // value at boot time. The handle() will be called after reading. - // - // nsISettingsServiceCallback implementation. - var initWifiEnabledCb = { - handle: function handle(aName, aResult) { - if (aName !== SETTINGS_WIFI_ENABLED) - return; - if (aResult === null) - aResult = true; - self.handleWifiEnabled(aResult); - }, - handleError: function handleError(aErrorMessage) { - debug("Error reading the 'wifi.enabled' setting. Default to wifi on."); - self.handleWifiEnabled(true); - } - }; - - var initWifiDebuggingEnabledCb = { - handle: function handle(aName, aResult) { - if (aName !== SETTINGS_WIFI_DEBUG_ENABLED) - return; - if (aResult === null) - aResult = false; - DEBUG = aResult; - updateDebug(); - }, - handleError: function handleError(aErrorMessage) { - debug("Error reading the 'wifi.debugging.enabled' setting. Default to debugging off."); - DEBUG = false; - updateDebug(); - } - }; - - this.initTetheringSettings(); - - let lock = gSettingsService.createLock(); - lock.get(SETTINGS_WIFI_ENABLED, initWifiEnabledCb); - lock.get(SETTINGS_WIFI_DEBUG_ENABLED, initWifiDebuggingEnabledCb); - - lock.get(SETTINGS_WIFI_SSID, this); - lock.get(SETTINGS_WIFI_SECURITY_TYPE, this); - lock.get(SETTINGS_WIFI_SECURITY_PASSWORD, this); - lock.get(SETTINGS_WIFI_IP, this); - lock.get(SETTINGS_WIFI_PREFIX, this); - lock.get(SETTINGS_WIFI_DHCPSERVER_STARTIP, this); - lock.get(SETTINGS_WIFI_DHCPSERVER_ENDIP, this); - lock.get(SETTINGS_WIFI_DNS1, this); - lock.get(SETTINGS_WIFI_DNS2, this); - lock.get(SETTINGS_WIFI_TETHERING_ENABLED, this); - - lock.get(SETTINGS_USB_DHCPSERVER_STARTIP, this); - lock.get(SETTINGS_USB_DHCPSERVER_ENDIP, this); - - this._wifiTetheringSettingsToRead = [SETTINGS_WIFI_SSID, - SETTINGS_WIFI_SECURITY_TYPE, - SETTINGS_WIFI_SECURITY_PASSWORD, - SETTINGS_WIFI_IP, - SETTINGS_WIFI_PREFIX, - SETTINGS_WIFI_DHCPSERVER_STARTIP, - SETTINGS_WIFI_DHCPSERVER_ENDIP, - SETTINGS_WIFI_DNS1, - SETTINGS_WIFI_DNS2, - SETTINGS_WIFI_TETHERING_ENABLED, - SETTINGS_USB_DHCPSERVER_STARTIP, - SETTINGS_USB_DHCPSERVER_ENDIP]; -} - -function translateState(state) { - switch (state) { - case "INTERFACE_DISABLED": - case "INACTIVE": - case "SCANNING": - case "DISCONNECTED": - default: - return "disconnected"; - - case "AUTHENTICATING": - case "ASSOCIATING": - case "ASSOCIATED": - case "FOUR_WAY_HANDSHAKE": - case "GROUP_HANDSHAKE": - return "connecting"; - - case "COMPLETED": - return WifiManager.getDhcpInfo() ? "connected" : "associated"; - } -} - -WifiWorker.prototype = { - classID: WIFIWORKER_CID, - classInfo: XPCOMUtils.generateCI({classID: WIFIWORKER_CID, - contractID: WIFIWORKER_CONTRACTID, - classDescription: "WifiWorker", - interfaces: [Ci.nsIWorkerHolder, - Ci.nsIWifi, - Ci.nsIObserver]}), - - QueryInterface: XPCOMUtils.generateQI([Ci.nsIWorkerHolder, - Ci.nsIWifi, - Ci.nsIObserver, - Ci.nsISettingsServiceCallback]), - - disconnectedByWifi: false, - - disconnectedByWifiTethering: false, - - _wifiTetheringSettingsToRead: [], - - _oldWifiTetheringEnabledState: null, - - tetheringSettings: {}, - - initTetheringSettings: function initTetheringSettings() { - this.tetheringSettings[SETTINGS_WIFI_TETHERING_ENABLED] = null; - this.tetheringSettings[SETTINGS_WIFI_SSID] = DEFAULT_WIFI_SSID; - this.tetheringSettings[SETTINGS_WIFI_SECURITY_TYPE] = DEFAULT_WIFI_SECURITY_TYPE; - this.tetheringSettings[SETTINGS_WIFI_SECURITY_PASSWORD] = DEFAULT_WIFI_SECURITY_PASSWORD; - this.tetheringSettings[SETTINGS_WIFI_IP] = DEFAULT_WIFI_IP; - this.tetheringSettings[SETTINGS_WIFI_PREFIX] = DEFAULT_WIFI_PREFIX; - this.tetheringSettings[SETTINGS_WIFI_DHCPSERVER_STARTIP] = DEFAULT_WIFI_DHCPSERVER_STARTIP; - this.tetheringSettings[SETTINGS_WIFI_DHCPSERVER_ENDIP] = DEFAULT_WIFI_DHCPSERVER_ENDIP; - this.tetheringSettings[SETTINGS_WIFI_DNS1] = DEFAULT_DNS1; - this.tetheringSettings[SETTINGS_WIFI_DNS2] = DEFAULT_DNS2; - - this.tetheringSettings[SETTINGS_USB_DHCPSERVER_STARTIP] = DEFAULT_USB_DHCPSERVER_STARTIP; - this.tetheringSettings[SETTINGS_USB_DHCPSERVER_ENDIP] = DEFAULT_USB_DHCPSERVER_ENDIP; - }, - - // Internal methods. - waitForScan: function(callback) { - this.wantScanResults.push(callback); - }, - - // In order to select a specific network, we disable the rest of the - // networks known to us. However, in general, we want the supplicant to - // connect to which ever network it thinks is best, so when we select the - // proper network (or fail to), we need to re-enable the rest. - _enableAllNetworks: function() { - for (let key in this.configuredNetworks) { - let net = this.configuredNetworks[key]; - WifiManager.enableNetwork(net.netId, false, function(ok) { - net.disabled = ok ? 1 : 0; - }); - } - }, - - _startConnectionInfoTimer: function() { - if (this._connectionInfoTimer) - return; - - var self = this; - function getConnectionInformation() { - WifiManager.getConnectionInfo(function(connInfo) { - // See comments in calculateSignal for information about this. - if (!connInfo) { - self._lastConnectionInfo = null; - return; - } - - let { rssi, linkspeed } = connInfo; - if (rssi > 0) - rssi -= 256; - if (rssi <= MIN_RSSI) - rssi = MIN_RSSI; - else if (rssi >= MAX_RSSI) - rssi = MAX_RSSI; - - let info = { signalStrength: rssi, - relSignalStrength: calculateSignal(rssi), - linkSpeed: linkspeed, - ipAddress: self.ipAddress }; - let last = self._lastConnectionInfo; - - // Only fire the event if the link speed changed or the signal - // strength changed by more than 10%. - function tensPlace(percent) { - return (percent / 10) | 0; - } - - if (last && last.linkSpeed === info.linkSpeed && - last.ipAddress === info.ipAddress && - tensPlace(last.relSignalStrength) === tensPlace(info.relSignalStrength)) { - return; - } - - self._lastConnectionInfo = info; - debug("Firing connectioninfoupdate: " + uneval(info)); - self._fireEvent("connectioninfoupdate", info); - }); - } - - // Prime our _lastConnectionInfo immediately and fire the event at the - // same time. - getConnectionInformation(); - - // Now, set up the timer for regular updates. - this._connectionInfoTimer = - Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); - this._connectionInfoTimer.init(getConnectionInformation, 5000, - Ci.nsITimer.TYPE_REPEATING_SLACK); - }, - - _stopConnectionInfoTimer: function() { - if (!this._connectionInfoTimer) - return; - - this._connectionInfoTimer.cancel(); - this._connectionInfoTimer = null; - this._lastConnectionInfo = null; - }, - - _reloadConfiguredNetworks: function(callback) { - WifiManager.getConfiguredNetworks((function(networks) { - if (!networks) { - debug("Unable to get configured networks"); - callback(false); - return; - } - - this._highestPriority = -1; - - // Convert between netId-based and ssid-based indexing. - for (let net in networks) { - let network = networks[net]; - delete networks[net]; - - if (!network.ssid) { - WifiManager.removeNetwork(network.netId, function() {}); - continue; - } - - if (network.hasOwnProperty("priority") && - network.priority > this._highestPriority) { - this._highestPriority = network.priority; - } - - let networkKey = getNetworkKey(network); - // Accept latest config of same network(same SSID and same security). - if (networks[networkKey]) { - WifiManager.removeNetwork(networks[networkKey].netId, function() {}); - } - networks[networkKey] = network; - } - - this.configuredNetworks = networks; - callback(true); - }).bind(this)); - }, - - // Important side effect: calls WifiManager.saveConfig. - _reprioritizeNetworks: function(callback) { - // First, sort the networks in orer of their priority. - var ordered = Object.getOwnPropertyNames(this.configuredNetworks); - let self = this; - ordered.sort(function(a, b) { - var neta = self.configuredNetworks[a], - netb = self.configuredNetworks[b]; - - // Sort unsorted networks to the end of the list. - if (isNaN(neta.priority)) - return isNaN(netb.priority) ? 0 : 1; - if (isNaN(netb.priority)) - return -1; - return netb.priority - neta.priority; - }); - - // Skip unsorted networks. - let newPriority = 0, i; - for (i = ordered.length - 1; i >= 0; --i) { - if (!isNaN(this.configuredNetworks[ordered[i]].priority)) - break; - } - - // No networks we care about? - if (i < 0) { - WifiManager.saveConfig(callback); - return; - } - - // Now assign priorities from 0 to length, starting with the smallest - // priority and heading towards the highest (note the dependency between - // total and i here). - let done = 0, errors = 0, total = i + 1; - for (; i >= 0; --i) { - let network = this.configuredNetworks[ordered[i]]; - network.priority = newPriority++; - - // Note: networkUpdated declared below since it happens logically after - // this loop. - WifiManager.updateNetwork(network, networkUpdated); - } - - function networkUpdated(ok) { - if (!ok) - ++errors; - if (++done === total) { - if (errors > 0) { - callback(false); - return; - } - - WifiManager.saveConfig(function(ok) { - if (!ok) { - callback(false); - return; - } - - self._reloadConfiguredNetworks(function(ok) { - callback(ok); - }); - }); - } - } - }, - - // nsIWifi - - _domManagers: [], - _fireEvent: function(message, data) { - this._domManagers.forEach(function(manager) { - // Note: We should never have a dead message manager here because we - // observe our child message managers shutting down, below. - manager.sendAsyncMessage("WifiManager:" + message, data); - }); - }, - - _sendMessage: function(message, success, data, msg) { - try { - msg.manager.sendAsyncMessage(message + (success ? ":OK" : ":NO"), - { data: data, rid: msg.rid, mid: msg.mid }); - } catch (e) { - debug("sendAsyncMessage error : " + e); - } - this._splicePendingRequest(msg); - }, - - _domRequest: [], - - _splicePendingRequest: function(msg) { - for (let i = 0; i < this._domRequest.length; i++) { - if (this._domRequest[i].msg === msg) { - this._domRequest.splice(i, 1); - return; - } - } - }, - - _clearPendingRequest: function() { - if (this._domRequest.length === 0) return; - this._domRequest.forEach((function(req) { - this._sendMessage(req.name + ":Return", false, "Wifi is disabled", req.msg); - }).bind(this)); - }, - - receiveMessage: function MessageManager_receiveMessage(aMessage) { - let msg = aMessage.data || {}; - msg.manager = aMessage.target; - - if (WifiManager.p2pSupported()) { - // If p2pObserver returns something truthy, return it! - // Otherwise, continue to do the rest of tasks. - var p2pRet = this._p2pObserver.onDOMMessage(aMessage); - if (p2pRet) { - return p2pRet; - } - } - - // Note: By the time we receive child-process-shutdown, the child process - // has already forgotten its permissions so we do this before the - // permissions check. - if (aMessage.name === "child-process-shutdown") { - let i; - if ((i = this._domManagers.indexOf(msg.manager)) != -1) { - this._domManagers.splice(i, 1); - } - for (i = this._domRequest.length - 1; i >= 0; i--) { - if (this._domRequest[i].msg.manager === msg.manager) { - this._domRequest.splice(i, 1); - } - } - return; - } - - if (!aMessage.target.assertPermission("wifi-manage")) { - return; - } - - // We are interested in DOMRequests only. - if (aMessage.name != "WifiManager:getState") { - this._domRequest.push({name: aMessage.name, msg:msg}); - } - - switch (aMessage.name) { - case "WifiManager:setWifiEnabled": - this.setWifiEnabled(msg); - break; - case "WifiManager:getNetworks": - this.getNetworks(msg); - break; - case "WifiManager:getKnownNetworks": - this.getKnownNetworks(msg); - break; - case "WifiManager:associate": - this.associate(msg); - break; - case "WifiManager:forget": - this.forget(msg); - break; - case "WifiManager:wps": - this.wps(msg); - break; - case "WifiManager:setPowerSavingMode": - this.setPowerSavingMode(msg); - break; - case "WifiManager:setHttpProxy": - this.setHttpProxy(msg); - break; - case "WifiManager:setStaticIpMode": - this.setStaticIpMode(msg); - break; - case "WifiManager:importCert": - this.importCert(msg); - break; - case "WifiManager:getImportedCerts": - this.getImportedCerts(msg); - break; - case "WifiManager:deleteCert": - this.deleteCert(msg); - break; - case "WifiManager:setWifiTethering": - this.setWifiTethering(msg); - break; - case "WifiManager:getState": { - let i; - if ((i = this._domManagers.indexOf(msg.manager)) === -1) { - this._domManagers.push(msg.manager); - } - - let net = this.currentNetwork ? netToDOM(this.currentNetwork) : null; - return { network: net, - connectionInfo: this._lastConnectionInfo, - enabled: WifiManager.enabled, - status: translateState(WifiManager.state), - macAddress: this.macAddress, - capabilities: WifiManager.getCapabilities()}; - } - } - }, - - getNetworks: function(msg) { - const message = "WifiManager:getNetworks:Return"; - if (!WifiManager.enabled) { - this._sendMessage(message, false, "Wifi is disabled", msg); - return; - } - - let sent = false; - let callback = (function (networks) { - if (sent) - return; - sent = true; - this._sendMessage(message, networks !== null, networks, msg); - }).bind(this); - this.waitForScan(callback); - - WifiManager.scan(true, (function(ok) { - // If the scan command succeeded, we're done. - if (ok) - return; - - // Avoid sending multiple responses. - if (sent) - return; - - // Otherwise, let the client know that it failed, it's responsible for - // trying again in a few seconds. - sent = true; - this._sendMessage(message, false, "ScanFailed", msg); - }).bind(this)); - }, - - getWifiScanResults: function(callback) { - var count = 0; - var timer = null; - var self = this; - - if (!WifiManager.enabled) { - callback.onfailure(); - return; - } - - self.waitForScan(waitForScanCallback); - doScan(); - function doScan() { - WifiManager.scan(true, (function (ok) { - if (!ok) { - if (!timer) { - count = 0; - timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); - } - - if (count++ >= 3) { - timer = null; - self.wantScanResults.splice(self.wantScanResults.indexOf(waitForScanCallback), 1); - callback.onfailure(); - return; - } - - // Else it's still running, continue waiting. - timer.initWithCallback(doScan, 10000, Ci.nsITimer.TYPE_ONE_SHOT); - return; - } - }).bind(this)); - } - - function waitForScanCallback(networks) { - if (networks === null) { - callback.onfailure(); - return; - } - - var wifiScanResults = new Array(); - var net; - for (let net in networks) { - let value = networks[net]; - wifiScanResults.push(transformResult(value)); - } - callback.onready(wifiScanResults.length, wifiScanResults); - } - - function transformResult(element) { - var result = new WifiScanResult(); - result.connected = false; - for (let id in element) { - if (id === "__exposedProps__") { - continue; - } - if (id === "security") { - result[id] = 0; - var security = element[id]; - for (let j = 0; j < security.length; j++) { - if (security[j] === "WPA-PSK") { - result[id] |= Ci.nsIWifiScanResult.WPA_PSK; - } else if (security[j] === "WPA-EAP") { - result[id] |= Ci.nsIWifiScanResult.WPA_EAP; - } else if (security[j] === "WEP") { - result[id] |= Ci.nsIWifiScanResult.WEP; - } else { - result[id] = 0; - } - } - } else { - result[id] = element[id]; - } - } - return result; - } - }, - - getKnownNetworks: function(msg) { - const message = "WifiManager:getKnownNetworks:Return"; - if (!WifiManager.enabled) { - this._sendMessage(message, false, "Wifi is disabled", msg); - return; - } - - this._reloadConfiguredNetworks((function(ok) { - if (!ok) { - this._sendMessage(message, false, "Failed", msg); - return; - } - - var networks = []; - for (let networkKey in this.configuredNetworks) { - networks.push(netToDOM(this.configuredNetworks[networkKey])); - } - - this._sendMessage(message, true, networks, msg); - }).bind(this)); - }, - - _setWifiEnabledCallback: function(status) { - if (status !== 0) { - this.requestDone(); - return; - } - - // If we're enabling ourselves, then wait until we've connected to the - // supplicant to notify. If we're disabling, we take care of this in - // supplicantlost. - if (WifiManager.supplicantStarted) - WifiManager.start(); - }, - - /** - * Compatibility flags for detecting if Gaia is controlling wifi by settings - * or API, once API is called, gecko will no longer accept wifi enable - * control from settings. - * This is used to deal with compatibility issue while Gaia adopted to use - * API but gecko doesn't remove the settings code in time. - * TODO: Remove this flag in Bug 1050147 - */ - ignoreWifiEnabledFromSettings: false, - setWifiEnabled: function(msg) { - const message = "WifiManager:setWifiEnabled:Return"; - let self = this; - let enabled = msg.data; - - self.ignoreWifiEnabledFromSettings = true; - // No change. - if (enabled === WifiManager.enabled) { - this._sendMessage(message, true, true, msg); - return; - } - - // Can't enable wifi while hotspot mode is enabled. - if (enabled && (this.tetheringSettings[SETTINGS_WIFI_TETHERING_ENABLED] || - WifiManager.isWifiTetheringEnabled(WifiManager.tetheringState))) { - self._sendMessage(message, false, "Can't enable Wifi while hotspot mode is enabled", msg); - return; - } - - WifiManager.setWifiEnabled(enabled, function(ok) { - if (ok === 0 || ok === "no change") { - self._sendMessage(message, true, true, msg); - - // Reply error to pending requests. - if (!enabled) { - self._clearPendingRequest(); - } else { - WifiManager.start(); - } - } else { - self._sendMessage(message, false, "Set wifi enabled failed", msg); - } - }); - }, - - _setWifiEnabled: function(enabled, callback) { - // Reply error to pending requests. - if (!enabled) { - this._clearPendingRequest(); - } - - WifiManager.setWifiEnabled(enabled, callback); - }, - - // requestDone() must be called to before callback complete(or error) - // so next queue in the request quene can be executed. - // TODO: Remove command queue in Bug 1050147 - queueRequest: function(data, callback) { - if (!callback) { - throw "Try to enqueue a request without callback"; - } - - let optimizeCommandList = ["setWifiEnabled", "setWifiApEnabled"]; - if (optimizeCommandList.indexOf(data.command) != -1) { - this._stateRequests = this._stateRequests.filter(function(element) { - return element.data.command !== data.command; - }); - } - - this._stateRequests.push({ - data: data, - callback: callback - }); - - this.nextRequest(); - }, - - getWifiTetheringParameters: function getWifiTetheringParameters(enable) { - if (this.useTetheringAPI) { - return this.getWifiTetheringConfiguration(enable); - } else { - return this.getWifiTetheringParametersBySetting(enable); - } - }, - - getWifiTetheringConfiguration: function getWifiTetheringConfiguration(enable) { - let config = {}; - let params = this.tetheringConfig; - - let check = function(field, _default) { - config[field] = field in params ? params[field] : _default; - }; - - check("ssid", DEFAULT_WIFI_SSID); - check("security", DEFAULT_WIFI_SECURITY_TYPE); - check("key", DEFAULT_WIFI_SECURITY_PASSWORD); - check("ip", DEFAULT_WIFI_IP); - check("prefix", DEFAULT_WIFI_PREFIX); - check("wifiStartIp", DEFAULT_WIFI_DHCPSERVER_STARTIP); - check("wifiEndIp", DEFAULT_WIFI_DHCPSERVER_ENDIP); - check("usbStartIp", DEFAULT_USB_DHCPSERVER_STARTIP); - check("usbEndIp", DEFAULT_USB_DHCPSERVER_ENDIP); - check("dns1", DEFAULT_DNS1); - check("dns2", DEFAULT_DNS2); - - config.enable = enable; - config.mode = enable ? WIFI_FIRMWARE_AP : WIFI_FIRMWARE_STATION; - config.link = enable ? NETWORK_INTERFACE_UP : NETWORK_INTERFACE_DOWN; - - // Check the format to prevent netd from crash. - if (enable && (!config.ssid || config.ssid == "")) { - debug("Invalid SSID value."); - return null; - } - - if (enable && (config.security != WIFI_SECURITY_TYPE_NONE && !config.key)) { - debug("Invalid security password."); - return null; - } - - // Using the default values here until application supports these settings. - if (config.ip == "" || config.prefix == "" || - config.wifiStartIp == "" || config.wifiEndIp == "" || - config.usbStartIp == "" || config.usbEndIp == "") { - debug("Invalid subnet information."); - return null; - } - - return config; - }, - - getWifiTetheringParametersBySetting: function getWifiTetheringParametersBySetting(enable) { - let ssid; - let securityType; - let securityId; - let interfaceIp; - let prefix; - let wifiDhcpStartIp; - let wifiDhcpEndIp; - let usbDhcpStartIp; - let usbDhcpEndIp; - let dns1; - let dns2; - - ssid = this.tetheringSettings[SETTINGS_WIFI_SSID]; - securityType = this.tetheringSettings[SETTINGS_WIFI_SECURITY_TYPE]; - securityId = this.tetheringSettings[SETTINGS_WIFI_SECURITY_PASSWORD]; - interfaceIp = this.tetheringSettings[SETTINGS_WIFI_IP]; - prefix = this.tetheringSettings[SETTINGS_WIFI_PREFIX]; - wifiDhcpStartIp = this.tetheringSettings[SETTINGS_WIFI_DHCPSERVER_STARTIP]; - wifiDhcpEndIp = this.tetheringSettings[SETTINGS_WIFI_DHCPSERVER_ENDIP]; - usbDhcpStartIp = this.tetheringSettings[SETTINGS_USB_DHCPSERVER_STARTIP]; - usbDhcpEndIp = this.tetheringSettings[SETTINGS_USB_DHCPSERVER_ENDIP]; - dns1 = this.tetheringSettings[SETTINGS_WIFI_DNS1]; - dns2 = this.tetheringSettings[SETTINGS_WIFI_DNS2]; - - // Check the format to prevent netd from crash. - if (!ssid || ssid == "") { - debug("Invalid SSID value."); - return null; - } - // Truncate ssid if its length of encoded to utf8 is longer than 32. - while (unescape(encodeURIComponent(ssid)).length > 32) - { - ssid = ssid.substring(0, ssid.length-1); - } - - if (securityType != WIFI_SECURITY_TYPE_NONE && - securityType != WIFI_SECURITY_TYPE_WPA_PSK && - securityType != WIFI_SECURITY_TYPE_WPA2_PSK) { - - debug("Invalid security type."); - return null; - } - if (securityType != WIFI_SECURITY_TYPE_NONE && !securityId) { - debug("Invalid security password."); - return null; - } - // Using the default values here until application supports these settings. - if (interfaceIp == "" || prefix == "" || - wifiDhcpStartIp == "" || wifiDhcpEndIp == "" || - usbDhcpStartIp == "" || usbDhcpEndIp == "") { - debug("Invalid subnet information."); - return null; - } - - return { - ssid: ssid, - security: securityType, - key: securityId, - ip: interfaceIp, - prefix: prefix, - wifiStartIp: wifiDhcpStartIp, - wifiEndIp: wifiDhcpEndIp, - usbStartIp: usbDhcpStartIp, - usbEndIp: usbDhcpEndIp, - dns1: dns1, - dns2: dns2, - enable: enable, - mode: enable ? WIFI_FIRMWARE_AP : WIFI_FIRMWARE_STATION, - link: enable ? NETWORK_INTERFACE_UP : NETWORK_INTERFACE_DOWN - }; - }, - - setWifiApEnabled: function(enabled, callback) { - let configuration = this.getWifiTetheringParameters(enabled); - - if (!configuration) { - this.requestDone(); - debug("Invalid Wifi Tethering configuration."); - return; - } - - WifiManager.setWifiApEnabled(enabled, configuration, callback); - }, - - associate: function(msg) { - const MAX_PRIORITY = 9999; - const message = "WifiManager:associate:Return"; - let network = msg.data; - - let privnet = network; - let dontConnect = privnet.dontConnect; - delete privnet.dontConnect; - - if (!WifiManager.enabled) { - this._sendMessage(message, false, "Wifi is disabled", msg); - return; - } - - let self = this; - function networkReady() { - // saveConfig now before we disable most of the other networks. - function selectAndConnect() { - WifiManager.enableNetwork(privnet.netId, true, function (ok) { - if (ok) - self._needToEnableNetworks = true; - if (WifiManager.state === "DISCONNECTED" || - WifiManager.state === "SCANNING") { - WifiManager.reconnect(function (ok) { - self._sendMessage(message, ok, ok, msg); - }); - } else { - self._sendMessage(message, ok, ok, msg); - } - }); - } - - var selectAndConnectOrReturn = dontConnect ? - function() { - self._sendMessage(message, true, "Wifi has been recorded", msg); - } : selectAndConnect; - if (self._highestPriority >= MAX_PRIORITY) { - self._reprioritizeNetworks(selectAndConnectOrReturn); - } else { - WifiManager.saveConfig(selectAndConnectOrReturn); - } - } - - function connectToNetwork() { - WifiManager.updateNetwork(privnet, (function(ok) { - if (!ok) { - self._sendMessage(message, false, "Network is misconfigured", msg); - return; - } - - networkReady(); - })); - } - - let ssid = privnet.ssid; - let networkKey = getNetworkKey(privnet); - let configured; - - if (networkKey in this._addingNetworks) { - this._sendMessage(message, false, "Racing associates"); - return; - } - - if (networkKey in this.configuredNetworks) - configured = this.configuredNetworks[networkKey]; - - netFromDOM(privnet, configured); - - privnet.priority = ++this._highestPriority; - if (configured) { - privnet.netId = configured.netId; - // Sync priority back to configured so if priority reaches MAX_PRIORITY, - // it can be sorted correctly in _reprioritizeNetworks() because the - // function sort network based on priority in configure list. - configured.priority = privnet.priority; - - // When investigating Bug 1123680, we observed that gaia may unexpectedly - // request to associate with incorrect password before successfully - // forgetting the network. It would cause the network unable to connect - // subsequently. Aside from preventing the racing forget/associate, we - // also try to disable network prior to updating the network. - WifiManager.getNetworkId(dequote(configured.ssid), function(netId) { - if (netId) { - WifiManager.disableNetwork(netId, function() { - connectToNetwork(); - }); - } - else { - connectToNetwork(); - } - }); - } else { - // networkReady, above, calls saveConfig. We want to remember the new - // network as being enabled, which isn't the default, so we explicitly - // set it to being "enabled" before we add it and save the - // configuration. - privnet.disabled = 0; - this._addingNetworks[networkKey] = privnet; - WifiManager.addNetwork(privnet, (function(ok) { - delete this._addingNetworks[networkKey]; - - if (!ok) { - this._sendMessage(message, false, "Network is misconfigured", msg); - return; - } - - this.configuredNetworks[networkKey] = privnet; - networkReady(); - }).bind(this)); - } - }, - - forget: function(msg) { - const message = "WifiManager:forget:Return"; - let network = msg.data; - if (!WifiManager.enabled) { - this._sendMessage(message, false, "Wifi is disabled", msg); - return; - } - - this._reloadConfiguredNetworks((function(ok) { - // Give it a chance to remove the network even if reload is failed. - if (!ok) { - debug("Warning !!! Failed to reload the configured networks"); - } - - let ssid = network.ssid; - let networkKey = getNetworkKey(network); - if (!(networkKey in this.configuredNetworks)) { - this._sendMessage(message, false, "Trying to forget an unknown network", msg); - return; - } - - let self = this; - let configured = this.configuredNetworks[networkKey]; - this._reconnectOnDisconnect = (this.currentNetwork && - (this.currentNetwork.ssid === ssid)); - WifiManager.removeNetwork(configured.netId, function(ok) { - if (self._needToEnableNetworks) { - self._enableAllNetworks(); - self._needToEnableNetworks = false; - } - - if (!ok) { - self._sendMessage(message, false, "Unable to remove the network", msg); - self._reconnectOnDisconnect = false; - return; - } - - WifiManager.saveConfig(function() { - self._reloadConfiguredNetworks(function() { - self._sendMessage(message, true, true, msg); - }); - }); - }); - }).bind(this)); - }, - - wps: function(msg) { - const message = "WifiManager:wps:Return"; - let self = this; - let detail = msg.data; - - if (!WifiManager.enabled) { - this._sendMessage(message, false, "Wifi is disabled", msg); - return; - } - - if (detail.method === "pbc") { - WifiManager.wpsPbc(function(ok) { - if (ok) - self._sendMessage(message, true, true, msg); - else - self._sendMessage(message, false, "WPS PBC failed", msg); - }); - } else if (detail.method === "pin") { - WifiManager.wpsPin(detail, function(pin) { - if (pin) - self._sendMessage(message, true, pin, msg); - else - self._sendMessage(message, false, "WPS PIN failed", msg); - }); - } else if (detail.method === "cancel") { - WifiManager.wpsCancel(function(ok) { - if (ok) - self._sendMessage(message, true, true, msg); - else - self._sendMessage(message, false, "WPS Cancel failed", msg); - }); - } else { - self._sendMessage(message, false, "Invalid WPS method=" + detail.method, - msg); - } - }, - - setPowerSavingMode: function(msg) { - const message = "WifiManager:setPowerSavingMode:Return"; - let self = this; - let enabled = msg.data; - let mode = enabled ? "AUTO" : "ACTIVE"; - - if (!WifiManager.enabled) { - this._sendMessage(message, false, "Wifi is disabled", msg); - return; - } - - // Some wifi drivers may not implement this command. Set power mode - // even if suspend optimization command failed. - WifiManager.setSuspendOptimizations(enabled, function(ok) { - WifiManager.setPowerMode(mode, function(ok) { - if (ok) { - self._sendMessage(message, true, true, msg); - } else { - self._sendMessage(message, false, "Set power saving mode failed", msg); - } - }); - }); - }, - - setHttpProxy: function(msg) { - const message = "WifiManager:setHttpProxy:Return"; - let self = this; - let network = msg.data.network; - let info = msg.data.info; - - if (!WifiManager.enabled) { - this._sendMessage(message, false, "Wifi is disabled", msg); - return; - } - - WifiManager.configureHttpProxy(network, info, function(ok) { - if (ok) { - // If configured network is current connected network - // need update http proxy immediately. - let setNetworkKey = getNetworkKey(network); - let curNetworkKey = self.currentNetwork ? getNetworkKey(self.currentNetwork) : null; - if (setNetworkKey === curNetworkKey) - WifiManager.setHttpProxy(network); - - self._sendMessage(message, true, true, msg); - } else { - self._sendMessage(message, false, "Set http proxy failed", msg); - } - }); - }, - - setStaticIpMode: function(msg) { - const message = "WifiManager:setStaticIpMode:Return"; - let self = this; - let network = msg.data.network; - let info = msg.data.info; - - if (!WifiManager.enabled) { - this._sendMessage(message, false, "Wifi is disabled", msg); - return; - } - - // To compatiable with DHCP returned info structure, do translation here - info.ipaddr_str = info.ipaddr; - info.proxy_str = info.proxy; - info.gateway_str = info.gateway; - info.dns1_str = info.dns1; - info.dns2_str = info.dns2; - - WifiManager.setStaticIpMode(network, info, function(ok) { - if (ok) { - self._sendMessage(message, true, true, msg); - } else { - self._sendMessage(message, false, "Set static ip mode failed", msg); - } - }); - }, - - importCert: function importCert(msg) { - const message = "WifiManager:importCert:Return"; - let self = this; - - if (!WifiManager.enabled) { - this._sendMessage(message, false, "Wifi is disabled", msg); - return; - } - - WifiManager.importCert(msg.data, function(data) { - if (data.status === 0) { - let usageString = ["ServerCert", "UserCert"]; - let usageArray = []; - for (let i = 0; i < usageString.length; i++) { - if (data.usageFlag & (0x01 << i)) { - usageArray.push(usageString[i]); - } - } - - self._sendMessage(message, true, { - nickname: data.nickname, - usage: usageArray - }, msg); - } else { - self._sendMessage(message, false, "Import Cert failed", msg); - } - }); - }, - - getImportedCerts: function getImportedCerts(msg) { - const message = "WifiManager:getImportedCerts:Return"; - let self = this; - - if (!WifiManager.enabled) { - this._sendMessage(message, false, "Wifi is disabled", msg); - return; - } - - let certDB = Cc["@mozilla.org/security/x509certdb;1"] - .getService(Ci.nsIX509CertDB); - if (!certDB) { - self._sendMessage(message, false, "Failed to query NSS DB service", msg); - } - - let certList = certDB.getCerts(); - if (!certList) { - self._sendMessage(message, false, "Failed to get certificate List", msg); - } - - let certListEnum = certList.getEnumerator(); - if (!certListEnum) { - self._sendMessage(message, false, "Failed to get certificate List enumerator", msg); - } - let importedCerts = { - ServerCert: [], - UserCert: [], - }; - let UsageMapping = { - SERVERCERT: "ServerCert", - USERCERT: "UserCert", - }; - - while (certListEnum.hasMoreElements()) { - let certInfo = certListEnum.getNext().QueryInterface(Ci.nsIX509Cert); - let certNicknameInfo = /WIFI\_([A-Z]*)\_(.*)/.exec(certInfo.nickname); - if (!certNicknameInfo) { - continue; - } - importedCerts[UsageMapping[certNicknameInfo[1]]].push(certNicknameInfo[2]); - } - - self._sendMessage(message, true, importedCerts, msg); - }, - - deleteCert: function deleteCert(msg) { - const message = "WifiManager:deleteCert:Return"; - let self = this; - - if (!WifiManager.enabled) { - this._sendMessage(message, false, "Wifi is disabled", msg); - return; - } - - WifiManager.deleteCert(msg.data, function(data) { - self._sendMessage(message, data.status === 0, "Delete Cert failed", msg); - }); - }, - - // TODO : These two variables should be removed once GAIA uses tethering API. - useTetheringAPI : false, - tetheringConfig : {}, - - setWifiTethering: function setWifiTethering(msg) { - const message = "WifiManager:setWifiTethering:Return"; - let self = this; - let enabled = msg.data.enabled; - - this.useTetheringAPI = true; - this.tetheringConfig = msg.data.config; - - if (WifiManager.enabled) { - this._sendMessage(message, false, "Wifi is enabled", msg); - return; - } - - this.setWifiApEnabled(enabled, function() { - if ((enabled && WifiManager.tetheringState == "COMPLETED") || - (!enabled && WifiManager.tetheringState == "UNINITIALIZED")) { - self._sendMessage(message, true, msg.data, msg); - } else { - msg.data.reason = enabled ? - "Enable WIFI tethering faild" : "Disable WIFI tethering faild"; - self._sendMessage(message, false, msg.data, msg); - } - }); - }, - - // This is a bit ugly, but works. In particular, this depends on the fact - // that RadioManager never actually tries to get the worker from us. - get worker() { throw "Not implemented"; }, - - shutdown: function() { - debug("shutting down ..."); - this.queueRequest({command: "setWifiEnabled", value: false}, function(data) { - this._setWifiEnabled(false, this._setWifiEnabledCallback.bind(this)); - }.bind(this)); - }, - - // TODO: Remove command queue in Bug 1050147. - requestProcessing: false, // Hold while dequeue and execution a request. - // Released upon the request is fully executed, - // i.e, mostly after callback is done. - requestDone: function requestDone() { - this.requestProcessing = false; - this.nextRequest(); - }, - - nextRequest: function nextRequest() { - // No request to process - if (this._stateRequests.length === 0) { - return; - } - - // Handling request, wait for it. - if (this.requestProcessing) { - return; - } - - // Hold processing lock - this.requestProcessing = true; - - // Find next valid request - let request = this._stateRequests.shift(); - - request.callback(request.data); - }, - - notifyTetheringOn: function notifyTetheringOn() { - // It's really sad that we don't have an API to notify the wifi - // hotspot status. Toggle settings to let gaia know that wifi hotspot - // is enabled. - let self = this; - this.tetheringSettings[SETTINGS_WIFI_TETHERING_ENABLED] = true; - this._oldWifiTetheringEnabledState = true; - gSettingsService.createLock().set( - SETTINGS_WIFI_TETHERING_ENABLED, - true, - { - handle: function(aName, aResult) { - self.requestDone(); - }, - handleError: function(aErrorMessage) { - self.requestDone(); - } - }); - }, - - notifyTetheringOff: function notifyTetheringOff() { - // It's really sad that we don't have an API to notify the wifi - // hotspot status. Toggle settings to let gaia know that wifi hotspot - // is disabled. - let self = this; - this.tetheringSettings[SETTINGS_WIFI_TETHERING_ENABLED] = false; - this._oldWifiTetheringEnabledState = false; - gSettingsService.createLock().set( - SETTINGS_WIFI_TETHERING_ENABLED, - false, - { - handle: function(aName, aResult) { - self.requestDone(); - }, - handleError: function(aErrorMessage) { - self.requestDone(); - } - }); - }, - - handleWifiEnabled: function(enabled) { - if (this.ignoreWifiEnabledFromSettings) { - return; - } - - // Make sure Wifi hotspot is idle before switching to Wifi mode. - if (enabled) { - this.queueRequest({command: "setWifiApEnabled", value: false}, function(data) { - if (this.tetheringSettings[SETTINGS_WIFI_TETHERING_ENABLED] || - WifiManager.isWifiTetheringEnabled(WifiManager.tetheringState)) { - this.disconnectedByWifi = true; - this.setWifiApEnabled(false, this.notifyTetheringOff.bind(this)); - } else { - this.requestDone(); - } - }.bind(this)); - } - - this.queueRequest({command: "setWifiEnabled", value: enabled}, function(data) { - this._setWifiEnabled(enabled, this._setWifiEnabledCallback.bind(this)); - }.bind(this)); - - if (!enabled) { - this.queueRequest({command: "setWifiApEnabled", value: true}, function(data) { - if (this.disconnectedByWifi) { - this.setWifiApEnabled(true, this.notifyTetheringOn.bind(this)); - } else { - this.requestDone(); - } - this.disconnectedByWifi = false; - }.bind(this)); - } - }, - - handleWifiTetheringEnabled: function(enabled) { - // Make sure Wifi is idle before switching to Wifi hotspot mode. - if (enabled) { - this.queueRequest({command: "setWifiEnabled", value: false}, function(data) { - if (WifiManager.isWifiEnabled(WifiManager.state)) { - this.disconnectedByWifiTethering = true; - this._setWifiEnabled(false, this._setWifiEnabledCallback.bind(this)); - } else { - this.requestDone(); - } - }.bind(this)); - } - - this.queueRequest({command: "setWifiApEnabled", value: enabled}, function(data) { - this.setWifiApEnabled(enabled, this.requestDone.bind(this)); - }.bind(this)); - - if (!enabled) { - this.queueRequest({command: "setWifiEnabled", value: true}, function(data) { - if (this.disconnectedByWifiTethering) { - this._setWifiEnabled(true, this._setWifiEnabledCallback.bind(this)); - } else { - this.requestDone(); - } - this.disconnectedByWifiTethering = false; - }.bind(this)); - } - }, - - // nsIObserver implementation - observe: function observe(subject, topic, data) { - switch (topic) { - case kMozSettingsChangedObserverTopic: - // To avoid WifiWorker setting the wifi again, don't need to deal with - // the "mozsettings-changed" event fired from internal setting. - if ("wrappedJSObject" in subject) { - subject = subject.wrappedJSObject; - } - if (subject.isInternalChange) { - return; - } - - this.handle(subject.key, subject.value); - break; - - case "xpcom-shutdown": - // Ensure the supplicant is detached from B2G to avoid XPCOM shutdown - // blocks forever. - WifiManager.ensureSupplicantDetached(() => { - let wifiService = Cc["@mozilla.org/wifi/service;1"].getService(Ci.nsIWifiProxyService); - wifiService.shutdown(); - let wifiCertService = Cc["@mozilla.org/wifi/certservice;1"].getService(Ci.nsIWifiCertService); - wifiCertService.shutdown(); - }); - break; - } - }, - - handle: function handle(aName, aResult) { - switch(aName) { - // TODO: Remove function call in Bug 1050147. - case SETTINGS_WIFI_ENABLED: - this.handleWifiEnabled(aResult) - break; - case SETTINGS_WIFI_DEBUG_ENABLED: - if (aResult === null) - aResult = false; - DEBUG = aResult; - updateDebug(); - break; - case SETTINGS_WIFI_TETHERING_ENABLED: - this._oldWifiTetheringEnabledState = this.tetheringSettings[SETTINGS_WIFI_TETHERING_ENABLED]; - // Fall through! - case SETTINGS_WIFI_SSID: - case SETTINGS_WIFI_SECURITY_TYPE: - case SETTINGS_WIFI_SECURITY_PASSWORD: - case SETTINGS_WIFI_IP: - case SETTINGS_WIFI_PREFIX: - case SETTINGS_WIFI_DHCPSERVER_STARTIP: - case SETTINGS_WIFI_DHCPSERVER_ENDIP: - case SETTINGS_WIFI_DNS1: - case SETTINGS_WIFI_DNS2: - case SETTINGS_USB_DHCPSERVER_STARTIP: - case SETTINGS_USB_DHCPSERVER_ENDIP: - // TODO: code related to wifi-tethering setting should be removed after GAIA - // use tethering API - if (this.useTetheringAPI) { - break; - } - - if (aResult !== null) { - this.tetheringSettings[aName] = aResult; - } - debug("'" + aName + "'" + " is now " + this.tetheringSettings[aName]); - let index = this._wifiTetheringSettingsToRead.indexOf(aName); - - if (index != -1) { - this._wifiTetheringSettingsToRead.splice(index, 1); - } - - if (this._wifiTetheringSettingsToRead.length) { - debug("We haven't read completely the wifi Tethering data from settings db."); - break; - } - - if (this._oldWifiTetheringEnabledState === this.tetheringSettings[SETTINGS_WIFI_TETHERING_ENABLED]) { - debug("No changes for SETTINGS_WIFI_TETHERING_ENABLED flag. Nothing to do."); - break; - } - - if (this._oldWifiTetheringEnabledState === null && - !this.tetheringSettings[SETTINGS_WIFI_TETHERING_ENABLED]) { - debug("Do nothing when initial settings for SETTINGS_WIFI_TETHERING_ENABLED flag is false."); - break; - } - - this._oldWifiTetheringEnabledState = this.tetheringSettings[SETTINGS_WIFI_TETHERING_ENABLED]; - this.handleWifiTetheringEnabled(aResult) - break; - }; - }, - - handleError: function handleError(aErrorMessage) { - debug("There was an error while reading Tethering settings."); - this.tetheringSettings = {}; - this.tetheringSettings[SETTINGS_WIFI_TETHERING_ENABLED] = false; - }, -}; - -this.NSGetFactory = XPCOMUtils.generateNSGetFactory([WifiWorker]); - -var debug; -function updateDebug() { - if (DEBUG) { - debug = function (s) { - dump("-*- WifiWorker component: " + s + "\n"); - }; - } else { - debug = function (s) {}; - } - WifiManager.syncDebug(); -} -updateDebug(); diff --git a/dom/wifi/WifiWorker.manifest b/dom/wifi/WifiWorker.manifest deleted file mode 100644 index e33d6401a..000000000 --- a/dom/wifi/WifiWorker.manifest +++ /dev/null @@ -1 +0,0 @@ -component {a14e8977-d259-433a-a88d-58dd44657e5b} WifiWorker.js diff --git a/dom/wifi/moz.build b/dom/wifi/moz.build deleted file mode 100644 index d769c649c..000000000 --- a/dom/wifi/moz.build +++ /dev/null @@ -1,41 +0,0 @@ -# -*- Mode: python; 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/. - -XPIDL_SOURCES += [ - 'nsIWifi.idl', - 'nsIWifiCertService.idl', - 'nsIWifiService.idl', -] - -XPIDL_MODULE = 'dom_wifi' - -EXTRA_COMPONENTS += [ - 'DOMWifiManager.js', - 'DOMWifiManager.manifest', - 'DOMWifiP2pManager.js', - 'DOMWifiP2pManager.manifest', - 'WifiWorker.js', - 'WifiWorker.manifest', -] - -EXTRA_JS_MODULES += [ - 'StateMachine.jsm', - 'WifiCommand.jsm', - 'WifiNetUtil.jsm', - 'WifiP2pManager.jsm', - 'WifiP2pWorkerObserver.jsm', -] - -if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk': - UNIFIED_SOURCES = [ - 'WifiCertService.cpp', - 'WifiHotspotUtils.cpp', - 'WifiProxyService.cpp', - 'WifiUtils.cpp', - ] - DEFINES['CERT_AddTempCertToPerm'] = '__CERT_AddTempCertToPerm' - -FINAL_LIBRARY = 'xul' diff --git a/dom/wifi/nsIWifi.idl b/dom/wifi/nsIWifi.idl deleted file mode 100644 index 82ab9a75b..000000000 --- a/dom/wifi/nsIWifi.idl +++ /dev/null @@ -1,60 +0,0 @@ -/* 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/. */ - -#include "nsISupports.idl" -#include "nsIDOMDOMRequest.idl" -#include "nsIDOMEvent.idl" - -interface nsIVariant; - -[scriptable, uuid(cf1ac02b-1f39-446e-815b-651ac78d2233)] -interface nsIWifiScanResult : nsISupports { - readonly attribute DOMString ssid; - readonly attribute DOMString bssid; - - const int32_t WPA_PSK = 0x01; - const int32_t WPA_EAP = 0x02; - const int32_t WEP = 0x04; - readonly attribute uint32_t capabilities; - - /** - * Strength of the signal to network. - */ - readonly attribute uint32_t signalStrength; - - readonly attribute uint32_t relSignalStrength; - readonly attribute boolean connected; -}; - -[scriptable, uuid(a6931ebf-8493-4014-90e2-99f406999982)] -interface nsIWifiScanResultsReady : nsISupports { - - /** - * Callback with list of networks. - */ - void onready(in uint32_t count, [array, size_is(count)] in nsIWifiScanResult results); - - /** - * Callback if scanning for networks failed after 3 retry attempts. - */ - void onfailure(); -}; - -[scriptable, uuid(08dfefed-5c5d-4468-8c5d-2c65c24692d9)] -interface nsIWifi : nsISupports -{ - /** - * Shutdown the wifi system. - */ - void shutdown(); - - /** - * Returns the list of currently available networks as well as the list of - * currently configured networks. - * - * On success a callback is notified with the list of networks. - * On failure after 3 scan retry attempts a callback is notified of failure. - */ - void getWifiScanResults(in nsIWifiScanResultsReady callback); -}; diff --git a/dom/wifi/nsIWifiCertService.idl b/dom/wifi/nsIWifiCertService.idl deleted file mode 100644 index fce2dd719..000000000 --- a/dom/wifi/nsIWifiCertService.idl +++ /dev/null @@ -1,54 +0,0 @@ -/* 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/. */ - -#include "nsISupports.idl" - -interface nsIDOMBlob; -interface nsIWifiEventListener; - -[scriptable, uuid(5d0edcd3-c2f1-4946-aae5-06adcbdf0992)] -interface nsIWifiCertService : nsISupports -{ - const unsigned short WIFI_CERT_USAGE_FLAG_SERVER = 0x01; - const unsigned short WIFI_CERT_USAGE_FLAG_USER = 0x02; - - void start(in nsIWifiEventListener listener); - void shutdown(); - - /** - * Import a certificate file. - * - * @param id - * Request ID. - * @param certBlob - * A Blob object containing raw data of certificate to be imported. - * @param certPassword - * Password of certificate. - * @param certNickname - * User assigned nickname for imported certificate. - */ - void importCert(in long id, - in nsIDOMBlob certBlob, - in DOMString certPassword, - in DOMString certNickname); - - /** - * Delete an imported certificate file - * - * @param id - * Request ID. - * @param certNickname - * Certificate nickname to delete. - */ - void deleteCert(in long id, - in DOMString certNickname); - - /** - * Check if certificate has private key. - * - * @param certNickname - * Certificate nickname to check for private key. - */ - boolean hasPrivateKey(in DOMString certNickname); -}; diff --git a/dom/wifi/nsIWifiService.idl b/dom/wifi/nsIWifiService.idl deleted file mode 100644 index 0f320ddda..000000000 --- a/dom/wifi/nsIWifiService.idl +++ /dev/null @@ -1,22 +0,0 @@ -/* 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/. */ - -#include "nsISupports.idl" - -[scriptable, uuid(4d4389e0-1547-11e3-8ffd-0800200c9a66)] -interface nsIWifiEventListener : nsISupports { - void onWaitEvent(in AString event, in ACString aInterface); - void onCommand(in jsval result, in ACString aInterface); -}; - -[scriptable, uuid(5e2bd8c0-1547-11e3-8ffd-0800200c9a66)] -interface nsIWifiProxyService : nsISupports { - void start(in nsIWifiEventListener listener, - [array, size_is(aNumOfInterface)] in string aInterfaces, - in unsigned long aNumOfInterface); - void shutdown(); - [implicit_jscontext] - void sendCommand(in jsval parameters, in ACString aInterface); - void waitForEvent(in ACString aInterface); -}; diff --git a/dom/wifi/test/marionette/head.js b/dom/wifi/test/marionette/head.js deleted file mode 100644 index f4a212b11..000000000 --- a/dom/wifi/test/marionette/head.js +++ /dev/null @@ -1,1486 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -// Emulate Promise.jsm semantics. -Promise.defer = function() { return new Deferred(); } -function Deferred() { - this.promise = new Promise(function(resolve, reject) { - this.resolve = resolve; - this.reject = reject; - }.bind(this)); - Object.freeze(this); -} - -const STOCK_HOSTAPD_NAME = 'goldfish-hostapd'; -const HOSTAPD_CONFIG_PATH = '/data/misc/wifi/remote-hostapd/'; - -const SETTINGS_RIL_DATA_ENABLED = 'ril.data.enabled'; -const SETTINGS_TETHERING_WIFI_ENABLED = 'tethering.wifi.enabled'; -const SETTINGS_TETHERING_WIFI_IP = 'tethering.wifi.ip'; -const SETTINGS_TETHERING_WIFI_SECURITY = 'tethering.wifi.security.type'; - -const HOSTAPD_COMMON_CONFIG = { - driver: 'test', - ctrl_interface: '/data/misc/wifi/remote-hostapd', - test_socket: 'DIR:/data/misc/wifi/sockets', - hw_mode: 'b', - channel: '2', -}; - -const HOSTAPD_CONFIG_LIST = [ - { ssid: 'ap0' }, - - { ssid: 'ap1', - wpa: 1, - wpa_pairwise: 'TKIP CCMP', - wpa_passphrase: '12345678' - }, - - { ssid: 'ap2', - wpa: 2, - rsn_pairwise: 'CCMP', - wpa_passphrase: '12345678', - }, -]; - -var gTestSuite = (function() { - let suite = {}; - - // Private member variables of the returned object |suite|. - let wifiManager; - let wifiOrigEnabled; - let pendingEmulatorShellCount = 0; - let sdkVersion; - - /** - * A wrapper function of "is". - * - * Calls the marionette function "is" as well as throws an exception - * if the givens values are not equal. - * - * @param value1 - * Any type of value to compare. - * - * @param value2 - * Any type of value to compare. - * - * @param message - * Debug message for this check. - * - */ - function isOrThrow(value1, value2, message) { - is(value1, value2, message); - if (value1 !== value2) { - throw message; - } - } - - /** - * Send emulator shell command with safe guard. - * - * We should only call |finish()| after all emulator command transactions - * end, so here comes with the pending counter. Resolve when the emulator - * gives positive response, and reject otherwise. - * - * Fulfill params: - * result -- an array of emulator response lines. - * Reject params: - * result -- an array of emulator response lines. - * - * @param aCommand - * A string command to be passed to emulator through its telnet console. - * - * @return A deferred promise. - */ - function runEmulatorShellSafe(aCommand) { - let deferred = Promise.defer(); - - ++pendingEmulatorShellCount; - runEmulatorShell(aCommand, function(aResult) { - --pendingEmulatorShellCount; - - ok(true, "Emulator shell response: " + JSON.stringify(aResult)); - if (Array.isArray(aResult)) { - deferred.resolve(aResult); - } else { - deferred.reject(aResult); - } - }); - - return deferred.promise; - } - - /** - * Wait for one named MozWifiManager event. - * - * Resolve if that named event occurs. Never reject. - * - * Fulfill params: the DOMEvent passed. - * - * @param aEventName - * A string event name. - * - * @return A deferred promise. - */ - function waitForWifiManagerEventOnce(aEventName) { - let deferred = Promise.defer(); - - wifiManager.addEventListener(aEventName, function onevent(aEvent) { - wifiManager.removeEventListener(aEventName, onevent); - - ok(true, "WifiManager event '" + aEventName + "' got."); - deferred.resolve(aEvent); - }); - - return deferred.promise; - } - - /** - * Wait for one named MozMobileConnection event. - * - * Resolve if that named event occurs. Never reject. - * - * Fulfill params: the DOMEvent passed. - * - * @param aEventName - * A string event name. - * - * @return A deferred promise. - */ - function waitForMobileConnectionEventOnce(aEventName, aServiceId) { - aServiceId = aServiceId || 0; - - let deferred = Promise.defer(); - let mobileconnection = navigator.mozMobileConnections[aServiceId]; - - mobileconnection.addEventListener(aEventName, function onevent(aEvent) { - mobileconnection.removeEventListener(aEventName, onevent); - - ok(true, "Mobile connection event '" + aEventName + "' got."); - deferred.resolve(aEvent); - }); - - return deferred.promise; - } - - /** - * Get the detail of currently running processes containing the given name. - * - * Use shell command 'ps' to get the desired process's detail. Never reject. - * - * Fulfill params: - * result -- an array of { pname, pid } - * - * @param aProcessName - * The process to get the detail. - * - * @return A deferred promise. - */ - function getProcessDetail(aProcessName) { - return runEmulatorShellSafe(['ps']) - .then(processes => { - // Sample 'ps' output: - // - // USER PID PPID VSIZE RSS WCHAN PC NAME - // root 1 0 284 204 c009e6c4 0000deb4 S /init - // root 2 0 0 0 c0052c64 00000000 S kthreadd - // root 3 2 0 0 c0044978 00000000 S ksoftirqd/0 - // - let detail = []; - - processes.shift(); // Skip the first line. - for (let i = 0; i < processes.length; i++) { - let tokens = processes[i].split(/\s+/); - let pname = tokens[tokens.length - 1]; - let pid = tokens[1]; - if (-1 !== pname.indexOf(aProcessName)) { - detail.push({ pname: pname, pid: pid }); - } - } - - return detail; - }); - } - - /** - * Add required permissions for wifi testing. Never reject. - * - * The permissions required for wifi testing are 'wifi-manage' and 'settings-write'. - * Never reject. - * - * Fulfill params: (none) - * - * @return A deferred promise. - */ - function addRequiredPermissions() { - let deferred = Promise.defer(); - - let permissions = [{ 'type': 'wifi-manage', 'allow': 1, 'context': window.document }, - { 'type': 'settings-write', 'allow': 1, 'context': window.document }, - { 'type': 'settings-read', 'allow': 1, 'context': window.document }, - { 'type': 'settings-api-write', 'allow': 1, 'context': window.document }, - { 'type': 'settings-api-read', 'allow': 1, 'context': window.document }, - { 'type': 'mobileconnection', 'allow': 1, 'context': window.document }]; - - SpecialPowers.pushPermissions(permissions, function() { - deferred.resolve(); - }); - - return deferred.promise; - } - - /** - * Wrap DOMRequest onsuccess/onerror events to Promise resolve/reject. - * - * Fulfill params: A DOMEvent. - * Reject params: A DOMEvent. - * - * @param aRequest - * A DOMRequest instance. - * - * @return A deferred promise. - */ - function wrapDomRequestAsPromise(aRequest) { - let deferred = Promise.defer(); - - ok(aRequest instanceof DOMRequest, - "aRequest is instanceof " + aRequest.constructor); - - aRequest.addEventListener("success", function(aEvent) { - deferred.resolve(aEvent); - }); - aRequest.addEventListener("error", function(aEvent) { - deferred.reject(aEvent); - }); - - return deferred.promise; - } - - /** - * Ensure wifi is enabled/disabled. - * - * Issue a wifi enable/disable request if wifi is not in the desired state; - * return a resolved promise otherwise. Note that you cannot rely on this - * function to test the correctness of enabling/disabling wifi. - * (use requestWifiEnabled instead) - * - * Fulfill params: (none) - * Reject params: (none) - * - * @return a resolved promise or deferred promise. - */ - function ensureWifiEnabled(aEnabled, useAPI) { - if (wifiManager.enabled === aEnabled) { - log('Already ' + (aEnabled ? 'enabled' : 'disabled')); - return Promise.resolve(); - } - return requestWifiEnabled(aEnabled, useAPI); - } - - /** - * Issue a request to enable/disable wifi. - * - * This function will attempt to enable/disable wifi, by calling API or by - * writing settings 'wifi.enabled' regardless of the wifi state, based on the - * value of |userAPI| parameter. - * Default is using settings. - * - * Note there's a limitation of co-existance of both method, per bug 930355, - * that once enable/disable wifi by API, the settings method won't work until - * reboot. So the test of wifi enable API should be executed last. - * TODO: Remove settings method after enable/disable wifi by settings is - * removed after bug 1050147. - * - * Fulfill params: (none) - * Reject params: (none) - * - * @return A deferred promise. - */ - function requestWifiEnabled(aEnabled, useAPI) { - return Promise.all([ - waitForWifiManagerEventOnce(aEnabled ? 'enabled' : 'disabled'), - useAPI ? - wrapDomRequestAsPromise(wifiManager.setWifiEnabled(aEnabled)) : - setSettings({ 'wifi.enabled': aEnabled }), - ]); - } - - /** - * Wait for RIL data being connected. - * - * This function will check |MozMobileConnection.data.connected| on - * every 'datachange' event. Resolve when |MozMobileConnection.data.connected| - * becomes the expected state. Never reject. - * - * Fulfill params: (none) - * Reject params: (none) - * - * @param aConnected - * Boolean that indicates the desired data state. - * - * @param aServiceId [optional] - * A numeric DSDS service id. Default: 0. - * - * @return A deferred promise. - */ - function waitForRilDataConnected(aConnected, aServiceId) { - aServiceId = aServiceId || 0; - return waitForMobileConnectionEventOnce('datachange', aServiceId) - .then(function () { - let mobileconnection = navigator.mozMobileConnections[aServiceId]; - if (mobileconnection.data.connected !== aConnected) { - return waitForRilDataConnected(aConnected, aServiceId); - } - }); - } - - /** - * Request to enable/disable wifi tethering. - * - * Enable/disable wifi tethering by changing the settings value 'tethering.wifi.enabled'. - * Resolve when the routing is verified to set up successfully in 20 seconds. The polling - * period is 1 second. - * - * Fulfill params: (none) - * Reject params: The error message. - * - * @param aEnabled - * Boolean that indicates to enable or disable wifi tethering. - * - * @return A deferred promise. - */ - function requestTetheringEnabled(aEnabled) { - let RETRY_INTERVAL_MS = 1000; - let retryCnt = 20; - - return setSettings1(SETTINGS_TETHERING_WIFI_ENABLED, aEnabled) - .then(function waitForRoutingVerified() { - return verifyTetheringRouting(aEnabled) - .then(null, function onreject(aReason) { - - log('verifyTetheringRouting rejected due to ' + aReason + - ' (' + retryCnt + ')'); - - if (!retryCnt--) { - throw aReason; - } - - return waitForTimeout(RETRY_INTERVAL_MS).then(waitForRoutingVerified); - }); - }); - } - - /** - * Forget the given network. - * - * Resolve when we successfully forget the given network; reject when any error - * occurs. - * - * Fulfill params: (none) - * Reject params: (none) - * - * @param aNetwork - * An object of MozWifiNetwork. - * - * @return A deferred promise. - */ - function forgetNetwork(aNetwork) { - let request = wifiManager.forget(aNetwork); - return wrapDomRequestAsPromise(request) - .then(event => event.target.result); - } - - /** - * Forget all known networks. - * - * Resolve when we successfully forget all the known network; - * reject when any error occurs. - * - * Fulfill params: (none) - * Reject params: (none) - * - * @return A deferred promise. - */ - function forgetAllKnownNetworks() { - - function createForgetNetworkChain(aNetworks) { - let chain = Promise.resolve(); - - aNetworks.forEach(function (aNetwork) { - chain = chain.then(() => forgetNetwork(aNetwork)); - }); - - return chain; - } - - return getKnownNetworks() - .then(networks => createForgetNetworkChain(networks)); - } - - /** - * Get all known networks. - * - * Resolve when we get all the known networks; reject when any error - * occurs. - * - * Fulfill params: An array of MozWifiNetwork - * Reject params: (none) - * - * @return A deferred promise. - */ - function getKnownNetworks() { - let request = wifiManager.getKnownNetworks(); - return wrapDomRequestAsPromise(request) - .then(event => event.target.result); - } - - /** - * Set the given network to static ip mode. - * - * Resolve when we set static ip mode successfully; reject when any error - * occurs. - * - * Fulfill params: (none) - * Reject params: (none) - * - * @return A deferred promise. - */ - function setStaticIpMode(aNetwork, aConfig) { - let request = wifiManager.setStaticIpMode(aNetwork, aConfig); - return wrapDomRequestAsPromise(request) - .then(event => event.target.result); - } - - /** - * Issue a request to scan all wifi available networks. - * - * Resolve when we get the scan result; reject when any error - * occurs. - * - * Fulfill params: An array of MozWifiNetwork - * Reject params: (none) - * - * @return A deferred promise. - */ - function requestWifiScan() { - let request = wifiManager.getNetworks(); - return wrapDomRequestAsPromise(request) - .then(event => event.target.result); - } - - /** - * Import a certificate with nickname and password. - * - * Resolve when we import certificate successfully; reject when any error - * occurs. - * - * Fulfill params: An object of certificate information. - * Reject params: (none) - * - * @return A deferred promise. - */ - function importCert(certBlob, password, nickname) { - let request = wifiManager.importCert(certBlob, password, nickname); - return wrapDomRequestAsPromise(request) - .then(event => event.target.result); - } - - /** - * Delete certificate of nickname. - * - * Resolve when we delete certificate successfully; reject when any error - * occurs. - * - * Fulfill params: (none) - * Reject params: (none) - * - * @return A deferred promise. - */ - function deleteCert(nickname) { - let request = wifiManager.deleteCert(nickname); - return wrapDomRequestAsPromise(request) - .then(event => event.target.result); - } - - /** - * Get list of imported certificates. - * - * Resolve when we get certificate list successfully; reject when any error - * occurs. - * - * Fulfill params: Nickname of imported certificate arranged by usage. - * Reject params: (none) - * - * @return A deferred promise. - */ - function getImportedCerts() { - let request = wifiManager.getImportedCerts(); - return wrapDomRequestAsPromise(request) - .then(event => event.target.result); - } - - /** - * Request wifi scan and verify the scan result as well. - * - * Issue a wifi scan request and check if the result is expected. - * Since the old APs may be cached and the newly added APs may be - * still not scan-able, a couple of attempts are acceptable. - * Resolve if we eventually get the expected scan result; reject otherwise. - * - * Fulfill params: The scan result, which is an array of MozWifiNetwork - * Reject params: (none) - * - * @param aRetryCnt - * The maxmimum number of attempts until we get the expected scan result. - * @param aExpectedNetworks - * An array of object, each of which contains at least the |ssid| property. - * - * @return A deferred promise. - */ - function testWifiScanWithRetry(aRetryCnt, aExpectedNetworks) { - - // Check if every single ssid of each |aScanResult| exists in |aExpectedNetworks| - // as well as the length of |aScanResult| equals to |aExpectedNetworks|. - function isScanResultExpected(aScanResult) { - if (aScanResult.length !== aExpectedNetworks.length) { - return false; - } - - for (let i = 0; i < aScanResult.length; i++) { - if (-1 === getFirstIndexBySsid(aScanResult[i].ssid, aExpectedNetworks)) { - return false; - } - } - return true; - } - - return requestWifiScan() - .then(function (networks) { - if (isScanResultExpected(networks, aExpectedNetworks)) { - return networks; - } - if (aRetryCnt > 0) { - return testWifiScanWithRetry(aRetryCnt - 1, aExpectedNetworks); - } - throw 'Unexpected scan result!'; - }); - } - - /** - * Test wifi association. - * - * Associate with the given network object which is obtained by - * MozWifiManager.getNetworks() (i.e. MozWifiNetwork). - * Resolve when the 'connected' status change event is received. - * Note that we might see other events like 'connecting' - * before 'connected'. So we need to call |waitForWifiManagerEventOnce| - * again whenever non 'connected' event is seen. Never reject. - * - * Fulfill params: (none) - * - * @param aNetwork - * An object of MozWifiNetwork. - * - * @return A deferred promise. - */ - function testAssociate(aNetwork) { - setPasswordIfNeeded(aNetwork); - - let promises = []; - - // Register the event listerner to wait for 'connected' event first - // to avoid racing issue. - promises.push(waitForConnected(aNetwork)); - - // Then we do the association. - let request = wifiManager.associate(aNetwork); - promises.push(wrapDomRequestAsPromise(request)); - - return Promise.all(promises); - } - - function waitForConnected(aExpectedNetwork) { - return waitForWifiManagerEventOnce('statuschange') - .then(function onstatuschange(event) { - log("event.status: " + event.status); - log("event.network.ssid: " + (event.network ? event.network.ssid : '')); - - if ("connected" === event.status && - event.network.ssid === aExpectedNetwork.ssid) { - return; // Got expected 'connected' event from aNetwork.ssid. - } - - log('Not expected "connected" statuschange event. Wait again!'); - return waitForConnected(aExpectedNetwork); - }); - } - - /** - * Set the password for associating the given network if needed. - * - * Set the password by looking up HOSTAPD_CONFIG_LIST. This function - * will also set |keyManagement| properly. - * - * @param aNetwork - * The MozWifiNetwork object. - */ - function setPasswordIfNeeded(aNetwork) { - let i = getFirstIndexBySsid(aNetwork.ssid, HOSTAPD_CONFIG_LIST); - if (-1 === i) { - log('unknown ssid: ' + aNetwork.ssid); - return; // Unknown network. Assume insecure. - } - - if (!aNetwork.security.length) { - return; // No need to set password. - } - - let security = aNetwork.security[0]; - if (/PSK$/.test(security)) { - aNetwork.psk = HOSTAPD_CONFIG_LIST[i].wpa_passphrase; - aNetwork.keyManagement = 'WPA-PSK'; - } else if (/WEP$/.test(security)) { - aNetwork.wep = HOSTAPD_CONFIG_LIST[i].wpa_passphrase; - aNetwork.keyManagement = 'WEP'; - } - } - - /** - * Set mozSettings values. - * - * Resolve if that mozSettings value is set successfully, reject otherwise. - * - * Fulfill params: (none) - * Reject params: (none) - * - * @param aSettings - * An object of format |{key1: value1, key2: value2, ...}|. - * @param aAllowError [optional] - * A boolean value. If set to true, an error response won't be treated - * as test failure. Default: false. - * - * @return A deferred promise. - */ - function setSettings(aSettings) { - let lock = window.navigator.mozSettings.createLock(); - let request = lock.set(aSettings); - let deferred = Promise.defer(); - lock.onsettingstransactionsuccess = function () { - ok(true, "setSettings(" + JSON.stringify(aSettings) + ")"); - deferred.resolve(); - }; - lock.onsettingstransactionfailure = function (aEvent) { - ok(false, "setSettings(" + JSON.stringify(aSettings) + ")"); - deferred.reject(); - throw aEvent.target.error; - }; - return deferred.promise; - } - - /** - * Set mozSettings value with only one key. - * - * Resolve if that mozSettings value is set successfully, reject otherwise. - * - * Fulfill params: (none) - * Reject params: (none) - * - * @param aKey - * A string key. - * @param aValue - * An object value. - * @param aAllowError [optional] - * A boolean value. If set to true, an error response won't be treated - * as test failure. Default: false. - * - * @return A deferred promise. - */ - function setSettings1(aKey, aValue, aAllowError) { - let settings = {}; - settings[aKey] = aValue; - return setSettings(settings, aAllowError); - } - - /** - * Get mozSettings value specified by @aKey. - * - * Resolve if that mozSettings value is retrieved successfully, reject - * otherwise. - * - * Fulfill params: - * The corresponding mozSettings value of the key. - * Reject params: (none) - * - * @param aKey - * A string. - * @param aAllowError [optional] - * A boolean value. If set to true, an error response won't be treated - * as test failure. Default: false. - * - * @return A deferred promise. - */ - function getSettings(aKey, aAllowError) { - let request = - navigator.mozSettings.createLock().get(aKey); - return wrapDomRequestAsPromise(request) - .then(function resolve(aEvent) { - ok(true, "getSettings(" + aKey + ") - success"); - return aEvent.target.result[aKey]; - }, function reject(aEvent) { - ok(aAllowError, "getSettings(" + aKey + ") - error"); - }); - } - - - /** - * Start hostapd processes with given configuration list. - * - * For starting one hostapd, we need to generate a specific config file - * then launch a hostapd process with the confg file path passed. The - * config file is generated by two sources: one is the common - * part (HOSTAPD_COMMON_CONFIG) and the other is from the given |aConfigList|. - * Resolve when all the hostpads are requested to start. It is not guaranteed - * that all the hostapds will be up and running successfully. Never reject. - * - * Fulfill params: (none) - * - * @param aConfigList - * An array of config objects, each property in which will be - * output to the confg file with the format: [key]=[value] in one line. - * See http://hostap.epitest.fi/cgit/hostap/plain/hostapd/hostapd.conf - * for more information. - * - * @return A deferred promise. - */ - function startHostapds(aConfigList) { - - function createConfigFromCommon(aIndex) { - // Create an copy of HOSTAPD_COMMON_CONFIG. - let config = JSON.parse(JSON.stringify(HOSTAPD_COMMON_CONFIG)); - - // Add user config. - for (let key in aConfigList[aIndex]) { - config[key] = aConfigList[aIndex][key]; - } - - // 'interface' is a required field but no need of being configurable - // for a test case. So we initialize this field on our own. - config.interface = 'AP-' + aIndex; - - return config; - } - - function startOneHostapd(aIndex) { - let configFileName = HOSTAPD_CONFIG_PATH + 'ap' + aIndex + '.conf'; - return writeHostapdConfFile(configFileName, createConfigFromCommon(aIndex)) - .then(() => runEmulatorShellSafe(['hostapd', '-B', configFileName])) - .then(function (reply) { - // It may fail at the first time due to the previous ungracefully terminated one. - if (reply.length === 0) { - // The hostapd starts successfully - return; - } - - if (reply[0].indexOf('bind(PF_UNIX): Address already in use') !== -1) { - return startOneHostapd(aIndex); - } - }); - } - - return Promise.all(aConfigList.map(function(aConfig, aIndex) { - return startOneHostapd(aIndex); - })); - } - - /** - * Kill all the running hostapd processes. - * - * Use shell command 'kill -9' to kill all hostapds. Never reject. - * - * Fulfill params: (none) - * - * @return A deferred promise. - */ - function killAllHostapd() { - return getProcessDetail('hostapd') - .then(function (runningHostapds) { - let promises = runningHostapds.map(runningHostapd => { - return runEmulatorShellSafe(['kill', '-9', runningHostapd.pid]); - }); - return Promise.all(promises); - }); - } - - /** - * Write out the config file to the given path. - * - * For each key/value pair in |aConfig|, - * - * [key]=[value] - * - * will be output to one new line. Never reject. - * - * Fulfill params: (none) - * - * @param aFilePath - * The file path that we desire the config file to be located. - * - * @param aConfig - * The config object. - * - * @return A deferred promise. - */ - function writeHostapdConfFile(aFilePath, aConfig) { - let content = ''; - for (let key in aConfig) { - if (aConfig.hasOwnProperty(key)) { - content += (key + '=' + aConfig[key] + '\n'); - } - } - return writeFile(aFilePath, content); - } - - /** - * Write file to the given path filled with given content. - * - * For now it is implemented by shell command 'echo'. Also, if the - * content contains whitespace, we need to quote the content to - * avoid error. Never reject. - * - * Fulfill params: (none) - * - * @param aFilePath - * The file path that we desire the file to be located. - * - * @param aContent - * The content as string which should be written to the file. - * - * @return A deferred promise. - */ - function writeFile(aFilePath, aContent) { - const CONTENT_MAX_LENGTH = 900; - var commands = []; - for (var i = 0; i < aContent.length; i += CONTENT_MAX_LENGTH) { - var content = aContent.substr(i, CONTENT_MAX_LENGTH); - if (-1 === content.indexOf(' ')) { - content = '"' + content + '"'; - } - commands.push(['echo', '-n', content, i === 0 ? '>' : '>>', aFilePath]); - } - - let chain = Promise.resolve(); - commands.forEach(function (command) { - chain = chain.then(() => runEmulatorShellSafe(command)); - }); - return chain; - } - - /** - * Check if a init service is running or not. - * - * Check the android property 'init.svc.[aServiceName]' to determine if - * a init service is running. Reject if the propery is neither 'running' - * nor 'stopped'. - * - * Fulfill params: - * result -- |true| if the init service is running; |false| otherwise. - * Reject params: (none) - * - * @param aServiceName - * The init service name. - * - * @return A deferred promise. - */ - function isInitServiceRunning(aServiceName) { - return runEmulatorShellSafe(['getprop', 'init.svc.' + aServiceName]) - .then(function (result) { - if ('running' !== result[0] && 'stopped' !== result[0]) { - throw 'Init service running state should be "running" or "stopped".'; - } - return 'running' === result[0]; - }); - } - - /** - * Wait for timeout. - * - * Resolve when the given duration elapsed. Never reject. - * - * Fulfill params: (none) - * - * @param aTimeoutMs - * The duration after which the timeout event should occurs. - * - * @return A deferred promise. - */ - function waitForTimeout(aTimeoutMs) { - let deferred = Promise.defer(); - - setTimeout(function() { - deferred.resolve(); - }, aTimeoutMs); - - return deferred.promise; - } - - /** - * Start or stop an init service. - * - * Use shell command 'start'/'stop' to start/stop an init service. - * The running state will also be checked after we start/stop the service. - * Resolve if the service is successfully started/stopped; Reject otherwise. - * - * Fulfill params: (none) - * Reject params: (none) - * - * @param aServiceName - * The name of the service we want to start/stop. - * - * @param aStart - * |true| for starting the init service. |false| for stopping. - * - * @return A deferred promise. - */ - function startStopInitService(aServiceName, aStart) { - let retryCnt = 5; - - return runEmulatorShellSafe([aStart ? 'start' : 'stop', aServiceName]) - .then(() => isInitServiceRunning(aServiceName)) - .then(function onIsServiceRunningResolved(aIsRunning) { - if (aStart === aIsRunning) { - return; - } - - if (retryCnt-- > 0) { - log('Failed to ' + (aStart ? 'start ' : 'stop ') + aServiceName + - '. Retry: ' + retryCnt); - - return waitForTimeout(500) - .then(() => isInitServiceRunning(aServiceName)) - .then(onIsServiceRunningResolved); - } - - throw 'Failed to ' + (aStart ? 'start' : 'stop') + ' ' + aServiceName; - }); - } - - /** - * Start the stock hostapd. - * - * Since the stock hostapd is an init service, use |startStopInitService| to - * start it. Note that we might fail to start the stock hostapd at the first time - * for unknown reason so give it the second chance to start again. - * Resolve when we are eventually successful to start the stock hostapd; Reject - * otherwise. - * - * Fulfill params: (none) - * Reject params: (none) - * - * @return A deferred promise. - */ - function startStockHostapd() { - return startStopInitService(STOCK_HOSTAPD_NAME, true) - .then(null, function onreject() { - log('Failed to restart goldfish-hostapd at the first time. Try again!'); - return startStopInitService((STOCK_HOSTAPD_NAME), true); - }); - } - - /** - * Stop the stock hostapd. - * - * Since the stock hostapd is an init service, use |startStopInitService| to - * stop it. - * - * Fulfill params: (none) - * Reject params: (none) - * - * @return A deferred promise. - */ - function stopStockHostapd() { - return startStopInitService(STOCK_HOSTAPD_NAME, false); - } - - /** - * Get the index of the first matching entry by |ssid|. - * - * Find the index of the first entry of |aArray| which property |ssid| - * is same as |aSsid|. - * - * @param aSsid - * The ssid that we want to match. - * @param aArray - * An array of objects, each of which should have the property |ssid|. - * - * @return The 0-based index of first matching entry if found; -1 otherwise. - */ - function getFirstIndexBySsid(aSsid, aArray) { - for (let i = 0; i < aArray.length; i++) { - if (aArray[i].ssid === aSsid) { - return i; - } - } - return -1; - } - - /** - * Count the number of running process and verify if the count is expected. - * - * Return a promise that resolves when the process has expected number - * of running instances and rejects otherwise. - * - * Fulfill params: (none) - * Reject params: (none) - * - * @param aOrigWifiEnabled - * Boolean which indicates wifi was originally enabled. - * - * @return A deferred promise. - */ - function verifyNumOfProcesses(aProcessName, aExpectedNum) { - return getProcessDetail(aProcessName) - .then(function (detail) { - if (detail.length === aExpectedNum) { - return; - } - throw 'Unexpected number of running processes:' + aProcessName + - ', expected: ' + aExpectedNum + ', actual: ' + detail.length; - }); - } - - /** - * Execute 'netcfg' shell and parse the result. - * - * Resolve when the executing is successful and reject otherwise. - * - * Fulfill params: Command result object, each key of which is the interface - * name and value is { ip(string), prefix(string) }. - * Reject params: String that indicates the reason of rejection. - * - * @return A deferred promise. - */ - function exeAndParseNetcfg() { - return runEmulatorShellSafe(['netcfg']) - .then(function (aLines) { - // Sample output: - // - // lo UP 127.0.0.1/8 0x00000049 00:00:00:00:00:00 - // eth0 UP 10.0.2.15/24 0x00001043 52:54:00:12:34:56 - // rmnet1 DOWN 0.0.0.0/0 0x00001002 52:54:00:12:34:58 - // rmnet2 DOWN 0.0.0.0/0 0x00001002 52:54:00:12:34:59 - // rmnet3 DOWN 0.0.0.0/0 0x00001002 52:54:00:12:34:5a - // wlan0 UP 192.168.1.1/24 0x00001043 52:54:00:12:34:5b - // sit0 DOWN 0.0.0.0/0 0x00000080 00:00:00:00:00:00 - // rmnet0 UP 10.0.2.100/24 0x00001043 52:54:00:12:34:57 - // - let netcfgResult = {}; - aLines.forEach(function (aLine) { - let tokens = aLine.split(/\s+/); - if (tokens.length < 5) { - return; - } - let ifname = tokens[0]; - let [ip, prefix] = tokens[2].split('/'); - netcfgResult[ifname] = { ip: ip, prefix: prefix }; - }); - log("netcfg result:" + JSON.stringify(netcfgResult)); - - return netcfgResult; - }); - } - - /** - * Execute 'ip route' and parse the result. - * - * Resolve when the executing is successful and reject otherwise. - * - * Fulfill params: Command result object, each key of which is the interface - * name and value is { src(string), gateway(string), - * default(boolean) }. - * Reject params: String that indicates the reason of rejection. - * - * @return A deferred promise. - */ - function exeAndParseIpRoute() { - return runEmulatorShellSafe(['ip', 'route']) - .then(function (aLines) { - // Sample output: - // - // 10.0.2.4 via 10.0.2.2 dev rmnet0 - // 10.0.2.3 via 10.0.2.2 dev rmnet0 - // 192.168.1.0/24 dev wlan0 proto kernel scope link src 192.168.1.1 - // 10.0.2.0/24 dev eth0 proto kernel scope link src 10.0.2.15 - // 10.0.2.0/24 dev rmnet0 proto kernel scope link src 10.0.2.100 - // default via 10.0.2.2 dev rmnet0 - // default via 10.0.2.2 dev eth0 metric 2 - // - - let ipRouteResult = {}; - - // Parse source ip for each interface. - aLines.forEach(function (aLine) { - let tokens = aLine.trim().split(/\s+/); - let srcIndex = tokens.indexOf('src'); - if (srcIndex < 0 || srcIndex + 1 >= tokens.length) { - return; - } - let ifname = tokens[2]; - let src = tokens[srcIndex + 1]; - ipRouteResult[ifname] = { src: src, default: false, gateway: null }; - }); - - // Parse default interfaces. - aLines.forEach(function (aLine) { - let tokens = aLine.split(/\s+/); - if (tokens.length < 2) { - return; - } - if ('default' === tokens[0]) { - let ifnameIndex = tokens.indexOf('dev'); - if (ifnameIndex < 0 || ifnameIndex + 1 >= tokens.length) { - return; - } - let ifname = tokens[ifnameIndex + 1]; - if (!ipRouteResult[ifname]) { - return; - } - ipRouteResult[ifname].default = true; - let gwIndex = tokens.indexOf('via'); - if (gwIndex < 0 || gwIndex + 1 >= tokens.length) { - return; - } - ipRouteResult[ifname].gateway = tokens[gwIndex + 1]; - return; - } - }); - log("ip route result:" + JSON.stringify(ipRouteResult)); - - return ipRouteResult; - }); - } - - /** - * Verify everything about routing when the wifi tethering is either on or off. - * - * We use two unix commands to verify the routing: 'netcfg' and 'ip route'. - * For now the following two things will be checked: - * 1) The default route interface should be 'rmnet0'. - * 2) wlan0 is up and its ip is set to a private subnet. - * - * We also verify iptables output as netd's NatController will execute - * $ iptables -t nat -A POSTROUTING -o rmnet0 -j MASQUERADE - * - * Resolve when the verification is successful and reject otherwise. - * - * Fulfill params: (none) - * Reject params: String that indicates the reason of rejection. - * - * @return A deferred promise. - */ - function verifyTetheringRouting(aEnabled) { - let netcfgResult; - let ipRouteResult; - - // Find MASQUERADE in POSTROUTING section. 'MASQUERADE' should be found - // when tethering is enabled. 'MASQUERADE' shouldn't be found when tethering - // is disabled. - function verifyIptables() { - let MASQUERADE_checkSection = 'POSTROUTING'; - if (sdkVersion > 15) { - // Check 'natctrl_nat_POSTROUTING' section after ICS. - MASQUERADE_checkSection = 'natctrl_nat_POSTROUTING'; - } - - return runEmulatorShellSafe(['iptables', '-t', 'nat', '-L', MASQUERADE_checkSection]) - .then(function(aLines) { - // $ iptables -t nat -L POSTROUTING - // - // Sample output (tethering on): - // - // Chain POSTROUTING (policy ACCEPT) - // target prot opt source destination - // MASQUERADE all -- anywhere anywhere - // - let found = (function find_MASQUERADE() { - // Skip first two lines. - for (let i = 2; i < aLines.length; i++) { - if (-1 !== aLines[i].indexOf('MASQUERADE')) { - return true; - } - } - return false; - })(); - - if ((aEnabled && !found) || (!aEnabled && found)) { - throw 'MASQUERADE' + (found ? '' : ' not') + ' found while tethering is ' + - (aEnabled ? 'enabled' : 'disabled'); - } - }); - } - - function verifyDefaultRouteAndIp(aExpectedWifiTetheringIp) { - if (aEnabled) { - isOrThrow(ipRouteResult['rmnet0'].src, netcfgResult['rmnet0'].ip, 'rmnet0.ip'); - isOrThrow(ipRouteResult['rmnet0'].default, true, 'rmnet0.default'); - - isOrThrow(ipRouteResult['wlan0'].src, netcfgResult['wlan0'].ip, 'wlan0.ip'); - isOrThrow(ipRouteResult['wlan0'].src, aExpectedWifiTetheringIp, 'expected ip'); - isOrThrow(ipRouteResult['wlan0'].default, false, 'wlan0.default'); - } - } - - return verifyIptables() - .then(exeAndParseNetcfg) - .then((aResult) => { netcfgResult = aResult; }) - .then(exeAndParseIpRoute) - .then((aResult) => { ipRouteResult = aResult; }) - .then(() => getSettings(SETTINGS_TETHERING_WIFI_IP)) - .then(ip => verifyDefaultRouteAndIp(ip)); - } - - /** - * Clean up all the allocated resources and running services for the test. - * - * After the test no matter success or failure, we should - * 1) Restore to the wifi original state (enabled or disabled) - * 2) Wait until all pending emulator shell commands are done. - * - * |finsih| will be called in the end. - * - * Fulfill params: (none) - * Reject params: (none) - * - * @return A deferred promise. - */ - function cleanUp() { - waitFor(function() { - return ensureWifiEnabled(true) - .then(forgetAllKnownNetworks) - .then(() => ensureWifiEnabled(wifiOrigEnabled)) - .then(finish); - }, function() { - return pendingEmulatorShellCount === 0; - }); - } - - /** - * Init the test environment. - * - * Mainly add the required permissions and initialize the wifiManager - * and the orignal state of wifi. Reject if failing to create - * window.navigator.mozWifiManager; resolve if all is well. - * - * |finsih| will be called in the end. - * - * Fulfill params: (none) - * Reject params: The reject reason. - * - * @return A deferred promise. - */ - function initTestEnvironment() { - return addRequiredPermissions() - .then(function() { - wifiManager = window.navigator.mozWifiManager; - if (!wifiManager) { - throw 'window.navigator.mozWifiManager is NULL'; - } - wifiOrigEnabled = wifiManager.enabled; - }) - .then(() => runEmulatorShellSafe(['getprop', 'ro.build.version.sdk'])) - .then(aLines => { - sdkVersion = parseInt(aLines[0]); - }); - } - - //--------------------------------------------------- - // Public test suite functions - //--------------------------------------------------- - suite.getWifiManager = (() => wifiManager); - suite.ensureWifiEnabled = ensureWifiEnabled; - suite.requestWifiEnabled = requestWifiEnabled; - suite.startHostapds = startHostapds; - suite.getProcessDetail = getProcessDetail; - suite.killAllHostapd = killAllHostapd; - suite.wrapDomRequestAsPromise = wrapDomRequestAsPromise; - suite.waitForWifiManagerEventOnce = waitForWifiManagerEventOnce; - suite.verifyNumOfProcesses = verifyNumOfProcesses; - suite.testWifiScanWithRetry = testWifiScanWithRetry; - suite.getFirstIndexBySsid = getFirstIndexBySsid; - suite.testAssociate = testAssociate; - suite.getKnownNetworks = getKnownNetworks; - suite.setStaticIpMode = setStaticIpMode; - suite.requestWifiScan = requestWifiScan; - suite.waitForConnected = waitForConnected; - suite.forgetNetwork = forgetNetwork; - suite.waitForTimeout = waitForTimeout; - suite.waitForRilDataConnected = waitForRilDataConnected; - suite.requestTetheringEnabled = requestTetheringEnabled; - suite.importCert = importCert; - suite.getImportedCerts = getImportedCerts; - suite.deleteCert = deleteCert; - suite.writeFile = writeFile; - suite.exeAndParseNetcfg = exeAndParseNetcfg; - suite.exeAndParseIpRoute = exeAndParseIpRoute; - - /** - * Common test routine. - * - * Start a test with the given test case chain. The test environment will be - * settled down before the test. After the test, all the affected things will - * be restored. - * - * Fulfill params: (none) - * Reject params: (none) - * - * @param aTestCaseChain - * The test case entry point, which can be a function or a promise. - * - * @return A deferred promise. - */ - suite.doTest = function(aTestCaseChain) { - return initTestEnvironment() - .then(aTestCaseChain) - .then(function onresolve() { - cleanUp(); - }, function onreject(aReason) { - ok(false, 'Promise rejects during test' + (aReason ? '(' + aReason + ')' : '')); - cleanUp(); - }); - }; - - /** - * Common test routine without the presence of stock hostapd. - * - * Same as doTest except stopping the stock hostapd before test - * and restarting it after test. - * - * Fulfill params: (none) - * Reject params: (none) - * - * @param aTestCaseChain - * The test case entry point, which can be a function or a promise. - * - * @return A deferred promise. - */ - suite.doTestWithoutStockAp = function(aTestCaseChain) { - return suite.doTest(function() { - return stopStockHostapd() - .then(aTestCaseChain) - .then(startStockHostapd); - }); - }; - - /** - * The common test routine for wifi tethering. - * - * Similar as doTest except that it will set 'ril.data.enabled' to true - * before testing and restore it afterward. It will also verify 'ril.data.enabled' - * and 'tethering.wifi.enabled' to be false in the beginning. Note that this routine - * will NOT change the state of 'tethering.wifi.enabled' so the user should enable - * than disable on his/her own. This routine will only check if tethering is turned - * off after testing. - * - * Fulfill params: (none) - * Reject params: (none) - * - * @param aTestCaseChain - * The test case entry point, which can be a function or a promise. - * - * @return A deferred promise. - */ - suite.doTestTethering = function(aTestCaseChain) { - - function verifyInitialState() { - return getSettings(SETTINGS_RIL_DATA_ENABLED) - .then(enabled => isOrThrow(enabled, false, SETTINGS_RIL_DATA_ENABLED)) - .then(() => getSettings(SETTINGS_TETHERING_WIFI_ENABLED)) - .then(enabled => isOrThrow(enabled, false, SETTINGS_TETHERING_WIFI_ENABLED)); - } - - function initTetheringTestEnvironment() { - // Enable ril data. - return Promise.all([waitForRilDataConnected(true), - setSettings1(SETTINGS_RIL_DATA_ENABLED, true)]) - .then(setSettings1(SETTINGS_TETHERING_WIFI_SECURITY, 'open')); - } - - function restoreToInitialState() { - return setSettings1(SETTINGS_RIL_DATA_ENABLED, false) - .then(() => getSettings(SETTINGS_TETHERING_WIFI_ENABLED)) - .then(enabled => is(enabled, false, 'Tethering should be turned off.')); - } - - return suite.doTest(function() { - return verifyInitialState() - .then(initTetheringTestEnvironment) - // Since stock hostapd is not reliable after ICS, we just - // turn off potential stock hostapd during testing to avoid - // interference. - .then(stopStockHostapd) - .then(aTestCaseChain) - .then(startStockHostapd) - .then(restoreToInitialState, function onreject(aReason) { - return restoreToInitialState() - .then(() => { throw aReason; }); // Re-throw the orignal reject reason. - }); - }); - }; - - /** - * Run test with imported certificate. - * - * Certificate will be imported and confirmed before running test, and be - * deleted after running test. - * - * Fulfill params: (none) - * - * @param certBlob - * Certificate content as Blob. - * @param password - * Password for importing certificate, only used for importing PKCS#12. - * @param nickanem - * Nickname for imported certificate. - * @param usage - * Expected usage of imported certificate. - * @param aTestCaseChain - * The test case entry point, which can be a function or a promise. - * - * @return A deferred promise. - */ - suite.doTestWithCertificate = function(certBlob, password, nickname, usage, aTestCaseChain) { - return suite.doTestWithoutStockAp(function() { - return ensureWifiEnabled(true) - // Import test certificate. - .then(() => importCert(certBlob, password, nickname)) - .then(function(info) { - // Check import result. - is(info.nickname, nickname, "Imported nickname"); - for (let i = 0; i < usage.length; i++) { - isnot(info.usage.indexOf(usage[i]), -1, "Usage " + usage[i]); - } - }) - // Get imported certificate list. - .then(getImportedCerts) - // Check if certificate exists in imported certificate list. - .then(function(list) { - for (let i = 0; i < usage.length; i++) { - isnot(list[usage[i]].indexOf(nickname), -1, - "Certificate \"" + nickname + "\" of usage " + usage[i] + " is imported"); - } - }) - // Run test case. - .then(aTestCaseChain) - // Delete imported certificates. - .then(() => deleteCert(nickname)) - // Check if certificate doesn't exist in imported certificate list. - .then(getImportedCerts) - .then(function(list) { - for (let i = 0; i < usage.length; i++) { - is(list[usage[i]].indexOf(nickname), -1, "Certificate is deleted"); - } - }) - }); - }; - - return suite; -})(); diff --git a/dom/wifi/test/marionette/manifest.ini b/dom/wifi/test/marionette/manifest.ini deleted file mode 100644 index 5d719e4b6..000000000 --- a/dom/wifi/test/marionette/manifest.ini +++ /dev/null @@ -1,22 +0,0 @@ -[DEFAULT] -run-if = buildapp == 'b2g' - -[test_wifi_enable.js] -[test_wifi_scan.js] -[test_wifi_associate.js] -[test_wifi_associate_wo_connect.js] -[test_wifi_auto_connect.js] -[test_wifi_static_ip.js] -[test_wifi_tethering_wifi_disabled.js] -[test_wifi_tethering_wifi_inactive.js] -[test_wifi_tethering_wifi_active.js] -[test_wifi_manage_server_certificate.js] -[test_wifi_manage_user_certificate.js] -[test_wifi_manage_pkcs12_certificate.js] -[test_wifi_associate_WPA_EAP_PEAP.js] -skip-if = android_version < '16' # EAP test not working before KK. -[test_wifi_associate_WPA_EAP_TTLS.js] -skip-if = android_version < '16' -[test_wifi_associate_WPA_EAP_TLS.js] -skip-if = android_version < '16' -[test_wifi_enable_api.js] diff --git a/dom/wifi/test/marionette/test_wifi_associate.js b/dom/wifi/test/marionette/test_wifi_associate.js deleted file mode 100644 index 0c00c583b..000000000 --- a/dom/wifi/test/marionette/test_wifi_associate.js +++ /dev/null @@ -1,35 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -MARIONETTE_TIMEOUT = 60000; -MARIONETTE_HEAD_JS = 'head.js'; - -const SCAN_RETRY_CNT = 5; - -/** - * Convert the given MozWifiNetwork object array to testAssociate chain. - * - * @param aNetworks - * An array of MozWifiNetwork which we want to convert. - * - * @return A promise chain which "then"s testAssociate accordingly. - */ -function convertToTestAssociateChain(aNetworks) { - let chain = Promise.resolve(); - - aNetworks.forEach(function (aNetwork) { - chain = chain.then(() => gTestSuite.testAssociate(aNetwork)); - }); - - return chain; -} - -gTestSuite.doTestWithoutStockAp(function() { - return gTestSuite.ensureWifiEnabled(true) - .then(() => gTestSuite.startHostapds(HOSTAPD_CONFIG_LIST)) - .then(() => gTestSuite.verifyNumOfProcesses('hostapd', HOSTAPD_CONFIG_LIST.length)) - .then(() => gTestSuite.testWifiScanWithRetry(SCAN_RETRY_CNT, HOSTAPD_CONFIG_LIST)) - .then(networks => convertToTestAssociateChain(networks)) - .then(gTestSuite.killAllHostapd) - .then(() => gTestSuite.verifyNumOfProcesses('hostapd', 0)); -}); diff --git a/dom/wifi/test/marionette/test_wifi_associate_WPA_EAP_PEAP.js b/dom/wifi/test/marionette/test_wifi_associate_WPA_EAP_PEAP.js deleted file mode 100644 index ce53da2d7..000000000 --- a/dom/wifi/test/marionette/test_wifi_associate_WPA_EAP_PEAP.js +++ /dev/null @@ -1,623 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -MARIONETTE_TIMEOUT = 60000; -MARIONETTE_HEAD_JS = 'head.js'; - -const SCAN_RETRY_CNT = 5; - -const EAP_USERNAME = 'username'; -const EAP_PASSWORD = 'password'; - -const SERVER_EAP_USER_CONF = { - path: HOSTAPD_CONFIG_PATH + 'hostapd.eap_user', - content: '* PEAP,TTLS,TLS\n' + - '"' + EAP_USERNAME + '" MSCHAPV2,TTLS-MSCHAPV2 "' + EAP_PASSWORD + '" [2]\n' -}; -const CA_CERT = { - path: HOSTAPD_CONFIG_PATH + 'ca.pem', - content: '-----BEGIN CERTIFICATE-----\n' + - 'MIIDsTCCApmgAwIBAgIJAKxTf+8X8qngMA0GCSqGSIb3DQEBCwUAMG4xCzAJBgNV\n' + - 'BAYTAlRXMRMwEQYDVQQIDApTb21lLVN0YXRlMREwDwYDVQQKDAhjaHVja2xlZTER\n' + - 'MA8GA1UEAwwIY2h1Y2tsZWUxJDAiBgkqhkiG9w0BCQEWFWNodWNrbGkwNzA2QGdt\n' + - 'YWlsLmNvbTAgFw0xNDEyMjQxMTI4NTBaGA8yMjg4MTAwNzExMjg1MFowbjELMAkG\n' + - 'A1UEBhMCVFcxEzARBgNVBAgMClNvbWUtU3RhdGUxETAPBgNVBAoMCGNodWNrbGVl\n' + - 'MREwDwYDVQQDDAhjaHVja2xlZTEkMCIGCSqGSIb3DQEJARYVY2h1Y2tsaTA3MDZA\n' + - 'Z21haWwuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAo3c2yFxY\n' + - 'o6gGg0I83jy00ME+MAfzCd+4ShL45ZLqysQP93jRBfPzU9ZuZ29ysVwgWIdqkZao\n' + - 'XTuV/NAW2GMGd8W1jQJ3J81fjb9wvhlny3rrACwvUn1N1S1BnM+BAAiDLGxEmvAQ\n' + - 'onp2aaa6HsHsYS8ONX+d2Qh4LEA4vupeSGAqJychCZv/l+aq/ErFZhFYB3CPUQEt\n' + - 'cClO24ucsIYP95lA0zhscnmAj06qplFD4Bv6IVrdDqujy1zNwCQwsJq/8OQdaTN/\n' + - 'h3y9pWvNKMBMM2niOUAjtuNpqsSK/lTS1WAT3PdtVECX9fYBi0Bg+HM92xs/6gt6\n' + - 'kh9jPV8keXHvSwIDAQABo1AwTjAdBgNVHQ4EFgQU7hBqhuG04xeCzrQ3ngx18ZJ3\n' + - 'lUswHwYDVR0jBBgwFoAU7hBqhuG04xeCzrQ3ngx18ZJ3lUswDAYDVR0TBAUwAwEB\n' + - '/zANBgkqhkiG9w0BAQsFAAOCAQEAFYX2iy680GAnBTttk0gyX6gk+8pYr3D22k/G\n' + - '6rvcjefzS7ELQPRKr6mfmwXq3mMf/4jiS2zI5zmXsestPYzHYxf2viQ6t7vr9XiJ\n' + - '3WfFjNw4ERlRisAvg0aqqTNNQq5v2VME4sdFZagy217f73C7azwCHl0bqOLH05rl\n' + - '8RubOxiHEj7ZybJqnRciK/bht4D+rZkwf4bBBmoloqH7xT0+rFQclpYXDGGjNUQB\n' + - 'LcHLF10xcr7g3ZVVu82fe6+d85gIGOIMR9+TKhdw6gO3CNcnDAj6gxksghgtcxmh\n' + - 'OzOggCn7nlIwImtsg2sZkpWB4lEi9hdv4lkNuyFjOL3bnuc+NA==\n' + - '-----END CERTIFICATE-----\n' -}; - -const SERVER_CERT = { - path: HOSTAPD_CONFIG_PATH + 'server.pem', - content: '-----BEGIN CERTIFICATE-----\n' + - 'MIID1DCCArygAwIBAgIBADANBgkqhkiG9w0BAQsFADBuMQswCQYDVQQGEwJUVzET\n' + - 'MBEGA1UECAwKU29tZS1TdGF0ZTERMA8GA1UECgwIY2h1Y2tsZWUxETAPBgNVBAMM\n' + - 'CGNodWNrbGVlMSQwIgYJKoZIhvcNAQkBFhVjaHVja2xpMDcwNkBnbWFpbC5jb20w\n' + - 'IBcNMTQxMjI0MTEyOTQ5WhgPMjI4ODEwMDcxMTI5NDlaMG4xCzAJBgNVBAYTAlRX\n' + - 'MRMwEQYDVQQIDApTb21lLVN0YXRlMREwDwYDVQQKDAhjaHVja2xlZTERMA8GA1UE\n' + - 'AwwIY2h1Y2tsZWUxJDAiBgkqhkiG9w0BCQEWFWNodWNrbGkwNzA2QGdtYWlsLmNv\n' + - 'bTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMdhQmKilTJbWZRxTiSV\n' + - 'rqIU+LYW1RKghx5o+0JpNRJVLuz5kBMaNskbbfUSNuHbEq0QA9BDKAZWIc4LSotk\n' + - 'lCo8TbcO9CJvJPQGGjGdHcohWX5vy6BE/OVE46CUteMFyZF6F8R2fNUww08iR/u1\n' + - 'YZebL5pWO1j43sPpAzEy6Tij2ACPt6EZcFaZG3SF2mVJWkCQnBqrojP65WUvZQqp\n' + - 'seUhW2YAS8Nu0Yrohgxz6VYk+cNDuDZVGs6qWRStZzJfYrfc76DtkHof5B14M+xp\n' + - 'XJaBLxN+whvnYkDTfinaCxnW1O7eXUltr87fLc5zmeBkgwaiaQuIdcfZm7vDUiz8\n' + - 'vnUCAwEAAaN7MHkwCQYDVR0TBAIwADAsBglghkgBhvhCAQ0EHxYdT3BlblNTTCBH\n' + - 'ZW5lcmF0ZWQgQ2VydGlmaWNhdGUwHQYDVR0OBBYEFKK4f9/YavTHOfEiAB83Deac\n' + - '6gT5MB8GA1UdIwQYMBaAFO4QaobhtOMXgs60N54MdfGSd5VLMA0GCSqGSIb3DQEB\n' + - 'CwUAA4IBAQBWnO9o9KSJIqjoz5Nwll63ULOdcvgGdOeJIw1fcKQ817Rsp+TVcjcH\n' + - 'IrIADsT/QZGXRO/l6p1750e2iFtJEo1hsRaxtA1wWn2I9HO3+av2spQhr3jpYGPf\n' + - 'zpsMTp4RNYV7Q8+q1kZIz9PY4V1T0p6lveK8+fUj2hSLnxSj0QiGSJJtnEC3w4Rv\n' + - 'C9T6oUwIeToULmi+8FXQFdEqwKRU98DPq3eLzN28ZxUgoPE1C8+42D2UW8uyp/Gm\n' + - 'tGOa/k7nzkCdVqZI7lX7f0AjEvQgjtAMQ/k7Mhxx7TzW2HO+1YPMoKji6Z4WkNwt\n' + - 'JEj9ZUBSNt8B26UksJMBDkcvSegF3a7o\n' + - '-----END CERTIFICATE-----\n' -}; - -const SERVER_KEY = { - path: HOSTAPD_CONFIG_PATH + 'server.key', - content: '-----BEGIN RSA PRIVATE KEY-----\n' + - 'MIIEpAIBAAKCAQEAx2FCYqKVMltZlHFOJJWuohT4thbVEqCHHmj7Qmk1ElUu7PmQ\n' + - 'Exo2yRtt9RI24dsSrRAD0EMoBlYhzgtKi2SUKjxNtw70Im8k9AYaMZ0dyiFZfm/L\n' + - 'oET85UTjoJS14wXJkXoXxHZ81TDDTyJH+7Vhl5svmlY7WPjew+kDMTLpOKPYAI+3\n' + - 'oRlwVpkbdIXaZUlaQJCcGquiM/rlZS9lCqmx5SFbZgBLw27RiuiGDHPpViT5w0O4\n' + - 'NlUazqpZFK1nMl9it9zvoO2Qeh/kHXgz7GlcloEvE37CG+diQNN+KdoLGdbU7t5d\n' + - 'SW2vzt8tznOZ4GSDBqJpC4h1x9mbu8NSLPy+dQIDAQABAoIBAASG4Mr8hgaurEoC\n' + - 'iJOsElr7vunjetMBcg/uskW/vcS8ymP3Bp5oafYG+WgnEbfvEW18f5mq7K24JuxW\n' + - 'tUqU7ghHdjxByqk9fMlNmiqmNpbwSufkAeuRpWxPNBvhRH/zEbCL5R5A0nTEtqqF\n' + - 'TL0aUSzwCRSoAJD0lZo9ICVt0n3GsDyM9rqQg/uZmh1qsRdwPsRuYORND9g48rKq\n' + - '6WN9leskSxhhsYE2D9ocOFd9bNt8Zxejh9ppVSnG/KsIdt18iBzcabatgAQ046fb\n' + - 'Z3vprcZJLg93Sg2gSuVqlSTs3M2W8VQnm22/EBMb1y0M48MSRCgnbPLG/CcCLLfF\n' + - 'LwxCOgECgYEA/eYt67xyJ6JeAdxdwOZuT1WWGbFpLiG9+2OgiHumyRQ5969XMTWo\n' + - 'fIhMKchDdjoy9RR236\/\/EFCs7UEyB7+a7ODRzNiK2zCD8Smjp+21fUPSthEeQesk\n' + - 'eiMYICIu5Ay35x9sxIX+XOUVvRhPOGcD29GVeRnKh1inTHOz2dje8LkCgYEAyQeY\n' + - 'STi9jjCEcHkM1E/UeDiLfHHepLXi8wS41JNRHl5Jacp7XB5djAjKu/jf367/VpFy\n' + - 'GDDMetE7n8eWkrnAvovxOwZ000YDMtL1sUYSjL+XtBS5s6VY1p4qaSAY9nUUGrJh\n' + - 'JvtvsuI7SKTtL+60vjBOH7zDnvOdBgAp0utLhZ0CgYEAuLzzqrPKB8afShFSchn4\n' + - 'J2dpuLYahsNsXW7HDqeR2nsKFosRETAusLXnXPtnAq4kB6jlOarwFqnsuRCX24Vx\n' + - 'r2uBm9/vYL7zMdUPTA+s30ErHuhjsKjsOKYyVqcooSwT32pBFNk+E89nutfmRG7I\n' + - 'IvhjHuNCNqqtx/Xj5d1jkZkCgYBQicppC2Jl5OoqZVTOem0U/RJk+PnJ41TZJ7sk\n' + - '7yBAmmWvDH\/\/l+rCf4M5a6vFYcbKV9rt9h711X2dtciNX/3oWQh8LUoAmrwNUJc+\n' + - 'PmSQHvIYI3WCk2vUD+nN1B4sHxu+1lg11eYaNKiroeeknG2tBI1ICcgVlmQCU25u\n' + - 'IfZPwQKBgQCdO6QHhPLtcHUDNFA6FQ1jKL1iEd7G0JLVRz4Xkpkn1Vrr5MD6JFDa\n' + - '5ccabADyl0lpFqDIVJQIzLku2hOD2i9aBNCY0pL391HeOS7CkZX+TdOY1tquoBq5\n' + - 'MnmixZjDCVd2VcrVyTA6ntOBoharKFW0rH1PqU+qu7dZF7CBPbAdEw==\n' + - '-----END RSA PRIVATE KEY-----\n' -}; - -const WPA_EAP_AP_LIST = [ - { - ssid: 'WPA-EAP-PEAP', - ieee8021x: 1, - eapol_version: 1, - eap_server: 1, - eapol_key_index_workaround: 0, - eap_user_file: SERVER_EAP_USER_CONF.path, - ca_cert: CA_CERT.path, - server_cert: SERVER_CERT.path, - private_key: SERVER_KEY.path, - wpa: 3, - wpa_key_mgmt: 'WPA-EAP' - } -]; - -const CLIENT_PKCS12_CERT = { - nickname: 'client', - password: 'password', - usage: ['UserCert', 'ServerCert'], - content: [0x30, 0x82, 0x0E, 0x01, 0x02, 0x01, 0x03, 0x30, - 0x82, 0x0D, 0xC7, 0x06, 0x09, 0x2A, 0x86, 0x48, - 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x01, 0xA0, 0x82, - 0x0D, 0xB8, 0x04, 0x82, 0x0D, 0xB4, 0x30, 0x82, - 0x0D, 0xB0, 0x30, 0x82, 0x08, 0x67, 0x06, 0x09, - 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, - 0x06, 0xA0, 0x82, 0x08, 0x58, 0x30, 0x82, 0x08, - 0x54, 0x02, 0x01, 0x00, 0x30, 0x82, 0x08, 0x4D, - 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, - 0x01, 0x07, 0x01, 0x30, 0x1C, 0x06, 0x0A, 0x2A, - 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x0C, 0x01, - 0x06, 0x30, 0x0E, 0x04, 0x08, 0x67, 0x7A, 0xF3, - 0x61, 0xBE, 0xE0, 0x51, 0xC1, 0x02, 0x02, 0x08, - 0x00, 0x80, 0x82, 0x08, 0x20, 0xFC, 0x6A, 0x79, - 0xA1, 0x6C, 0xAF, 0xBE, 0xEE, 0x62, 0x45, 0x33, - 0xB8, 0x48, 0xE1, 0x68, 0xA1, 0x15, 0x11, 0x4B, - 0x95, 0xCB, 0x77, 0xC0, 0x5D, 0xA2, 0xCB, 0xDB, - 0xD1, 0x83, 0x74, 0x60, 0xD7, 0xEC, 0x42, 0xA6, - 0x3A, 0x23, 0xF7, 0x85, 0xEB, 0xC1, 0xFE, 0x6A, - 0x57, 0x8E, 0xC1, 0x44, 0xF3, 0x1F, 0xFE, 0xB8, - 0x2D, 0x8C, 0x4D, 0xC9, 0x5B, 0xAE, 0x21, 0x2E, - 0x4C, 0x1A, 0xEB, 0x84, 0x09, 0xF3, 0x40, 0x92, - 0x39, 0x7F, 0x56, 0x02, 0x46, 0x61, 0x16, 0xDE, - 0x5C, 0x48, 0xB6, 0x0C, 0x1D, 0xD3, 0x5F, 0x10, - 0x9A, 0x39, 0xB8, 0x66, 0x31, 0xFC, 0x39, 0x71, - 0x87, 0x23, 0x46, 0x9D, 0xE8, 0x3C, 0x2B, 0xA1, - 0x39, 0x8A, 0xD3, 0xFF, 0xD9, 0x43, 0xB6, 0x61, - 0xC6, 0x67, 0x70, 0x40, 0xBD, 0xFE, 0xD3, 0xC1, - 0x68, 0xF5, 0xF7, 0xC8, 0x89, 0xD8, 0x17, 0xC5, - 0xE8, 0x3D, 0x29, 0xD5, 0x91, 0xDF, 0x1F, 0x56, - 0x74, 0x5A, 0xC4, 0xA8, 0x14, 0xBA, 0xD4, 0xFA, - 0x13, 0x49, 0x2A, 0x9F, 0x63, 0xF1, 0xB2, 0x45, - 0xF1, 0xF0, 0x2A, 0xDD, 0x75, 0x66, 0x8A, 0xF7, - 0xAB, 0x73, 0x86, 0x26, 0x9D, 0x1F, 0x07, 0xAD, - 0xD3, 0xFE, 0xE0, 0xA3, 0xED, 0xA0, 0x96, 0x3E, - 0x1E, 0x89, 0x86, 0x02, 0x4C, 0x28, 0xFD, 0x57, - 0xA1, 0x67, 0x55, 0xF0, 0x82, 0x3B, 0x7F, 0xCC, - 0x2A, 0x32, 0x01, 0x93, 0x1D, 0x8B, 0x66, 0x8A, - 0x20, 0x52, 0x84, 0xDD, 0x2C, 0xFD, 0xEE, 0x72, - 0xF3, 0x8C, 0x58, 0xB9, 0x99, 0xE5, 0xC1, 0x22, - 0x63, 0x59, 0x00, 0xE2, 0x76, 0xC5, 0x3A, 0x17, - 0x7F, 0x93, 0xE9, 0x67, 0x61, 0xAA, 0x10, 0xC3, - 0xD9, 0xC8, 0x24, 0x46, 0x5B, 0xBE, 0x8C, 0x1F, - 0x2D, 0x66, 0x48, 0xD2, 0x02, 0x11, 0xFB, 0x74, - 0x14, 0x76, 0x76, 0x5A, 0x98, 0x54, 0x35, 0xA7, - 0x85, 0x66, 0x20, 0x26, 0x8B, 0x13, 0x6F, 0x68, - 0xE3, 0xC9, 0x58, 0x7D, 0x1C, 0x3E, 0x01, 0x8D, - 0xF8, 0xD6, 0x7F, 0xCF, 0xA2, 0x07, 0xB7, 0x95, - 0xFD, 0xF0, 0x02, 0x34, 0x32, 0x30, 0xE8, 0xD4, - 0x57, 0x5E, 0x53, 0xFB, 0x54, 0xE2, 0x03, 0x32, - 0xCC, 0x52, 0x2E, 0xD2, 0x35, 0xD9, 0x58, 0x85, - 0x2D, 0xEC, 0x2D, 0x71, 0xD1, 0x8A, 0x29, 0xD0, - 0xB0, 0x24, 0xBD, 0x24, 0xDC, 0x1A, 0x28, 0x3F, - 0xA0, 0x12, 0x81, 0x15, 0x24, 0xC9, 0xB5, 0x4A, - 0x23, 0xB6, 0xA3, 0x45, 0x50, 0x2D, 0x73, 0x99, - 0x6B, 0x1C, 0xFB, 0xA4, 0x53, 0xD7, 0x5C, 0xF4, - 0x6C, 0xB0, 0xE5, 0x74, 0xB3, 0x76, 0xF8, 0xB1, - 0x0D, 0x59, 0x70, 0x9F, 0xCA, 0xDE, 0xF2, 0xAA, - 0x4C, 0x7D, 0x11, 0x54, 0xC4, 0x19, 0x0F, 0x36, - 0x4A, 0x62, 0xFF, 0x8B, 0x10, 0xCB, 0x93, 0x50, - 0xDA, 0x79, 0x5E, 0x4E, 0x09, 0x1F, 0x22, 0xC8, - 0x19, 0x85, 0xE9, 0xEE, 0xB7, 0x71, 0x65, 0xB9, - 0x10, 0xD2, 0x0A, 0x73, 0x5B, 0xA6, 0xDA, 0x37, - 0x46, 0x02, 0x00, 0x98, 0x9E, 0x20, 0x6C, 0x7D, - 0xC7, 0x69, 0xBB, 0xC2, 0x00, 0x40, 0x9C, 0x57, - 0x00, 0xC2, 0x36, 0x76, 0xE8, 0x2A, 0x8D, 0xAD, - 0x62, 0x57, 0xC8, 0xD0, 0x9D, 0x66, 0x27, 0x5A, - 0xD8, 0x0D, 0x35, 0x60, 0x28, 0x38, 0x62, 0x94, - 0x78, 0x36, 0x25, 0x58, 0xFD, 0xF8, 0x66, 0x1F, - 0x68, 0x04, 0x0F, 0xD8, 0x00, 0xDF, 0xA0, 0x6C, - 0x25, 0x42, 0x9A, 0x4C, 0xEB, 0x80, 0x13, 0x51, - 0x7D, 0x2D, 0xA8, 0x89, 0xD6, 0x1B, 0x67, 0x72, - 0x01, 0xF3, 0x2D, 0x16, 0x77, 0xFE, 0x22, 0xBC, - 0x8A, 0x45, 0x09, 0x1F, 0x9C, 0x2F, 0x2A, 0xA9, - 0x61, 0x5B, 0x4A, 0xE6, 0x64, 0x2C, 0x62, 0x1A, - 0x3A, 0x96, 0xE6, 0x0A, 0xAE, 0x05, 0x1A, 0xC8, - 0xCB, 0xD6, 0x8F, 0x3A, 0x4B, 0xE0, 0x7F, 0x82, - 0xB4, 0x98, 0xF1, 0x9D, 0xD7, 0x14, 0x76, 0x5E, - 0x77, 0x85, 0x87, 0xEC, 0x13, 0xDA, 0xFD, 0xAF, - 0xCB, 0xA3, 0x1C, 0x99, 0xC1, 0xFE, 0x17, 0x0C, - 0x40, 0x4D, 0x3C, 0x8F, 0x70, 0x86, 0x63, 0x64, - 0xB7, 0x75, 0xA8, 0x71, 0x36, 0xDC, 0x54, 0x10, - 0x57, 0x0C, 0xA8, 0xF2, 0xA1, 0xBB, 0xED, 0x03, - 0x41, 0x57, 0x34, 0x2C, 0x8F, 0x7C, 0xA0, 0x09, - 0xF3, 0x9E, 0x41, 0xB7, 0xA8, 0xD4, 0x66, 0x0D, - 0x0D, 0xC0, 0x6A, 0xFC, 0x6A, 0xA2, 0xAC, 0xE2, - 0x60, 0x00, 0xE3, 0xF7, 0x75, 0x43, 0x23, 0xEB, - 0xC8, 0x61, 0xFA, 0xB3, 0xB8, 0x28, 0xCE, 0xCA, - 0xF4, 0x47, 0x7F, 0x30, 0x6D, 0x61, 0x89, 0x47, - 0xA1, 0x4A, 0xFE, 0xD1, 0x21, 0x0B, 0x6D, 0xF4, - 0x3F, 0x00, 0x86, 0x30, 0x8E, 0x33, 0x21, 0x6F, - 0xDA, 0x15, 0xFD, 0x5F, 0xEC, 0x8E, 0xF1, 0x12, - 0x3F, 0xC9, 0x83, 0x0C, 0xCA, 0x22, 0x01, 0xF1, - 0x70, 0x5F, 0x1F, 0x66, 0xB5, 0xF8, 0x3E, 0x7A, - 0x6F, 0xDE, 0xDB, 0xA7, 0x8D, 0x18, 0x9E, 0xBE, - 0xDB, 0xAD, 0x3D, 0x66, 0x30, 0xC1, 0x6C, 0x0C, - 0x87, 0xB4, 0x65, 0x75, 0xE0, 0x9D, 0xEA, 0x16, - 0x0D, 0x07, 0x37, 0x33, 0xC5, 0xEC, 0x97, 0x93, - 0x37, 0xEB, 0x8E, 0x65, 0x9C, 0x40, 0x63, 0x6C, - 0x43, 0x60, 0xB0, 0x40, 0x4D, 0x85, 0xEF, 0xC2, - 0x47, 0x5F, 0xE7, 0x6B, 0xCB, 0x40, 0xE8, 0xEA, - 0xD8, 0xAB, 0xB1, 0x9A, 0x72, 0xDC, 0x4C, 0x14, - 0xFA, 0x43, 0x61, 0x5F, 0xA6, 0x5C, 0x3A, 0x05, - 0x17, 0x2E, 0x74, 0xF3, 0x5E, 0x45, 0xD9, 0x47, - 0xAA, 0x59, 0xB6, 0x8F, 0x42, 0x66, 0x42, 0x29, - 0x90, 0x95, 0x48, 0x46, 0x91, 0x88, 0x3C, 0x8C, - 0xDE, 0xCC, 0xED, 0xB3, 0xAA, 0x62, 0xEA, 0xBC, - 0xB4, 0x0C, 0x48, 0x4C, 0x53, 0x23, 0x5E, 0x24, - 0x85, 0xBF, 0x92, 0xDA, 0x14, 0xDB, 0x1A, 0x3D, - 0xEF, 0x30, 0xD9, 0x49, 0x64, 0x4D, 0xE5, 0x01, - 0xFC, 0xA4, 0x4B, 0xD1, 0x9F, 0xDE, 0x96, 0x7F, - 0x50, 0xBC, 0x4D, 0x38, 0x44, 0xE9, 0x23, 0x5F, - 0x37, 0x57, 0x1A, 0xA6, 0x52, 0x5A, 0x0F, 0x4F, - 0x87, 0x33, 0x4A, 0x7B, 0x66, 0xEE, 0x3D, 0x66, - 0x0A, 0x63, 0x39, 0x1F, 0x23, 0x38, 0x35, 0x73, - 0x60, 0x5E, 0x47, 0x20, 0x4F, 0xC0, 0xC8, 0x3C, - 0x09, 0xF9, 0x29, 0x4F, 0x5E, 0x55, 0x69, 0xC4, - 0x6B, 0xE8, 0xF8, 0x91, 0xC0, 0x22, 0x65, 0x15, - 0x1E, 0xFB, 0xB9, 0x61, 0xCE, 0x45, 0xBE, 0x2B, - 0xEE, 0xB9, 0x04, 0x2B, 0xFD, 0xAE, 0x61, 0x1C, - 0x3D, 0x3D, 0x7C, 0xBF, 0xC1, 0xF7, 0x3C, 0x4E, - 0x9E, 0x0E, 0x54, 0xC8, 0xAD, 0xA9, 0xDF, 0x43, - 0x49, 0xB9, 0x41, 0x05, 0xE5, 0xF1, 0x49, 0xAA, - 0x77, 0x6C, 0x34, 0x5B, 0x93, 0x24, 0x24, 0x23, - 0x74, 0x68, 0x11, 0xCE, 0x15, 0x80, 0xA1, 0xA4, - 0x1F, 0x8D, 0x81, 0xCD, 0xB2, 0x98, 0xCA, 0x14, - 0x0B, 0x0C, 0x61, 0x50, 0x69, 0x72, 0xAE, 0xFA, - 0x8B, 0xC0, 0x3F, 0x0D, 0xE7, 0xF2, 0x0F, 0xEB, - 0xC1, 0x11, 0xB9, 0x10, 0x03, 0x6A, 0xF5, 0x97, - 0x3C, 0x53, 0x2F, 0x67, 0x86, 0x09, 0x6A, 0xE3, - 0x28, 0xC0, 0x78, 0xC8, 0xB4, 0x39, 0x8E, 0xD1, - 0xCE, 0x25, 0xE8, 0x66, 0xF7, 0x09, 0x40, 0x7D, - 0x81, 0xFB, 0xAF, 0xFA, 0x59, 0xC4, 0x9B, 0x2B, - 0x83, 0x45, 0x5B, 0xA8, 0x66, 0x9E, 0x38, 0xC8, - 0xFD, 0xAC, 0xF2, 0x2D, 0x21, 0xDE, 0x50, 0x4C, - 0x03, 0xCB, 0x88, 0x42, 0xDD, 0x84, 0x09, 0x99, - 0x8E, 0x8B, 0x40, 0x97, 0x1B, 0x14, 0x85, 0x37, - 0x11, 0x01, 0xE0, 0x74, 0x6B, 0x33, 0x52, 0x8C, - 0x68, 0x3A, 0x89, 0xB2, 0xAF, 0x35, 0xE6, 0x65, - 0xC3, 0x58, 0x70, 0xD2, 0xE7, 0x1F, 0x1F, 0xF6, - 0xE5, 0x0A, 0xB1, 0xFE, 0xD0, 0xC9, 0x51, 0x50, - 0xE7, 0xFD, 0x58, 0xF5, 0xC4, 0x58, 0x65, 0x94, - 0xD1, 0x57, 0x55, 0x5E, 0xD2, 0x27, 0x98, 0xAF, - 0xE7, 0x55, 0x0B, 0x87, 0x50, 0x9B, 0xEF, 0xE8, - 0x2B, 0xFC, 0xE7, 0x3B, 0x4E, 0xD7, 0xB7, 0x4D, - 0xF4, 0xBC, 0xF4, 0x88, 0x63, 0xE4, 0x8A, 0x20, - 0x4B, 0x22, 0xB0, 0xA0, 0x53, 0x7F, 0xA8, 0xC9, - 0x0C, 0xF8, 0xD7, 0xBD, 0x46, 0x39, 0xA7, 0x7D, - 0xDD, 0x10, 0x91, 0x50, 0x54, 0x06, 0x47, 0xF0, - 0x3C, 0xAA, 0x43, 0x40, 0xF8, 0x54, 0xDD, 0x8A, - 0xEA, 0x8A, 0x0B, 0xA5, 0x7F, 0xCD, 0x5E, 0xAA, - 0x02, 0x2E, 0x1F, 0xC6, 0x50, 0x15, 0xF8, 0x0A, - 0x0C, 0x1B, 0x3C, 0x55, 0x3A, 0xC3, 0x6F, 0x88, - 0xD7, 0xBF, 0xB1, 0x02, 0xCC, 0xE0, 0x08, 0x29, - 0x97, 0xD2, 0xAA, 0x23, 0xC4, 0x6D, 0xE3, 0xE3, - 0x76, 0x39, 0x92, 0xC3, 0x2E, 0x7A, 0xE2, 0x98, - 0xD1, 0xFC, 0xAE, 0xCC, 0x95, 0xD8, 0xB4, 0xDC, - 0x92, 0xEA, 0x6A, 0x5F, 0xF2, 0x92, 0x17, 0x0B, - 0x8D, 0xC3, 0xFA, 0x9C, 0x62, 0xCE, 0x44, 0x8D, - 0xC3, 0x1E, 0xC3, 0xB2, 0xD5, 0x00, 0xCD, 0xB4, - 0x9E, 0x2D, 0x7B, 0xF2, 0x98, 0xA3, 0x00, 0x8B, - 0x81, 0x30, 0x77, 0x5B, 0x02, 0x99, 0xB1, 0xCD, - 0xC3, 0x1D, 0x74, 0x74, 0xEF, 0x41, 0xCB, 0x69, - 0x63, 0x8E, 0xA6, 0xD3, 0x2D, 0x3E, 0x1F, 0x1D, - 0x12, 0x9E, 0xD9, 0x18, 0x67, 0x06, 0xAF, 0x37, - 0x29, 0xAD, 0x65, 0xD8, 0xEB, 0x71, 0xC4, 0x7D, - 0x94, 0x3D, 0xEA, 0xCC, 0xDF, 0x72, 0x41, 0x51, - 0x3C, 0xA1, 0x66, 0x98, 0x32, 0x32, 0x40, 0x54, - 0xB0, 0x2F, 0xEB, 0xCE, 0xDF, 0x4A, 0x64, 0xFB, - 0x9A, 0x90, 0xDC, 0xF6, 0x6F, 0xA9, 0xD4, 0xCA, - 0xCB, 0x91, 0xC4, 0xFE, 0xEE, 0x9C, 0x01, 0x50, - 0x2E, 0xAC, 0xCC, 0x5F, 0x89, 0xD0, 0x91, 0xA3, - 0xD9, 0xF9, 0x4B, 0x8D, 0xDE, 0x6C, 0x60, 0x21, - 0x19, 0xB1, 0xD3, 0x4D, 0x75, 0x56, 0x6F, 0xB8, - 0x25, 0xA4, 0x92, 0x4F, 0x12, 0xF5, 0x8F, 0xC1, - 0x17, 0x4B, 0xB3, 0x34, 0x21, 0x22, 0xAC, 0x52, - 0xD2, 0x64, 0xC9, 0x9A, 0x7D, 0xFC, 0xC0, 0x0A, - 0x89, 0x34, 0xFF, 0x08, 0xD3, 0x04, 0xDC, 0xFE, - 0x7C, 0xB3, 0xB8, 0xFD, 0x85, 0xDD, 0x79, 0x51, - 0xA7, 0x89, 0xE8, 0xF1, 0x23, 0xB1, 0xDF, 0xD7, - 0x1F, 0x7B, 0xB1, 0x5D, 0x42, 0xF9, 0x61, 0xF8, - 0xDC, 0x81, 0x04, 0xF1, 0xCC, 0xFA, 0xD7, 0xED, - 0xBF, 0x47, 0xAC, 0xBD, 0xE5, 0xFA, 0xAC, 0xB3, - 0x1C, 0xD9, 0xA1, 0xB3, 0x60, 0xEE, 0x9C, 0x8A, - 0x36, 0x57, 0xB4, 0x2F, 0xA1, 0xA2, 0xF3, 0xE2, - 0x09, 0x9A, 0x6E, 0x43, 0x9B, 0xE5, 0x93, 0xB8, - 0x3D, 0x9E, 0x9F, 0xC1, 0xC6, 0x0D, 0x02, 0xEB, - 0x4D, 0x38, 0xE9, 0xB4, 0x9F, 0xEA, 0x33, 0x8C, - 0x07, 0xD8, 0xB4, 0x71, 0xAD, 0xE5, 0x43, 0xB2, - 0xCC, 0x55, 0x93, 0x6A, 0xDB, 0x1E, 0x80, 0xDB, - 0xC2, 0xEA, 0x42, 0x8E, 0xFC, 0x86, 0x44, 0xC9, - 0x8A, 0xC4, 0xF2, 0x46, 0xA7, 0x39, 0x50, 0x0D, - 0x1A, 0xAA, 0x07, 0x04, 0xBE, 0xD4, 0xCE, 0x62, - 0x4D, 0x0F, 0x91, 0x7D, 0x29, 0x88, 0x9C, 0x4C, - 0xAF, 0xF7, 0xD8, 0x40, 0x93, 0x88, 0xC7, 0x20, - 0xD2, 0x17, 0x2A, 0xC4, 0x92, 0x72, 0xD0, 0xC0, - 0x4E, 0x56, 0x47, 0xB1, 0x27, 0x02, 0xE6, 0x61, - 0x82, 0x5E, 0xC8, 0x2E, 0x90, 0xD2, 0x31, 0x22, - 0xE2, 0xA9, 0x4A, 0x91, 0x45, 0x69, 0xB1, 0xA5, - 0x0F, 0x66, 0x2C, 0x30, 0xAD, 0x7F, 0x1B, 0x0E, - 0x22, 0x17, 0x60, 0x2E, 0x3D, 0x7F, 0x7F, 0x8C, - 0x33, 0x51, 0xA0, 0x25, 0xDE, 0xFD, 0x75, 0xBC, - 0xEF, 0xE6, 0xE7, 0x20, 0x04, 0x5A, 0xEC, 0x50, - 0x21, 0x48, 0x56, 0x98, 0xE2, 0x33, 0x6D, 0x22, - 0x5C, 0xC3, 0xFB, 0xFC, 0x6F, 0xB3, 0xA7, 0x8E, - 0x6F, 0x67, 0x70, 0x9D, 0xDA, 0x02, 0x01, 0x59, - 0x7B, 0x3D, 0x2B, 0x38, 0xCC, 0x0F, 0x44, 0x3D, - 0xFB, 0x9A, 0xB3, 0x23, 0x15, 0x50, 0x6E, 0xBF, - 0x8B, 0xA1, 0x94, 0x33, 0xE5, 0x7B, 0x88, 0x4E, - 0xCB, 0x6D, 0x9F, 0xBF, 0xBC, 0x7A, 0xA8, 0x1E, - 0x68, 0x25, 0xED, 0x8E, 0x53, 0x21, 0x72, 0xC5, - 0x70, 0xB3, 0xE4, 0xA6, 0xA1, 0x5A, 0x2D, 0xC8, - 0x43, 0x9D, 0x60, 0x77, 0x78, 0xE0, 0xC4, 0xAF, - 0xC8, 0x29, 0xBA, 0xD0, 0x4D, 0x39, 0x83, 0x51, - 0xA7, 0x10, 0x7F, 0x0C, 0x34, 0x0E, 0x6C, 0x75, - 0x26, 0xD7, 0xD6, 0xC7, 0x32, 0x53, 0xAF, 0x4E, - 0xBE, 0xF2, 0xC2, 0x0F, 0x99, 0x23, 0xB9, 0xE1, - 0xC8, 0xB4, 0xBC, 0x5A, 0xC6, 0xCB, 0xEB, 0x4D, - 0x28, 0x56, 0x72, 0xFE, 0x1B, 0x2C, 0x5D, 0xE3, - 0xBC, 0xC7, 0xA3, 0xC0, 0x7D, 0x27, 0xF0, 0xD0, - 0x4F, 0x3F, 0x1F, 0xF7, 0x87, 0x15, 0xF2, 0xEA, - 0xD4, 0x03, 0x6D, 0x2F, 0xD4, 0x8E, 0x50, 0x4B, - 0x05, 0xBF, 0xF7, 0x8C, 0x67, 0x5A, 0xDC, 0x4D, - 0xCD, 0xCF, 0x9D, 0x02, 0xB6, 0xE7, 0xAE, 0x49, - 0xD1, 0x7C, 0x00, 0xE7, 0x3B, 0xEA, 0xFB, 0x0D, - 0x2A, 0x7B, 0x41, 0x33, 0x66, 0xD0, 0x29, 0x9F, - 0xB3, 0x8A, 0x71, 0xB0, 0xE2, 0x76, 0xA9, 0xDB, - 0xFD, 0x64, 0x04, 0x69, 0xDF, 0x89, 0x1F, 0x56, - 0x86, 0x92, 0xD9, 0xD9, 0xB9, 0xF3, 0x4F, 0xAC, - 0xAE, 0x61, 0x48, 0x20, 0xCE, 0x3C, 0x2B, 0x44, - 0xAB, 0x42, 0xFA, 0xAB, 0x2E, 0x94, 0x82, 0xC8, - 0xD9, 0x97, 0xCF, 0x27, 0xDF, 0xAC, 0xAC, 0xE7, - 0xCA, 0xB2, 0x84, 0xAB, 0xF2, 0x5D, 0xDF, 0x56, - 0x0C, 0x8C, 0x07, 0x3C, 0x3D, 0xA8, 0xDD, 0xBE, - 0xFF, 0x4E, 0x28, 0x0D, 0xB2, 0x2D, 0xE6, 0x9D, - 0x44, 0x21, 0xCB, 0xE7, 0x33, 0x63, 0x22, 0x8F, - 0x4C, 0xFF, 0xB6, 0x1D, 0x9A, 0x71, 0x3F, 0xB1, - 0x29, 0xAE, 0x3A, 0x35, 0xEE, 0x9C, 0x97, 0x68, - 0xA7, 0x52, 0x66, 0x01, 0xD8, 0x9A, 0x5D, 0xF4, - 0xB3, 0x2F, 0x5C, 0xD4, 0x0E, 0xF9, 0xCF, 0x07, - 0xF6, 0x8C, 0xBA, 0xA6, 0x8D, 0x6B, 0xC6, 0x01, - 0xC2, 0x69, 0xAE, 0x60, 0x08, 0x1A, 0x0E, 0x3F, - 0xAE, 0x60, 0x29, 0xF3, 0x48, 0x0D, 0xE0, 0xD0, - 0xAE, 0x52, 0x44, 0xE9, 0x7F, 0x1F, 0x92, 0x5F, - 0x71, 0xAD, 0xEC, 0x6B, 0x47, 0x66, 0x92, 0x22, - 0x27, 0xAE, 0x6E, 0x25, 0xCD, 0xF3, 0x5F, 0x55, - 0x59, 0xBD, 0x73, 0xCE, 0x2B, 0x7E, 0x99, 0x44, - 0x56, 0x70, 0xA3, 0xE7, 0x7A, 0x59, 0x75, 0xD8, - 0x48, 0x0C, 0x39, 0x2B, 0xD7, 0x53, 0xC6, 0xAD, - 0x4A, 0x6F, 0xB4, 0x14, 0x96, 0xDF, 0xF2, 0x4A, - 0x0C, 0xA2, 0xD5, 0x29, 0x98, 0x7C, 0x42, 0x87, - 0xD9, 0x1F, 0x97, 0x61, 0xD9, 0xBF, 0x99, 0x4F, - 0x2C, 0x4C, 0x75, 0xAC, 0xB8, 0x06, 0x75, 0xD6, - 0x87, 0x76, 0x7E, 0xE3, 0x23, 0x4B, 0xEA, 0x1A, - 0x1A, 0xF4, 0xB7, 0x09, 0xAF, 0x53, 0xEB, 0xA6, - 0x39, 0x10, 0xFE, 0xD4, 0xEB, 0x1B, 0xAE, 0x38, - 0x31, 0x33, 0xBA, 0x68, 0xEE, 0xC7, 0x65, 0x76, - 0xFB, 0x49, 0x77, 0xD4, 0x19, 0xC4, 0xE6, 0xA7, - 0x05, 0xFE, 0x2A, 0xDA, 0x39, 0x99, 0x1A, 0x92, - 0xD2, 0xF0, 0x61, 0x97, 0xF6, 0x06, 0x6C, 0x88, - 0x7B, 0x6F, 0x60, 0xE6, 0x70, 0x08, 0xF0, 0xB4, - 0x6B, 0x39, 0x6F, 0x05, 0x41, 0x81, 0xF9, 0xBE, - 0x7A, 0x51, 0xC4, 0x75, 0xB0, 0x6A, 0x89, 0xA0, - 0xA6, 0x9A, 0x5B, 0xEE, 0x7D, 0x78, 0x17, 0x5F, - 0x9F, 0x3B, 0x7D, 0xDD, 0x8A, 0x9E, 0xAA, 0x1A, - 0xDA, 0x49, 0x08, 0xE9, 0xFD, 0x91, 0xA6, 0xFA, - 0xCE, 0xCF, 0x67, 0xDF, 0x0F, 0xC9, 0xD6, 0x38, - 0xD9, 0xD5, 0xD1, 0xC0, 0x76, 0x59, 0x42, 0x53, - 0xBF, 0x48, 0xE9, 0x11, 0x74, 0xC7, 0x11, 0xD8, - 0xE7, 0x8E, 0xD3, 0xC8, 0x25, 0xA1, 0x26, 0x50, - 0xBB, 0xB4, 0x35, 0xAF, 0xAF, 0x06, 0x23, 0x69, - 0x3E, 0x30, 0xFD, 0x7B, 0x34, 0x83, 0x07, 0xD0, - 0xF0, 0x0F, 0x6C, 0x9A, 0x13, 0x5D, 0xC2, 0x7B, - 0xDF, 0x6F, 0xDD, 0x8E, 0xF4, 0x30, 0x82, 0x05, - 0x41, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, - 0x0D, 0x01, 0x07, 0x01, 0xA0, 0x82, 0x05, 0x32, - 0x04, 0x82, 0x05, 0x2E, 0x30, 0x82, 0x05, 0x2A, - 0x30, 0x82, 0x05, 0x26, 0x06, 0x0B, 0x2A, 0x86, - 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x0C, 0x0A, 0x01, - 0x02, 0xA0, 0x82, 0x04, 0xEE, 0x30, 0x82, 0x04, - 0xEA, 0x30, 0x1C, 0x06, 0x0A, 0x2A, 0x86, 0x48, - 0x86, 0xF7, 0x0D, 0x01, 0x0C, 0x01, 0x03, 0x30, - 0x0E, 0x04, 0x08, 0x74, 0xC0, 0x84, 0x8F, 0xC7, - 0x74, 0x5E, 0x21, 0x02, 0x02, 0x08, 0x00, 0x04, - 0x82, 0x04, 0xC8, 0x1E, 0xF4, 0xE9, 0x07, 0x27, - 0x9E, 0x5A, 0xC9, 0x39, 0x1D, 0x37, 0x2C, 0x06, - 0x4B, 0x57, 0xEA, 0xC5, 0x42, 0x9A, 0x60, 0xD5, - 0x42, 0xB2, 0x34, 0x2D, 0xD3, 0x88, 0x7C, 0x78, - 0x87, 0xB6, 0xE9, 0x42, 0x44, 0x1F, 0x67, 0x32, - 0x92, 0x54, 0x22, 0xDA, 0xB2, 0x43, 0xE7, 0x40, - 0xBE, 0x1F, 0xAF, 0x3A, 0xCD, 0x2A, 0x9F, 0xD7, - 0x44, 0x5B, 0x37, 0x69, 0x85, 0xDF, 0xEB, 0x2A, - 0xB9, 0xE2, 0x92, 0x3B, 0xEA, 0xD5, 0x42, 0x53, - 0x95, 0x4A, 0xB0, 0x1B, 0xA5, 0xEF, 0xA6, 0x0D, - 0x29, 0xF4, 0x33, 0xFE, 0xD7, 0x49, 0x04, 0x1E, - 0x8C, 0xAD, 0x63, 0x1E, 0x79, 0x63, 0x74, 0x0C, - 0xE5, 0x5E, 0xA2, 0x2C, 0xBE, 0xB8, 0x90, 0xCE, - 0x06, 0x25, 0xBF, 0xD1, 0x5A, 0x50, 0xCF, 0x3B, - 0x52, 0xE2, 0xA7, 0xFF, 0x19, 0x02, 0xCF, 0xD0, - 0x9B, 0xD9, 0xF7, 0x28, 0x07, 0x38, 0x1F, 0xF2, - 0xAF, 0x44, 0x91, 0x3F, 0x0F, 0xB6, 0x6E, 0x8C, - 0xC0, 0x32, 0x92, 0xC0, 0xCD, 0x25, 0x98, 0x67, - 0xF1, 0x47, 0x52, 0x50, 0xF0, 0xA3, 0x7B, 0xE6, - 0x74, 0xDC, 0x72, 0x28, 0xC8, 0xAB, 0xB3, 0x31, - 0x7D, 0xA3, 0xF7, 0xC7, 0xD1, 0xE6, 0x99, 0xB4, - 0xB6, 0x5A, 0x3A, 0x4D, 0x83, 0x4F, 0xB8, 0xB5, - 0x86, 0xF8, 0x37, 0x7F, 0xA0, 0x16, 0x2F, 0x3C, - 0x62, 0x7A, 0xD4, 0x3A, 0xEB, 0xC2, 0xE8, 0x03, - 0x49, 0x17, 0x9E, 0xFB, 0xD7, 0xAF, 0x91, 0x32, - 0xFD, 0xEA, 0x4F, 0x64, 0xC6, 0x6E, 0x02, 0xEA, - 0xC4, 0xC8, 0x1F, 0x16, 0xC5, 0x4C, 0xFB, 0xC5, - 0x42, 0xF5, 0x85, 0x05, 0x92, 0x59, 0x4B, 0x31, - 0xE5, 0xE9, 0x69, 0xE7, 0x02, 0x98, 0x33, 0xBA, - 0x4C, 0x17, 0x09, 0xEF, 0x89, 0x20, 0xFA, 0x83, - 0x9F, 0xAE, 0x0E, 0x1B, 0x7D, 0x98, 0xB9, 0xF2, - 0x3C, 0x0F, 0xB7, 0x1C, 0x72, 0xDF, 0x17, 0x84, - 0x7F, 0x0A, 0xFD, 0x12, 0x3C, 0x6F, 0x68, 0x5D, - 0x45, 0xEB, 0xB8, 0xD6, 0x24, 0x65, 0x42, 0x75, - 0x5C, 0xC2, 0xF3, 0x3A, 0x6A, 0x4E, 0x51, 0x34, - 0x1B, 0xB6, 0x81, 0xB2, 0x8A, 0xEF, 0x28, 0xA4, - 0xC5, 0x88, 0x9A, 0x97, 0xE0, 0xEF, 0x31, 0x12, - 0x01, 0x7E, 0x1B, 0x43, 0x0F, 0x27, 0x80, 0x87, - 0x98, 0xC5, 0xD5, 0x83, 0xCB, 0x4B, 0xB7, 0x01, - 0x79, 0x60, 0xA1, 0x1A, 0x03, 0x05, 0xC6, 0x36, - 0x04, 0x31, 0x3C, 0x06, 0xDB, 0x08, 0xA8, 0xDA, - 0x8E, 0x32, 0x19, 0x91, 0xF1, 0x0D, 0x61, 0x6F, - 0xE4, 0xB2, 0x79, 0x8A, 0xDE, 0xF4, 0xF7, 0xFB, - 0x2C, 0x23, 0x5B, 0xD9, 0x64, 0x2F, 0xB7, 0xB3, - 0x8B, 0xCA, 0xB8, 0x8C, 0x1D, 0x3B, 0x49, 0x05, - 0x38, 0xA1, 0xE5, 0x8C, 0x1A, 0xDC, 0xA5, 0x61, - 0xFE, 0xF4, 0x2B, 0xDC, 0x77, 0x28, 0xF6, 0x19, - 0xE7, 0xB7, 0x8F, 0x4D, 0x27, 0x2D, 0xED, 0x8A, - 0x3F, 0x3D, 0xDC, 0x9F, 0xD1, 0x30, 0xFF, 0xD6, - 0xC3, 0xBE, 0x41, 0x25, 0xE3, 0xA5, 0x9B, 0x73, - 0xDF, 0x6A, 0xD9, 0xF9, 0x70, 0x84, 0x02, 0x4C, - 0x35, 0xD4, 0x3E, 0x05, 0x76, 0x3A, 0xDC, 0x6D, - 0x5A, 0x81, 0xB3, 0x94, 0xF7, 0x22, 0xF7, 0xDC, - 0xC1, 0x43, 0x31, 0x57, 0x5B, 0x42, 0x9A, 0x0B, - 0xF4, 0x95, 0x30, 0xA9, 0xBB, 0xD8, 0x06, 0xFB, - 0x1D, 0x6F, 0x9B, 0xC3, 0xBB, 0xF3, 0xBF, 0xFB, - 0xB4, 0x9F, 0x35, 0x64, 0x0A, 0x69, 0xB7, 0xD1, - 0x3E, 0xCA, 0x78, 0x07, 0x04, 0x03, 0x79, 0xD4, - 0xF3, 0xA8, 0xEC, 0x18, 0xDB, 0x03, 0x5E, 0x47, - 0xD7, 0xD0, 0x56, 0x2C, 0x74, 0x94, 0x86, 0x04, - 0x46, 0xB8, 0xD4, 0x35, 0x0A, 0x7B, 0xE6, 0x78, - 0xC4, 0x43, 0x3C, 0x56, 0xCC, 0x37, 0x8B, 0xFD, - 0xE8, 0xF4, 0x57, 0xEA, 0xAE, 0xCF, 0x36, 0x97, - 0x12, 0xAC, 0x39, 0xCF, 0x7C, 0xEF, 0x22, 0x67, - 0x01, 0xEC, 0xD8, 0x09, 0x49, 0x4E, 0xE3, 0x74, - 0xDD, 0x39, 0xE1, 0x39, 0xD7, 0x0C, 0x5F, 0x1B, - 0xCE, 0x69, 0xBC, 0x72, 0x44, 0x87, 0x64, 0x1C, - 0x08, 0x05, 0x93, 0x69, 0x6D, 0x7F, 0x90, 0x0A, - 0x2C, 0xCB, 0x8A, 0xBB, 0x7F, 0xE3, 0xE0, 0x80, - 0x31, 0xD0, 0x0A, 0x3A, 0x95, 0xFF, 0xF7, 0xB4, - 0x36, 0x38, 0x93, 0xE0, 0x0C, 0x11, 0x37, 0x12, - 0x06, 0xF6, 0xAD, 0xE9, 0xB1, 0x7A, 0x00, 0xF5, - 0xD2, 0x32, 0x6B, 0xD0, 0x27, 0xA5, 0x1B, 0x3D, - 0xE8, 0xDB, 0xCC, 0xA9, 0x1F, 0x1F, 0xB1, 0x99, - 0x3D, 0x7C, 0xB7, 0xCA, 0xDA, 0x27, 0x2C, 0x64, - 0x1C, 0x49, 0xB6, 0x87, 0x44, 0x06, 0x94, 0x9D, - 0xBC, 0x6B, 0x20, 0xA2, 0x68, 0x15, 0x1F, 0xE2, - 0xF2, 0xAD, 0x6D, 0x23, 0x2E, 0x2B, 0x74, 0xE2, - 0x5D, 0xE4, 0xB0, 0xC7, 0x84, 0xCB, 0x64, 0xBF, - 0xE0, 0xA8, 0x18, 0x83, 0xB4, 0xC9, 0xD9, 0x73, - 0xA8, 0xE6, 0xA9, 0x36, 0xD5, 0x63, 0x1E, 0x2C, - 0x2A, 0x55, 0x09, 0x77, 0x5E, 0xB3, 0x4B, 0xEA, - 0xB5, 0xD0, 0x14, 0x5F, 0xEB, 0x50, 0x7B, 0xAA, - 0xEF, 0x94, 0xBA, 0x2B, 0xD7, 0x8A, 0x07, 0xF1, - 0xF9, 0x5E, 0x12, 0x12, 0x21, 0x52, 0xE5, 0x0A, - 0x3E, 0xC0, 0xBC, 0x5D, 0x4C, 0xE2, 0x12, 0x7C, - 0x39, 0xF9, 0x16, 0x9D, 0xBD, 0x96, 0x83, 0x3B, - 0x7F, 0x3D, 0x6A, 0xEC, 0xF1, 0x25, 0xD2, 0xB0, - 0xB0, 0xEB, 0x20, 0x06, 0x07, 0xD6, 0xD9, 0x4C, - 0x07, 0x9A, 0x82, 0xC1, 0xFC, 0xF7, 0x66, 0x15, - 0xBD, 0x62, 0x65, 0xD8, 0x6C, 0xF6, 0x33, 0x7B, - 0x5A, 0x28, 0xEC, 0x90, 0xA1, 0x26, 0x9F, 0xC3, - 0x28, 0x4A, 0x64, 0x50, 0x5F, 0xCA, 0xE2, 0x6D, - 0xB8, 0x0F, 0xE2, 0x94, 0xB5, 0x8E, 0x1F, 0x8A, - 0x8F, 0x6B, 0xA6, 0x86, 0x1F, 0xEE, 0xDC, 0x24, - 0xB4, 0xB8, 0x25, 0xEC, 0x28, 0x2D, 0xF9, 0xCB, - 0x7D, 0x38, 0xFF, 0xC7, 0x74, 0x2E, 0xD3, 0x10, - 0xEC, 0x03, 0x31, 0xEE, 0x83, 0xE7, 0xA4, 0xF7, - 0xBA, 0x28, 0x21, 0xE0, 0x7F, 0xB4, 0xB7, 0xE1, - 0x7A, 0xF9, 0x2B, 0xB0, 0x2C, 0x3B, 0x80, 0x5F, - 0xE0, 0x5D, 0xB2, 0x7E, 0x59, 0xFF, 0x59, 0x07, - 0x58, 0x42, 0x57, 0xEE, 0x44, 0xF1, 0xB1, 0xAD, - 0xBA, 0xDE, 0xCB, 0x1D, 0x8A, 0x36, 0x67, 0xE8, - 0x45, 0xFF, 0x07, 0x8D, 0xEE, 0xA4, 0x51, 0x9C, - 0x4C, 0x83, 0x5D, 0x2E, 0x2F, 0xE1, 0x5B, 0x75, - 0xE8, 0x29, 0xCD, 0x0B, 0x07, 0x62, 0xE0, 0xC3, - 0x0D, 0x1D, 0xEA, 0xCF, 0xF0, 0x8A, 0x65, 0x27, - 0x70, 0x42, 0x9F, 0x26, 0x00, 0x15, 0x70, 0xC5, - 0x4A, 0xF6, 0x25, 0xD0, 0x40, 0x72, 0xE9, 0xC1, - 0x73, 0xFD, 0x48, 0x94, 0xA3, 0x8D, 0x66, 0x63, - 0x96, 0x4F, 0xF7, 0xEE, 0xFB, 0x4C, 0xC7, 0xB8, - 0x6B, 0xE9, 0x90, 0xE1, 0x2A, 0x66, 0x80, 0x99, - 0x3B, 0xB0, 0x1A, 0x6C, 0xF9, 0x0E, 0x72, 0xDA, - 0x8E, 0x4F, 0x46, 0xC2, 0x6A, 0x4B, 0x7A, 0x16, - 0xE5, 0x26, 0x0B, 0x5C, 0xD4, 0x47, 0x34, 0xE5, - 0x37, 0xBE, 0x68, 0x6C, 0xDA, 0xD3, 0x9B, 0x6F, - 0xAE, 0x51, 0x9C, 0x99, 0x0A, 0x5B, 0xF8, 0x37, - 0xBC, 0xDE, 0xFC, 0x93, 0xC5, 0xE7, 0x0F, 0xEF, - 0x0B, 0xA6, 0x07, 0xC2, 0xA6, 0xE6, 0xDA, 0x2D, - 0x1B, 0x49, 0xC9, 0xDE, 0x6B, 0x27, 0xDC, 0x00, - 0xEF, 0x23, 0x87, 0x0E, 0xEB, 0xD1, 0x48, 0x7D, - 0xB4, 0xF2, 0x58, 0xC6, 0x3C, 0xE2, 0x89, 0xBA, - 0xB0, 0x05, 0xAC, 0x94, 0x41, 0x9A, 0xA8, 0xFF, - 0x3E, 0xBC, 0x3A, 0x52, 0x9C, 0xF9, 0x7F, 0x07, - 0x8B, 0xB0, 0x2C, 0x71, 0x83, 0x7B, 0xCF, 0x2E, - 0x7F, 0x7C, 0x96, 0x65, 0xD9, 0x08, 0x17, 0xEC, - 0xFA, 0xDE, 0x4E, 0x40, 0x12, 0x26, 0x70, 0x71, - 0x65, 0xA5, 0xDC, 0x98, 0x47, 0xA3, 0xFC, 0xE0, - 0x9A, 0x16, 0xED, 0x45, 0x56, 0x72, 0x50, 0x05, - 0x28, 0x2C, 0x99, 0xEC, 0x20, 0x2E, 0x40, 0xC0, - 0x26, 0x69, 0xCD, 0x49, 0x45, 0x17, 0xA4, 0xA3, - 0x42, 0x0D, 0x14, 0x65, 0x87, 0x33, 0x8C, 0x92, - 0xC5, 0xC4, 0x61, 0xFD, 0xE8, 0x68, 0x56, 0x20, - 0x57, 0xF5, 0x8E, 0x5F, 0xCF, 0x7E, 0x97, 0xF6, - 0x49, 0x97, 0x0A, 0xFE, 0xD3, 0x60, 0x1A, 0x5B, - 0x0C, 0x75, 0xDD, 0x8E, 0x31, 0x78, 0x29, 0xA6, - 0xB1, 0x4D, 0xAA, 0xDF, 0x8A, 0xD1, 0xE6, 0x91, - 0xE3, 0x32, 0x3F, 0xEC, 0x8A, 0x1F, 0x0E, 0x35, - 0x07, 0x6E, 0x4B, 0x83, 0x3B, 0xE5, 0x67, 0x34, - 0x1F, 0x0C, 0x81, 0xD8, 0xD5, 0x25, 0x68, 0xE5, - 0x28, 0x1B, 0x5C, 0x81, 0x3E, 0xE3, 0x5C, 0xB4, - 0xB6, 0xBD, 0x62, 0x6A, 0x70, 0x33, 0xC2, 0xC5, - 0x75, 0x27, 0xF4, 0x30, 0xE1, 0x1D, 0xC1, 0x4C, - 0xC5, 0x02, 0x12, 0x46, 0xAC, 0xEC, 0xF9, 0xE8, - 0xE7, 0x58, 0x24, 0x11, 0xB1, 0xF3, 0xB7, 0x8C, - 0x3C, 0xA4, 0x0A, 0x94, 0xA6, 0x7C, 0x68, 0x54, - 0x5B, 0xB9, 0x4D, 0x57, 0x9C, 0xE7, 0x28, 0x09, - 0x6B, 0x89, 0x26, 0x5D, 0xE7, 0x50, 0xA9, 0x95, - 0x90, 0x91, 0x8E, 0x00, 0x59, 0xF8, 0x3A, 0x70, - 0xAF, 0x48, 0x2E, 0xE8, 0xC4, 0x34, 0x8C, 0xF4, - 0x5F, 0x7F, 0xCB, 0x07, 0xAA, 0xF0, 0xD9, 0xFB, - 0x5C, 0x32, 0x90, 0x22, 0x1A, 0xD2, 0x1A, 0xCF, - 0x92, 0x06, 0x02, 0xCF, 0x10, 0x18, 0x7B, 0x93, - 0xCC, 0x07, 0x4A, 0x31, 0x25, 0x30, 0x23, 0x06, - 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, - 0x09, 0x15, 0x31, 0x16, 0x04, 0x14, 0xD1, 0xDE, - 0x23, 0x16, 0x9F, 0x6E, 0xF4, 0x42, 0x21, 0x23, - 0xE1, 0x11, 0xAA, 0xC8, 0x7C, 0x60, 0x4A, 0x78, - 0x9D, 0x24, 0x30, 0x31, 0x30, 0x21, 0x30, 0x09, - 0x06, 0x05, 0x2B, 0x0E, 0x03, 0x02, 0x1A, 0x05, - 0x00, 0x04, 0x14, 0xD6, 0x4A, 0xBB, 0x75, 0xB1, - 0xF9, 0x9E, 0xD3, 0x58, 0x6D, 0xD1, 0x74, 0x9F, - 0x00, 0x8A, 0xF2, 0xC8, 0xAA, 0x52, 0x4D, 0x04, - 0x08, 0x77, 0x46, 0xE7, 0xBA, 0x25, 0x4B, 0xDA, - 0x41, 0x02, 0x02, 0x08, 0x00] -}; - -const WPA_EAP_CLIENT_LIST = [ - { - ssid: 'WPA-EAP-PEAP', - keyManagement: 'WPA-EAP', - eap: 'PEAP', - identity: EAP_USERNAME, - password: EAP_PASSWORD, - serverCertificate: CLIENT_PKCS12_CERT.nickname, - phase2: 'MSCHAPV2' - } -]; - -/** - * Convert the given MozWifiNetwork object array to testAssociate chain. - * - * @param aNetworks - * An array of MozWifiNetwork which we want to convert. - * - * @return A promise chain which "then"s testAssociate accordingly. - */ -function convertToTestAssociateChain(aNetworks) { - let chain = Promise.resolve(); - - aNetworks.forEach(function (aNetwork) { - network = new window.MozWifiNetwork(aNetwork); - chain = chain.then(() => gTestSuite.testAssociate(network)); - }); - - return chain; -} - -gTestSuite.doTestWithCertificate( - new Blob([new Uint8Array(CLIENT_PKCS12_CERT.content)]), - CLIENT_PKCS12_CERT.password, - CLIENT_PKCS12_CERT.nickname, - CLIENT_PKCS12_CERT.usage, - function() { - return gTestSuite.ensureWifiEnabled(true) - // Load required server files. - .then(() => gTestSuite.writeFile(SERVER_EAP_USER_CONF.path, SERVER_EAP_USER_CONF.content)) - .then(() => gTestSuite.writeFile(CA_CERT.path, CA_CERT.content)) - .then(() => gTestSuite.writeFile(SERVER_CERT.path, SERVER_CERT.content)) - .then(() => gTestSuite.writeFile(SERVER_KEY.path, SERVER_KEY.content)) - // Start AP. - .then(() => gTestSuite.startHostapds(WPA_EAP_AP_LIST)) - // Scan test. - .then(() => gTestSuite.testWifiScanWithRetry(SCAN_RETRY_CNT, WPA_EAP_AP_LIST)) - // Associate test. - .then(() => convertToTestAssociateChain(WPA_EAP_CLIENT_LIST)) - // Tear down. - .then(gTestSuite.killAllHostapd) -}); diff --git a/dom/wifi/test/marionette/test_wifi_associate_WPA_EAP_TLS.js b/dom/wifi/test/marionette/test_wifi_associate_WPA_EAP_TLS.js deleted file mode 100644 index 35b942f8e..000000000 --- a/dom/wifi/test/marionette/test_wifi_associate_WPA_EAP_TLS.js +++ /dev/null @@ -1,622 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -MARIONETTE_TIMEOUT = 60000; -MARIONETTE_HEAD_JS = 'head.js'; - -const SCAN_RETRY_CNT = 5; - -const EAP_USERNAME = 'username'; -const EAP_PASSWORD = 'password'; - -const SERVER_EAP_USER_CONF = { - path: HOSTAPD_CONFIG_PATH + 'hostapd.eap_user', - content: '* PEAP,TTLS,TLS\n' + - '"' + EAP_USERNAME + '" MSCHAPV2,TTLS-MSCHAPV2 "' + EAP_PASSWORD + '" [2]\n' -}; -const CA_CERT = { - path: HOSTAPD_CONFIG_PATH + 'ca.pem', - content: '-----BEGIN CERTIFICATE-----\n' + - 'MIIDsTCCApmgAwIBAgIJAKxTf+8X8qngMA0GCSqGSIb3DQEBCwUAMG4xCzAJBgNV\n' + - 'BAYTAlRXMRMwEQYDVQQIDApTb21lLVN0YXRlMREwDwYDVQQKDAhjaHVja2xlZTER\n' + - 'MA8GA1UEAwwIY2h1Y2tsZWUxJDAiBgkqhkiG9w0BCQEWFWNodWNrbGkwNzA2QGdt\n' + - 'YWlsLmNvbTAgFw0xNDEyMjQxMTI4NTBaGA8yMjg4MTAwNzExMjg1MFowbjELMAkG\n' + - 'A1UEBhMCVFcxEzARBgNVBAgMClNvbWUtU3RhdGUxETAPBgNVBAoMCGNodWNrbGVl\n' + - 'MREwDwYDVQQDDAhjaHVja2xlZTEkMCIGCSqGSIb3DQEJARYVY2h1Y2tsaTA3MDZA\n' + - 'Z21haWwuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAo3c2yFxY\n' + - 'o6gGg0I83jy00ME+MAfzCd+4ShL45ZLqysQP93jRBfPzU9ZuZ29ysVwgWIdqkZao\n' + - 'XTuV/NAW2GMGd8W1jQJ3J81fjb9wvhlny3rrACwvUn1N1S1BnM+BAAiDLGxEmvAQ\n' + - 'onp2aaa6HsHsYS8ONX+d2Qh4LEA4vupeSGAqJychCZv/l+aq/ErFZhFYB3CPUQEt\n' + - 'cClO24ucsIYP95lA0zhscnmAj06qplFD4Bv6IVrdDqujy1zNwCQwsJq/8OQdaTN/\n' + - 'h3y9pWvNKMBMM2niOUAjtuNpqsSK/lTS1WAT3PdtVECX9fYBi0Bg+HM92xs/6gt6\n' + - 'kh9jPV8keXHvSwIDAQABo1AwTjAdBgNVHQ4EFgQU7hBqhuG04xeCzrQ3ngx18ZJ3\n' + - 'lUswHwYDVR0jBBgwFoAU7hBqhuG04xeCzrQ3ngx18ZJ3lUswDAYDVR0TBAUwAwEB\n' + - '/zANBgkqhkiG9w0BAQsFAAOCAQEAFYX2iy680GAnBTttk0gyX6gk+8pYr3D22k/G\n' + - '6rvcjefzS7ELQPRKr6mfmwXq3mMf/4jiS2zI5zmXsestPYzHYxf2viQ6t7vr9XiJ\n' + - '3WfFjNw4ERlRisAvg0aqqTNNQq5v2VME4sdFZagy217f73C7azwCHl0bqOLH05rl\n' + - '8RubOxiHEj7ZybJqnRciK/bht4D+rZkwf4bBBmoloqH7xT0+rFQclpYXDGGjNUQB\n' + - 'LcHLF10xcr7g3ZVVu82fe6+d85gIGOIMR9+TKhdw6gO3CNcnDAj6gxksghgtcxmh\n' + - 'OzOggCn7nlIwImtsg2sZkpWB4lEi9hdv4lkNuyFjOL3bnuc+NA==\n' + - '-----END CERTIFICATE-----\n' -}; - -const SERVER_CERT = { - path: HOSTAPD_CONFIG_PATH + 'server.pem', - content: '-----BEGIN CERTIFICATE-----\n' + - 'MIID1DCCArygAwIBAgIBADANBgkqhkiG9w0BAQsFADBuMQswCQYDVQQGEwJUVzET\n' + - 'MBEGA1UECAwKU29tZS1TdGF0ZTERMA8GA1UECgwIY2h1Y2tsZWUxETAPBgNVBAMM\n' + - 'CGNodWNrbGVlMSQwIgYJKoZIhvcNAQkBFhVjaHVja2xpMDcwNkBnbWFpbC5jb20w\n' + - 'IBcNMTQxMjI0MTEyOTQ5WhgPMjI4ODEwMDcxMTI5NDlaMG4xCzAJBgNVBAYTAlRX\n' + - 'MRMwEQYDVQQIDApTb21lLVN0YXRlMREwDwYDVQQKDAhjaHVja2xlZTERMA8GA1UE\n' + - 'AwwIY2h1Y2tsZWUxJDAiBgkqhkiG9w0BCQEWFWNodWNrbGkwNzA2QGdtYWlsLmNv\n' + - 'bTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMdhQmKilTJbWZRxTiSV\n' + - 'rqIU+LYW1RKghx5o+0JpNRJVLuz5kBMaNskbbfUSNuHbEq0QA9BDKAZWIc4LSotk\n' + - 'lCo8TbcO9CJvJPQGGjGdHcohWX5vy6BE/OVE46CUteMFyZF6F8R2fNUww08iR/u1\n' + - 'YZebL5pWO1j43sPpAzEy6Tij2ACPt6EZcFaZG3SF2mVJWkCQnBqrojP65WUvZQqp\n' + - 'seUhW2YAS8Nu0Yrohgxz6VYk+cNDuDZVGs6qWRStZzJfYrfc76DtkHof5B14M+xp\n' + - 'XJaBLxN+whvnYkDTfinaCxnW1O7eXUltr87fLc5zmeBkgwaiaQuIdcfZm7vDUiz8\n' + - 'vnUCAwEAAaN7MHkwCQYDVR0TBAIwADAsBglghkgBhvhCAQ0EHxYdT3BlblNTTCBH\n' + - 'ZW5lcmF0ZWQgQ2VydGlmaWNhdGUwHQYDVR0OBBYEFKK4f9/YavTHOfEiAB83Deac\n' + - '6gT5MB8GA1UdIwQYMBaAFO4QaobhtOMXgs60N54MdfGSd5VLMA0GCSqGSIb3DQEB\n' + - 'CwUAA4IBAQBWnO9o9KSJIqjoz5Nwll63ULOdcvgGdOeJIw1fcKQ817Rsp+TVcjcH\n' + - 'IrIADsT/QZGXRO/l6p1750e2iFtJEo1hsRaxtA1wWn2I9HO3+av2spQhr3jpYGPf\n' + - 'zpsMTp4RNYV7Q8+q1kZIz9PY4V1T0p6lveK8+fUj2hSLnxSj0QiGSJJtnEC3w4Rv\n' + - 'C9T6oUwIeToULmi+8FXQFdEqwKRU98DPq3eLzN28ZxUgoPE1C8+42D2UW8uyp/Gm\n' + - 'tGOa/k7nzkCdVqZI7lX7f0AjEvQgjtAMQ/k7Mhxx7TzW2HO+1YPMoKji6Z4WkNwt\n' + - 'JEj9ZUBSNt8B26UksJMBDkcvSegF3a7o\n' + - '-----END CERTIFICATE-----\n' -}; - -const SERVER_KEY = { - path: HOSTAPD_CONFIG_PATH + 'server.key', - content: '-----BEGIN RSA PRIVATE KEY-----\n' + - 'MIIEpAIBAAKCAQEAx2FCYqKVMltZlHFOJJWuohT4thbVEqCHHmj7Qmk1ElUu7PmQ\n' + - 'Exo2yRtt9RI24dsSrRAD0EMoBlYhzgtKi2SUKjxNtw70Im8k9AYaMZ0dyiFZfm/L\n' + - 'oET85UTjoJS14wXJkXoXxHZ81TDDTyJH+7Vhl5svmlY7WPjew+kDMTLpOKPYAI+3\n' + - 'oRlwVpkbdIXaZUlaQJCcGquiM/rlZS9lCqmx5SFbZgBLw27RiuiGDHPpViT5w0O4\n' + - 'NlUazqpZFK1nMl9it9zvoO2Qeh/kHXgz7GlcloEvE37CG+diQNN+KdoLGdbU7t5d\n' + - 'SW2vzt8tznOZ4GSDBqJpC4h1x9mbu8NSLPy+dQIDAQABAoIBAASG4Mr8hgaurEoC\n' + - 'iJOsElr7vunjetMBcg/uskW/vcS8ymP3Bp5oafYG+WgnEbfvEW18f5mq7K24JuxW\n' + - 'tUqU7ghHdjxByqk9fMlNmiqmNpbwSufkAeuRpWxPNBvhRH/zEbCL5R5A0nTEtqqF\n' + - 'TL0aUSzwCRSoAJD0lZo9ICVt0n3GsDyM9rqQg/uZmh1qsRdwPsRuYORND9g48rKq\n' + - '6WN9leskSxhhsYE2D9ocOFd9bNt8Zxejh9ppVSnG/KsIdt18iBzcabatgAQ046fb\n' + - 'Z3vprcZJLg93Sg2gSuVqlSTs3M2W8VQnm22/EBMb1y0M48MSRCgnbPLG/CcCLLfF\n' + - 'LwxCOgECgYEA/eYt67xyJ6JeAdxdwOZuT1WWGbFpLiG9+2OgiHumyRQ5969XMTWo\n' + - 'fIhMKchDdjoy9RR236\/\/EFCs7UEyB7+a7ODRzNiK2zCD8Smjp+21fUPSthEeQesk\n' + - 'eiMYICIu5Ay35x9sxIX+XOUVvRhPOGcD29GVeRnKh1inTHOz2dje8LkCgYEAyQeY\n' + - 'STi9jjCEcHkM1E/UeDiLfHHepLXi8wS41JNRHl5Jacp7XB5djAjKu/jf367/VpFy\n' + - 'GDDMetE7n8eWkrnAvovxOwZ000YDMtL1sUYSjL+XtBS5s6VY1p4qaSAY9nUUGrJh\n' + - 'JvtvsuI7SKTtL+60vjBOH7zDnvOdBgAp0utLhZ0CgYEAuLzzqrPKB8afShFSchn4\n' + - 'J2dpuLYahsNsXW7HDqeR2nsKFosRETAusLXnXPtnAq4kB6jlOarwFqnsuRCX24Vx\n' + - 'r2uBm9/vYL7zMdUPTA+s30ErHuhjsKjsOKYyVqcooSwT32pBFNk+E89nutfmRG7I\n' + - 'IvhjHuNCNqqtx/Xj5d1jkZkCgYBQicppC2Jl5OoqZVTOem0U/RJk+PnJ41TZJ7sk\n' + - '7yBAmmWvDH\/\/l+rCf4M5a6vFYcbKV9rt9h711X2dtciNX/3oWQh8LUoAmrwNUJc+\n' + - 'PmSQHvIYI3WCk2vUD+nN1B4sHxu+1lg11eYaNKiroeeknG2tBI1ICcgVlmQCU25u\n' + - 'IfZPwQKBgQCdO6QHhPLtcHUDNFA6FQ1jKL1iEd7G0JLVRz4Xkpkn1Vrr5MD6JFDa\n' + - '5ccabADyl0lpFqDIVJQIzLku2hOD2i9aBNCY0pL391HeOS7CkZX+TdOY1tquoBq5\n' + - 'MnmixZjDCVd2VcrVyTA6ntOBoharKFW0rH1PqU+qu7dZF7CBPbAdEw==\n' + - '-----END RSA PRIVATE KEY-----\n' -}; - -const WPA_EAP_AP_LIST = [ - { - ssid: 'WPA-EAP-TLS', - ieee8021x: 1, - eapol_version: 1, - eap_server: 1, - eapol_key_index_workaround: 0, - eap_user_file: SERVER_EAP_USER_CONF.path, - ca_cert: CA_CERT.path, - server_cert: SERVER_CERT.path, - private_key: SERVER_KEY.path, - wpa: 2, - wpa_key_mgmt: 'WPA-EAP' - } -]; - -const CLIENT_PKCS12_CERT = { - nickname: 'client', - password: 'password', - usage: ['UserCert', 'ServerCert'], - content: [0x30, 0x82, 0x0E, 0x01, 0x02, 0x01, 0x03, 0x30, - 0x82, 0x0D, 0xC7, 0x06, 0x09, 0x2A, 0x86, 0x48, - 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x01, 0xA0, 0x82, - 0x0D, 0xB8, 0x04, 0x82, 0x0D, 0xB4, 0x30, 0x82, - 0x0D, 0xB0, 0x30, 0x82, 0x08, 0x67, 0x06, 0x09, - 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, - 0x06, 0xA0, 0x82, 0x08, 0x58, 0x30, 0x82, 0x08, - 0x54, 0x02, 0x01, 0x00, 0x30, 0x82, 0x08, 0x4D, - 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, - 0x01, 0x07, 0x01, 0x30, 0x1C, 0x06, 0x0A, 0x2A, - 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x0C, 0x01, - 0x06, 0x30, 0x0E, 0x04, 0x08, 0x67, 0x7A, 0xF3, - 0x61, 0xBE, 0xE0, 0x51, 0xC1, 0x02, 0x02, 0x08, - 0x00, 0x80, 0x82, 0x08, 0x20, 0xFC, 0x6A, 0x79, - 0xA1, 0x6C, 0xAF, 0xBE, 0xEE, 0x62, 0x45, 0x33, - 0xB8, 0x48, 0xE1, 0x68, 0xA1, 0x15, 0x11, 0x4B, - 0x95, 0xCB, 0x77, 0xC0, 0x5D, 0xA2, 0xCB, 0xDB, - 0xD1, 0x83, 0x74, 0x60, 0xD7, 0xEC, 0x42, 0xA6, - 0x3A, 0x23, 0xF7, 0x85, 0xEB, 0xC1, 0xFE, 0x6A, - 0x57, 0x8E, 0xC1, 0x44, 0xF3, 0x1F, 0xFE, 0xB8, - 0x2D, 0x8C, 0x4D, 0xC9, 0x5B, 0xAE, 0x21, 0x2E, - 0x4C, 0x1A, 0xEB, 0x84, 0x09, 0xF3, 0x40, 0x92, - 0x39, 0x7F, 0x56, 0x02, 0x46, 0x61, 0x16, 0xDE, - 0x5C, 0x48, 0xB6, 0x0C, 0x1D, 0xD3, 0x5F, 0x10, - 0x9A, 0x39, 0xB8, 0x66, 0x31, 0xFC, 0x39, 0x71, - 0x87, 0x23, 0x46, 0x9D, 0xE8, 0x3C, 0x2B, 0xA1, - 0x39, 0x8A, 0xD3, 0xFF, 0xD9, 0x43, 0xB6, 0x61, - 0xC6, 0x67, 0x70, 0x40, 0xBD, 0xFE, 0xD3, 0xC1, - 0x68, 0xF5, 0xF7, 0xC8, 0x89, 0xD8, 0x17, 0xC5, - 0xE8, 0x3D, 0x29, 0xD5, 0x91, 0xDF, 0x1F, 0x56, - 0x74, 0x5A, 0xC4, 0xA8, 0x14, 0xBA, 0xD4, 0xFA, - 0x13, 0x49, 0x2A, 0x9F, 0x63, 0xF1, 0xB2, 0x45, - 0xF1, 0xF0, 0x2A, 0xDD, 0x75, 0x66, 0x8A, 0xF7, - 0xAB, 0x73, 0x86, 0x26, 0x9D, 0x1F, 0x07, 0xAD, - 0xD3, 0xFE, 0xE0, 0xA3, 0xED, 0xA0, 0x96, 0x3E, - 0x1E, 0x89, 0x86, 0x02, 0x4C, 0x28, 0xFD, 0x57, - 0xA1, 0x67, 0x55, 0xF0, 0x82, 0x3B, 0x7F, 0xCC, - 0x2A, 0x32, 0x01, 0x93, 0x1D, 0x8B, 0x66, 0x8A, - 0x20, 0x52, 0x84, 0xDD, 0x2C, 0xFD, 0xEE, 0x72, - 0xF3, 0x8C, 0x58, 0xB9, 0x99, 0xE5, 0xC1, 0x22, - 0x63, 0x59, 0x00, 0xE2, 0x76, 0xC5, 0x3A, 0x17, - 0x7F, 0x93, 0xE9, 0x67, 0x61, 0xAA, 0x10, 0xC3, - 0xD9, 0xC8, 0x24, 0x46, 0x5B, 0xBE, 0x8C, 0x1F, - 0x2D, 0x66, 0x48, 0xD2, 0x02, 0x11, 0xFB, 0x74, - 0x14, 0x76, 0x76, 0x5A, 0x98, 0x54, 0x35, 0xA7, - 0x85, 0x66, 0x20, 0x26, 0x8B, 0x13, 0x6F, 0x68, - 0xE3, 0xC9, 0x58, 0x7D, 0x1C, 0x3E, 0x01, 0x8D, - 0xF8, 0xD6, 0x7F, 0xCF, 0xA2, 0x07, 0xB7, 0x95, - 0xFD, 0xF0, 0x02, 0x34, 0x32, 0x30, 0xE8, 0xD4, - 0x57, 0x5E, 0x53, 0xFB, 0x54, 0xE2, 0x03, 0x32, - 0xCC, 0x52, 0x2E, 0xD2, 0x35, 0xD9, 0x58, 0x85, - 0x2D, 0xEC, 0x2D, 0x71, 0xD1, 0x8A, 0x29, 0xD0, - 0xB0, 0x24, 0xBD, 0x24, 0xDC, 0x1A, 0x28, 0x3F, - 0xA0, 0x12, 0x81, 0x15, 0x24, 0xC9, 0xB5, 0x4A, - 0x23, 0xB6, 0xA3, 0x45, 0x50, 0x2D, 0x73, 0x99, - 0x6B, 0x1C, 0xFB, 0xA4, 0x53, 0xD7, 0x5C, 0xF4, - 0x6C, 0xB0, 0xE5, 0x74, 0xB3, 0x76, 0xF8, 0xB1, - 0x0D, 0x59, 0x70, 0x9F, 0xCA, 0xDE, 0xF2, 0xAA, - 0x4C, 0x7D, 0x11, 0x54, 0xC4, 0x19, 0x0F, 0x36, - 0x4A, 0x62, 0xFF, 0x8B, 0x10, 0xCB, 0x93, 0x50, - 0xDA, 0x79, 0x5E, 0x4E, 0x09, 0x1F, 0x22, 0xC8, - 0x19, 0x85, 0xE9, 0xEE, 0xB7, 0x71, 0x65, 0xB9, - 0x10, 0xD2, 0x0A, 0x73, 0x5B, 0xA6, 0xDA, 0x37, - 0x46, 0x02, 0x00, 0x98, 0x9E, 0x20, 0x6C, 0x7D, - 0xC7, 0x69, 0xBB, 0xC2, 0x00, 0x40, 0x9C, 0x57, - 0x00, 0xC2, 0x36, 0x76, 0xE8, 0x2A, 0x8D, 0xAD, - 0x62, 0x57, 0xC8, 0xD0, 0x9D, 0x66, 0x27, 0x5A, - 0xD8, 0x0D, 0x35, 0x60, 0x28, 0x38, 0x62, 0x94, - 0x78, 0x36, 0x25, 0x58, 0xFD, 0xF8, 0x66, 0x1F, - 0x68, 0x04, 0x0F, 0xD8, 0x00, 0xDF, 0xA0, 0x6C, - 0x25, 0x42, 0x9A, 0x4C, 0xEB, 0x80, 0x13, 0x51, - 0x7D, 0x2D, 0xA8, 0x89, 0xD6, 0x1B, 0x67, 0x72, - 0x01, 0xF3, 0x2D, 0x16, 0x77, 0xFE, 0x22, 0xBC, - 0x8A, 0x45, 0x09, 0x1F, 0x9C, 0x2F, 0x2A, 0xA9, - 0x61, 0x5B, 0x4A, 0xE6, 0x64, 0x2C, 0x62, 0x1A, - 0x3A, 0x96, 0xE6, 0x0A, 0xAE, 0x05, 0x1A, 0xC8, - 0xCB, 0xD6, 0x8F, 0x3A, 0x4B, 0xE0, 0x7F, 0x82, - 0xB4, 0x98, 0xF1, 0x9D, 0xD7, 0x14, 0x76, 0x5E, - 0x77, 0x85, 0x87, 0xEC, 0x13, 0xDA, 0xFD, 0xAF, - 0xCB, 0xA3, 0x1C, 0x99, 0xC1, 0xFE, 0x17, 0x0C, - 0x40, 0x4D, 0x3C, 0x8F, 0x70, 0x86, 0x63, 0x64, - 0xB7, 0x75, 0xA8, 0x71, 0x36, 0xDC, 0x54, 0x10, - 0x57, 0x0C, 0xA8, 0xF2, 0xA1, 0xBB, 0xED, 0x03, - 0x41, 0x57, 0x34, 0x2C, 0x8F, 0x7C, 0xA0, 0x09, - 0xF3, 0x9E, 0x41, 0xB7, 0xA8, 0xD4, 0x66, 0x0D, - 0x0D, 0xC0, 0x6A, 0xFC, 0x6A, 0xA2, 0xAC, 0xE2, - 0x60, 0x00, 0xE3, 0xF7, 0x75, 0x43, 0x23, 0xEB, - 0xC8, 0x61, 0xFA, 0xB3, 0xB8, 0x28, 0xCE, 0xCA, - 0xF4, 0x47, 0x7F, 0x30, 0x6D, 0x61, 0x89, 0x47, - 0xA1, 0x4A, 0xFE, 0xD1, 0x21, 0x0B, 0x6D, 0xF4, - 0x3F, 0x00, 0x86, 0x30, 0x8E, 0x33, 0x21, 0x6F, - 0xDA, 0x15, 0xFD, 0x5F, 0xEC, 0x8E, 0xF1, 0x12, - 0x3F, 0xC9, 0x83, 0x0C, 0xCA, 0x22, 0x01, 0xF1, - 0x70, 0x5F, 0x1F, 0x66, 0xB5, 0xF8, 0x3E, 0x7A, - 0x6F, 0xDE, 0xDB, 0xA7, 0x8D, 0x18, 0x9E, 0xBE, - 0xDB, 0xAD, 0x3D, 0x66, 0x30, 0xC1, 0x6C, 0x0C, - 0x87, 0xB4, 0x65, 0x75, 0xE0, 0x9D, 0xEA, 0x16, - 0x0D, 0x07, 0x37, 0x33, 0xC5, 0xEC, 0x97, 0x93, - 0x37, 0xEB, 0x8E, 0x65, 0x9C, 0x40, 0x63, 0x6C, - 0x43, 0x60, 0xB0, 0x40, 0x4D, 0x85, 0xEF, 0xC2, - 0x47, 0x5F, 0xE7, 0x6B, 0xCB, 0x40, 0xE8, 0xEA, - 0xD8, 0xAB, 0xB1, 0x9A, 0x72, 0xDC, 0x4C, 0x14, - 0xFA, 0x43, 0x61, 0x5F, 0xA6, 0x5C, 0x3A, 0x05, - 0x17, 0x2E, 0x74, 0xF3, 0x5E, 0x45, 0xD9, 0x47, - 0xAA, 0x59, 0xB6, 0x8F, 0x42, 0x66, 0x42, 0x29, - 0x90, 0x95, 0x48, 0x46, 0x91, 0x88, 0x3C, 0x8C, - 0xDE, 0xCC, 0xED, 0xB3, 0xAA, 0x62, 0xEA, 0xBC, - 0xB4, 0x0C, 0x48, 0x4C, 0x53, 0x23, 0x5E, 0x24, - 0x85, 0xBF, 0x92, 0xDA, 0x14, 0xDB, 0x1A, 0x3D, - 0xEF, 0x30, 0xD9, 0x49, 0x64, 0x4D, 0xE5, 0x01, - 0xFC, 0xA4, 0x4B, 0xD1, 0x9F, 0xDE, 0x96, 0x7F, - 0x50, 0xBC, 0x4D, 0x38, 0x44, 0xE9, 0x23, 0x5F, - 0x37, 0x57, 0x1A, 0xA6, 0x52, 0x5A, 0x0F, 0x4F, - 0x87, 0x33, 0x4A, 0x7B, 0x66, 0xEE, 0x3D, 0x66, - 0x0A, 0x63, 0x39, 0x1F, 0x23, 0x38, 0x35, 0x73, - 0x60, 0x5E, 0x47, 0x20, 0x4F, 0xC0, 0xC8, 0x3C, - 0x09, 0xF9, 0x29, 0x4F, 0x5E, 0x55, 0x69, 0xC4, - 0x6B, 0xE8, 0xF8, 0x91, 0xC0, 0x22, 0x65, 0x15, - 0x1E, 0xFB, 0xB9, 0x61, 0xCE, 0x45, 0xBE, 0x2B, - 0xEE, 0xB9, 0x04, 0x2B, 0xFD, 0xAE, 0x61, 0x1C, - 0x3D, 0x3D, 0x7C, 0xBF, 0xC1, 0xF7, 0x3C, 0x4E, - 0x9E, 0x0E, 0x54, 0xC8, 0xAD, 0xA9, 0xDF, 0x43, - 0x49, 0xB9, 0x41, 0x05, 0xE5, 0xF1, 0x49, 0xAA, - 0x77, 0x6C, 0x34, 0x5B, 0x93, 0x24, 0x24, 0x23, - 0x74, 0x68, 0x11, 0xCE, 0x15, 0x80, 0xA1, 0xA4, - 0x1F, 0x8D, 0x81, 0xCD, 0xB2, 0x98, 0xCA, 0x14, - 0x0B, 0x0C, 0x61, 0x50, 0x69, 0x72, 0xAE, 0xFA, - 0x8B, 0xC0, 0x3F, 0x0D, 0xE7, 0xF2, 0x0F, 0xEB, - 0xC1, 0x11, 0xB9, 0x10, 0x03, 0x6A, 0xF5, 0x97, - 0x3C, 0x53, 0x2F, 0x67, 0x86, 0x09, 0x6A, 0xE3, - 0x28, 0xC0, 0x78, 0xC8, 0xB4, 0x39, 0x8E, 0xD1, - 0xCE, 0x25, 0xE8, 0x66, 0xF7, 0x09, 0x40, 0x7D, - 0x81, 0xFB, 0xAF, 0xFA, 0x59, 0xC4, 0x9B, 0x2B, - 0x83, 0x45, 0x5B, 0xA8, 0x66, 0x9E, 0x38, 0xC8, - 0xFD, 0xAC, 0xF2, 0x2D, 0x21, 0xDE, 0x50, 0x4C, - 0x03, 0xCB, 0x88, 0x42, 0xDD, 0x84, 0x09, 0x99, - 0x8E, 0x8B, 0x40, 0x97, 0x1B, 0x14, 0x85, 0x37, - 0x11, 0x01, 0xE0, 0x74, 0x6B, 0x33, 0x52, 0x8C, - 0x68, 0x3A, 0x89, 0xB2, 0xAF, 0x35, 0xE6, 0x65, - 0xC3, 0x58, 0x70, 0xD2, 0xE7, 0x1F, 0x1F, 0xF6, - 0xE5, 0x0A, 0xB1, 0xFE, 0xD0, 0xC9, 0x51, 0x50, - 0xE7, 0xFD, 0x58, 0xF5, 0xC4, 0x58, 0x65, 0x94, - 0xD1, 0x57, 0x55, 0x5E, 0xD2, 0x27, 0x98, 0xAF, - 0xE7, 0x55, 0x0B, 0x87, 0x50, 0x9B, 0xEF, 0xE8, - 0x2B, 0xFC, 0xE7, 0x3B, 0x4E, 0xD7, 0xB7, 0x4D, - 0xF4, 0xBC, 0xF4, 0x88, 0x63, 0xE4, 0x8A, 0x20, - 0x4B, 0x22, 0xB0, 0xA0, 0x53, 0x7F, 0xA8, 0xC9, - 0x0C, 0xF8, 0xD7, 0xBD, 0x46, 0x39, 0xA7, 0x7D, - 0xDD, 0x10, 0x91, 0x50, 0x54, 0x06, 0x47, 0xF0, - 0x3C, 0xAA, 0x43, 0x40, 0xF8, 0x54, 0xDD, 0x8A, - 0xEA, 0x8A, 0x0B, 0xA5, 0x7F, 0xCD, 0x5E, 0xAA, - 0x02, 0x2E, 0x1F, 0xC6, 0x50, 0x15, 0xF8, 0x0A, - 0x0C, 0x1B, 0x3C, 0x55, 0x3A, 0xC3, 0x6F, 0x88, - 0xD7, 0xBF, 0xB1, 0x02, 0xCC, 0xE0, 0x08, 0x29, - 0x97, 0xD2, 0xAA, 0x23, 0xC4, 0x6D, 0xE3, 0xE3, - 0x76, 0x39, 0x92, 0xC3, 0x2E, 0x7A, 0xE2, 0x98, - 0xD1, 0xFC, 0xAE, 0xCC, 0x95, 0xD8, 0xB4, 0xDC, - 0x92, 0xEA, 0x6A, 0x5F, 0xF2, 0x92, 0x17, 0x0B, - 0x8D, 0xC3, 0xFA, 0x9C, 0x62, 0xCE, 0x44, 0x8D, - 0xC3, 0x1E, 0xC3, 0xB2, 0xD5, 0x00, 0xCD, 0xB4, - 0x9E, 0x2D, 0x7B, 0xF2, 0x98, 0xA3, 0x00, 0x8B, - 0x81, 0x30, 0x77, 0x5B, 0x02, 0x99, 0xB1, 0xCD, - 0xC3, 0x1D, 0x74, 0x74, 0xEF, 0x41, 0xCB, 0x69, - 0x63, 0x8E, 0xA6, 0xD3, 0x2D, 0x3E, 0x1F, 0x1D, - 0x12, 0x9E, 0xD9, 0x18, 0x67, 0x06, 0xAF, 0x37, - 0x29, 0xAD, 0x65, 0xD8, 0xEB, 0x71, 0xC4, 0x7D, - 0x94, 0x3D, 0xEA, 0xCC, 0xDF, 0x72, 0x41, 0x51, - 0x3C, 0xA1, 0x66, 0x98, 0x32, 0x32, 0x40, 0x54, - 0xB0, 0x2F, 0xEB, 0xCE, 0xDF, 0x4A, 0x64, 0xFB, - 0x9A, 0x90, 0xDC, 0xF6, 0x6F, 0xA9, 0xD4, 0xCA, - 0xCB, 0x91, 0xC4, 0xFE, 0xEE, 0x9C, 0x01, 0x50, - 0x2E, 0xAC, 0xCC, 0x5F, 0x89, 0xD0, 0x91, 0xA3, - 0xD9, 0xF9, 0x4B, 0x8D, 0xDE, 0x6C, 0x60, 0x21, - 0x19, 0xB1, 0xD3, 0x4D, 0x75, 0x56, 0x6F, 0xB8, - 0x25, 0xA4, 0x92, 0x4F, 0x12, 0xF5, 0x8F, 0xC1, - 0x17, 0x4B, 0xB3, 0x34, 0x21, 0x22, 0xAC, 0x52, - 0xD2, 0x64, 0xC9, 0x9A, 0x7D, 0xFC, 0xC0, 0x0A, - 0x89, 0x34, 0xFF, 0x08, 0xD3, 0x04, 0xDC, 0xFE, - 0x7C, 0xB3, 0xB8, 0xFD, 0x85, 0xDD, 0x79, 0x51, - 0xA7, 0x89, 0xE8, 0xF1, 0x23, 0xB1, 0xDF, 0xD7, - 0x1F, 0x7B, 0xB1, 0x5D, 0x42, 0xF9, 0x61, 0xF8, - 0xDC, 0x81, 0x04, 0xF1, 0xCC, 0xFA, 0xD7, 0xED, - 0xBF, 0x47, 0xAC, 0xBD, 0xE5, 0xFA, 0xAC, 0xB3, - 0x1C, 0xD9, 0xA1, 0xB3, 0x60, 0xEE, 0x9C, 0x8A, - 0x36, 0x57, 0xB4, 0x2F, 0xA1, 0xA2, 0xF3, 0xE2, - 0x09, 0x9A, 0x6E, 0x43, 0x9B, 0xE5, 0x93, 0xB8, - 0x3D, 0x9E, 0x9F, 0xC1, 0xC6, 0x0D, 0x02, 0xEB, - 0x4D, 0x38, 0xE9, 0xB4, 0x9F, 0xEA, 0x33, 0x8C, - 0x07, 0xD8, 0xB4, 0x71, 0xAD, 0xE5, 0x43, 0xB2, - 0xCC, 0x55, 0x93, 0x6A, 0xDB, 0x1E, 0x80, 0xDB, - 0xC2, 0xEA, 0x42, 0x8E, 0xFC, 0x86, 0x44, 0xC9, - 0x8A, 0xC4, 0xF2, 0x46, 0xA7, 0x39, 0x50, 0x0D, - 0x1A, 0xAA, 0x07, 0x04, 0xBE, 0xD4, 0xCE, 0x62, - 0x4D, 0x0F, 0x91, 0x7D, 0x29, 0x88, 0x9C, 0x4C, - 0xAF, 0xF7, 0xD8, 0x40, 0x93, 0x88, 0xC7, 0x20, - 0xD2, 0x17, 0x2A, 0xC4, 0x92, 0x72, 0xD0, 0xC0, - 0x4E, 0x56, 0x47, 0xB1, 0x27, 0x02, 0xE6, 0x61, - 0x82, 0x5E, 0xC8, 0x2E, 0x90, 0xD2, 0x31, 0x22, - 0xE2, 0xA9, 0x4A, 0x91, 0x45, 0x69, 0xB1, 0xA5, - 0x0F, 0x66, 0x2C, 0x30, 0xAD, 0x7F, 0x1B, 0x0E, - 0x22, 0x17, 0x60, 0x2E, 0x3D, 0x7F, 0x7F, 0x8C, - 0x33, 0x51, 0xA0, 0x25, 0xDE, 0xFD, 0x75, 0xBC, - 0xEF, 0xE6, 0xE7, 0x20, 0x04, 0x5A, 0xEC, 0x50, - 0x21, 0x48, 0x56, 0x98, 0xE2, 0x33, 0x6D, 0x22, - 0x5C, 0xC3, 0xFB, 0xFC, 0x6F, 0xB3, 0xA7, 0x8E, - 0x6F, 0x67, 0x70, 0x9D, 0xDA, 0x02, 0x01, 0x59, - 0x7B, 0x3D, 0x2B, 0x38, 0xCC, 0x0F, 0x44, 0x3D, - 0xFB, 0x9A, 0xB3, 0x23, 0x15, 0x50, 0x6E, 0xBF, - 0x8B, 0xA1, 0x94, 0x33, 0xE5, 0x7B, 0x88, 0x4E, - 0xCB, 0x6D, 0x9F, 0xBF, 0xBC, 0x7A, 0xA8, 0x1E, - 0x68, 0x25, 0xED, 0x8E, 0x53, 0x21, 0x72, 0xC5, - 0x70, 0xB3, 0xE4, 0xA6, 0xA1, 0x5A, 0x2D, 0xC8, - 0x43, 0x9D, 0x60, 0x77, 0x78, 0xE0, 0xC4, 0xAF, - 0xC8, 0x29, 0xBA, 0xD0, 0x4D, 0x39, 0x83, 0x51, - 0xA7, 0x10, 0x7F, 0x0C, 0x34, 0x0E, 0x6C, 0x75, - 0x26, 0xD7, 0xD6, 0xC7, 0x32, 0x53, 0xAF, 0x4E, - 0xBE, 0xF2, 0xC2, 0x0F, 0x99, 0x23, 0xB9, 0xE1, - 0xC8, 0xB4, 0xBC, 0x5A, 0xC6, 0xCB, 0xEB, 0x4D, - 0x28, 0x56, 0x72, 0xFE, 0x1B, 0x2C, 0x5D, 0xE3, - 0xBC, 0xC7, 0xA3, 0xC0, 0x7D, 0x27, 0xF0, 0xD0, - 0x4F, 0x3F, 0x1F, 0xF7, 0x87, 0x15, 0xF2, 0xEA, - 0xD4, 0x03, 0x6D, 0x2F, 0xD4, 0x8E, 0x50, 0x4B, - 0x05, 0xBF, 0xF7, 0x8C, 0x67, 0x5A, 0xDC, 0x4D, - 0xCD, 0xCF, 0x9D, 0x02, 0xB6, 0xE7, 0xAE, 0x49, - 0xD1, 0x7C, 0x00, 0xE7, 0x3B, 0xEA, 0xFB, 0x0D, - 0x2A, 0x7B, 0x41, 0x33, 0x66, 0xD0, 0x29, 0x9F, - 0xB3, 0x8A, 0x71, 0xB0, 0xE2, 0x76, 0xA9, 0xDB, - 0xFD, 0x64, 0x04, 0x69, 0xDF, 0x89, 0x1F, 0x56, - 0x86, 0x92, 0xD9, 0xD9, 0xB9, 0xF3, 0x4F, 0xAC, - 0xAE, 0x61, 0x48, 0x20, 0xCE, 0x3C, 0x2B, 0x44, - 0xAB, 0x42, 0xFA, 0xAB, 0x2E, 0x94, 0x82, 0xC8, - 0xD9, 0x97, 0xCF, 0x27, 0xDF, 0xAC, 0xAC, 0xE7, - 0xCA, 0xB2, 0x84, 0xAB, 0xF2, 0x5D, 0xDF, 0x56, - 0x0C, 0x8C, 0x07, 0x3C, 0x3D, 0xA8, 0xDD, 0xBE, - 0xFF, 0x4E, 0x28, 0x0D, 0xB2, 0x2D, 0xE6, 0x9D, - 0x44, 0x21, 0xCB, 0xE7, 0x33, 0x63, 0x22, 0x8F, - 0x4C, 0xFF, 0xB6, 0x1D, 0x9A, 0x71, 0x3F, 0xB1, - 0x29, 0xAE, 0x3A, 0x35, 0xEE, 0x9C, 0x97, 0x68, - 0xA7, 0x52, 0x66, 0x01, 0xD8, 0x9A, 0x5D, 0xF4, - 0xB3, 0x2F, 0x5C, 0xD4, 0x0E, 0xF9, 0xCF, 0x07, - 0xF6, 0x8C, 0xBA, 0xA6, 0x8D, 0x6B, 0xC6, 0x01, - 0xC2, 0x69, 0xAE, 0x60, 0x08, 0x1A, 0x0E, 0x3F, - 0xAE, 0x60, 0x29, 0xF3, 0x48, 0x0D, 0xE0, 0xD0, - 0xAE, 0x52, 0x44, 0xE9, 0x7F, 0x1F, 0x92, 0x5F, - 0x71, 0xAD, 0xEC, 0x6B, 0x47, 0x66, 0x92, 0x22, - 0x27, 0xAE, 0x6E, 0x25, 0xCD, 0xF3, 0x5F, 0x55, - 0x59, 0xBD, 0x73, 0xCE, 0x2B, 0x7E, 0x99, 0x44, - 0x56, 0x70, 0xA3, 0xE7, 0x7A, 0x59, 0x75, 0xD8, - 0x48, 0x0C, 0x39, 0x2B, 0xD7, 0x53, 0xC6, 0xAD, - 0x4A, 0x6F, 0xB4, 0x14, 0x96, 0xDF, 0xF2, 0x4A, - 0x0C, 0xA2, 0xD5, 0x29, 0x98, 0x7C, 0x42, 0x87, - 0xD9, 0x1F, 0x97, 0x61, 0xD9, 0xBF, 0x99, 0x4F, - 0x2C, 0x4C, 0x75, 0xAC, 0xB8, 0x06, 0x75, 0xD6, - 0x87, 0x76, 0x7E, 0xE3, 0x23, 0x4B, 0xEA, 0x1A, - 0x1A, 0xF4, 0xB7, 0x09, 0xAF, 0x53, 0xEB, 0xA6, - 0x39, 0x10, 0xFE, 0xD4, 0xEB, 0x1B, 0xAE, 0x38, - 0x31, 0x33, 0xBA, 0x68, 0xEE, 0xC7, 0x65, 0x76, - 0xFB, 0x49, 0x77, 0xD4, 0x19, 0xC4, 0xE6, 0xA7, - 0x05, 0xFE, 0x2A, 0xDA, 0x39, 0x99, 0x1A, 0x92, - 0xD2, 0xF0, 0x61, 0x97, 0xF6, 0x06, 0x6C, 0x88, - 0x7B, 0x6F, 0x60, 0xE6, 0x70, 0x08, 0xF0, 0xB4, - 0x6B, 0x39, 0x6F, 0x05, 0x41, 0x81, 0xF9, 0xBE, - 0x7A, 0x51, 0xC4, 0x75, 0xB0, 0x6A, 0x89, 0xA0, - 0xA6, 0x9A, 0x5B, 0xEE, 0x7D, 0x78, 0x17, 0x5F, - 0x9F, 0x3B, 0x7D, 0xDD, 0x8A, 0x9E, 0xAA, 0x1A, - 0xDA, 0x49, 0x08, 0xE9, 0xFD, 0x91, 0xA6, 0xFA, - 0xCE, 0xCF, 0x67, 0xDF, 0x0F, 0xC9, 0xD6, 0x38, - 0xD9, 0xD5, 0xD1, 0xC0, 0x76, 0x59, 0x42, 0x53, - 0xBF, 0x48, 0xE9, 0x11, 0x74, 0xC7, 0x11, 0xD8, - 0xE7, 0x8E, 0xD3, 0xC8, 0x25, 0xA1, 0x26, 0x50, - 0xBB, 0xB4, 0x35, 0xAF, 0xAF, 0x06, 0x23, 0x69, - 0x3E, 0x30, 0xFD, 0x7B, 0x34, 0x83, 0x07, 0xD0, - 0xF0, 0x0F, 0x6C, 0x9A, 0x13, 0x5D, 0xC2, 0x7B, - 0xDF, 0x6F, 0xDD, 0x8E, 0xF4, 0x30, 0x82, 0x05, - 0x41, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, - 0x0D, 0x01, 0x07, 0x01, 0xA0, 0x82, 0x05, 0x32, - 0x04, 0x82, 0x05, 0x2E, 0x30, 0x82, 0x05, 0x2A, - 0x30, 0x82, 0x05, 0x26, 0x06, 0x0B, 0x2A, 0x86, - 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x0C, 0x0A, 0x01, - 0x02, 0xA0, 0x82, 0x04, 0xEE, 0x30, 0x82, 0x04, - 0xEA, 0x30, 0x1C, 0x06, 0x0A, 0x2A, 0x86, 0x48, - 0x86, 0xF7, 0x0D, 0x01, 0x0C, 0x01, 0x03, 0x30, - 0x0E, 0x04, 0x08, 0x74, 0xC0, 0x84, 0x8F, 0xC7, - 0x74, 0x5E, 0x21, 0x02, 0x02, 0x08, 0x00, 0x04, - 0x82, 0x04, 0xC8, 0x1E, 0xF4, 0xE9, 0x07, 0x27, - 0x9E, 0x5A, 0xC9, 0x39, 0x1D, 0x37, 0x2C, 0x06, - 0x4B, 0x57, 0xEA, 0xC5, 0x42, 0x9A, 0x60, 0xD5, - 0x42, 0xB2, 0x34, 0x2D, 0xD3, 0x88, 0x7C, 0x78, - 0x87, 0xB6, 0xE9, 0x42, 0x44, 0x1F, 0x67, 0x32, - 0x92, 0x54, 0x22, 0xDA, 0xB2, 0x43, 0xE7, 0x40, - 0xBE, 0x1F, 0xAF, 0x3A, 0xCD, 0x2A, 0x9F, 0xD7, - 0x44, 0x5B, 0x37, 0x69, 0x85, 0xDF, 0xEB, 0x2A, - 0xB9, 0xE2, 0x92, 0x3B, 0xEA, 0xD5, 0x42, 0x53, - 0x95, 0x4A, 0xB0, 0x1B, 0xA5, 0xEF, 0xA6, 0x0D, - 0x29, 0xF4, 0x33, 0xFE, 0xD7, 0x49, 0x04, 0x1E, - 0x8C, 0xAD, 0x63, 0x1E, 0x79, 0x63, 0x74, 0x0C, - 0xE5, 0x5E, 0xA2, 0x2C, 0xBE, 0xB8, 0x90, 0xCE, - 0x06, 0x25, 0xBF, 0xD1, 0x5A, 0x50, 0xCF, 0x3B, - 0x52, 0xE2, 0xA7, 0xFF, 0x19, 0x02, 0xCF, 0xD0, - 0x9B, 0xD9, 0xF7, 0x28, 0x07, 0x38, 0x1F, 0xF2, - 0xAF, 0x44, 0x91, 0x3F, 0x0F, 0xB6, 0x6E, 0x8C, - 0xC0, 0x32, 0x92, 0xC0, 0xCD, 0x25, 0x98, 0x67, - 0xF1, 0x47, 0x52, 0x50, 0xF0, 0xA3, 0x7B, 0xE6, - 0x74, 0xDC, 0x72, 0x28, 0xC8, 0xAB, 0xB3, 0x31, - 0x7D, 0xA3, 0xF7, 0xC7, 0xD1, 0xE6, 0x99, 0xB4, - 0xB6, 0x5A, 0x3A, 0x4D, 0x83, 0x4F, 0xB8, 0xB5, - 0x86, 0xF8, 0x37, 0x7F, 0xA0, 0x16, 0x2F, 0x3C, - 0x62, 0x7A, 0xD4, 0x3A, 0xEB, 0xC2, 0xE8, 0x03, - 0x49, 0x17, 0x9E, 0xFB, 0xD7, 0xAF, 0x91, 0x32, - 0xFD, 0xEA, 0x4F, 0x64, 0xC6, 0x6E, 0x02, 0xEA, - 0xC4, 0xC8, 0x1F, 0x16, 0xC5, 0x4C, 0xFB, 0xC5, - 0x42, 0xF5, 0x85, 0x05, 0x92, 0x59, 0x4B, 0x31, - 0xE5, 0xE9, 0x69, 0xE7, 0x02, 0x98, 0x33, 0xBA, - 0x4C, 0x17, 0x09, 0xEF, 0x89, 0x20, 0xFA, 0x83, - 0x9F, 0xAE, 0x0E, 0x1B, 0x7D, 0x98, 0xB9, 0xF2, - 0x3C, 0x0F, 0xB7, 0x1C, 0x72, 0xDF, 0x17, 0x84, - 0x7F, 0x0A, 0xFD, 0x12, 0x3C, 0x6F, 0x68, 0x5D, - 0x45, 0xEB, 0xB8, 0xD6, 0x24, 0x65, 0x42, 0x75, - 0x5C, 0xC2, 0xF3, 0x3A, 0x6A, 0x4E, 0x51, 0x34, - 0x1B, 0xB6, 0x81, 0xB2, 0x8A, 0xEF, 0x28, 0xA4, - 0xC5, 0x88, 0x9A, 0x97, 0xE0, 0xEF, 0x31, 0x12, - 0x01, 0x7E, 0x1B, 0x43, 0x0F, 0x27, 0x80, 0x87, - 0x98, 0xC5, 0xD5, 0x83, 0xCB, 0x4B, 0xB7, 0x01, - 0x79, 0x60, 0xA1, 0x1A, 0x03, 0x05, 0xC6, 0x36, - 0x04, 0x31, 0x3C, 0x06, 0xDB, 0x08, 0xA8, 0xDA, - 0x8E, 0x32, 0x19, 0x91, 0xF1, 0x0D, 0x61, 0x6F, - 0xE4, 0xB2, 0x79, 0x8A, 0xDE, 0xF4, 0xF7, 0xFB, - 0x2C, 0x23, 0x5B, 0xD9, 0x64, 0x2F, 0xB7, 0xB3, - 0x8B, 0xCA, 0xB8, 0x8C, 0x1D, 0x3B, 0x49, 0x05, - 0x38, 0xA1, 0xE5, 0x8C, 0x1A, 0xDC, 0xA5, 0x61, - 0xFE, 0xF4, 0x2B, 0xDC, 0x77, 0x28, 0xF6, 0x19, - 0xE7, 0xB7, 0x8F, 0x4D, 0x27, 0x2D, 0xED, 0x8A, - 0x3F, 0x3D, 0xDC, 0x9F, 0xD1, 0x30, 0xFF, 0xD6, - 0xC3, 0xBE, 0x41, 0x25, 0xE3, 0xA5, 0x9B, 0x73, - 0xDF, 0x6A, 0xD9, 0xF9, 0x70, 0x84, 0x02, 0x4C, - 0x35, 0xD4, 0x3E, 0x05, 0x76, 0x3A, 0xDC, 0x6D, - 0x5A, 0x81, 0xB3, 0x94, 0xF7, 0x22, 0xF7, 0xDC, - 0xC1, 0x43, 0x31, 0x57, 0x5B, 0x42, 0x9A, 0x0B, - 0xF4, 0x95, 0x30, 0xA9, 0xBB, 0xD8, 0x06, 0xFB, - 0x1D, 0x6F, 0x9B, 0xC3, 0xBB, 0xF3, 0xBF, 0xFB, - 0xB4, 0x9F, 0x35, 0x64, 0x0A, 0x69, 0xB7, 0xD1, - 0x3E, 0xCA, 0x78, 0x07, 0x04, 0x03, 0x79, 0xD4, - 0xF3, 0xA8, 0xEC, 0x18, 0xDB, 0x03, 0x5E, 0x47, - 0xD7, 0xD0, 0x56, 0x2C, 0x74, 0x94, 0x86, 0x04, - 0x46, 0xB8, 0xD4, 0x35, 0x0A, 0x7B, 0xE6, 0x78, - 0xC4, 0x43, 0x3C, 0x56, 0xCC, 0x37, 0x8B, 0xFD, - 0xE8, 0xF4, 0x57, 0xEA, 0xAE, 0xCF, 0x36, 0x97, - 0x12, 0xAC, 0x39, 0xCF, 0x7C, 0xEF, 0x22, 0x67, - 0x01, 0xEC, 0xD8, 0x09, 0x49, 0x4E, 0xE3, 0x74, - 0xDD, 0x39, 0xE1, 0x39, 0xD7, 0x0C, 0x5F, 0x1B, - 0xCE, 0x69, 0xBC, 0x72, 0x44, 0x87, 0x64, 0x1C, - 0x08, 0x05, 0x93, 0x69, 0x6D, 0x7F, 0x90, 0x0A, - 0x2C, 0xCB, 0x8A, 0xBB, 0x7F, 0xE3, 0xE0, 0x80, - 0x31, 0xD0, 0x0A, 0x3A, 0x95, 0xFF, 0xF7, 0xB4, - 0x36, 0x38, 0x93, 0xE0, 0x0C, 0x11, 0x37, 0x12, - 0x06, 0xF6, 0xAD, 0xE9, 0xB1, 0x7A, 0x00, 0xF5, - 0xD2, 0x32, 0x6B, 0xD0, 0x27, 0xA5, 0x1B, 0x3D, - 0xE8, 0xDB, 0xCC, 0xA9, 0x1F, 0x1F, 0xB1, 0x99, - 0x3D, 0x7C, 0xB7, 0xCA, 0xDA, 0x27, 0x2C, 0x64, - 0x1C, 0x49, 0xB6, 0x87, 0x44, 0x06, 0x94, 0x9D, - 0xBC, 0x6B, 0x20, 0xA2, 0x68, 0x15, 0x1F, 0xE2, - 0xF2, 0xAD, 0x6D, 0x23, 0x2E, 0x2B, 0x74, 0xE2, - 0x5D, 0xE4, 0xB0, 0xC7, 0x84, 0xCB, 0x64, 0xBF, - 0xE0, 0xA8, 0x18, 0x83, 0xB4, 0xC9, 0xD9, 0x73, - 0xA8, 0xE6, 0xA9, 0x36, 0xD5, 0x63, 0x1E, 0x2C, - 0x2A, 0x55, 0x09, 0x77, 0x5E, 0xB3, 0x4B, 0xEA, - 0xB5, 0xD0, 0x14, 0x5F, 0xEB, 0x50, 0x7B, 0xAA, - 0xEF, 0x94, 0xBA, 0x2B, 0xD7, 0x8A, 0x07, 0xF1, - 0xF9, 0x5E, 0x12, 0x12, 0x21, 0x52, 0xE5, 0x0A, - 0x3E, 0xC0, 0xBC, 0x5D, 0x4C, 0xE2, 0x12, 0x7C, - 0x39, 0xF9, 0x16, 0x9D, 0xBD, 0x96, 0x83, 0x3B, - 0x7F, 0x3D, 0x6A, 0xEC, 0xF1, 0x25, 0xD2, 0xB0, - 0xB0, 0xEB, 0x20, 0x06, 0x07, 0xD6, 0xD9, 0x4C, - 0x07, 0x9A, 0x82, 0xC1, 0xFC, 0xF7, 0x66, 0x15, - 0xBD, 0x62, 0x65, 0xD8, 0x6C, 0xF6, 0x33, 0x7B, - 0x5A, 0x28, 0xEC, 0x90, 0xA1, 0x26, 0x9F, 0xC3, - 0x28, 0x4A, 0x64, 0x50, 0x5F, 0xCA, 0xE2, 0x6D, - 0xB8, 0x0F, 0xE2, 0x94, 0xB5, 0x8E, 0x1F, 0x8A, - 0x8F, 0x6B, 0xA6, 0x86, 0x1F, 0xEE, 0xDC, 0x24, - 0xB4, 0xB8, 0x25, 0xEC, 0x28, 0x2D, 0xF9, 0xCB, - 0x7D, 0x38, 0xFF, 0xC7, 0x74, 0x2E, 0xD3, 0x10, - 0xEC, 0x03, 0x31, 0xEE, 0x83, 0xE7, 0xA4, 0xF7, - 0xBA, 0x28, 0x21, 0xE0, 0x7F, 0xB4, 0xB7, 0xE1, - 0x7A, 0xF9, 0x2B, 0xB0, 0x2C, 0x3B, 0x80, 0x5F, - 0xE0, 0x5D, 0xB2, 0x7E, 0x59, 0xFF, 0x59, 0x07, - 0x58, 0x42, 0x57, 0xEE, 0x44, 0xF1, 0xB1, 0xAD, - 0xBA, 0xDE, 0xCB, 0x1D, 0x8A, 0x36, 0x67, 0xE8, - 0x45, 0xFF, 0x07, 0x8D, 0xEE, 0xA4, 0x51, 0x9C, - 0x4C, 0x83, 0x5D, 0x2E, 0x2F, 0xE1, 0x5B, 0x75, - 0xE8, 0x29, 0xCD, 0x0B, 0x07, 0x62, 0xE0, 0xC3, - 0x0D, 0x1D, 0xEA, 0xCF, 0xF0, 0x8A, 0x65, 0x27, - 0x70, 0x42, 0x9F, 0x26, 0x00, 0x15, 0x70, 0xC5, - 0x4A, 0xF6, 0x25, 0xD0, 0x40, 0x72, 0xE9, 0xC1, - 0x73, 0xFD, 0x48, 0x94, 0xA3, 0x8D, 0x66, 0x63, - 0x96, 0x4F, 0xF7, 0xEE, 0xFB, 0x4C, 0xC7, 0xB8, - 0x6B, 0xE9, 0x90, 0xE1, 0x2A, 0x66, 0x80, 0x99, - 0x3B, 0xB0, 0x1A, 0x6C, 0xF9, 0x0E, 0x72, 0xDA, - 0x8E, 0x4F, 0x46, 0xC2, 0x6A, 0x4B, 0x7A, 0x16, - 0xE5, 0x26, 0x0B, 0x5C, 0xD4, 0x47, 0x34, 0xE5, - 0x37, 0xBE, 0x68, 0x6C, 0xDA, 0xD3, 0x9B, 0x6F, - 0xAE, 0x51, 0x9C, 0x99, 0x0A, 0x5B, 0xF8, 0x37, - 0xBC, 0xDE, 0xFC, 0x93, 0xC5, 0xE7, 0x0F, 0xEF, - 0x0B, 0xA6, 0x07, 0xC2, 0xA6, 0xE6, 0xDA, 0x2D, - 0x1B, 0x49, 0xC9, 0xDE, 0x6B, 0x27, 0xDC, 0x00, - 0xEF, 0x23, 0x87, 0x0E, 0xEB, 0xD1, 0x48, 0x7D, - 0xB4, 0xF2, 0x58, 0xC6, 0x3C, 0xE2, 0x89, 0xBA, - 0xB0, 0x05, 0xAC, 0x94, 0x41, 0x9A, 0xA8, 0xFF, - 0x3E, 0xBC, 0x3A, 0x52, 0x9C, 0xF9, 0x7F, 0x07, - 0x8B, 0xB0, 0x2C, 0x71, 0x83, 0x7B, 0xCF, 0x2E, - 0x7F, 0x7C, 0x96, 0x65, 0xD9, 0x08, 0x17, 0xEC, - 0xFA, 0xDE, 0x4E, 0x40, 0x12, 0x26, 0x70, 0x71, - 0x65, 0xA5, 0xDC, 0x98, 0x47, 0xA3, 0xFC, 0xE0, - 0x9A, 0x16, 0xED, 0x45, 0x56, 0x72, 0x50, 0x05, - 0x28, 0x2C, 0x99, 0xEC, 0x20, 0x2E, 0x40, 0xC0, - 0x26, 0x69, 0xCD, 0x49, 0x45, 0x17, 0xA4, 0xA3, - 0x42, 0x0D, 0x14, 0x65, 0x87, 0x33, 0x8C, 0x92, - 0xC5, 0xC4, 0x61, 0xFD, 0xE8, 0x68, 0x56, 0x20, - 0x57, 0xF5, 0x8E, 0x5F, 0xCF, 0x7E, 0x97, 0xF6, - 0x49, 0x97, 0x0A, 0xFE, 0xD3, 0x60, 0x1A, 0x5B, - 0x0C, 0x75, 0xDD, 0x8E, 0x31, 0x78, 0x29, 0xA6, - 0xB1, 0x4D, 0xAA, 0xDF, 0x8A, 0xD1, 0xE6, 0x91, - 0xE3, 0x32, 0x3F, 0xEC, 0x8A, 0x1F, 0x0E, 0x35, - 0x07, 0x6E, 0x4B, 0x83, 0x3B, 0xE5, 0x67, 0x34, - 0x1F, 0x0C, 0x81, 0xD8, 0xD5, 0x25, 0x68, 0xE5, - 0x28, 0x1B, 0x5C, 0x81, 0x3E, 0xE3, 0x5C, 0xB4, - 0xB6, 0xBD, 0x62, 0x6A, 0x70, 0x33, 0xC2, 0xC5, - 0x75, 0x27, 0xF4, 0x30, 0xE1, 0x1D, 0xC1, 0x4C, - 0xC5, 0x02, 0x12, 0x46, 0xAC, 0xEC, 0xF9, 0xE8, - 0xE7, 0x58, 0x24, 0x11, 0xB1, 0xF3, 0xB7, 0x8C, - 0x3C, 0xA4, 0x0A, 0x94, 0xA6, 0x7C, 0x68, 0x54, - 0x5B, 0xB9, 0x4D, 0x57, 0x9C, 0xE7, 0x28, 0x09, - 0x6B, 0x89, 0x26, 0x5D, 0xE7, 0x50, 0xA9, 0x95, - 0x90, 0x91, 0x8E, 0x00, 0x59, 0xF8, 0x3A, 0x70, - 0xAF, 0x48, 0x2E, 0xE8, 0xC4, 0x34, 0x8C, 0xF4, - 0x5F, 0x7F, 0xCB, 0x07, 0xAA, 0xF0, 0xD9, 0xFB, - 0x5C, 0x32, 0x90, 0x22, 0x1A, 0xD2, 0x1A, 0xCF, - 0x92, 0x06, 0x02, 0xCF, 0x10, 0x18, 0x7B, 0x93, - 0xCC, 0x07, 0x4A, 0x31, 0x25, 0x30, 0x23, 0x06, - 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, - 0x09, 0x15, 0x31, 0x16, 0x04, 0x14, 0xD1, 0xDE, - 0x23, 0x16, 0x9F, 0x6E, 0xF4, 0x42, 0x21, 0x23, - 0xE1, 0x11, 0xAA, 0xC8, 0x7C, 0x60, 0x4A, 0x78, - 0x9D, 0x24, 0x30, 0x31, 0x30, 0x21, 0x30, 0x09, - 0x06, 0x05, 0x2B, 0x0E, 0x03, 0x02, 0x1A, 0x05, - 0x00, 0x04, 0x14, 0xD6, 0x4A, 0xBB, 0x75, 0xB1, - 0xF9, 0x9E, 0xD3, 0x58, 0x6D, 0xD1, 0x74, 0x9F, - 0x00, 0x8A, 0xF2, 0xC8, 0xAA, 0x52, 0x4D, 0x04, - 0x08, 0x77, 0x46, 0xE7, 0xBA, 0x25, 0x4B, 0xDA, - 0x41, 0x02, 0x02, 0x08, 0x00] -}; - -const WPA_EAP_CLIENT_LIST = [ - { - ssid: 'WPA-EAP-TLS', - keyManagement: 'WPA-EAP', - eap: 'TLS', - identity: EAP_USERNAME, - serverCertificate: CLIENT_PKCS12_CERT.nickname, - userCertificate: CLIENT_PKCS12_CERT.nickname - } -]; - -/** - * Convert the given MozWifiNetwork object array to testAssociate chain. - * - * @param aNetworks - * An array of MozWifiNetwork which we want to convert. - * - * @return A promise chain which "then"s testAssociate accordingly. - */ -function convertToTestAssociateChain(aNetworks) { - let chain = Promise.resolve(); - - aNetworks.forEach(function (aNetwork) { - network = new window.MozWifiNetwork(aNetwork); - chain = chain.then(() => gTestSuite.testAssociate(network)); - }); - - return chain; -} - -gTestSuite.doTestWithCertificate( - new Blob([new Uint8Array(CLIENT_PKCS12_CERT.content)]), - CLIENT_PKCS12_CERT.password, - CLIENT_PKCS12_CERT.nickname, - CLIENT_PKCS12_CERT.usage, - function() { - return gTestSuite.ensureWifiEnabled(true) - // Load required server files. - .then(() => gTestSuite.writeFile(SERVER_EAP_USER_CONF.path, SERVER_EAP_USER_CONF.content)) - .then(() => gTestSuite.writeFile(CA_CERT.path, CA_CERT.content)) - .then(() => gTestSuite.writeFile(SERVER_CERT.path, SERVER_CERT.content)) - .then(() => gTestSuite.writeFile(SERVER_KEY.path, SERVER_KEY.content)) - // Start AP. - .then(() => gTestSuite.startHostapds(WPA_EAP_AP_LIST)) - // Scan test. - .then(() => gTestSuite.testWifiScanWithRetry(SCAN_RETRY_CNT, WPA_EAP_AP_LIST)) - // Associate test. - .then(() => convertToTestAssociateChain(WPA_EAP_CLIENT_LIST)) - // Tear down. - .then(gTestSuite.killAllHostapd) -}); diff --git a/dom/wifi/test/marionette/test_wifi_associate_WPA_EAP_TTLS.js b/dom/wifi/test/marionette/test_wifi_associate_WPA_EAP_TTLS.js deleted file mode 100644 index 06e052909..000000000 --- a/dom/wifi/test/marionette/test_wifi_associate_WPA_EAP_TTLS.js +++ /dev/null @@ -1,623 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -MARIONETTE_TIMEOUT = 60000; -MARIONETTE_HEAD_JS = 'head.js'; - -const SCAN_RETRY_CNT = 5; - -const EAP_USERNAME = 'username'; -const EAP_PASSWORD = 'password'; - -const SERVER_EAP_USER_CONF = { - path: HOSTAPD_CONFIG_PATH + 'hostapd.eap_user', - content: '* PEAP,TTLS,TLS\n' + - '"' + EAP_USERNAME + '" MSCHAPV2,TTLS-MSCHAPV2 "' + EAP_PASSWORD + '" [2]\n' -}; -const CA_CERT = { - path: HOSTAPD_CONFIG_PATH + 'ca.pem', - content: '-----BEGIN CERTIFICATE-----\n' + - 'MIIDsTCCApmgAwIBAgIJAKxTf+8X8qngMA0GCSqGSIb3DQEBCwUAMG4xCzAJBgNV\n' + - 'BAYTAlRXMRMwEQYDVQQIDApTb21lLVN0YXRlMREwDwYDVQQKDAhjaHVja2xlZTER\n' + - 'MA8GA1UEAwwIY2h1Y2tsZWUxJDAiBgkqhkiG9w0BCQEWFWNodWNrbGkwNzA2QGdt\n' + - 'YWlsLmNvbTAgFw0xNDEyMjQxMTI4NTBaGA8yMjg4MTAwNzExMjg1MFowbjELMAkG\n' + - 'A1UEBhMCVFcxEzARBgNVBAgMClNvbWUtU3RhdGUxETAPBgNVBAoMCGNodWNrbGVl\n' + - 'MREwDwYDVQQDDAhjaHVja2xlZTEkMCIGCSqGSIb3DQEJARYVY2h1Y2tsaTA3MDZA\n' + - 'Z21haWwuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAo3c2yFxY\n' + - 'o6gGg0I83jy00ME+MAfzCd+4ShL45ZLqysQP93jRBfPzU9ZuZ29ysVwgWIdqkZao\n' + - 'XTuV/NAW2GMGd8W1jQJ3J81fjb9wvhlny3rrACwvUn1N1S1BnM+BAAiDLGxEmvAQ\n' + - 'onp2aaa6HsHsYS8ONX+d2Qh4LEA4vupeSGAqJychCZv/l+aq/ErFZhFYB3CPUQEt\n' + - 'cClO24ucsIYP95lA0zhscnmAj06qplFD4Bv6IVrdDqujy1zNwCQwsJq/8OQdaTN/\n' + - 'h3y9pWvNKMBMM2niOUAjtuNpqsSK/lTS1WAT3PdtVECX9fYBi0Bg+HM92xs/6gt6\n' + - 'kh9jPV8keXHvSwIDAQABo1AwTjAdBgNVHQ4EFgQU7hBqhuG04xeCzrQ3ngx18ZJ3\n' + - 'lUswHwYDVR0jBBgwFoAU7hBqhuG04xeCzrQ3ngx18ZJ3lUswDAYDVR0TBAUwAwEB\n' + - '/zANBgkqhkiG9w0BAQsFAAOCAQEAFYX2iy680GAnBTttk0gyX6gk+8pYr3D22k/G\n' + - '6rvcjefzS7ELQPRKr6mfmwXq3mMf/4jiS2zI5zmXsestPYzHYxf2viQ6t7vr9XiJ\n' + - '3WfFjNw4ERlRisAvg0aqqTNNQq5v2VME4sdFZagy217f73C7azwCHl0bqOLH05rl\n' + - '8RubOxiHEj7ZybJqnRciK/bht4D+rZkwf4bBBmoloqH7xT0+rFQclpYXDGGjNUQB\n' + - 'LcHLF10xcr7g3ZVVu82fe6+d85gIGOIMR9+TKhdw6gO3CNcnDAj6gxksghgtcxmh\n' + - 'OzOggCn7nlIwImtsg2sZkpWB4lEi9hdv4lkNuyFjOL3bnuc+NA==\n' + - '-----END CERTIFICATE-----\n' -}; - -const SERVER_CERT = { - path: HOSTAPD_CONFIG_PATH + 'server.pem', - content: '-----BEGIN CERTIFICATE-----\n' + - 'MIID1DCCArygAwIBAgIBADANBgkqhkiG9w0BAQsFADBuMQswCQYDVQQGEwJUVzET\n' + - 'MBEGA1UECAwKU29tZS1TdGF0ZTERMA8GA1UECgwIY2h1Y2tsZWUxETAPBgNVBAMM\n' + - 'CGNodWNrbGVlMSQwIgYJKoZIhvcNAQkBFhVjaHVja2xpMDcwNkBnbWFpbC5jb20w\n' + - 'IBcNMTQxMjI0MTEyOTQ5WhgPMjI4ODEwMDcxMTI5NDlaMG4xCzAJBgNVBAYTAlRX\n' + - 'MRMwEQYDVQQIDApTb21lLVN0YXRlMREwDwYDVQQKDAhjaHVja2xlZTERMA8GA1UE\n' + - 'AwwIY2h1Y2tsZWUxJDAiBgkqhkiG9w0BCQEWFWNodWNrbGkwNzA2QGdtYWlsLmNv\n' + - 'bTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMdhQmKilTJbWZRxTiSV\n' + - 'rqIU+LYW1RKghx5o+0JpNRJVLuz5kBMaNskbbfUSNuHbEq0QA9BDKAZWIc4LSotk\n' + - 'lCo8TbcO9CJvJPQGGjGdHcohWX5vy6BE/OVE46CUteMFyZF6F8R2fNUww08iR/u1\n' + - 'YZebL5pWO1j43sPpAzEy6Tij2ACPt6EZcFaZG3SF2mVJWkCQnBqrojP65WUvZQqp\n' + - 'seUhW2YAS8Nu0Yrohgxz6VYk+cNDuDZVGs6qWRStZzJfYrfc76DtkHof5B14M+xp\n' + - 'XJaBLxN+whvnYkDTfinaCxnW1O7eXUltr87fLc5zmeBkgwaiaQuIdcfZm7vDUiz8\n' + - 'vnUCAwEAAaN7MHkwCQYDVR0TBAIwADAsBglghkgBhvhCAQ0EHxYdT3BlblNTTCBH\n' + - 'ZW5lcmF0ZWQgQ2VydGlmaWNhdGUwHQYDVR0OBBYEFKK4f9/YavTHOfEiAB83Deac\n' + - '6gT5MB8GA1UdIwQYMBaAFO4QaobhtOMXgs60N54MdfGSd5VLMA0GCSqGSIb3DQEB\n' + - 'CwUAA4IBAQBWnO9o9KSJIqjoz5Nwll63ULOdcvgGdOeJIw1fcKQ817Rsp+TVcjcH\n' + - 'IrIADsT/QZGXRO/l6p1750e2iFtJEo1hsRaxtA1wWn2I9HO3+av2spQhr3jpYGPf\n' + - 'zpsMTp4RNYV7Q8+q1kZIz9PY4V1T0p6lveK8+fUj2hSLnxSj0QiGSJJtnEC3w4Rv\n' + - 'C9T6oUwIeToULmi+8FXQFdEqwKRU98DPq3eLzN28ZxUgoPE1C8+42D2UW8uyp/Gm\n' + - 'tGOa/k7nzkCdVqZI7lX7f0AjEvQgjtAMQ/k7Mhxx7TzW2HO+1YPMoKji6Z4WkNwt\n' + - 'JEj9ZUBSNt8B26UksJMBDkcvSegF3a7o\n' + - '-----END CERTIFICATE-----\n' -}; - -const SERVER_KEY = { - path: HOSTAPD_CONFIG_PATH + 'server.key', - content: '-----BEGIN RSA PRIVATE KEY-----\n' + - 'MIIEpAIBAAKCAQEAx2FCYqKVMltZlHFOJJWuohT4thbVEqCHHmj7Qmk1ElUu7PmQ\n' + - 'Exo2yRtt9RI24dsSrRAD0EMoBlYhzgtKi2SUKjxNtw70Im8k9AYaMZ0dyiFZfm/L\n' + - 'oET85UTjoJS14wXJkXoXxHZ81TDDTyJH+7Vhl5svmlY7WPjew+kDMTLpOKPYAI+3\n' + - 'oRlwVpkbdIXaZUlaQJCcGquiM/rlZS9lCqmx5SFbZgBLw27RiuiGDHPpViT5w0O4\n' + - 'NlUazqpZFK1nMl9it9zvoO2Qeh/kHXgz7GlcloEvE37CG+diQNN+KdoLGdbU7t5d\n' + - 'SW2vzt8tznOZ4GSDBqJpC4h1x9mbu8NSLPy+dQIDAQABAoIBAASG4Mr8hgaurEoC\n' + - 'iJOsElr7vunjetMBcg/uskW/vcS8ymP3Bp5oafYG+WgnEbfvEW18f5mq7K24JuxW\n' + - 'tUqU7ghHdjxByqk9fMlNmiqmNpbwSufkAeuRpWxPNBvhRH/zEbCL5R5A0nTEtqqF\n' + - 'TL0aUSzwCRSoAJD0lZo9ICVt0n3GsDyM9rqQg/uZmh1qsRdwPsRuYORND9g48rKq\n' + - '6WN9leskSxhhsYE2D9ocOFd9bNt8Zxejh9ppVSnG/KsIdt18iBzcabatgAQ046fb\n' + - 'Z3vprcZJLg93Sg2gSuVqlSTs3M2W8VQnm22/EBMb1y0M48MSRCgnbPLG/CcCLLfF\n' + - 'LwxCOgECgYEA/eYt67xyJ6JeAdxdwOZuT1WWGbFpLiG9+2OgiHumyRQ5969XMTWo\n' + - 'fIhMKchDdjoy9RR236\/\/EFCs7UEyB7+a7ODRzNiK2zCD8Smjp+21fUPSthEeQesk\n' + - 'eiMYICIu5Ay35x9sxIX+XOUVvRhPOGcD29GVeRnKh1inTHOz2dje8LkCgYEAyQeY\n' + - 'STi9jjCEcHkM1E/UeDiLfHHepLXi8wS41JNRHl5Jacp7XB5djAjKu/jf367/VpFy\n' + - 'GDDMetE7n8eWkrnAvovxOwZ000YDMtL1sUYSjL+XtBS5s6VY1p4qaSAY9nUUGrJh\n' + - 'JvtvsuI7SKTtL+60vjBOH7zDnvOdBgAp0utLhZ0CgYEAuLzzqrPKB8afShFSchn4\n' + - 'J2dpuLYahsNsXW7HDqeR2nsKFosRETAusLXnXPtnAq4kB6jlOarwFqnsuRCX24Vx\n' + - 'r2uBm9/vYL7zMdUPTA+s30ErHuhjsKjsOKYyVqcooSwT32pBFNk+E89nutfmRG7I\n' + - 'IvhjHuNCNqqtx/Xj5d1jkZkCgYBQicppC2Jl5OoqZVTOem0U/RJk+PnJ41TZJ7sk\n' + - '7yBAmmWvDH\/\/l+rCf4M5a6vFYcbKV9rt9h711X2dtciNX/3oWQh8LUoAmrwNUJc+\n' + - 'PmSQHvIYI3WCk2vUD+nN1B4sHxu+1lg11eYaNKiroeeknG2tBI1ICcgVlmQCU25u\n' + - 'IfZPwQKBgQCdO6QHhPLtcHUDNFA6FQ1jKL1iEd7G0JLVRz4Xkpkn1Vrr5MD6JFDa\n' + - '5ccabADyl0lpFqDIVJQIzLku2hOD2i9aBNCY0pL391HeOS7CkZX+TdOY1tquoBq5\n' + - 'MnmixZjDCVd2VcrVyTA6ntOBoharKFW0rH1PqU+qu7dZF7CBPbAdEw==\n' + - '-----END RSA PRIVATE KEY-----\n' -}; - -const WPA_EAP_AP_LIST = [ - { - ssid: 'WPA-EAP-TTLS', - ieee8021x: 1, - eapol_version: 1, - eap_server: 1, - eapol_key_index_workaround: 0, - eap_user_file: SERVER_EAP_USER_CONF.path, - ca_cert: CA_CERT.path, - server_cert: SERVER_CERT.path, - private_key: SERVER_KEY.path, - wpa: 3, - wpa_key_mgmt: 'WPA-EAP' - } -]; - -const CLIENT_PKCS12_CERT = { - nickname: 'client', - password: 'password', - usage: ['UserCert', 'ServerCert'], - content: [0x30, 0x82, 0x0E, 0x01, 0x02, 0x01, 0x03, 0x30, - 0x82, 0x0D, 0xC7, 0x06, 0x09, 0x2A, 0x86, 0x48, - 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x01, 0xA0, 0x82, - 0x0D, 0xB8, 0x04, 0x82, 0x0D, 0xB4, 0x30, 0x82, - 0x0D, 0xB0, 0x30, 0x82, 0x08, 0x67, 0x06, 0x09, - 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, - 0x06, 0xA0, 0x82, 0x08, 0x58, 0x30, 0x82, 0x08, - 0x54, 0x02, 0x01, 0x00, 0x30, 0x82, 0x08, 0x4D, - 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, - 0x01, 0x07, 0x01, 0x30, 0x1C, 0x06, 0x0A, 0x2A, - 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x0C, 0x01, - 0x06, 0x30, 0x0E, 0x04, 0x08, 0x67, 0x7A, 0xF3, - 0x61, 0xBE, 0xE0, 0x51, 0xC1, 0x02, 0x02, 0x08, - 0x00, 0x80, 0x82, 0x08, 0x20, 0xFC, 0x6A, 0x79, - 0xA1, 0x6C, 0xAF, 0xBE, 0xEE, 0x62, 0x45, 0x33, - 0xB8, 0x48, 0xE1, 0x68, 0xA1, 0x15, 0x11, 0x4B, - 0x95, 0xCB, 0x77, 0xC0, 0x5D, 0xA2, 0xCB, 0xDB, - 0xD1, 0x83, 0x74, 0x60, 0xD7, 0xEC, 0x42, 0xA6, - 0x3A, 0x23, 0xF7, 0x85, 0xEB, 0xC1, 0xFE, 0x6A, - 0x57, 0x8E, 0xC1, 0x44, 0xF3, 0x1F, 0xFE, 0xB8, - 0x2D, 0x8C, 0x4D, 0xC9, 0x5B, 0xAE, 0x21, 0x2E, - 0x4C, 0x1A, 0xEB, 0x84, 0x09, 0xF3, 0x40, 0x92, - 0x39, 0x7F, 0x56, 0x02, 0x46, 0x61, 0x16, 0xDE, - 0x5C, 0x48, 0xB6, 0x0C, 0x1D, 0xD3, 0x5F, 0x10, - 0x9A, 0x39, 0xB8, 0x66, 0x31, 0xFC, 0x39, 0x71, - 0x87, 0x23, 0x46, 0x9D, 0xE8, 0x3C, 0x2B, 0xA1, - 0x39, 0x8A, 0xD3, 0xFF, 0xD9, 0x43, 0xB6, 0x61, - 0xC6, 0x67, 0x70, 0x40, 0xBD, 0xFE, 0xD3, 0xC1, - 0x68, 0xF5, 0xF7, 0xC8, 0x89, 0xD8, 0x17, 0xC5, - 0xE8, 0x3D, 0x29, 0xD5, 0x91, 0xDF, 0x1F, 0x56, - 0x74, 0x5A, 0xC4, 0xA8, 0x14, 0xBA, 0xD4, 0xFA, - 0x13, 0x49, 0x2A, 0x9F, 0x63, 0xF1, 0xB2, 0x45, - 0xF1, 0xF0, 0x2A, 0xDD, 0x75, 0x66, 0x8A, 0xF7, - 0xAB, 0x73, 0x86, 0x26, 0x9D, 0x1F, 0x07, 0xAD, - 0xD3, 0xFE, 0xE0, 0xA3, 0xED, 0xA0, 0x96, 0x3E, - 0x1E, 0x89, 0x86, 0x02, 0x4C, 0x28, 0xFD, 0x57, - 0xA1, 0x67, 0x55, 0xF0, 0x82, 0x3B, 0x7F, 0xCC, - 0x2A, 0x32, 0x01, 0x93, 0x1D, 0x8B, 0x66, 0x8A, - 0x20, 0x52, 0x84, 0xDD, 0x2C, 0xFD, 0xEE, 0x72, - 0xF3, 0x8C, 0x58, 0xB9, 0x99, 0xE5, 0xC1, 0x22, - 0x63, 0x59, 0x00, 0xE2, 0x76, 0xC5, 0x3A, 0x17, - 0x7F, 0x93, 0xE9, 0x67, 0x61, 0xAA, 0x10, 0xC3, - 0xD9, 0xC8, 0x24, 0x46, 0x5B, 0xBE, 0x8C, 0x1F, - 0x2D, 0x66, 0x48, 0xD2, 0x02, 0x11, 0xFB, 0x74, - 0x14, 0x76, 0x76, 0x5A, 0x98, 0x54, 0x35, 0xA7, - 0x85, 0x66, 0x20, 0x26, 0x8B, 0x13, 0x6F, 0x68, - 0xE3, 0xC9, 0x58, 0x7D, 0x1C, 0x3E, 0x01, 0x8D, - 0xF8, 0xD6, 0x7F, 0xCF, 0xA2, 0x07, 0xB7, 0x95, - 0xFD, 0xF0, 0x02, 0x34, 0x32, 0x30, 0xE8, 0xD4, - 0x57, 0x5E, 0x53, 0xFB, 0x54, 0xE2, 0x03, 0x32, - 0xCC, 0x52, 0x2E, 0xD2, 0x35, 0xD9, 0x58, 0x85, - 0x2D, 0xEC, 0x2D, 0x71, 0xD1, 0x8A, 0x29, 0xD0, - 0xB0, 0x24, 0xBD, 0x24, 0xDC, 0x1A, 0x28, 0x3F, - 0xA0, 0x12, 0x81, 0x15, 0x24, 0xC9, 0xB5, 0x4A, - 0x23, 0xB6, 0xA3, 0x45, 0x50, 0x2D, 0x73, 0x99, - 0x6B, 0x1C, 0xFB, 0xA4, 0x53, 0xD7, 0x5C, 0xF4, - 0x6C, 0xB0, 0xE5, 0x74, 0xB3, 0x76, 0xF8, 0xB1, - 0x0D, 0x59, 0x70, 0x9F, 0xCA, 0xDE, 0xF2, 0xAA, - 0x4C, 0x7D, 0x11, 0x54, 0xC4, 0x19, 0x0F, 0x36, - 0x4A, 0x62, 0xFF, 0x8B, 0x10, 0xCB, 0x93, 0x50, - 0xDA, 0x79, 0x5E, 0x4E, 0x09, 0x1F, 0x22, 0xC8, - 0x19, 0x85, 0xE9, 0xEE, 0xB7, 0x71, 0x65, 0xB9, - 0x10, 0xD2, 0x0A, 0x73, 0x5B, 0xA6, 0xDA, 0x37, - 0x46, 0x02, 0x00, 0x98, 0x9E, 0x20, 0x6C, 0x7D, - 0xC7, 0x69, 0xBB, 0xC2, 0x00, 0x40, 0x9C, 0x57, - 0x00, 0xC2, 0x36, 0x76, 0xE8, 0x2A, 0x8D, 0xAD, - 0x62, 0x57, 0xC8, 0xD0, 0x9D, 0x66, 0x27, 0x5A, - 0xD8, 0x0D, 0x35, 0x60, 0x28, 0x38, 0x62, 0x94, - 0x78, 0x36, 0x25, 0x58, 0xFD, 0xF8, 0x66, 0x1F, - 0x68, 0x04, 0x0F, 0xD8, 0x00, 0xDF, 0xA0, 0x6C, - 0x25, 0x42, 0x9A, 0x4C, 0xEB, 0x80, 0x13, 0x51, - 0x7D, 0x2D, 0xA8, 0x89, 0xD6, 0x1B, 0x67, 0x72, - 0x01, 0xF3, 0x2D, 0x16, 0x77, 0xFE, 0x22, 0xBC, - 0x8A, 0x45, 0x09, 0x1F, 0x9C, 0x2F, 0x2A, 0xA9, - 0x61, 0x5B, 0x4A, 0xE6, 0x64, 0x2C, 0x62, 0x1A, - 0x3A, 0x96, 0xE6, 0x0A, 0xAE, 0x05, 0x1A, 0xC8, - 0xCB, 0xD6, 0x8F, 0x3A, 0x4B, 0xE0, 0x7F, 0x82, - 0xB4, 0x98, 0xF1, 0x9D, 0xD7, 0x14, 0x76, 0x5E, - 0x77, 0x85, 0x87, 0xEC, 0x13, 0xDA, 0xFD, 0xAF, - 0xCB, 0xA3, 0x1C, 0x99, 0xC1, 0xFE, 0x17, 0x0C, - 0x40, 0x4D, 0x3C, 0x8F, 0x70, 0x86, 0x63, 0x64, - 0xB7, 0x75, 0xA8, 0x71, 0x36, 0xDC, 0x54, 0x10, - 0x57, 0x0C, 0xA8, 0xF2, 0xA1, 0xBB, 0xED, 0x03, - 0x41, 0x57, 0x34, 0x2C, 0x8F, 0x7C, 0xA0, 0x09, - 0xF3, 0x9E, 0x41, 0xB7, 0xA8, 0xD4, 0x66, 0x0D, - 0x0D, 0xC0, 0x6A, 0xFC, 0x6A, 0xA2, 0xAC, 0xE2, - 0x60, 0x00, 0xE3, 0xF7, 0x75, 0x43, 0x23, 0xEB, - 0xC8, 0x61, 0xFA, 0xB3, 0xB8, 0x28, 0xCE, 0xCA, - 0xF4, 0x47, 0x7F, 0x30, 0x6D, 0x61, 0x89, 0x47, - 0xA1, 0x4A, 0xFE, 0xD1, 0x21, 0x0B, 0x6D, 0xF4, - 0x3F, 0x00, 0x86, 0x30, 0x8E, 0x33, 0x21, 0x6F, - 0xDA, 0x15, 0xFD, 0x5F, 0xEC, 0x8E, 0xF1, 0x12, - 0x3F, 0xC9, 0x83, 0x0C, 0xCA, 0x22, 0x01, 0xF1, - 0x70, 0x5F, 0x1F, 0x66, 0xB5, 0xF8, 0x3E, 0x7A, - 0x6F, 0xDE, 0xDB, 0xA7, 0x8D, 0x18, 0x9E, 0xBE, - 0xDB, 0xAD, 0x3D, 0x66, 0x30, 0xC1, 0x6C, 0x0C, - 0x87, 0xB4, 0x65, 0x75, 0xE0, 0x9D, 0xEA, 0x16, - 0x0D, 0x07, 0x37, 0x33, 0xC5, 0xEC, 0x97, 0x93, - 0x37, 0xEB, 0x8E, 0x65, 0x9C, 0x40, 0x63, 0x6C, - 0x43, 0x60, 0xB0, 0x40, 0x4D, 0x85, 0xEF, 0xC2, - 0x47, 0x5F, 0xE7, 0x6B, 0xCB, 0x40, 0xE8, 0xEA, - 0xD8, 0xAB, 0xB1, 0x9A, 0x72, 0xDC, 0x4C, 0x14, - 0xFA, 0x43, 0x61, 0x5F, 0xA6, 0x5C, 0x3A, 0x05, - 0x17, 0x2E, 0x74, 0xF3, 0x5E, 0x45, 0xD9, 0x47, - 0xAA, 0x59, 0xB6, 0x8F, 0x42, 0x66, 0x42, 0x29, - 0x90, 0x95, 0x48, 0x46, 0x91, 0x88, 0x3C, 0x8C, - 0xDE, 0xCC, 0xED, 0xB3, 0xAA, 0x62, 0xEA, 0xBC, - 0xB4, 0x0C, 0x48, 0x4C, 0x53, 0x23, 0x5E, 0x24, - 0x85, 0xBF, 0x92, 0xDA, 0x14, 0xDB, 0x1A, 0x3D, - 0xEF, 0x30, 0xD9, 0x49, 0x64, 0x4D, 0xE5, 0x01, - 0xFC, 0xA4, 0x4B, 0xD1, 0x9F, 0xDE, 0x96, 0x7F, - 0x50, 0xBC, 0x4D, 0x38, 0x44, 0xE9, 0x23, 0x5F, - 0x37, 0x57, 0x1A, 0xA6, 0x52, 0x5A, 0x0F, 0x4F, - 0x87, 0x33, 0x4A, 0x7B, 0x66, 0xEE, 0x3D, 0x66, - 0x0A, 0x63, 0x39, 0x1F, 0x23, 0x38, 0x35, 0x73, - 0x60, 0x5E, 0x47, 0x20, 0x4F, 0xC0, 0xC8, 0x3C, - 0x09, 0xF9, 0x29, 0x4F, 0x5E, 0x55, 0x69, 0xC4, - 0x6B, 0xE8, 0xF8, 0x91, 0xC0, 0x22, 0x65, 0x15, - 0x1E, 0xFB, 0xB9, 0x61, 0xCE, 0x45, 0xBE, 0x2B, - 0xEE, 0xB9, 0x04, 0x2B, 0xFD, 0xAE, 0x61, 0x1C, - 0x3D, 0x3D, 0x7C, 0xBF, 0xC1, 0xF7, 0x3C, 0x4E, - 0x9E, 0x0E, 0x54, 0xC8, 0xAD, 0xA9, 0xDF, 0x43, - 0x49, 0xB9, 0x41, 0x05, 0xE5, 0xF1, 0x49, 0xAA, - 0x77, 0x6C, 0x34, 0x5B, 0x93, 0x24, 0x24, 0x23, - 0x74, 0x68, 0x11, 0xCE, 0x15, 0x80, 0xA1, 0xA4, - 0x1F, 0x8D, 0x81, 0xCD, 0xB2, 0x98, 0xCA, 0x14, - 0x0B, 0x0C, 0x61, 0x50, 0x69, 0x72, 0xAE, 0xFA, - 0x8B, 0xC0, 0x3F, 0x0D, 0xE7, 0xF2, 0x0F, 0xEB, - 0xC1, 0x11, 0xB9, 0x10, 0x03, 0x6A, 0xF5, 0x97, - 0x3C, 0x53, 0x2F, 0x67, 0x86, 0x09, 0x6A, 0xE3, - 0x28, 0xC0, 0x78, 0xC8, 0xB4, 0x39, 0x8E, 0xD1, - 0xCE, 0x25, 0xE8, 0x66, 0xF7, 0x09, 0x40, 0x7D, - 0x81, 0xFB, 0xAF, 0xFA, 0x59, 0xC4, 0x9B, 0x2B, - 0x83, 0x45, 0x5B, 0xA8, 0x66, 0x9E, 0x38, 0xC8, - 0xFD, 0xAC, 0xF2, 0x2D, 0x21, 0xDE, 0x50, 0x4C, - 0x03, 0xCB, 0x88, 0x42, 0xDD, 0x84, 0x09, 0x99, - 0x8E, 0x8B, 0x40, 0x97, 0x1B, 0x14, 0x85, 0x37, - 0x11, 0x01, 0xE0, 0x74, 0x6B, 0x33, 0x52, 0x8C, - 0x68, 0x3A, 0x89, 0xB2, 0xAF, 0x35, 0xE6, 0x65, - 0xC3, 0x58, 0x70, 0xD2, 0xE7, 0x1F, 0x1F, 0xF6, - 0xE5, 0x0A, 0xB1, 0xFE, 0xD0, 0xC9, 0x51, 0x50, - 0xE7, 0xFD, 0x58, 0xF5, 0xC4, 0x58, 0x65, 0x94, - 0xD1, 0x57, 0x55, 0x5E, 0xD2, 0x27, 0x98, 0xAF, - 0xE7, 0x55, 0x0B, 0x87, 0x50, 0x9B, 0xEF, 0xE8, - 0x2B, 0xFC, 0xE7, 0x3B, 0x4E, 0xD7, 0xB7, 0x4D, - 0xF4, 0xBC, 0xF4, 0x88, 0x63, 0xE4, 0x8A, 0x20, - 0x4B, 0x22, 0xB0, 0xA0, 0x53, 0x7F, 0xA8, 0xC9, - 0x0C, 0xF8, 0xD7, 0xBD, 0x46, 0x39, 0xA7, 0x7D, - 0xDD, 0x10, 0x91, 0x50, 0x54, 0x06, 0x47, 0xF0, - 0x3C, 0xAA, 0x43, 0x40, 0xF8, 0x54, 0xDD, 0x8A, - 0xEA, 0x8A, 0x0B, 0xA5, 0x7F, 0xCD, 0x5E, 0xAA, - 0x02, 0x2E, 0x1F, 0xC6, 0x50, 0x15, 0xF8, 0x0A, - 0x0C, 0x1B, 0x3C, 0x55, 0x3A, 0xC3, 0x6F, 0x88, - 0xD7, 0xBF, 0xB1, 0x02, 0xCC, 0xE0, 0x08, 0x29, - 0x97, 0xD2, 0xAA, 0x23, 0xC4, 0x6D, 0xE3, 0xE3, - 0x76, 0x39, 0x92, 0xC3, 0x2E, 0x7A, 0xE2, 0x98, - 0xD1, 0xFC, 0xAE, 0xCC, 0x95, 0xD8, 0xB4, 0xDC, - 0x92, 0xEA, 0x6A, 0x5F, 0xF2, 0x92, 0x17, 0x0B, - 0x8D, 0xC3, 0xFA, 0x9C, 0x62, 0xCE, 0x44, 0x8D, - 0xC3, 0x1E, 0xC3, 0xB2, 0xD5, 0x00, 0xCD, 0xB4, - 0x9E, 0x2D, 0x7B, 0xF2, 0x98, 0xA3, 0x00, 0x8B, - 0x81, 0x30, 0x77, 0x5B, 0x02, 0x99, 0xB1, 0xCD, - 0xC3, 0x1D, 0x74, 0x74, 0xEF, 0x41, 0xCB, 0x69, - 0x63, 0x8E, 0xA6, 0xD3, 0x2D, 0x3E, 0x1F, 0x1D, - 0x12, 0x9E, 0xD9, 0x18, 0x67, 0x06, 0xAF, 0x37, - 0x29, 0xAD, 0x65, 0xD8, 0xEB, 0x71, 0xC4, 0x7D, - 0x94, 0x3D, 0xEA, 0xCC, 0xDF, 0x72, 0x41, 0x51, - 0x3C, 0xA1, 0x66, 0x98, 0x32, 0x32, 0x40, 0x54, - 0xB0, 0x2F, 0xEB, 0xCE, 0xDF, 0x4A, 0x64, 0xFB, - 0x9A, 0x90, 0xDC, 0xF6, 0x6F, 0xA9, 0xD4, 0xCA, - 0xCB, 0x91, 0xC4, 0xFE, 0xEE, 0x9C, 0x01, 0x50, - 0x2E, 0xAC, 0xCC, 0x5F, 0x89, 0xD0, 0x91, 0xA3, - 0xD9, 0xF9, 0x4B, 0x8D, 0xDE, 0x6C, 0x60, 0x21, - 0x19, 0xB1, 0xD3, 0x4D, 0x75, 0x56, 0x6F, 0xB8, - 0x25, 0xA4, 0x92, 0x4F, 0x12, 0xF5, 0x8F, 0xC1, - 0x17, 0x4B, 0xB3, 0x34, 0x21, 0x22, 0xAC, 0x52, - 0xD2, 0x64, 0xC9, 0x9A, 0x7D, 0xFC, 0xC0, 0x0A, - 0x89, 0x34, 0xFF, 0x08, 0xD3, 0x04, 0xDC, 0xFE, - 0x7C, 0xB3, 0xB8, 0xFD, 0x85, 0xDD, 0x79, 0x51, - 0xA7, 0x89, 0xE8, 0xF1, 0x23, 0xB1, 0xDF, 0xD7, - 0x1F, 0x7B, 0xB1, 0x5D, 0x42, 0xF9, 0x61, 0xF8, - 0xDC, 0x81, 0x04, 0xF1, 0xCC, 0xFA, 0xD7, 0xED, - 0xBF, 0x47, 0xAC, 0xBD, 0xE5, 0xFA, 0xAC, 0xB3, - 0x1C, 0xD9, 0xA1, 0xB3, 0x60, 0xEE, 0x9C, 0x8A, - 0x36, 0x57, 0xB4, 0x2F, 0xA1, 0xA2, 0xF3, 0xE2, - 0x09, 0x9A, 0x6E, 0x43, 0x9B, 0xE5, 0x93, 0xB8, - 0x3D, 0x9E, 0x9F, 0xC1, 0xC6, 0x0D, 0x02, 0xEB, - 0x4D, 0x38, 0xE9, 0xB4, 0x9F, 0xEA, 0x33, 0x8C, - 0x07, 0xD8, 0xB4, 0x71, 0xAD, 0xE5, 0x43, 0xB2, - 0xCC, 0x55, 0x93, 0x6A, 0xDB, 0x1E, 0x80, 0xDB, - 0xC2, 0xEA, 0x42, 0x8E, 0xFC, 0x86, 0x44, 0xC9, - 0x8A, 0xC4, 0xF2, 0x46, 0xA7, 0x39, 0x50, 0x0D, - 0x1A, 0xAA, 0x07, 0x04, 0xBE, 0xD4, 0xCE, 0x62, - 0x4D, 0x0F, 0x91, 0x7D, 0x29, 0x88, 0x9C, 0x4C, - 0xAF, 0xF7, 0xD8, 0x40, 0x93, 0x88, 0xC7, 0x20, - 0xD2, 0x17, 0x2A, 0xC4, 0x92, 0x72, 0xD0, 0xC0, - 0x4E, 0x56, 0x47, 0xB1, 0x27, 0x02, 0xE6, 0x61, - 0x82, 0x5E, 0xC8, 0x2E, 0x90, 0xD2, 0x31, 0x22, - 0xE2, 0xA9, 0x4A, 0x91, 0x45, 0x69, 0xB1, 0xA5, - 0x0F, 0x66, 0x2C, 0x30, 0xAD, 0x7F, 0x1B, 0x0E, - 0x22, 0x17, 0x60, 0x2E, 0x3D, 0x7F, 0x7F, 0x8C, - 0x33, 0x51, 0xA0, 0x25, 0xDE, 0xFD, 0x75, 0xBC, - 0xEF, 0xE6, 0xE7, 0x20, 0x04, 0x5A, 0xEC, 0x50, - 0x21, 0x48, 0x56, 0x98, 0xE2, 0x33, 0x6D, 0x22, - 0x5C, 0xC3, 0xFB, 0xFC, 0x6F, 0xB3, 0xA7, 0x8E, - 0x6F, 0x67, 0x70, 0x9D, 0xDA, 0x02, 0x01, 0x59, - 0x7B, 0x3D, 0x2B, 0x38, 0xCC, 0x0F, 0x44, 0x3D, - 0xFB, 0x9A, 0xB3, 0x23, 0x15, 0x50, 0x6E, 0xBF, - 0x8B, 0xA1, 0x94, 0x33, 0xE5, 0x7B, 0x88, 0x4E, - 0xCB, 0x6D, 0x9F, 0xBF, 0xBC, 0x7A, 0xA8, 0x1E, - 0x68, 0x25, 0xED, 0x8E, 0x53, 0x21, 0x72, 0xC5, - 0x70, 0xB3, 0xE4, 0xA6, 0xA1, 0x5A, 0x2D, 0xC8, - 0x43, 0x9D, 0x60, 0x77, 0x78, 0xE0, 0xC4, 0xAF, - 0xC8, 0x29, 0xBA, 0xD0, 0x4D, 0x39, 0x83, 0x51, - 0xA7, 0x10, 0x7F, 0x0C, 0x34, 0x0E, 0x6C, 0x75, - 0x26, 0xD7, 0xD6, 0xC7, 0x32, 0x53, 0xAF, 0x4E, - 0xBE, 0xF2, 0xC2, 0x0F, 0x99, 0x23, 0xB9, 0xE1, - 0xC8, 0xB4, 0xBC, 0x5A, 0xC6, 0xCB, 0xEB, 0x4D, - 0x28, 0x56, 0x72, 0xFE, 0x1B, 0x2C, 0x5D, 0xE3, - 0xBC, 0xC7, 0xA3, 0xC0, 0x7D, 0x27, 0xF0, 0xD0, - 0x4F, 0x3F, 0x1F, 0xF7, 0x87, 0x15, 0xF2, 0xEA, - 0xD4, 0x03, 0x6D, 0x2F, 0xD4, 0x8E, 0x50, 0x4B, - 0x05, 0xBF, 0xF7, 0x8C, 0x67, 0x5A, 0xDC, 0x4D, - 0xCD, 0xCF, 0x9D, 0x02, 0xB6, 0xE7, 0xAE, 0x49, - 0xD1, 0x7C, 0x00, 0xE7, 0x3B, 0xEA, 0xFB, 0x0D, - 0x2A, 0x7B, 0x41, 0x33, 0x66, 0xD0, 0x29, 0x9F, - 0xB3, 0x8A, 0x71, 0xB0, 0xE2, 0x76, 0xA9, 0xDB, - 0xFD, 0x64, 0x04, 0x69, 0xDF, 0x89, 0x1F, 0x56, - 0x86, 0x92, 0xD9, 0xD9, 0xB9, 0xF3, 0x4F, 0xAC, - 0xAE, 0x61, 0x48, 0x20, 0xCE, 0x3C, 0x2B, 0x44, - 0xAB, 0x42, 0xFA, 0xAB, 0x2E, 0x94, 0x82, 0xC8, - 0xD9, 0x97, 0xCF, 0x27, 0xDF, 0xAC, 0xAC, 0xE7, - 0xCA, 0xB2, 0x84, 0xAB, 0xF2, 0x5D, 0xDF, 0x56, - 0x0C, 0x8C, 0x07, 0x3C, 0x3D, 0xA8, 0xDD, 0xBE, - 0xFF, 0x4E, 0x28, 0x0D, 0xB2, 0x2D, 0xE6, 0x9D, - 0x44, 0x21, 0xCB, 0xE7, 0x33, 0x63, 0x22, 0x8F, - 0x4C, 0xFF, 0xB6, 0x1D, 0x9A, 0x71, 0x3F, 0xB1, - 0x29, 0xAE, 0x3A, 0x35, 0xEE, 0x9C, 0x97, 0x68, - 0xA7, 0x52, 0x66, 0x01, 0xD8, 0x9A, 0x5D, 0xF4, - 0xB3, 0x2F, 0x5C, 0xD4, 0x0E, 0xF9, 0xCF, 0x07, - 0xF6, 0x8C, 0xBA, 0xA6, 0x8D, 0x6B, 0xC6, 0x01, - 0xC2, 0x69, 0xAE, 0x60, 0x08, 0x1A, 0x0E, 0x3F, - 0xAE, 0x60, 0x29, 0xF3, 0x48, 0x0D, 0xE0, 0xD0, - 0xAE, 0x52, 0x44, 0xE9, 0x7F, 0x1F, 0x92, 0x5F, - 0x71, 0xAD, 0xEC, 0x6B, 0x47, 0x66, 0x92, 0x22, - 0x27, 0xAE, 0x6E, 0x25, 0xCD, 0xF3, 0x5F, 0x55, - 0x59, 0xBD, 0x73, 0xCE, 0x2B, 0x7E, 0x99, 0x44, - 0x56, 0x70, 0xA3, 0xE7, 0x7A, 0x59, 0x75, 0xD8, - 0x48, 0x0C, 0x39, 0x2B, 0xD7, 0x53, 0xC6, 0xAD, - 0x4A, 0x6F, 0xB4, 0x14, 0x96, 0xDF, 0xF2, 0x4A, - 0x0C, 0xA2, 0xD5, 0x29, 0x98, 0x7C, 0x42, 0x87, - 0xD9, 0x1F, 0x97, 0x61, 0xD9, 0xBF, 0x99, 0x4F, - 0x2C, 0x4C, 0x75, 0xAC, 0xB8, 0x06, 0x75, 0xD6, - 0x87, 0x76, 0x7E, 0xE3, 0x23, 0x4B, 0xEA, 0x1A, - 0x1A, 0xF4, 0xB7, 0x09, 0xAF, 0x53, 0xEB, 0xA6, - 0x39, 0x10, 0xFE, 0xD4, 0xEB, 0x1B, 0xAE, 0x38, - 0x31, 0x33, 0xBA, 0x68, 0xEE, 0xC7, 0x65, 0x76, - 0xFB, 0x49, 0x77, 0xD4, 0x19, 0xC4, 0xE6, 0xA7, - 0x05, 0xFE, 0x2A, 0xDA, 0x39, 0x99, 0x1A, 0x92, - 0xD2, 0xF0, 0x61, 0x97, 0xF6, 0x06, 0x6C, 0x88, - 0x7B, 0x6F, 0x60, 0xE6, 0x70, 0x08, 0xF0, 0xB4, - 0x6B, 0x39, 0x6F, 0x05, 0x41, 0x81, 0xF9, 0xBE, - 0x7A, 0x51, 0xC4, 0x75, 0xB0, 0x6A, 0x89, 0xA0, - 0xA6, 0x9A, 0x5B, 0xEE, 0x7D, 0x78, 0x17, 0x5F, - 0x9F, 0x3B, 0x7D, 0xDD, 0x8A, 0x9E, 0xAA, 0x1A, - 0xDA, 0x49, 0x08, 0xE9, 0xFD, 0x91, 0xA6, 0xFA, - 0xCE, 0xCF, 0x67, 0xDF, 0x0F, 0xC9, 0xD6, 0x38, - 0xD9, 0xD5, 0xD1, 0xC0, 0x76, 0x59, 0x42, 0x53, - 0xBF, 0x48, 0xE9, 0x11, 0x74, 0xC7, 0x11, 0xD8, - 0xE7, 0x8E, 0xD3, 0xC8, 0x25, 0xA1, 0x26, 0x50, - 0xBB, 0xB4, 0x35, 0xAF, 0xAF, 0x06, 0x23, 0x69, - 0x3E, 0x30, 0xFD, 0x7B, 0x34, 0x83, 0x07, 0xD0, - 0xF0, 0x0F, 0x6C, 0x9A, 0x13, 0x5D, 0xC2, 0x7B, - 0xDF, 0x6F, 0xDD, 0x8E, 0xF4, 0x30, 0x82, 0x05, - 0x41, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, - 0x0D, 0x01, 0x07, 0x01, 0xA0, 0x82, 0x05, 0x32, - 0x04, 0x82, 0x05, 0x2E, 0x30, 0x82, 0x05, 0x2A, - 0x30, 0x82, 0x05, 0x26, 0x06, 0x0B, 0x2A, 0x86, - 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x0C, 0x0A, 0x01, - 0x02, 0xA0, 0x82, 0x04, 0xEE, 0x30, 0x82, 0x04, - 0xEA, 0x30, 0x1C, 0x06, 0x0A, 0x2A, 0x86, 0x48, - 0x86, 0xF7, 0x0D, 0x01, 0x0C, 0x01, 0x03, 0x30, - 0x0E, 0x04, 0x08, 0x74, 0xC0, 0x84, 0x8F, 0xC7, - 0x74, 0x5E, 0x21, 0x02, 0x02, 0x08, 0x00, 0x04, - 0x82, 0x04, 0xC8, 0x1E, 0xF4, 0xE9, 0x07, 0x27, - 0x9E, 0x5A, 0xC9, 0x39, 0x1D, 0x37, 0x2C, 0x06, - 0x4B, 0x57, 0xEA, 0xC5, 0x42, 0x9A, 0x60, 0xD5, - 0x42, 0xB2, 0x34, 0x2D, 0xD3, 0x88, 0x7C, 0x78, - 0x87, 0xB6, 0xE9, 0x42, 0x44, 0x1F, 0x67, 0x32, - 0x92, 0x54, 0x22, 0xDA, 0xB2, 0x43, 0xE7, 0x40, - 0xBE, 0x1F, 0xAF, 0x3A, 0xCD, 0x2A, 0x9F, 0xD7, - 0x44, 0x5B, 0x37, 0x69, 0x85, 0xDF, 0xEB, 0x2A, - 0xB9, 0xE2, 0x92, 0x3B, 0xEA, 0xD5, 0x42, 0x53, - 0x95, 0x4A, 0xB0, 0x1B, 0xA5, 0xEF, 0xA6, 0x0D, - 0x29, 0xF4, 0x33, 0xFE, 0xD7, 0x49, 0x04, 0x1E, - 0x8C, 0xAD, 0x63, 0x1E, 0x79, 0x63, 0x74, 0x0C, - 0xE5, 0x5E, 0xA2, 0x2C, 0xBE, 0xB8, 0x90, 0xCE, - 0x06, 0x25, 0xBF, 0xD1, 0x5A, 0x50, 0xCF, 0x3B, - 0x52, 0xE2, 0xA7, 0xFF, 0x19, 0x02, 0xCF, 0xD0, - 0x9B, 0xD9, 0xF7, 0x28, 0x07, 0x38, 0x1F, 0xF2, - 0xAF, 0x44, 0x91, 0x3F, 0x0F, 0xB6, 0x6E, 0x8C, - 0xC0, 0x32, 0x92, 0xC0, 0xCD, 0x25, 0x98, 0x67, - 0xF1, 0x47, 0x52, 0x50, 0xF0, 0xA3, 0x7B, 0xE6, - 0x74, 0xDC, 0x72, 0x28, 0xC8, 0xAB, 0xB3, 0x31, - 0x7D, 0xA3, 0xF7, 0xC7, 0xD1, 0xE6, 0x99, 0xB4, - 0xB6, 0x5A, 0x3A, 0x4D, 0x83, 0x4F, 0xB8, 0xB5, - 0x86, 0xF8, 0x37, 0x7F, 0xA0, 0x16, 0x2F, 0x3C, - 0x62, 0x7A, 0xD4, 0x3A, 0xEB, 0xC2, 0xE8, 0x03, - 0x49, 0x17, 0x9E, 0xFB, 0xD7, 0xAF, 0x91, 0x32, - 0xFD, 0xEA, 0x4F, 0x64, 0xC6, 0x6E, 0x02, 0xEA, - 0xC4, 0xC8, 0x1F, 0x16, 0xC5, 0x4C, 0xFB, 0xC5, - 0x42, 0xF5, 0x85, 0x05, 0x92, 0x59, 0x4B, 0x31, - 0xE5, 0xE9, 0x69, 0xE7, 0x02, 0x98, 0x33, 0xBA, - 0x4C, 0x17, 0x09, 0xEF, 0x89, 0x20, 0xFA, 0x83, - 0x9F, 0xAE, 0x0E, 0x1B, 0x7D, 0x98, 0xB9, 0xF2, - 0x3C, 0x0F, 0xB7, 0x1C, 0x72, 0xDF, 0x17, 0x84, - 0x7F, 0x0A, 0xFD, 0x12, 0x3C, 0x6F, 0x68, 0x5D, - 0x45, 0xEB, 0xB8, 0xD6, 0x24, 0x65, 0x42, 0x75, - 0x5C, 0xC2, 0xF3, 0x3A, 0x6A, 0x4E, 0x51, 0x34, - 0x1B, 0xB6, 0x81, 0xB2, 0x8A, 0xEF, 0x28, 0xA4, - 0xC5, 0x88, 0x9A, 0x97, 0xE0, 0xEF, 0x31, 0x12, - 0x01, 0x7E, 0x1B, 0x43, 0x0F, 0x27, 0x80, 0x87, - 0x98, 0xC5, 0xD5, 0x83, 0xCB, 0x4B, 0xB7, 0x01, - 0x79, 0x60, 0xA1, 0x1A, 0x03, 0x05, 0xC6, 0x36, - 0x04, 0x31, 0x3C, 0x06, 0xDB, 0x08, 0xA8, 0xDA, - 0x8E, 0x32, 0x19, 0x91, 0xF1, 0x0D, 0x61, 0x6F, - 0xE4, 0xB2, 0x79, 0x8A, 0xDE, 0xF4, 0xF7, 0xFB, - 0x2C, 0x23, 0x5B, 0xD9, 0x64, 0x2F, 0xB7, 0xB3, - 0x8B, 0xCA, 0xB8, 0x8C, 0x1D, 0x3B, 0x49, 0x05, - 0x38, 0xA1, 0xE5, 0x8C, 0x1A, 0xDC, 0xA5, 0x61, - 0xFE, 0xF4, 0x2B, 0xDC, 0x77, 0x28, 0xF6, 0x19, - 0xE7, 0xB7, 0x8F, 0x4D, 0x27, 0x2D, 0xED, 0x8A, - 0x3F, 0x3D, 0xDC, 0x9F, 0xD1, 0x30, 0xFF, 0xD6, - 0xC3, 0xBE, 0x41, 0x25, 0xE3, 0xA5, 0x9B, 0x73, - 0xDF, 0x6A, 0xD9, 0xF9, 0x70, 0x84, 0x02, 0x4C, - 0x35, 0xD4, 0x3E, 0x05, 0x76, 0x3A, 0xDC, 0x6D, - 0x5A, 0x81, 0xB3, 0x94, 0xF7, 0x22, 0xF7, 0xDC, - 0xC1, 0x43, 0x31, 0x57, 0x5B, 0x42, 0x9A, 0x0B, - 0xF4, 0x95, 0x30, 0xA9, 0xBB, 0xD8, 0x06, 0xFB, - 0x1D, 0x6F, 0x9B, 0xC3, 0xBB, 0xF3, 0xBF, 0xFB, - 0xB4, 0x9F, 0x35, 0x64, 0x0A, 0x69, 0xB7, 0xD1, - 0x3E, 0xCA, 0x78, 0x07, 0x04, 0x03, 0x79, 0xD4, - 0xF3, 0xA8, 0xEC, 0x18, 0xDB, 0x03, 0x5E, 0x47, - 0xD7, 0xD0, 0x56, 0x2C, 0x74, 0x94, 0x86, 0x04, - 0x46, 0xB8, 0xD4, 0x35, 0x0A, 0x7B, 0xE6, 0x78, - 0xC4, 0x43, 0x3C, 0x56, 0xCC, 0x37, 0x8B, 0xFD, - 0xE8, 0xF4, 0x57, 0xEA, 0xAE, 0xCF, 0x36, 0x97, - 0x12, 0xAC, 0x39, 0xCF, 0x7C, 0xEF, 0x22, 0x67, - 0x01, 0xEC, 0xD8, 0x09, 0x49, 0x4E, 0xE3, 0x74, - 0xDD, 0x39, 0xE1, 0x39, 0xD7, 0x0C, 0x5F, 0x1B, - 0xCE, 0x69, 0xBC, 0x72, 0x44, 0x87, 0x64, 0x1C, - 0x08, 0x05, 0x93, 0x69, 0x6D, 0x7F, 0x90, 0x0A, - 0x2C, 0xCB, 0x8A, 0xBB, 0x7F, 0xE3, 0xE0, 0x80, - 0x31, 0xD0, 0x0A, 0x3A, 0x95, 0xFF, 0xF7, 0xB4, - 0x36, 0x38, 0x93, 0xE0, 0x0C, 0x11, 0x37, 0x12, - 0x06, 0xF6, 0xAD, 0xE9, 0xB1, 0x7A, 0x00, 0xF5, - 0xD2, 0x32, 0x6B, 0xD0, 0x27, 0xA5, 0x1B, 0x3D, - 0xE8, 0xDB, 0xCC, 0xA9, 0x1F, 0x1F, 0xB1, 0x99, - 0x3D, 0x7C, 0xB7, 0xCA, 0xDA, 0x27, 0x2C, 0x64, - 0x1C, 0x49, 0xB6, 0x87, 0x44, 0x06, 0x94, 0x9D, - 0xBC, 0x6B, 0x20, 0xA2, 0x68, 0x15, 0x1F, 0xE2, - 0xF2, 0xAD, 0x6D, 0x23, 0x2E, 0x2B, 0x74, 0xE2, - 0x5D, 0xE4, 0xB0, 0xC7, 0x84, 0xCB, 0x64, 0xBF, - 0xE0, 0xA8, 0x18, 0x83, 0xB4, 0xC9, 0xD9, 0x73, - 0xA8, 0xE6, 0xA9, 0x36, 0xD5, 0x63, 0x1E, 0x2C, - 0x2A, 0x55, 0x09, 0x77, 0x5E, 0xB3, 0x4B, 0xEA, - 0xB5, 0xD0, 0x14, 0x5F, 0xEB, 0x50, 0x7B, 0xAA, - 0xEF, 0x94, 0xBA, 0x2B, 0xD7, 0x8A, 0x07, 0xF1, - 0xF9, 0x5E, 0x12, 0x12, 0x21, 0x52, 0xE5, 0x0A, - 0x3E, 0xC0, 0xBC, 0x5D, 0x4C, 0xE2, 0x12, 0x7C, - 0x39, 0xF9, 0x16, 0x9D, 0xBD, 0x96, 0x83, 0x3B, - 0x7F, 0x3D, 0x6A, 0xEC, 0xF1, 0x25, 0xD2, 0xB0, - 0xB0, 0xEB, 0x20, 0x06, 0x07, 0xD6, 0xD9, 0x4C, - 0x07, 0x9A, 0x82, 0xC1, 0xFC, 0xF7, 0x66, 0x15, - 0xBD, 0x62, 0x65, 0xD8, 0x6C, 0xF6, 0x33, 0x7B, - 0x5A, 0x28, 0xEC, 0x90, 0xA1, 0x26, 0x9F, 0xC3, - 0x28, 0x4A, 0x64, 0x50, 0x5F, 0xCA, 0xE2, 0x6D, - 0xB8, 0x0F, 0xE2, 0x94, 0xB5, 0x8E, 0x1F, 0x8A, - 0x8F, 0x6B, 0xA6, 0x86, 0x1F, 0xEE, 0xDC, 0x24, - 0xB4, 0xB8, 0x25, 0xEC, 0x28, 0x2D, 0xF9, 0xCB, - 0x7D, 0x38, 0xFF, 0xC7, 0x74, 0x2E, 0xD3, 0x10, - 0xEC, 0x03, 0x31, 0xEE, 0x83, 0xE7, 0xA4, 0xF7, - 0xBA, 0x28, 0x21, 0xE0, 0x7F, 0xB4, 0xB7, 0xE1, - 0x7A, 0xF9, 0x2B, 0xB0, 0x2C, 0x3B, 0x80, 0x5F, - 0xE0, 0x5D, 0xB2, 0x7E, 0x59, 0xFF, 0x59, 0x07, - 0x58, 0x42, 0x57, 0xEE, 0x44, 0xF1, 0xB1, 0xAD, - 0xBA, 0xDE, 0xCB, 0x1D, 0x8A, 0x36, 0x67, 0xE8, - 0x45, 0xFF, 0x07, 0x8D, 0xEE, 0xA4, 0x51, 0x9C, - 0x4C, 0x83, 0x5D, 0x2E, 0x2F, 0xE1, 0x5B, 0x75, - 0xE8, 0x29, 0xCD, 0x0B, 0x07, 0x62, 0xE0, 0xC3, - 0x0D, 0x1D, 0xEA, 0xCF, 0xF0, 0x8A, 0x65, 0x27, - 0x70, 0x42, 0x9F, 0x26, 0x00, 0x15, 0x70, 0xC5, - 0x4A, 0xF6, 0x25, 0xD0, 0x40, 0x72, 0xE9, 0xC1, - 0x73, 0xFD, 0x48, 0x94, 0xA3, 0x8D, 0x66, 0x63, - 0x96, 0x4F, 0xF7, 0xEE, 0xFB, 0x4C, 0xC7, 0xB8, - 0x6B, 0xE9, 0x90, 0xE1, 0x2A, 0x66, 0x80, 0x99, - 0x3B, 0xB0, 0x1A, 0x6C, 0xF9, 0x0E, 0x72, 0xDA, - 0x8E, 0x4F, 0x46, 0xC2, 0x6A, 0x4B, 0x7A, 0x16, - 0xE5, 0x26, 0x0B, 0x5C, 0xD4, 0x47, 0x34, 0xE5, - 0x37, 0xBE, 0x68, 0x6C, 0xDA, 0xD3, 0x9B, 0x6F, - 0xAE, 0x51, 0x9C, 0x99, 0x0A, 0x5B, 0xF8, 0x37, - 0xBC, 0xDE, 0xFC, 0x93, 0xC5, 0xE7, 0x0F, 0xEF, - 0x0B, 0xA6, 0x07, 0xC2, 0xA6, 0xE6, 0xDA, 0x2D, - 0x1B, 0x49, 0xC9, 0xDE, 0x6B, 0x27, 0xDC, 0x00, - 0xEF, 0x23, 0x87, 0x0E, 0xEB, 0xD1, 0x48, 0x7D, - 0xB4, 0xF2, 0x58, 0xC6, 0x3C, 0xE2, 0x89, 0xBA, - 0xB0, 0x05, 0xAC, 0x94, 0x41, 0x9A, 0xA8, 0xFF, - 0x3E, 0xBC, 0x3A, 0x52, 0x9C, 0xF9, 0x7F, 0x07, - 0x8B, 0xB0, 0x2C, 0x71, 0x83, 0x7B, 0xCF, 0x2E, - 0x7F, 0x7C, 0x96, 0x65, 0xD9, 0x08, 0x17, 0xEC, - 0xFA, 0xDE, 0x4E, 0x40, 0x12, 0x26, 0x70, 0x71, - 0x65, 0xA5, 0xDC, 0x98, 0x47, 0xA3, 0xFC, 0xE0, - 0x9A, 0x16, 0xED, 0x45, 0x56, 0x72, 0x50, 0x05, - 0x28, 0x2C, 0x99, 0xEC, 0x20, 0x2E, 0x40, 0xC0, - 0x26, 0x69, 0xCD, 0x49, 0x45, 0x17, 0xA4, 0xA3, - 0x42, 0x0D, 0x14, 0x65, 0x87, 0x33, 0x8C, 0x92, - 0xC5, 0xC4, 0x61, 0xFD, 0xE8, 0x68, 0x56, 0x20, - 0x57, 0xF5, 0x8E, 0x5F, 0xCF, 0x7E, 0x97, 0xF6, - 0x49, 0x97, 0x0A, 0xFE, 0xD3, 0x60, 0x1A, 0x5B, - 0x0C, 0x75, 0xDD, 0x8E, 0x31, 0x78, 0x29, 0xA6, - 0xB1, 0x4D, 0xAA, 0xDF, 0x8A, 0xD1, 0xE6, 0x91, - 0xE3, 0x32, 0x3F, 0xEC, 0x8A, 0x1F, 0x0E, 0x35, - 0x07, 0x6E, 0x4B, 0x83, 0x3B, 0xE5, 0x67, 0x34, - 0x1F, 0x0C, 0x81, 0xD8, 0xD5, 0x25, 0x68, 0xE5, - 0x28, 0x1B, 0x5C, 0x81, 0x3E, 0xE3, 0x5C, 0xB4, - 0xB6, 0xBD, 0x62, 0x6A, 0x70, 0x33, 0xC2, 0xC5, - 0x75, 0x27, 0xF4, 0x30, 0xE1, 0x1D, 0xC1, 0x4C, - 0xC5, 0x02, 0x12, 0x46, 0xAC, 0xEC, 0xF9, 0xE8, - 0xE7, 0x58, 0x24, 0x11, 0xB1, 0xF3, 0xB7, 0x8C, - 0x3C, 0xA4, 0x0A, 0x94, 0xA6, 0x7C, 0x68, 0x54, - 0x5B, 0xB9, 0x4D, 0x57, 0x9C, 0xE7, 0x28, 0x09, - 0x6B, 0x89, 0x26, 0x5D, 0xE7, 0x50, 0xA9, 0x95, - 0x90, 0x91, 0x8E, 0x00, 0x59, 0xF8, 0x3A, 0x70, - 0xAF, 0x48, 0x2E, 0xE8, 0xC4, 0x34, 0x8C, 0xF4, - 0x5F, 0x7F, 0xCB, 0x07, 0xAA, 0xF0, 0xD9, 0xFB, - 0x5C, 0x32, 0x90, 0x22, 0x1A, 0xD2, 0x1A, 0xCF, - 0x92, 0x06, 0x02, 0xCF, 0x10, 0x18, 0x7B, 0x93, - 0xCC, 0x07, 0x4A, 0x31, 0x25, 0x30, 0x23, 0x06, - 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, - 0x09, 0x15, 0x31, 0x16, 0x04, 0x14, 0xD1, 0xDE, - 0x23, 0x16, 0x9F, 0x6E, 0xF4, 0x42, 0x21, 0x23, - 0xE1, 0x11, 0xAA, 0xC8, 0x7C, 0x60, 0x4A, 0x78, - 0x9D, 0x24, 0x30, 0x31, 0x30, 0x21, 0x30, 0x09, - 0x06, 0x05, 0x2B, 0x0E, 0x03, 0x02, 0x1A, 0x05, - 0x00, 0x04, 0x14, 0xD6, 0x4A, 0xBB, 0x75, 0xB1, - 0xF9, 0x9E, 0xD3, 0x58, 0x6D, 0xD1, 0x74, 0x9F, - 0x00, 0x8A, 0xF2, 0xC8, 0xAA, 0x52, 0x4D, 0x04, - 0x08, 0x77, 0x46, 0xE7, 0xBA, 0x25, 0x4B, 0xDA, - 0x41, 0x02, 0x02, 0x08, 0x00] -}; - -const WPA_EAP_CLIENT_LIST = [ - { - ssid: 'WPA-EAP-TTLS', - keyManagement: 'WPA-EAP', - eap: 'TTLS', - identity: EAP_USERNAME, - password: EAP_PASSWORD, - serverCertificate: CLIENT_PKCS12_CERT.nickname, - phase2: 'MSCHAPV2' - } -]; - -/** - * Convert the given MozWifiNetwork object array to testAssociate chain. - * - * @param aNetworks - * An array of MozWifiNetwork which we want to convert. - * - * @return A promise chain which "then"s testAssociate accordingly. - */ -function convertToTestAssociateChain(aNetworks) { - let chain = Promise.resolve(); - - aNetworks.forEach(function (aNetwork) { - network = new window.MozWifiNetwork(aNetwork); - chain = chain.then(() => gTestSuite.testAssociate(network)); - }); - - return chain; -} - -gTestSuite.doTestWithCertificate( - new Blob([new Uint8Array(CLIENT_PKCS12_CERT.content)]), - CLIENT_PKCS12_CERT.password, - CLIENT_PKCS12_CERT.nickname, - CLIENT_PKCS12_CERT.usage, - function() { - return gTestSuite.ensureWifiEnabled(true) - // Load required server files. - .then(() => gTestSuite.writeFile(SERVER_EAP_USER_CONF.path, SERVER_EAP_USER_CONF.content)) - .then(() => gTestSuite.writeFile(CA_CERT.path, CA_CERT.content)) - .then(() => gTestSuite.writeFile(SERVER_CERT.path, SERVER_CERT.content)) - .then(() => gTestSuite.writeFile(SERVER_KEY.path, SERVER_KEY.content)) - // Start AP. - .then(() => gTestSuite.startHostapds(WPA_EAP_AP_LIST)) - // Scan test. - .then(() => gTestSuite.testWifiScanWithRetry(SCAN_RETRY_CNT, WPA_EAP_AP_LIST)) - // Associate test. - .then(() => convertToTestAssociateChain(WPA_EAP_CLIENT_LIST)) - // Tear down. - .then(gTestSuite.killAllHostapd) -}); diff --git a/dom/wifi/test/marionette/test_wifi_associate_wo_connect.js b/dom/wifi/test/marionette/test_wifi_associate_wo_connect.js deleted file mode 100644 index 3fba0b2c6..000000000 --- a/dom/wifi/test/marionette/test_wifi_associate_wo_connect.js +++ /dev/null @@ -1,55 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -MARIONETTE_TIMEOUT = 60000; -MARIONETTE_HEAD_JS = 'head.js'; - -/** - * Associate with the given networks but don't connect to it. - * - * Issue a association-only request, which will not have us connect - * to the network. Instead, the network config will be added as the - * known networks. After calling the "associate" API, we will wait - * a while to make sure the "connected" event is not received. - * - * Fulfill params: (none) - * Reject params: (none) - * - * @param aNetwork - * MozWifiNetwork object. - * - * @return A deferred promise. - */ -function associateButDontConnect(aNetwork) { - log('Associating with ' + aNetwork.ssid); - aNetwork.dontConnect = true; - - let promises = []; - promises.push(gTestSuite.waitForTimeout(10 * 1000) - .then(() => { throw 'timeout'; })); - - promises.push(gTestSuite.testAssociate(aNetwork)); - - return Promise.all(promises) - .then(() => { throw 'unexpected state'; }, - function(aReason) { - is(typeof aReason, 'string', 'typeof aReason'); - is(aReason, 'timeout', aReason); - }); -} - -gTestSuite.doTest(function() { - let firstNetwork; - return gTestSuite.ensureWifiEnabled(true) - .then(gTestSuite.requestWifiScan) - .then(function(aNetworks) { - firstNetwork = aNetworks[0]; - return associateButDontConnect(firstNetwork); - }) - .then(gTestSuite.getKnownNetworks) - .then(function(aKnownNetworks) { - is(1, aKnownNetworks.length, 'There should be only one known network!'); - is(aKnownNetworks[0].ssid, firstNetwork.ssid, - 'The only one known network should be ' + firstNetwork.ssid) - }); -}); diff --git a/dom/wifi/test/marionette/test_wifi_auto_connect.js b/dom/wifi/test/marionette/test_wifi_auto_connect.js deleted file mode 100644 index 7add9f03d..000000000 --- a/dom/wifi/test/marionette/test_wifi_auto_connect.js +++ /dev/null @@ -1,44 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -MARIONETTE_TIMEOUT = 60000; -MARIONETTE_HEAD_JS = 'head.js'; - -const TESTING_HOSTAPD = [{ ssid: 'ap0' }]; - -gTestSuite.doTestWithoutStockAp(function() { - let firstNetwork; - return gTestSuite.ensureWifiEnabled(true) - // Start custom hostapd for testing. - .then(() => gTestSuite.startHostapds(TESTING_HOSTAPD)) - .then(() => gTestSuite.verifyNumOfProcesses('hostapd', TESTING_HOSTAPD.length)) - - // Request the first scan. - .then(gTestSuite.requestWifiScan) - .then(function(networks) { - firstNetwork = networks[0]; - return gTestSuite.testAssociate(firstNetwork); - }) - - // Note that due to Bug 1168285, we need to re-start testing hostapd - // after wifi has been re-enabled. - - // Disable wifi and kill running hostapd. - .then(() => gTestSuite.requestWifiEnabled(false)) - .then(gTestSuite.killAllHostapd) - .then(() => gTestSuite.verifyNumOfProcesses('hostapd', 0)) - - // Re-enable wifi. - .then(() => gTestSuite.requestWifiEnabled(true)) - - // Restart hostapd. - .then(() => gTestSuite.startHostapds(TESTING_HOSTAPD)) - .then(() => gTestSuite.verifyNumOfProcesses('hostapd', TESTING_HOSTAPD.length)) - - // Wait for connection automatically. - .then(() => gTestSuite.waitForConnected(firstNetwork)) - - // Kill running hostapd. - .then(gTestSuite.killAllHostapd) - .then(() => gTestSuite.verifyNumOfProcesses('hostapd', 0)) -}); diff --git a/dom/wifi/test/marionette/test_wifi_enable.js b/dom/wifi/test/marionette/test_wifi_enable.js deleted file mode 100644 index 6a1bec7a2..000000000 --- a/dom/wifi/test/marionette/test_wifi_enable.js +++ /dev/null @@ -1,11 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -MARIONETTE_TIMEOUT = 60000; -MARIONETTE_HEAD_JS = 'head.js'; - -gTestSuite.doTest(function() { - return Promise.resolve() - .then(() => gTestSuite.ensureWifiEnabled(false)) - .then(() => gTestSuite.requestWifiEnabled(true)); -});
\ No newline at end of file diff --git a/dom/wifi/test/marionette/test_wifi_enable_api.js b/dom/wifi/test/marionette/test_wifi_enable_api.js deleted file mode 100644 index 3728330a2..000000000 --- a/dom/wifi/test/marionette/test_wifi_enable_api.js +++ /dev/null @@ -1,13 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -MARIONETTE_TIMEOUT = 60000; -MARIONETTE_HEAD_JS = 'head.js'; - -gTestSuite.doTest(function() { - return Promise.resolve() - .then(() => gTestSuite.ensureWifiEnabled(false, true)) - .then(() => gTestSuite.requestWifiEnabled(true, true)) - .then(() => gTestSuite.requestWifiEnabled(false, true)) - .then(() => gTestSuite.ensureWifiEnabled(true, true)); -}); diff --git a/dom/wifi/test/marionette/test_wifi_manage_pkcs12_certificate.js b/dom/wifi/test/marionette/test_wifi_manage_pkcs12_certificate.js deleted file mode 100644 index f85ef00c9..000000000 --- a/dom/wifi/test/marionette/test_wifi_manage_pkcs12_certificate.js +++ /dev/null @@ -1,338 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -MARIONETTE_TIMEOUT = 60000; -MARIONETTE_HEAD_JS = 'head.js'; - -// Binary form of test certificate. -var testCertInfo = { - nickname: 'Test Certificate', - password: '12345678', - usage: ['UserCert', 'ServerCert'], - blob: [0x30, 0x82, 0x09, 0xF1, 0x02, 0x01, 0x03, 0x30, - 0x82, 0x09, 0xB7, 0x06, 0x09, 0x2A, 0x86, 0x48, - 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x01, 0xA0, 0x82, - 0x09, 0xA8, 0x04, 0x82, 0x09, 0xA4, 0x30, 0x82, - 0x09, 0xA0, 0x30, 0x82, 0x06, 0x9F, 0x06, 0x09, - 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, - 0x06, 0xA0, 0x82, 0x06, 0x90, 0x30, 0x82, 0x06, - 0x8C, 0x02, 0x01, 0x00, 0x30, 0x82, 0x06, 0x85, - 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, - 0x01, 0x07, 0x01, 0x30, 0x1C, 0x06, 0x0A, 0x2A, - 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x0C, 0x01, - 0x06, 0x30, 0x0E, 0x04, 0x08, 0x13, 0xB5, 0x2F, - 0x5A, 0xB9, 0x49, 0xE6, 0x0B, 0x02, 0x02, 0x08, - 0x00, 0x80, 0x82, 0x06, 0x58, 0x35, 0x77, 0x6B, - 0xBF, 0x5C, 0x06, 0x09, 0xD8, 0xF0, 0x36, 0x06, - 0x69, 0x8D, 0xA2, 0x86, 0xCF, 0x6B, 0x73, 0x86, - 0x14, 0xFA, 0x51, 0x9A, 0x87, 0x73, 0x29, 0x71, - 0xC5, 0xB1, 0x4F, 0xFB, 0xEC, 0x64, 0x84, 0x20, - 0xFC, 0x06, 0x4A, 0x93, 0x74, 0x01, 0xFB, 0xEB, - 0x1F, 0xDC, 0xF8, 0xF7, 0xBB, 0xDC, 0x42, 0xA1, - 0x4A, 0x71, 0xDE, 0x08, 0x33, 0x7A, 0xCA, 0xD3, - 0xD8, 0x40, 0x24, 0x47, 0xAE, 0x41, 0x42, 0x8E, - 0xC8, 0x4E, 0xBE, 0x8B, 0xB3, 0xE5, 0x77, 0xAC, - 0xBD, 0x98, 0x0C, 0x0E, 0x53, 0xBE, 0x38, 0xB7, - 0xEA, 0xD2, 0x29, 0x35, 0xD2, 0xC4, 0xF4, 0xC7, - 0xD8, 0xB1, 0x73, 0x2A, 0x13, 0x11, 0x65, 0xF7, - 0x0C, 0x8B, 0xC0, 0x43, 0xFB, 0x31, 0x6C, 0xD2, - 0xE4, 0x43, 0x85, 0x51, 0x16, 0xBF, 0x35, 0xB5, - 0x05, 0x6B, 0x86, 0x11, 0xEA, 0x78, 0x64, 0x9F, - 0x42, 0x29, 0xB9, 0x79, 0xAF, 0xB0, 0x7C, 0xBF, - 0xC0, 0x89, 0xAD, 0xC7, 0x37, 0xD2, 0x30, 0x8C, - 0xDC, 0xF6, 0x77, 0x5E, 0x1F, 0x26, 0x28, 0x8F, - 0xAC, 0x19, 0x6C, 0xA0, 0x15, 0xC7, 0x12, 0xA3, - 0x0A, 0xD5, 0xC6, 0x15, 0x60, 0x58, 0x16, 0xB8, - 0x30, 0x12, 0x3C, 0x78, 0x3C, 0x93, 0x23, 0xA1, - 0x56, 0x75, 0x0B, 0x77, 0xAA, 0x0B, 0x0B, 0x2B, - 0x91, 0xB6, 0x41, 0xAB, 0xF5, 0x09, 0x4C, 0x1E, - 0x36, 0xC0, 0x88, 0xC3, 0x08, 0xF2, 0x65, 0xCB, - 0x58, 0x8F, 0x94, 0xB4, 0xB4, 0x05, 0xCC, 0x44, - 0x49, 0x73, 0x1B, 0x25, 0x6F, 0x5D, 0x83, 0xBD, - 0xF0, 0x70, 0xD0, 0xE8, 0x0D, 0x18, 0x2E, 0x44, - 0xD7, 0x89, 0x64, 0x6A, 0xED, 0x23, 0x30, 0xDF, - 0xAD, 0x84, 0x3B, 0x74, 0x2C, 0x0D, 0x2B, 0x51, - 0x84, 0xA2, 0xA4, 0x9E, 0x42, 0xC3, 0x81, 0x69, - 0xFA, 0x56, 0x76, 0x9F, 0xD9, 0x02, 0x64, 0x04, - 0xFE, 0xF0, 0xD9, 0x01, 0xBC, 0xE2, 0xC9, 0xDD, - 0x88, 0xAC, 0xFA, 0x24, 0x7E, 0xB1, 0xF8, 0x39, - 0x27, 0xA2, 0xEB, 0xE4, 0x53, 0xC1, 0xF3, 0xFE, - 0x2D, 0x9A, 0x49, 0x73, 0xFF, 0x7C, 0x8E, 0x39, - 0xF7, 0x15, 0x27, 0xB3, 0x47, 0x48, 0x92, 0x8C, - 0x57, 0x60, 0x9C, 0x97, 0xBA, 0x80, 0xD2, 0x25, - 0x80, 0x94, 0xCE, 0x2C, 0x0C, 0x00, 0x44, 0x8C, - 0x8C, 0x37, 0x82, 0x5D, 0x5F, 0x62, 0x8B, 0x05, - 0x6F, 0xB0, 0x07, 0x34, 0xF9, 0xC3, 0xA1, 0x34, - 0x3D, 0xE4, 0x90, 0xB0, 0x03, 0x59, 0x97, 0x6E, - 0xFB, 0xF2, 0x92, 0xE5, 0xB5, 0x30, 0x7C, 0x0D, - 0x3B, 0x8F, 0x90, 0x8E, 0x04, 0x47, 0x01, 0x0E, - 0x88, 0x50, 0x4A, 0x88, 0xA0, 0xFF, 0xB7, 0x9E, - 0x2B, 0x2C, 0x98, 0xD0, 0x3E, 0x16, 0x35, 0x5B, - 0xD5, 0xEA, 0x54, 0x86, 0xE0, 0xFB, 0x9F, 0x2F, - 0x62, 0x89, 0x36, 0x36, 0x9D, 0x6E, 0x62, 0xCB, - 0xC8, 0x6C, 0x62, 0x34, 0x8F, 0x66, 0x07, 0x62, - 0xA7, 0x00, 0x90, 0x31, 0xFA, 0x5D, 0xDD, 0x12, - 0x33, 0x69, 0xD0, 0x74, 0x0E, 0x0B, 0x42, 0x9A, - 0xF3, 0x40, 0x7E, 0x3E, 0x48, 0x1D, 0xF2, 0x5C, - 0x71, 0x0B, 0x78, 0x7E, 0xD5, 0x15, 0xA4, 0x16, - 0x1E, 0xBD, 0x71, 0x18, 0x87, 0x3A, 0xC9, 0xE3, - 0x45, 0xEE, 0x70, 0xA2, 0x4C, 0x50, 0xF5, 0x16, - 0x5C, 0xF8, 0x76, 0xE6, 0x9F, 0x8D, 0x86, 0x41, - 0x7E, 0xF8, 0x60, 0x3D, 0x75, 0x6D, 0x55, 0x96, - 0x9E, 0x43, 0x48, 0x82, 0xF7, 0xB6, 0xAC, 0x98, - 0x6F, 0x10, 0xAA, 0x20, 0x64, 0xD0, 0x7C, 0x25, - 0x24, 0xF7, 0xD8, 0xA4, 0xCC, 0x2D, 0xBF, 0x85, - 0x62, 0x6C, 0x4F, 0xFF, 0x9D, 0x71, 0x04, 0x98, - 0x61, 0xB0, 0xBC, 0x31, 0xC1, 0xE9, 0xB8, 0x29, - 0xA5, 0xEB, 0xD1, 0x1D, 0x65, 0x8E, 0xAE, 0x38, - 0x55, 0x65, 0x22, 0xC7, 0xFD, 0x7E, 0xF2, 0x6A, - 0xB6, 0xB1, 0x51, 0x37, 0x4B, 0x05, 0x8F, 0xA7, - 0x2D, 0x3F, 0x5C, 0x04, 0x2B, 0xBA, 0x2C, 0x37, - 0xCA, 0xDE, 0xD5, 0x3E, 0xA0, 0xA5, 0x86, 0x59, - 0xA7, 0xD7, 0x38, 0x07, 0xFB, 0x79, 0xF6, 0x2D, - 0xE1, 0xAA, 0x7C, 0xD1, 0x91, 0xBE, 0x39, 0xDF, - 0x53, 0x3C, 0xD1, 0x44, 0x2C, 0xF9, 0x12, 0x7D, - 0xB1, 0xCD, 0xF3, 0x35, 0x1F, 0x85, 0xA6, 0x64, - 0x2F, 0xFD, 0x28, 0xF2, 0x85, 0xA8, 0xA7, 0x1F, - 0x7F, 0xD9, 0x79, 0x30, 0x9B, 0xFC, 0x69, 0x3A, - 0x9B, 0x1F, 0x55, 0x70, 0xC9, 0x60, 0x82, 0x3D, - 0xE9, 0x5A, 0x37, 0x5F, 0x8C, 0xBD, 0x19, 0x5D, - 0xCC, 0x1C, 0xBE, 0x26, 0x4A, 0xEA, 0x8B, 0x39, - 0xCE, 0x0D, 0xBD, 0x63, 0x05, 0x98, 0x75, 0xAB, - 0x08, 0x79, 0x90, 0xC7, 0x20, 0xFF, 0xE4, 0x0D, - 0xB1, 0xA0, 0x92, 0x2B, 0x0C, 0x4B, 0x0C, 0xDC, - 0xB9, 0x72, 0x2A, 0xA4, 0xCC, 0xA6, 0x32, 0xA3, - 0x57, 0x82, 0xB4, 0xB9, 0x0F, 0x81, 0xC5, 0xD9, - 0x7C, 0xB8, 0x0F, 0x7D, 0xEA, 0x5D, 0xD3, 0xC4, - 0x2F, 0x31, 0x79, 0x11, 0xAD, 0x36, 0x56, 0x1F, - 0xFA, 0xE3, 0xCE, 0xD2, 0x29, 0x23, 0xE8, 0x2C, - 0xDF, 0x7D, 0x94, 0x28, 0x28, 0x9A, 0x0E, 0x64, - 0xFC, 0x07, 0x11, 0x96, 0x06, 0x1A, 0x39, 0xCD, - 0x04, 0x37, 0x37, 0xDB, 0xFE, 0x68, 0x37, 0xF5, - 0x59, 0x54, 0xBC, 0xEF, 0xDB, 0x0C, 0x80, 0xCD, - 0xD3, 0x46, 0xA8, 0xA2, 0xBE, 0xE0, 0x63, 0x80, - 0xA1, 0x5F, 0x5D, 0xF1, 0xFB, 0x96, 0x8C, 0x06, - 0x38, 0xB6, 0xCB, 0x70, 0xB0, 0xFB, 0xD3, 0x26, - 0xB3, 0x8B, 0xC6, 0x85, 0x34, 0xB7, 0xAB, 0x5F, - 0x7E, 0xC6, 0xAA, 0x79, 0x5B, 0x48, 0x11, 0x65, - 0x9E, 0x2A, 0xCD, 0x6A, 0xF0, 0xB2, 0x93, 0xF5, - 0x2B, 0x88, 0x45, 0xB7, 0xC9, 0xBE, 0x1A, 0x72, - 0x60, 0x62, 0xA4, 0xA5, 0x3B, 0xC2, 0x1C, 0xC6, - 0x21, 0x09, 0xA9, 0x40, 0xF6, 0x58, 0x2B, 0xE5, - 0x70, 0xDC, 0xFC, 0x47, 0x3B, 0x08, 0xEE, 0xA9, - 0x94, 0x26, 0x43, 0xFE, 0xA7, 0x75, 0xD6, 0x4E, - 0x52, 0xF6, 0x46, 0xD1, 0x80, 0xEB, 0x3B, 0x8E, - 0xBE, 0x54, 0x4F, 0xBD, 0x42, 0x0E, 0x41, 0xF9, - 0x36, 0x7D, 0xB6, 0x7F, 0x99, 0x20, 0xC9, 0x63, - 0xE7, 0x93, 0x02, 0x62, 0x59, 0x94, 0xCB, 0xC6, - 0x62, 0xA9, 0x26, 0xE1, 0x1E, 0x03, 0x5A, 0x41, - 0x2F, 0x43, 0x28, 0x75, 0xB7, 0x0C, 0x02, 0x9C, - 0x1E, 0xE0, 0x40, 0xB3, 0xE2, 0x9A, 0xED, 0xC6, - 0x20, 0x49, 0xEC, 0xDD, 0xC5, 0x64, 0x95, 0x83, - 0x51, 0xAE, 0x46, 0x9D, 0x70, 0x17, 0xC6, 0x47, - 0xD3, 0x82, 0xCC, 0x6A, 0x5D, 0x93, 0xB2, 0x85, - 0x5B, 0x25, 0x05, 0xE7, 0x26, 0x2E, 0xD3, 0xDA, - 0x1C, 0xD9, 0x06, 0xB6, 0x16, 0x69, 0x8C, 0x7F, - 0xC8, 0xCF, 0x95, 0x18, 0xB5, 0x98, 0xC0, 0x42, - 0x61, 0xDE, 0x77, 0x41, 0x3A, 0xF6, 0xE1, 0xB0, - 0xE8, 0x64, 0x4A, 0xC2, 0x58, 0xBE, 0x27, 0xC6, - 0x9B, 0x0D, 0x47, 0x1A, 0x09, 0x56, 0x7D, 0x2B, - 0x19, 0x01, 0x88, 0xC7, 0xFB, 0x1E, 0xCF, 0x5E, - 0xF6, 0xB0, 0x82, 0x87, 0xC0, 0xBE, 0xD6, 0xA5, - 0xC3, 0xAC, 0x3A, 0x97, 0x88, 0x25, 0x81, 0xAA, - 0x3A, 0xCE, 0x66, 0x88, 0x0F, 0xC3, 0x02, 0x50, - 0x1C, 0xC3, 0x2B, 0xBC, 0x53, 0x52, 0xFE, 0xD2, - 0x3F, 0x50, 0xC8, 0xB2, 0x19, 0x0A, 0x14, 0xB1, - 0x73, 0x18, 0xB4, 0xDF, 0xBD, 0xED, 0x43, 0xC5, - 0x91, 0xF4, 0x91, 0xBA, 0x7E, 0xB0, 0x7E, 0xA9, - 0x43, 0x67, 0x06, 0xCF, 0x51, 0xC1, 0xBF, 0x63, - 0x7E, 0x91, 0x76, 0xFF, 0x4F, 0x48, 0x91, 0xCF, - 0xDF, 0x01, 0x4D, 0x7E, 0x81, 0x22, 0xFB, 0x79, - 0xFC, 0x1D, 0xE3, 0xA7, 0x45, 0x16, 0xFB, 0xF2, - 0x83, 0xC7, 0xAE, 0xC6, 0xC5, 0x81, 0xDB, 0xA2, - 0x9F, 0x2F, 0xEA, 0xE6, 0x8E, 0x12, 0x8D, 0x43, - 0x14, 0x26, 0x25, 0x0E, 0xB4, 0x18, 0xE8, 0x41, - 0x84, 0xA3, 0x04, 0xDF, 0x97, 0xFF, 0xAA, 0x45, - 0xEC, 0x18, 0xAA, 0xB1, 0xFC, 0xDC, 0xB9, 0xAB, - 0xEE, 0xD1, 0xC4, 0x9E, 0x42, 0x3F, 0x5B, 0x8F, - 0x9F, 0x22, 0xAF, 0xCC, 0x6F, 0xA0, 0x41, 0x41, - 0xCB, 0xD3, 0xAC, 0x96, 0x20, 0xF1, 0x63, 0x56, - 0x65, 0xCE, 0x83, 0xC6, 0x62, 0x04, 0x85, 0x16, - 0x7F, 0x4E, 0xFB, 0xA0, 0x68, 0x11, 0x85, 0x5B, - 0x51, 0xB6, 0x9F, 0xA2, 0xF5, 0xA1, 0xCF, 0x01, - 0x9A, 0x80, 0x68, 0xC3, 0xE9, 0x7F, 0x9E, 0x2E, - 0x83, 0x84, 0xDC, 0x3C, 0x35, 0xCF, 0x24, 0xBF, - 0xF5, 0x00, 0x91, 0x45, 0x14, 0x65, 0xE0, 0xC5, - 0x75, 0xDA, 0xEF, 0x14, 0xBD, 0xDB, 0x28, 0x8D, - 0x30, 0x96, 0xC9, 0xFE, 0xA8, 0x49, 0x76, 0xC9, - 0xED, 0x90, 0x4C, 0x2E, 0xF1, 0x14, 0x2C, 0xF7, - 0x13, 0x7C, 0xF1, 0xCC, 0x67, 0xA5, 0x11, 0x55, - 0xBD, 0x66, 0x13, 0x8A, 0x76, 0xF9, 0xAC, 0xC9, - 0x51, 0x8A, 0xBB, 0x5D, 0x29, 0xEF, 0xF6, 0x37, - 0xA0, 0x3E, 0x99, 0x77, 0x6B, 0xE5, 0xCD, 0x06, - 0xAC, 0x57, 0x07, 0x37, 0x44, 0x3D, 0x5D, 0xD7, - 0xB6, 0x5C, 0xCB, 0x77, 0xD0, 0x4C, 0x28, 0x9D, - 0x12, 0x69, 0x5A, 0x68, 0xD1, 0x15, 0x30, 0xC4, - 0x30, 0xD2, 0x20, 0xDF, 0xD5, 0x73, 0x9F, 0x83, - 0xE9, 0x4C, 0x55, 0xF5, 0xAF, 0xAA, 0x37, 0xF8, - 0x28, 0xB6, 0x3F, 0x99, 0x4B, 0x15, 0x1E, 0x40, - 0xAB, 0x4F, 0x58, 0x3D, 0x3B, 0x81, 0x7D, 0x62, - 0x28, 0x6E, 0x73, 0x58, 0x50, 0x36, 0x49, 0x01, - 0xF7, 0x04, 0x3A, 0x23, 0x28, 0xDA, 0x15, 0xC5, - 0xE3, 0xF6, 0x6F, 0xE1, 0x79, 0x07, 0xFB, 0xAA, - 0xFF, 0x44, 0x48, 0x53, 0x9E, 0x7F, 0x8D, 0x89, - 0x88, 0x1A, 0x9A, 0xF9, 0x47, 0x58, 0x20, 0xBB, - 0x79, 0x4A, 0x2A, 0x14, 0x03, 0x9B, 0x65, 0x4C, - 0x67, 0x02, 0x02, 0xFE, 0xEB, 0xCD, 0xCB, 0x84, - 0xF5, 0xCE, 0x32, 0x59, 0xBC, 0xEA, 0xEC, 0xB1, - 0x3C, 0x22, 0xCF, 0x9D, 0xB0, 0x34, 0x6D, 0xE6, - 0x5A, 0x37, 0xC0, 0x22, 0xAA, 0xF3, 0xB5, 0x71, - 0x90, 0x21, 0xE0, 0xB6, 0x19, 0xE9, 0xB3, 0x10, - 0xCE, 0x5B, 0xF9, 0xD4, 0x25, 0x30, 0x7D, 0xF6, - 0x7D, 0xB6, 0x16, 0xFC, 0x20, 0x3C, 0x2F, 0x96, - 0xD5, 0x79, 0x90, 0x88, 0x24, 0x5D, 0x46, 0x64, - 0x99, 0xC1, 0xF8, 0x7F, 0x96, 0xA7, 0xB5, 0xA9, - 0x47, 0xA3, 0x14, 0xED, 0x93, 0xED, 0x30, 0x56, - 0x58, 0xA5, 0xD4, 0x54, 0x2A, 0xF3, 0x89, 0x27, - 0x7C, 0x55, 0x41, 0x11, 0x27, 0x9D, 0xF6, 0x4D, - 0xA6, 0xB1, 0x00, 0xE0, 0xB0, 0xF6, 0x1E, 0xAB, - 0x20, 0x1F, 0xAE, 0x8A, 0x82, 0xA7, 0x49, 0xFC, - 0xBB, 0x66, 0xAC, 0x97, 0x95, 0x49, 0x29, 0xCB, - 0x6F, 0xF4, 0xC1, 0xB7, 0x6B, 0xF9, 0x8C, 0x25, - 0xC6, 0xF0, 0xB5, 0x81, 0xB0, 0xA2, 0x4D, 0xCC, - 0x2E, 0xD0, 0x13, 0x5F, 0x96, 0x3F, 0xCD, 0xD0, - 0x52, 0xD1, 0xFE, 0xF9, 0xC2, 0x7E, 0x9D, 0xAB, - 0xCB, 0x95, 0x0F, 0x27, 0x01, 0x9E, 0x23, 0x6B, - 0x19, 0xFF, 0x52, 0x55, 0x71, 0x0A, 0xD4, 0xBB, - 0x43, 0x65, 0x29, 0x66, 0xBE, 0x2D, 0x6C, 0xE3, - 0x2A, 0x7C, 0xB4, 0x02, 0x32, 0x59, 0x94, 0x80, - 0x14, 0xE7, 0x62, 0xE4, 0xCE, 0xB0, 0xCA, 0xCA, - 0x37, 0xD7, 0x0C, 0x68, 0x29, 0xE2, 0x92, 0xE1, - 0xEB, 0x91, 0xE5, 0xA1, 0x0C, 0xFC, 0x55, 0xCB, - 0x56, 0xB3, 0x96, 0xFB, 0x64, 0xD9, 0x53, 0x8E, - 0x82, 0x2B, 0xDF, 0x7F, 0xCB, 0x2A, 0xF6, 0x3C, - 0xA7, 0x89, 0x52, 0x13, 0x2C, 0x6A, 0x93, 0xA2, - 0x74, 0xF5, 0x91, 0x00, 0x17, 0xAA, 0x74, 0x45, - 0x63, 0x5A, 0xE5, 0xC3, 0x16, 0xFC, 0x0E, 0xF7, - 0xF3, 0xA4, 0x55, 0x8A, 0xA2, 0x60, 0x24, 0x57, - 0x25, 0x2C, 0x94, 0xE0, 0xF5, 0x32, 0x54, 0x4A, - 0x2D, 0x63, 0x5F, 0xD8, 0x35, 0x96, 0xBD, 0xFE, - 0x90, 0x33, 0x17, 0xF6, 0xB5, 0x81, 0x02, 0xFA, - 0x5C, 0x94, 0x3A, 0xBE, 0x22, 0xB9, 0xFC, 0x3E, - 0x09, 0xE4, 0x76, 0xD7, 0x03, 0x38, 0x38, 0xC2, - 0xC2, 0x0D, 0x66, 0x3C, 0xD0, 0x91, 0x5C, 0xF4, - 0x0E, 0xC2, 0xDE, 0x46, 0x90, 0x2E, 0xF5, 0x22, - 0xA9, 0x3D, 0x15, 0x20, 0x5F, 0x17, 0x10, 0x5A, - 0x54, 0x63, 0x93, 0x7B, 0xC3, 0x00, 0x3D, 0x42, - 0x73, 0xF1, 0xAD, 0xC1, 0xDE, 0x76, 0x18, 0x9C, - 0x68, 0x17, 0xBF, 0x3B, 0xE0, 0x30, 0x82, 0x02, - 0xF9, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, - 0x0D, 0x01, 0x07, 0x01, 0xA0, 0x82, 0x02, 0xEA, - 0x04, 0x82, 0x02, 0xE6, 0x30, 0x82, 0x02, 0xE2, - 0x30, 0x82, 0x02, 0xDE, 0x06, 0x0B, 0x2A, 0x86, - 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x0C, 0x0A, 0x01, - 0x02, 0xA0, 0x82, 0x02, 0xA6, 0x30, 0x82, 0x02, - 0xA2, 0x30, 0x1C, 0x06, 0x0A, 0x2A, 0x86, 0x48, - 0x86, 0xF7, 0x0D, 0x01, 0x0C, 0x01, 0x03, 0x30, - 0x0E, 0x04, 0x08, 0x34, 0x37, 0x27, 0x5F, 0xE8, - 0xD6, 0x00, 0x0D, 0x02, 0x02, 0x08, 0x00, 0x04, - 0x82, 0x02, 0x80, 0xC0, 0xE6, 0xB1, 0x63, 0x73, - 0xFC, 0xBF, 0x50, 0xFB, 0x54, 0xCF, 0x67, 0x16, - 0xF8, 0x28, 0x48, 0x13, 0x7F, 0xF2, 0xBD, 0x66, - 0x70, 0xC7, 0xF6, 0x01, 0xD0, 0x58, 0xF4, 0xA4, - 0xD9, 0x45, 0xE2, 0x63, 0x92, 0x7F, 0x78, 0x2B, - 0xB6, 0xDB, 0x16, 0x44, 0x1D, 0x11, 0xCB, 0xC3, - 0x20, 0xA9, 0x8A, 0x96, 0x13, 0xB8, 0x6E, 0xF3, - 0xDA, 0x46, 0x05, 0x2C, 0xF9, 0x67, 0xBB, 0x05, - 0x88, 0xC0, 0xC8, 0x60, 0x09, 0xA3, 0x82, 0x27, - 0x33, 0xEB, 0xEE, 0x43, 0x98, 0xE9, 0xE2, 0x24, - 0xA8, 0x06, 0xD5, 0xFF, 0xF5, 0xC0, 0x79, 0x4B, - 0x06, 0x40, 0xE6, 0x28, 0xC6, 0x6E, 0x4E, 0x03, - 0xCC, 0x9B, 0xB6, 0xBD, 0xB6, 0x81, 0x88, 0x5C, - 0x34, 0x6B, 0x8B, 0x15, 0x23, 0x75, 0x21, 0xAC, - 0x79, 0xFD, 0xDB, 0x80, 0x1D, 0x20, 0x84, 0xF1, - 0x47, 0xAF, 0x7B, 0x40, 0x6C, 0xD2, 0x64, 0x52, - 0x11, 0x1B, 0x01, 0x1E, 0xB5, 0xA9, 0x4B, 0xC4, - 0x51, 0x54, 0x40, 0xE2, 0xC8, 0xEB, 0x20, 0x48, - 0x2D, 0x40, 0xF8, 0xC6, 0x58, 0x5A, 0xE3, 0x34, - 0xD8, 0x79, 0x04, 0xD7, 0xD6, 0x07, 0xF2, 0x12, - 0x66, 0xC8, 0x31, 0x37, 0x71, 0x60, 0xF4, 0x75, - 0xDC, 0x60, 0x54, 0x19, 0x6A, 0x75, 0x56, 0xC5, - 0xA9, 0x67, 0x4A, 0x03, 0x7A, 0xFD, 0x12, 0x59, - 0x2B, 0x74, 0xE6, 0xA5, 0xE2, 0xF8, 0xBB, 0x1E, - 0x76, 0x96, 0xD4, 0xD4, 0x3F, 0x8B, 0xAD, 0x90, - 0xAF, 0x04, 0x41, 0xDB, 0xD8, 0xCC, 0x2D, 0x37, - 0x06, 0x20, 0x9B, 0xE7, 0x98, 0x87, 0x12, 0xAC, - 0x70, 0xC9, 0xF4, 0x1C, 0x28, 0xFB, 0x2C, 0x9E, - 0x18, 0xE1, 0x6D, 0x79, 0x34, 0xBC, 0xAC, 0xCB, - 0x75, 0x92, 0x7E, 0x8E, 0x7C, 0xA9, 0x0B, 0x86, - 0x4A, 0x88, 0xFB, 0xE8, 0xBE, 0x6A, 0x32, 0xEF, - 0x58, 0xCC, 0x4C, 0x89, 0x50, 0xEF, 0xDF, 0xE0, - 0xDD, 0x35, 0x07, 0x8C, 0x01, 0x8B, 0x57, 0x38, - 0xB5, 0x64, 0xBB, 0x0A, 0xC2, 0xD8, 0xAB, 0xC5, - 0x45, 0xA6, 0x83, 0xBF, 0xA6, 0xA2, 0xCC, 0x06, - 0x64, 0xBE, 0x84, 0x04, 0x55, 0x8E, 0xF4, 0x4C, - 0xB5, 0xBC, 0xE5, 0x97, 0x2B, 0x3C, 0x42, 0x44, - 0x91, 0x9B, 0xB2, 0x65, 0x70, 0x02, 0xC5, 0xB7, - 0x71, 0xB3, 0xF0, 0xAA, 0x46, 0x4F, 0x42, 0x40, - 0x53, 0x65, 0x89, 0xA5, 0x6C, 0xBC, 0xB5, 0x6C, - 0x0C, 0x3B, 0x50, 0x46, 0x67, 0xFA, 0x14, 0x68, - 0x01, 0xE7, 0xA6, 0xD4, 0xB5, 0xD0, 0x82, 0x44, - 0x92, 0x2C, 0xE3, 0x43, 0x5D, 0x34, 0x7C, 0x04, - 0xA3, 0x4D, 0x2F, 0x5A, 0x75, 0xE7, 0x0B, 0x64, - 0xD0, 0xAE, 0x7F, 0xCB, 0xDD, 0x7D, 0x05, 0x88, - 0x4C, 0x34, 0xBB, 0xF4, 0x00, 0xCE, 0x1C, 0x13, - 0x4E, 0xA3, 0xE3, 0x60, 0x4B, 0x50, 0x4E, 0xE1, - 0x26, 0x22, 0x51, 0xD4, 0x32, 0x60, 0xC6, 0x3E, - 0x7D, 0x4A, 0x3E, 0x56, 0x78, 0xBD, 0x5F, 0x23, - 0x7F, 0x0A, 0xA0, 0xC1, 0x1A, 0x60, 0xA2, 0x7C, - 0x9E, 0x17, 0x6F, 0xD8, 0x73, 0x0F, 0x1A, 0x1F, - 0x47, 0x58, 0x44, 0x20, 0x80, 0xC6, 0x5D, 0x6E, - 0xEC, 0xFF, 0xCA, 0x65, 0xA1, 0xFB, 0xEE, 0xF2, - 0x56, 0x1A, 0x16, 0x9E, 0x4D, 0xCA, 0x67, 0x81, - 0x23, 0xDE, 0xBE, 0x5E, 0x31, 0x56, 0xF0, 0x34, - 0xBA, 0x12, 0xFC, 0x07, 0x03, 0x96, 0xD2, 0x8E, - 0xCE, 0xA6, 0xF6, 0x74, 0x07, 0x4F, 0x63, 0x40, - 0x14, 0x0A, 0xD6, 0x45, 0xB4, 0xF1, 0x72, 0x87, - 0x34, 0x89, 0x5C, 0x06, 0x1B, 0x8C, 0x0E, 0xA2, - 0x84, 0x50, 0x12, 0xAD, 0x26, 0x5B, 0x4F, 0x6B, - 0x23, 0x9D, 0x3C, 0xBB, 0x8A, 0xDA, 0x08, 0x4B, - 0x93, 0x47, 0x02, 0x96, 0x76, 0xD4, 0x87, 0xE9, - 0x4B, 0x69, 0x82, 0xD6, 0xCC, 0x69, 0x02, 0xC0, - 0xA4, 0x75, 0x7A, 0x90, 0xFD, 0xF6, 0xD6, 0x9D, - 0xE2, 0x4C, 0xB6, 0xFA, 0x61, 0xA5, 0x7C, 0x18, - 0xEA, 0x84, 0xA1, 0x74, 0x85, 0x2E, 0xCA, 0xF9, - 0x17, 0x29, 0xFF, 0x67, 0x70, 0xC9, 0x6F, 0xF1, - 0x41, 0xEF, 0xA1, 0x59, 0x54, 0xA0, 0x99, 0x14, - 0x48, 0x74, 0x5D, 0x14, 0x3E, 0x04, 0xCE, 0xF7, - 0x16, 0x9F, 0x8A, 0x41, 0xF4, 0xAE, 0xB3, 0x10, - 0xCE, 0x19, 0xC2, 0x83, 0x7B, 0xD0, 0x26, 0x1E, - 0x75, 0x8A, 0x0A, 0x40, 0x4A, 0xB8, 0xE0, 0x5C, - 0x13, 0x8B, 0xCC, 0x6F, 0xF3, 0x00, 0xB3, 0x64, - 0x1B, 0x3C, 0x3D, 0x08, 0x3B, 0x9F, 0xD0, 0x9B, - 0xE5, 0x72, 0x45, 0x96, 0x95, 0x4D, 0x66, 0xC7, - 0x79, 0x5D, 0x3A, 0x1A, 0x94, 0x64, 0x94, 0x07, - 0x1A, 0xE8, 0x7C, 0xD1, 0x1C, 0xB1, 0x7E, 0x32, - 0x28, 0x1A, 0x90, 0x22, 0xD9, 0x86, 0x9B, 0x9C, - 0x9B, 0x0C, 0x04, 0x31, 0x85, 0x10, 0x42, 0x50, - 0x40, 0x11, 0x72, 0xAB, 0x94, 0x0C, 0xAF, 0xC3, - 0x22, 0x1A, 0xC1, 0x31, 0x25, 0x30, 0x23, 0x06, - 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, - 0x09, 0x15, 0x31, 0x16, 0x04, 0x14, 0xFD, 0x78, - 0xA7, 0x70, 0x1F, 0x8A, 0xE9, 0x07, 0xB9, 0xCA, - 0x3C, 0xD1, 0xE8, 0xDC, 0x68, 0xFF, 0x02, 0x61, - 0x29, 0x97, 0x30, 0x31, 0x30, 0x21, 0x30, 0x09, - 0x06, 0x05, 0x2B, 0x0E, 0x03, 0x02, 0x1A, 0x05, - 0x00, 0x04, 0x14, 0x22, 0x7E, 0x99, 0x10, 0xB3, - 0x99, 0x79, 0xE7, 0x14, 0x7F, 0x91, 0x59, 0x24, - 0x4F, 0x2F, 0xCF, 0xE8, 0x53, 0x1D, 0x0F, 0x04, - 0x08, 0x30, 0x1E, 0x5C, 0xE4, 0x3C, 0x66, 0xDF, - 0xB0, 0x02, 0x02, 0x08, 0x00] -}; - -gTestSuite.doTestWithCertificate( - new Blob([new Uint8Array(testCertInfo.blob)]), - testCertInfo.password, - testCertInfo.nickname, - testCertInfo.usage -); diff --git a/dom/wifi/test/marionette/test_wifi_manage_server_certificate.js b/dom/wifi/test/marionette/test_wifi_manage_server_certificate.js deleted file mode 100644 index dfaf524b2..000000000 --- a/dom/wifi/test/marionette/test_wifi_manage_server_certificate.js +++ /dev/null @@ -1,106 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -MARIONETTE_TIMEOUT = 60000; -MARIONETTE_HEAD_JS = 'head.js'; - -// Binary form of test certificate. -var testCertInfo = { - nickname: 'Test Certificate', - password: '', - usage: ['ServerCert'], - blob: [0x30, 0x82, 0x02, 0xae, 0x30, 0x82, 0x02, 0x17, - 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x09, 0x00, - 0x92, 0x49, 0xe2, 0x62, 0x71, 0xf6, 0xc7, 0x92, - 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, - 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, - 0x70, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, - 0x04, 0x06, 0x13, 0x02, 0x54, 0x57, 0x31, 0x0f, - 0x30, 0x0d, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, - 0x06, 0x54, 0x61, 0x69, 0x70, 0x65, 0x69, 0x31, - 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x0a, - 0x0c, 0x07, 0x4d, 0x6f, 0x7a, 0x69, 0x6c, 0x6c, - 0x61, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, - 0x04, 0x0b, 0x0c, 0x02, 0x51, 0x41, 0x31, 0x0e, - 0x30, 0x0c, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, - 0x05, 0x47, 0x65, 0x72, 0x72, 0x79, 0x31, 0x21, - 0x30, 0x1f, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, - 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x12, 0x67, - 0x63, 0x68, 0x61, 0x6e, 0x67, 0x40, 0x6d, 0x6f, - 0x7a, 0x69, 0x6c, 0x6c, 0x61, 0x2e, 0x63, 0x6f, - 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x34, 0x30, - 0x35, 0x32, 0x33, 0x30, 0x39, 0x34, 0x32, 0x33, - 0x37, 0x5a, 0x17, 0x0d, 0x31, 0x37, 0x30, 0x35, - 0x32, 0x32, 0x30, 0x39, 0x34, 0x32, 0x33, 0x37, - 0x5a, 0x30, 0x70, 0x31, 0x0b, 0x30, 0x09, 0x06, - 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x54, 0x57, - 0x31, 0x0f, 0x30, 0x0d, 0x06, 0x03, 0x55, 0x04, - 0x08, 0x0c, 0x06, 0x54, 0x61, 0x69, 0x70, 0x65, - 0x69, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, - 0x04, 0x0a, 0x0c, 0x07, 0x4d, 0x6f, 0x7a, 0x69, - 0x6c, 0x6c, 0x61, 0x31, 0x0b, 0x30, 0x09, 0x06, - 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x02, 0x51, 0x41, - 0x31, 0x0e, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x04, - 0x03, 0x0c, 0x05, 0x47, 0x65, 0x72, 0x72, 0x79, - 0x31, 0x21, 0x30, 0x1f, 0x06, 0x09, 0x2a, 0x86, - 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, - 0x12, 0x67, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x40, - 0x6d, 0x6f, 0x7a, 0x69, 0x6c, 0x6c, 0x61, 0x2e, - 0x63, 0x6f, 0x6d, 0x30, 0x81, 0x9f, 0x30, 0x0d, - 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, - 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x81, 0x8d, - 0x00, 0x30, 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, - 0xd3, 0xdb, 0x54, 0xcc, 0xca, 0x0b, 0xee, 0xf9, - 0x8a, 0x37, 0x0d, 0x06, 0x8b, 0x20, 0x00, 0x4a, - 0x55, 0x84, 0x90, 0x1a, 0xb7, 0x9c, 0x91, 0xb2, - 0x38, 0x6b, 0x8b, 0x32, 0x7a, 0x89, 0x9e, 0x79, - 0x71, 0x88, 0x43, 0x21, 0x94, 0x18, 0xa8, 0xfc, - 0xe3, 0x7a, 0x8a, 0xb3, 0xa1, 0xf7, 0x23, 0xe7, - 0x1a, 0xe3, 0xe7, 0x0d, 0xf1, 0x66, 0x21, 0x58, - 0x21, 0x85, 0x5b, 0x35, 0xec, 0x68, 0xd2, 0xfd, - 0x44, 0x76, 0x93, 0x05, 0xbb, 0x89, 0x7d, 0x92, - 0xf9, 0xce, 0x75, 0xa3, 0xeb, 0x39, 0xc1, 0x7d, - 0x7e, 0x50, 0xf9, 0xb8, 0x60, 0x61, 0xf7, 0x2f, - 0x54, 0x39, 0xfe, 0x8a, 0x20, 0xb2, 0x0d, 0x48, - 0x7f, 0x18, 0x0d, 0x02, 0xcc, 0x7b, 0x8e, 0x31, - 0xe9, 0xbe, 0xfc, 0x96, 0x2e, 0x63, 0x6f, 0xfa, - 0x4c, 0xc4, 0xcf, 0x8a, 0xe4, 0x13, 0x67, 0xf1, - 0xec, 0x3e, 0xd8, 0x23, 0xa1, 0xbf, 0x67, 0x71, - 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x50, 0x30, - 0x4e, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, - 0x04, 0x16, 0x04, 0x14, 0x13, 0xe1, 0xac, 0xa4, - 0x75, 0x3d, 0x2c, 0x5f, 0xe5, 0x41, 0x42, 0x90, - 0x5a, 0x48, 0x5c, 0x46, 0xbc, 0x24, 0x8e, 0xa1, - 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, - 0x18, 0x30, 0x16, 0x80, 0x14, 0x13, 0xe1, 0xac, - 0xa4, 0x75, 0x3d, 0x2c, 0x5f, 0xe5, 0x41, 0x42, - 0x90, 0x5a, 0x48, 0x5c, 0x46, 0xbc, 0x24, 0x8e, - 0xa1, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, - 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, - 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, - 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x81, - 0x81, 0x00, 0xaa, 0x6b, 0x62, 0x53, 0x74, 0x2a, - 0x20, 0x76, 0xab, 0xd2, 0x60, 0x06, 0xfd, 0x88, - 0xf5, 0x1c, 0x85, 0xe6, 0x57, 0xf1, 0xf0, 0x18, - 0x97, 0x7c, 0x70, 0xb8, 0xb4, 0x7c, 0xcc, 0x58, - 0x8d, 0xf4, 0x7c, 0xb6, 0x34, 0xcc, 0x15, 0x79, - 0xaf, 0x75, 0xa9, 0x0b, 0xd1, 0xea, 0xf8, 0x85, - 0x7c, 0xe8, 0x19, 0xe9, 0x13, 0x90, 0x84, 0x5f, - 0x21, 0x94, 0x0a, 0x4d, 0x15, 0xef, 0xd1, 0x16, - 0xd4, 0xba, 0x2c, 0x59, 0x1b, 0x83, 0x23, 0xf5, - 0xa5, 0xcd, 0xbd, 0xda, 0x32, 0x73, 0x46, 0x49, - 0x98, 0xf3, 0xfb, 0x50, 0x6e, 0x30, 0xd7, 0x3e, - 0x31, 0xd6, 0xe8, 0x65, 0x2f, 0x5a, 0xf1, 0x0f, - 0x7b, 0x0a, 0x21, 0x61, 0x8e, 0x45, 0x29, 0x4f, - 0x7a, 0x04, 0xda, 0x29, 0xfc, 0x6f, 0xc5, 0x5e, - 0xee, 0xe1, 0x0f, 0xd5, 0x4b, 0xb7, 0xc9, 0x6a, - 0x8e, 0x7c, 0x19, 0xef, 0x6e, 0x64, 0x98, 0xfe, - 0xe3, 0x35] -}; - -gTestSuite.doTestWithCertificate( - new Blob([new Uint8Array(testCertInfo.blob)]), - testCertInfo.password, - testCertInfo.nickname, - testCertInfo.usage -); diff --git a/dom/wifi/test/marionette/test_wifi_manage_user_certificate.js b/dom/wifi/test/marionette/test_wifi_manage_user_certificate.js deleted file mode 100644 index 950ceae4e..000000000 --- a/dom/wifi/test/marionette/test_wifi_manage_user_certificate.js +++ /dev/null @@ -1,34 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -MARIONETTE_TIMEOUT = 60000; -MARIONETTE_HEAD_JS = 'head.js'; - -// Binary form of test certificate. -var testCertInfo = { - nickname: 'Test Certificate', - password: '', - usage: ['UserCert'], - blob: '-----BEGIN CERTIFICATE-----\n' + - 'MIICTjCCAbegAwIBAgICNV4wDQYJKoZIhvcNAQEEBQAwgYUxCzAJBgNVBAYTAklU\n' + - 'MRYwFAYDVQQKEw1aZXJvc2hlbGwubmV0MRAwDgYDVQQLEwdFeGFtcGxlMR0wGwYD\n' + - 'VQQDExRaZXJvU2hlbGwgRXhhbXBsZSBDQTEtMCsGCSqGSIb3DQEJARYeRnVsdmlv\n' + - 'LlJpY2NpYXJkaUB6ZXJvc2hlbGwubmV0MB4XDTEzMDMxMTAzMzg1MloXDTE0MDMx\n' + - 'MTAzMzg1MlowIzEOMAwGA1UECxMFVXNlcnMxETAPBgNVBAMTCGNodWNrbGVlMIGf\n' + - 'MA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDvVzFhQAVqAIHW5DlAhp4FEGEei7k7\n' + - 'uVUeqkH7JAsww6zmDLg9yZlcZAc95N0lkz022gLXehH2M0R1FOR++nkqofzWfc7w\n' + - 'n79ith+dU2GQMeKq7vPGDYXpgIkEKbYfzKj3fY3129MlTxJQt1UD/ejz38V8HKgw\n' + - 'qKSuwo0NVeY66QIDAQABoy4wLDALBgNVHQ8EBAMCBLAwHQYDVR0lBBYwFAYIKwYB\n' + - 'BQUHAwIGCCsGAQUFBwMEMA0GCSqGSIb3DQEBBAUAA4GBAJWgfX5vYSD7MGZk1rTF\n' + - 'DSziWYGqpR+Moo3qQ+9qLG8m+XVM9hckWpY31A5sWAeCZCe1SSNLFbbgsaOyPZE2\n' + - 'NqMyvs61Vszpc2mmWAYT6j2OU2tw8p5pcUZd6eIp7Gc3fLymiX/WoSmilZKmrGUZ\n' + - 'Q15R+TCpclUsaNrUGjybgaw7\n' + - '-----END CERTIFICATE-----' -}; - -gTestSuite.doTestWithCertificate( - new Blob([testCertInfo.blob]), - testCertInfo.password, - testCertInfo.nickname, - testCertInfo.usage -); diff --git a/dom/wifi/test/marionette/test_wifi_scan.js b/dom/wifi/test/marionette/test_wifi_scan.js deleted file mode 100644 index 4bb7d1a3d..000000000 --- a/dom/wifi/test/marionette/test_wifi_scan.js +++ /dev/null @@ -1,43 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -MARIONETTE_TIMEOUT = 60000; -MARIONETTE_HEAD_JS = 'head.js'; - -const SCAN_RETRY_CNT = 5; - -/** - * Test scan with no AP present. - * - * The precondition is: - * 1) Wifi is enabled. - * 2) All the hostapds are turned off. - * - * @return deferred promise. - */ -function testScanNoAp() { - return gTestSuite.testWifiScanWithRetry(SCAN_RETRY_CNT, []); -} - -/** - * Test scan with APs present. - * - * The precondition is: - * 1) Wifi is enabled. - * 2) All the hostapds are turned off. - * - * @return deferred promise. - */ -function testScanWithAps() { - return gTestSuite.startHostapds(HOSTAPD_CONFIG_LIST) - .then(() => gTestSuite.verifyNumOfProcesses('hostapd', HOSTAPD_CONFIG_LIST.length)) - .then(() => gTestSuite.testWifiScanWithRetry(SCAN_RETRY_CNT, HOSTAPD_CONFIG_LIST)) - .then(gTestSuite.killAllHostapd) - .then(() => gTestSuite.verifyNumOfProcesses('hostapd', 0)); -} - -gTestSuite.doTestWithoutStockAp(function() { - return gTestSuite.ensureWifiEnabled(true) - .then(testScanNoAp) - .then(testScanWithAps); -}); diff --git a/dom/wifi/test/marionette/test_wifi_static_ip.js b/dom/wifi/test/marionette/test_wifi_static_ip.js deleted file mode 100644 index 90436b6fe..000000000 --- a/dom/wifi/test/marionette/test_wifi_static_ip.js +++ /dev/null @@ -1,65 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -MARIONETTE_TIMEOUT = 60000; -MARIONETTE_HEAD_JS = 'head.js'; - -const STATIC_IP_CONFIG = { - enabled: true, - ipaddr: "192.168.111.222", - proxy: "", - maskLength: 24, - gateway: "192.168.111.1", - dns1: "8.8.8.8", - dns2: "8.8.4.4", -}; - -const TESTING_HOSTAPD = [{ ssid: 'ap0' }]; - -function testAssociateWithStaticIp(aNetwork, aStaticIpConfig) { - return gTestSuite.setStaticIpMode(aNetwork, aStaticIpConfig) - .then(() => gTestSuite.testAssociate(aNetwork)) - // Check ip address and prefix. - .then(() => gTestSuite.exeAndParseNetcfg()) - .then((aResult) => { - is(aResult["wlan0"].ip, aStaticIpConfig.ipaddr, "Check ip address"); - is(aResult["wlan0"].prefix, aStaticIpConfig.maskLength, "Check prefix"); - }) - // Check routing. - .then(() => gTestSuite.exeAndParseIpRoute()) - .then((aResult) => { - is(aResult["wlan0"].src, aStaticIpConfig.ipaddr, "Check ip address"); - is(aResult["wlan0"].default, true, "Check default route"); - is(aResult["wlan0"].gateway, aStaticIpConfig.gateway, "Check gateway"); - }); -} - -function findDesireNetwork(aNetworks) { - let i = gTestSuite.getFirstIndexBySsid(TESTING_HOSTAPD[0].ssid, aNetworks); - - if (-1 !== i) { - return aNetworks[i]; - } - - return aNetworks[0]; -} - -// Start test. -gTestSuite.doTestWithoutStockAp(function() { - return gTestSuite.ensureWifiEnabled(true) - - // Start custom hostapd for testing. - .then(() => gTestSuite.startHostapds(TESTING_HOSTAPD)) - .then(() => gTestSuite.verifyNumOfProcesses('hostapd', - TESTING_HOSTAPD.length)) - - // Perform a wifi scan, and then run the static ip test - .then(() => gTestSuite.requestWifiScan()) - .then((aNetworks) => findDesireNetwork(aNetworks)) - .then((aNetwork) => testAssociateWithStaticIp(aNetwork, - STATIC_IP_CONFIG)) - - // Kill running hostapd. - .then(gTestSuite.killAllHostapd) - .then(() => gTestSuite.verifyNumOfProcesses('hostapd', 0)); -}); diff --git a/dom/wifi/test/marionette/test_wifi_tethering_wifi_active.js b/dom/wifi/test/marionette/test_wifi_tethering_wifi_active.js deleted file mode 100644 index af0df01a0..000000000 --- a/dom/wifi/test/marionette/test_wifi_tethering_wifi_active.js +++ /dev/null @@ -1,74 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -MARIONETTE_TIMEOUT = 60000; -MARIONETTE_HEAD_JS = 'head.js'; - -const TESTING_HOSTAPD = [{ ssid: 'ap0' }]; - -function connectToFirstNetwork() { - let firstNetwork; - return gTestSuite.requestWifiScan() - .then(function (networks) { - firstNetwork = networks[0]; - return gTestSuite.testAssociate(firstNetwork); - }) - .then(() => firstNetwork); -} - -gTestSuite.doTestTethering(function() { - let firstNetwork; - - return gTestSuite.ensureWifiEnabled(true) - // Start custom hostapd for testing. - .then(() => gTestSuite.startHostapds(TESTING_HOSTAPD)) - .then(() => gTestSuite.verifyNumOfProcesses('hostapd', TESTING_HOSTAPD.length)) - - // Connect to the testing AP and wait for data becoming disconnected. - .then(function () { - return Promise.all([ - // 1) Set up the event listener first: - // RIL data should become disconnected after connecting to wifi. - gTestSuite.waitForRilDataConnected(false), - - // 2) Connect to the first scanned network. - connectToFirstNetwork() - .then(aFirstNetwork => firstNetwork = aFirstNetwork) - ]); - }) - .then(function() { - return Promise.all([ - // 1) Set up the event listeners first: - // Wifi should be turned off and RIL data should be connected. - gTestSuite.waitForWifiManagerEventOnce('disabled'), - gTestSuite.waitForRilDataConnected(true), - - // 2) Start wifi tethering. - gTestSuite.requestTetheringEnabled(true) - ]); - }) - .then(function() { - return Promise.all([ - // 1) Set up the event listeners first: - // Wifi should be enabled, RIL data should become disconnected and - // we should connect to an wifi AP. - gTestSuite.waitForWifiManagerEventOnce('enabled'), - - // Due to Bug 1168285, after re-enablin wifi, the remembered network - // will not be connected automatically. Leave "auto connect test" - // covered by test_wifi_auto_connect.js. - //gTestSuite.waitForRilDataConnected(false), - //gTestSuite.waitForConnected(firstNetwork), - - // 2) Stop wifi tethering. - gTestSuite.requestTetheringEnabled(false) - ]); - }) - // Remove wlan0 from default route by disabling wifi. Otherwise, - // it will cause the subsequent test cases loading page error. - .then(() => gTestSuite.requestWifiEnabled(false)) - - // Kill running hostapd. - .then(gTestSuite.killAllHostapd) - .then(() => gTestSuite.verifyNumOfProcesses('hostapd', 0)); -});
\ No newline at end of file diff --git a/dom/wifi/test/marionette/test_wifi_tethering_wifi_disabled.js b/dom/wifi/test/marionette/test_wifi_tethering_wifi_disabled.js deleted file mode 100644 index 860a91cf6..000000000 --- a/dom/wifi/test/marionette/test_wifi_tethering_wifi_disabled.js +++ /dev/null @@ -1,11 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -MARIONETTE_TIMEOUT = 60000; -MARIONETTE_HEAD_JS = 'head.js'; - -gTestSuite.doTestTethering(function() { - return gTestSuite.ensureWifiEnabled(false) - .then(() => gTestSuite.requestTetheringEnabled(true)) - .then(() => gTestSuite.requestTetheringEnabled(false)) -}); diff --git a/dom/wifi/test/marionette/test_wifi_tethering_wifi_inactive.js b/dom/wifi/test/marionette/test_wifi_tethering_wifi_inactive.js deleted file mode 100644 index 2de6ab667..000000000 --- a/dom/wifi/test/marionette/test_wifi_tethering_wifi_inactive.js +++ /dev/null @@ -1,21 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -MARIONETTE_TIMEOUT = 60000; -MARIONETTE_HEAD_JS = 'head.js'; - -gTestSuite.doTestTethering(function() { - return gTestSuite.ensureWifiEnabled(true) - .then(function() { - return Promise.all([ - gTestSuite.waitForWifiManagerEventOnce('disabled'), - gTestSuite.requestTetheringEnabled(true) - ]); - }) - .then(function() { - return Promise.all([ - gTestSuite.waitForWifiManagerEventOnce('enabled'), - gTestSuite.requestTetheringEnabled(false) - ]); - }); -}); diff --git a/dom/xhr/tests/mochitest.ini b/dom/xhr/tests/mochitest.ini index 35ba1e3db..a2a52787a 100644 --- a/dom/xhr/tests/mochitest.ini +++ b/dom/xhr/tests/mochitest.ini @@ -68,13 +68,11 @@ support-files = [test_bug1300552.html] [test_html_in_xhr.html] [test_relativeLoad.html] -skip-if = buildapp == 'b2g' # b2g(Failed to load script: relativeLoad_import.js) b2g-debug(Failed to load script: relativeLoad_import.js) b2g-desktop(Failed to load script: relativeLoad_import.js) [test_sync_xhr_timer.xhtml] skip-if = toolkit == 'android' [test_sync_xhr_unload.html] [test_temporaryFileBlob.html] [test_worker_terminateSyncXHR.html] -skip-if = buildapp == 'b2g' [test_worker_xhr.html] [test_worker_xhr2.html] [test_worker_xhr_3rdparty.html] @@ -82,7 +80,6 @@ skip-if = buildapp == 'b2g' [test_worker_xhr_headers.html] [test_worker_xhr_implicit_cancel.html] [test_worker_xhr_parameters.html] -skip-if = buildapp == 'b2g' [test_worker_xhr_responseURL.html] [test_worker_xhr_system.html] [test_worker_xhr_timeout.html] @@ -96,17 +93,13 @@ skip-if = toolkit == 'android' [test_XHR_header.html] [test_XHR_onuploadprogress.html] [test_xhr_overridemimetype_throws_on_invalid_state.html] -skip-if = buildapp == 'b2g' # Requires webgl support [test_XHR_parameters.html] -skip-if = buildapp == 'b2g' # b2g(86 total, 4 failing - testing mozAnon - got false, expected true) b2g-debug(86 total, 4 failing - testing mozAnon - got false, expected true) b2g-desktop(86 total, 4 failing - testing mozAnon - got false, expected true) [test_xhr_progressevents.html] skip-if = toolkit == 'android' [test_xhr_send.html] [test_xhr_send_readystate.html] [test_XHR_system.html] -skip-if = (buildapp == 'b2g' && (toolkit != 'gonk' || debug)) # b2g-debug(12 total, 2 failing - .mozSystem == true - got false, expected true + ) b2g-desktop(12 total, 2 failing - .mozSystem == true - got false, expected true + ) [test_XHR_timeout.html] -skip-if = buildapp == 'b2g' || (android_version == '18' && debug) # b2g(flaky on B2G, bug 960743) b2g-debug(flaky on B2G, bug 960743) b2g-desktop(flaky on B2G, bug 960743) support-files = test_XHR_timeout.js [test_xhr_withCredentials.html] [test_XHRDocURI.html] |