summaryrefslogtreecommitdiff
path: root/dom
diff options
context:
space:
mode:
authorwolfbeast <mcwerewolf@gmail.com>2018-05-12 11:09:44 +0200
committerwolfbeast <mcwerewolf@gmail.com>2018-05-12 11:09:44 +0200
commitcfe5ef4ac7cd59f094b538252161ad74223c47da (patch)
treee5c0ee7e70db84bd2bfc6062784006769e9df730 /dom
parent28cf922aa9af4d4b8e0a3ce91dc1270a55986909 (diff)
downloaduxp-cfe5ef4ac7cd59f094b538252161ad74223c47da.tar.gz
Remove Gonk build directories
Diffstat (limited to 'dom')
-rw-r--r--dom/media/MediaPermissionGonk.cpp522
-rw-r--r--dom/media/MediaPermissionGonk.h39
-rw-r--r--dom/media/moz.build13
-rw-r--r--dom/media/platforms/gonk/GonkAudioDecoderManager.cpp268
-rw-r--r--dom/media/platforms/gonk/GonkAudioDecoderManager.h59
-rw-r--r--dom/media/platforms/gonk/GonkDecoderModule.cpp63
-rw-r--r--dom/media/platforms/gonk/GonkDecoderModule.h37
-rw-r--r--dom/media/platforms/gonk/GonkMediaDataDecoder.cpp385
-rw-r--r--dom/media/platforms/gonk/GonkMediaDataDecoder.h214
-rw-r--r--dom/media/platforms/gonk/GonkVideoDecoderManager.cpp772
-rw-r--r--dom/media/platforms/gonk/GonkVideoDecoderManager.h149
-rw-r--r--dom/media/platforms/gonk/moz.build39
-rw-r--r--dom/media/platforms/moz.build4
-rw-r--r--dom/secureelement/SEUtils.jsm116
-rw-r--r--dom/secureelement/gonk/ACEService.js139
-rw-r--r--dom/secureelement/gonk/ACEService.manifest2
-rw-r--r--dom/secureelement/gonk/GPAccessRulesManager.js436
-rw-r--r--dom/secureelement/gonk/GPAccessRulesManager.manifest2
-rw-r--r--dom/secureelement/gonk/SecureElement.js514
-rw-r--r--dom/secureelement/gonk/SecureElement.manifest18
-rw-r--r--dom/secureelement/gonk/UiccConnector.js360
-rw-r--r--dom/secureelement/gonk/UiccConnector.manifest17
-rw-r--r--dom/secureelement/gonk/gp_consts.js62
-rw-r--r--dom/secureelement/gonk/nsIAccessControlEnforcer.idl32
-rw-r--r--dom/secureelement/gonk/nsIAccessRulesManager.idl50
-rw-r--r--dom/secureelement/gonk/nsISecureElementConnector.idl124
-rw-r--r--dom/secureelement/gonk/se_consts.js68
-rw-r--r--dom/secureelement/moz.build24
-rw-r--r--dom/system/gonk/AudioChannelManager.cpp181
-rw-r--r--dom/system/gonk/AudioChannelManager.h87
-rw-r--r--dom/system/gonk/AudioManager.cpp1412
-rw-r--r--dom/system/gonk/AudioManager.h180
-rw-r--r--dom/system/gonk/AutoMounter.cpp1496
-rw-r--r--dom/system/gonk/AutoMounter.h101
-rw-r--r--dom/system/gonk/AutoMounterSetting.cpp284
-rw-r--r--dom/system/gonk/AutoMounterSetting.h38
-rw-r--r--dom/system/gonk/DataCallInterfaceService.js276
-rw-r--r--dom/system/gonk/DataCallInterfaceService.manifest6
-rw-r--r--dom/system/gonk/DataCallManager.js1726
-rw-r--r--dom/system/gonk/DataCallManager.manifest4
-rw-r--r--dom/system/gonk/GeolocationUtil.cpp28
-rw-r--r--dom/system/gonk/GeolocationUtil.h13
-rw-r--r--dom/system/gonk/GonkGPSGeolocationProvider.cpp706
-rw-r--r--dom/system/gonk/GonkGPSGeolocationProvider.h103
-rw-r--r--dom/system/gonk/MozMtpCommon.h56
-rw-r--r--dom/system/gonk/MozMtpDatabase.cpp1542
-rw-r--r--dom/system/gonk/MozMtpDatabase.h288
-rw-r--r--dom/system/gonk/MozMtpServer.cpp263
-rw-r--r--dom/system/gonk/MozMtpServer.h61
-rw-r--r--dom/system/gonk/MozMtpStorage.cpp135
-rw-r--r--dom/system/gonk/MozMtpStorage.h47
-rw-r--r--dom/system/gonk/NetIdManager.cpp68
-rw-r--r--dom/system/gonk/NetIdManager.h45
-rw-r--r--dom/system/gonk/NetworkInterfaceListService.js110
-rw-r--r--dom/system/gonk/NetworkInterfaceListService.manifest17
-rw-r--r--dom/system/gonk/NetworkManager.js1219
-rw-r--r--dom/system/gonk/NetworkManager.manifest3
-rw-r--r--dom/system/gonk/NetworkService.js862
-rw-r--r--dom/system/gonk/NetworkService.manifest3
-rw-r--r--dom/system/gonk/NetworkUtils.cpp2973
-rw-r--r--dom/system/gonk/NetworkUtils.h498
-rw-r--r--dom/system/gonk/NetworkWorker.cpp271
-rw-r--r--dom/system/gonk/NetworkWorker.h37
-rw-r--r--dom/system/gonk/OpenFileFinder.cpp251
-rw-r--r--dom/system/gonk/OpenFileFinder.h63
-rw-r--r--dom/system/gonk/RILSystemMessenger.jsm338
-rw-r--r--dom/system/gonk/RILSystemMessengerHelper.js169
-rw-r--r--dom/system/gonk/RILSystemMessengerHelper.manifest6
-rw-r--r--dom/system/gonk/RadioInterfaceLayer.js1324
-rw-r--r--dom/system/gonk/RadioInterfaceLayer.manifest18
-rw-r--r--dom/system/gonk/SystemProperty.cpp98
-rw-r--r--dom/system/gonk/SystemProperty.h39
-rw-r--r--dom/system/gonk/SystemWorkerManager.cpp214
-rw-r--r--dom/system/gonk/SystemWorkerManager.h75
-rw-r--r--dom/system/gonk/TetheringService.js891
-rw-r--r--dom/system/gonk/TetheringService.manifest4
-rw-r--r--dom/system/gonk/TimeZoneSettingObserver.cpp239
-rw-r--r--dom/system/gonk/TimeZoneSettingObserver.h20
-rw-r--r--dom/system/gonk/Volume.cpp596
-rw-r--r--dom/system/gonk/Volume.h157
-rw-r--r--dom/system/gonk/VolumeCommand.cpp85
-rw-r--r--dom/system/gonk/VolumeCommand.h204
-rw-r--r--dom/system/gonk/VolumeManager.cpp591
-rw-r--r--dom/system/gonk/VolumeManager.h192
-rw-r--r--dom/system/gonk/VolumeManagerLog.h27
-rw-r--r--dom/system/gonk/VolumeServiceIOThread.cpp82
-rw-r--r--dom/system/gonk/VolumeServiceIOThread.h49
-rw-r--r--dom/system/gonk/VolumeServiceTest.cpp202
-rw-r--r--dom/system/gonk/VolumeServiceTest.h19
-rw-r--r--dom/system/gonk/android_audio/AudioSystem.h1134
-rw-r--r--dom/system/gonk/android_audio/AudioTrack.h489
-rw-r--r--dom/system/gonk/android_audio/EffectApi.h798
-rw-r--r--dom/system/gonk/android_audio/IAudioFlinger.h184
-rw-r--r--dom/system/gonk/android_audio/IAudioFlingerClient.h55
-rw-r--r--dom/system/gonk/android_audio/IAudioRecord.h68
-rw-r--r--dom/system/gonk/android_audio/IAudioTrack.h89
-rw-r--r--dom/system/gonk/android_audio/IEffect.h60
-rw-r--r--dom/system/gonk/android_audio/IEffectClient.h54
-rw-r--r--dom/system/gonk/moz.build107
-rw-r--r--dom/system/gonk/mozstumbler/MozStumbler.cpp426
-rw-r--r--dom/system/gonk/mozstumbler/MozStumbler.h47
-rw-r--r--dom/system/gonk/mozstumbler/StumblerLogging.cpp13
-rw-r--r--dom/system/gonk/mozstumbler/StumblerLogging.h18
-rw-r--r--dom/system/gonk/mozstumbler/UploadStumbleRunnable.cpp151
-rw-r--r--dom/system/gonk/mozstumbler/UploadStumbleRunnable.h46
-rw-r--r--dom/system/gonk/mozstumbler/WriteStumbleOnThread.cpp321
-rw-r--r--dom/system/gonk/mozstumbler/WriteStumbleOnThread.h91
-rw-r--r--dom/system/gonk/nsIAudioManager.idl58
-rw-r--r--dom/system/gonk/nsIDataCallInterfaceService.idl268
-rw-r--r--dom/system/gonk/nsIDataCallManager.idl81
-rw-r--r--dom/system/gonk/nsIGonkDataCallInterfaceService.idl18
-rw-r--r--dom/system/gonk/nsINetworkInterface.idl108
-rw-r--r--dom/system/gonk/nsINetworkInterfaceListService.idl40
-rw-r--r--dom/system/gonk/nsINetworkManager.idl135
-rw-r--r--dom/system/gonk/nsINetworkService.idl619
-rw-r--r--dom/system/gonk/nsINetworkWorker.idl18
-rw-r--r--dom/system/gonk/nsIRadioInterfaceLayer.idl53
-rw-r--r--dom/system/gonk/nsISystemWorkerManager.idl16
-rw-r--r--dom/system/gonk/nsITetheringService.idl39
-rw-r--r--dom/system/gonk/nsIVolume.idl114
-rw-r--r--dom/system/gonk/nsIVolumeMountLock.idl12
-rw-r--r--dom/system/gonk/nsIVolumeService.idl36
-rw-r--r--dom/system/gonk/nsIVolumeStat.idl12
-rw-r--r--dom/system/gonk/nsIWorkerHolder.idl11
-rw-r--r--dom/system/gonk/nsVolume.cpp467
-rw-r--r--dom/system/gonk/nsVolume.h114
-rw-r--r--dom/system/gonk/nsVolumeMountLock.cpp171
-rw-r--r--dom/system/gonk/nsVolumeMountLock.h56
-rw-r--r--dom/system/gonk/nsVolumeService.cpp553
-rw-r--r--dom/system/gonk/nsVolumeService.h78
-rw-r--r--dom/system/gonk/nsVolumeStat.cpp33
-rw-r--r--dom/system/gonk/nsVolumeStat.h33
-rw-r--r--dom/system/gonk/ril_consts.js3338
-rw-r--r--dom/system/gonk/ril_worker.js15206
-rw-r--r--dom/system/gonk/ril_worker_buf_object.js168
-rw-r--r--dom/system/gonk/ril_worker_telephony_request_queue.js157
-rw-r--r--dom/system/gonk/systemlibs.js201
-rw-r--r--dom/system/gonk/tests/header_helpers.js217
-rw-r--r--dom/system/gonk/tests/marionette/head.js345
-rw-r--r--dom/system/gonk/tests/marionette/manifest.ini19
-rw-r--r--dom/system/gonk/tests/marionette/ril_jshint/README.md9
-rw-r--r--dom/system/gonk/tests/marionette/ril_jshint/jshint.js11096
-rw-r--r--dom/system/gonk/tests/marionette/ril_jshint/jshintrc118
-rw-r--r--dom/system/gonk/tests/marionette/test_all_network_info.js106
-rw-r--r--dom/system/gonk/tests/marionette/test_data_connection.js70
-rw-r--r--dom/system/gonk/tests/marionette/test_data_connection_proxy.js99
-rw-r--r--dom/system/gonk/tests/marionette/test_dsds_numRadioInterfaces.js43
-rw-r--r--dom/system/gonk/tests/marionette/test_fakevolume.js25
-rw-r--r--dom/system/gonk/tests/marionette/test_geolocation.js117
-rw-r--r--dom/system/gonk/tests/marionette/test_multiple_data_connection.js89
-rw-r--r--dom/system/gonk/tests/marionette/test_network_active_changed.js52
-rw-r--r--dom/system/gonk/tests/marionette/test_network_interface_list_service.js95
-rw-r--r--dom/system/gonk/tests/marionette/test_network_interface_mtu.js100
-rw-r--r--dom/system/gonk/tests/marionette/test_ril_code_quality.py371
-rw-r--r--dom/system/gonk/tests/marionette/test_screen_state.js47
-rw-r--r--dom/system/gonk/tests/marionette/test_timezone_changes.js135
-rw-r--r--dom/system/gonk/tests/test_ril_system_messenger.js1187
-rw-r--r--dom/system/gonk/tests/test_ril_worker_barring_password.js61
-rw-r--r--dom/system/gonk/tests/test_ril_worker_buf.js187
-rw-r--r--dom/system/gonk/tests/test_ril_worker_cdma_info_rec.js234
-rw-r--r--dom/system/gonk/tests/test_ril_worker_cellbroadcast_config.js470
-rw-r--r--dom/system/gonk/tests/test_ril_worker_cellbroadcast_gsm.js230
-rw-r--r--dom/system/gonk/tests/test_ril_worker_cellbroadcast_umts.js105
-rw-r--r--dom/system/gonk/tests/test_ril_worker_cf.js126
-rw-r--r--dom/system/gonk/tests/test_ril_worker_clip.js59
-rw-r--r--dom/system/gonk/tests/test_ril_worker_clir.js122
-rw-r--r--dom/system/gonk/tests/test_ril_worker_cw.js104
-rw-r--r--dom/system/gonk/tests/test_ril_worker_ecm.js168
-rw-r--r--dom/system/gonk/tests/test_ril_worker_icc_BerTlvHelper.js87
-rw-r--r--dom/system/gonk/tests/test_ril_worker_icc_CardLock.js282
-rw-r--r--dom/system/gonk/tests/test_ril_worker_icc_CardState.js210
-rw-r--r--dom/system/gonk/tests/test_ril_worker_icc_GsmPDUHelper.js79
-rw-r--r--dom/system/gonk/tests/test_ril_worker_icc_ICCContactHelper.js1042
-rw-r--r--dom/system/gonk/tests/test_ril_worker_icc_ICCIOHelper.js173
-rw-r--r--dom/system/gonk/tests/test_ril_worker_icc_ICCPDUHelper.js652
-rw-r--r--dom/system/gonk/tests/test_ril_worker_icc_ICCRecordHelper.js1080
-rw-r--r--dom/system/gonk/tests/test_ril_worker_icc_ICCUtilsHelper.js326
-rw-r--r--dom/system/gonk/tests/test_ril_worker_icc_IconLoader.js771
-rw-r--r--dom/system/gonk/tests/test_ril_worker_icc_SimRecordHelper.js1648
-rw-r--r--dom/system/gonk/tests/test_ril_worker_ruim.js328
-rw-r--r--dom/system/gonk/tests/test_ril_worker_sms.js273
-rw-r--r--dom/system/gonk/tests/test_ril_worker_sms_cdma.js298
-rw-r--r--dom/system/gonk/tests/test_ril_worker_sms_cdmapduhelper.js210
-rw-r--r--dom/system/gonk/tests/test_ril_worker_sms_gsmpduhelper.js282
-rw-r--r--dom/system/gonk/tests/test_ril_worker_sms_nl_tables.js77
-rw-r--r--dom/system/gonk/tests/test_ril_worker_sms_segment_info.js115
-rw-r--r--dom/system/gonk/tests/test_ril_worker_smsc_address.js112
-rw-r--r--dom/system/gonk/tests/test_ril_worker_ssn.js104
-rw-r--r--dom/system/gonk/tests/test_ril_worker_stk.js1698
-rw-r--r--dom/system/gonk/tests/test_ril_worker_voiceprivacy.js94
-rw-r--r--dom/system/gonk/tests/xpcshell.ini43
-rw-r--r--dom/system/gonk/worker_buf.js623
-rw-r--r--dom/system/moz.build2
193 files changed, 0 insertions, 78799 deletions
diff --git a/dom/media/MediaPermissionGonk.cpp b/dom/media/MediaPermissionGonk.cpp
deleted file mode 100644
index 2a9cbf331c..0000000000
--- a/dom/media/MediaPermissionGonk.cpp
+++ /dev/null
@@ -1,522 +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 "MediaManager.h"
-#include "MediaPermissionGonk.h"
-
-#include "nsArray.h"
-#include "nsCOMPtr.h"
-#include "nsIContentPermissionPrompt.h"
-#include "nsIDocument.h"
-#include "nsIDOMNavigatorUserMedia.h"
-#include "nsIStringEnumerator.h"
-#include "nsJSUtils.h"
-#include "nsQueryObject.h"
-#include "nsPIDOMWindow.h"
-#include "nsTArray.h"
-#include "GetUserMediaRequest.h"
-#include "mozilla/dom/PBrowserChild.h"
-#include "mozilla/dom/MediaStreamTrackBinding.h"
-#include "mozilla/dom/MediaStreamError.h"
-#include "nsISupportsPrimitives.h"
-#include "nsServiceManagerUtils.h"
-#include "nsArrayUtils.h"
-#include "nsContentPermissionHelper.h"
-#include "mozilla/dom/PermissionMessageUtils.h"
-
-#define AUDIO_PERMISSION_NAME "audio-capture"
-#define VIDEO_PERMISSION_NAME "video-capture"
-
-using namespace mozilla::dom;
-
-namespace mozilla {
-
-static MediaPermissionManager *gMediaPermMgr = nullptr;
-
-static void
-CreateDeviceNameList(nsTArray<nsCOMPtr<nsIMediaDevice> > &aDevices,
- nsTArray<nsString> &aDeviceNameList)
-{
- for (uint32_t i = 0; i < aDevices.Length(); ++i) {
- nsString name;
- nsresult rv = aDevices[i]->GetName(name);
- NS_ENSURE_SUCCESS_VOID(rv);
- aDeviceNameList.AppendElement(name);
- }
-}
-
-static already_AddRefed<nsIMediaDevice>
-FindDeviceByName(nsTArray<nsCOMPtr<nsIMediaDevice> > &aDevices,
- const nsAString &aDeviceName)
-{
- for (uint32_t i = 0; i < aDevices.Length(); ++i) {
- nsCOMPtr<nsIMediaDevice> device = aDevices[i];
- nsString deviceName;
- device->GetName(deviceName);
- if (deviceName.Equals(aDeviceName)) {
- return device.forget();
- }
- }
-
- return nullptr;
-}
-
-// Helper function for notifying permission granted
-static nsresult
-NotifyPermissionAllow(const nsAString &aCallID, nsTArray<nsCOMPtr<nsIMediaDevice> > &aDevices)
-{
- nsresult rv;
- nsCOMPtr<nsIMutableArray> array = nsArray::Create();
-
- for (uint32_t i = 0; i < aDevices.Length(); ++i) {
- rv = array->AppendElement(aDevices.ElementAt(i), /*weak =*/ false);
- NS_ENSURE_SUCCESS(rv, rv);
- }
-
- nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
- NS_ENSURE_TRUE(obs, NS_ERROR_FAILURE);
-
- return obs->NotifyObservers(array, "getUserMedia:response:allow",
- aCallID.BeginReading());
-}
-
-// Helper function for notifying permision denial or error
-static nsresult
-NotifyPermissionDeny(const nsAString &aCallID, const nsAString &aErrorMsg)
-{
- nsresult rv;
- nsCOMPtr<nsISupportsString> supportsString =
- do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID, &rv);
- NS_ENSURE_SUCCESS(rv, rv);
-
- rv = supportsString->SetData(aErrorMsg);
- NS_ENSURE_SUCCESS(rv, rv);
-
- nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
- NS_ENSURE_TRUE(obs, NS_ERROR_FAILURE);
-
- return obs->NotifyObservers(supportsString, "getUserMedia:response:deny",
- aCallID.BeginReading());
-}
-
-namespace {
-
-/**
- * MediaPermissionRequest will send a prompt ipdl request to b2g process according
- * to its owned type.
- */
-class MediaPermissionRequest : public nsIContentPermissionRequest
-{
-public:
- NS_DECL_ISUPPORTS
- NS_DECL_NSICONTENTPERMISSIONREQUEST
-
- MediaPermissionRequest(RefPtr<dom::GetUserMediaRequest> &aRequest,
- nsTArray<nsCOMPtr<nsIMediaDevice> > &aDevices);
-
- already_AddRefed<nsPIDOMWindowInner> GetOwner();
-
-protected:
- virtual ~MediaPermissionRequest() {}
-
-private:
- nsresult DoAllow(const nsString &audioDevice, const nsString &videoDevice);
-
- bool mAudio; // Request for audio permission
- bool mVideo; // Request for video permission
- RefPtr<dom::GetUserMediaRequest> mRequest;
- nsTArray<nsCOMPtr<nsIMediaDevice> > mAudioDevices; // candidate audio devices
- nsTArray<nsCOMPtr<nsIMediaDevice> > mVideoDevices; // candidate video devices
- nsCOMPtr<nsIContentPermissionRequester> mRequester;
-};
-
-// MediaPermissionRequest
-NS_IMPL_ISUPPORTS(MediaPermissionRequest, nsIContentPermissionRequest)
-
-MediaPermissionRequest::MediaPermissionRequest(RefPtr<dom::GetUserMediaRequest> &aRequest,
- nsTArray<nsCOMPtr<nsIMediaDevice> > &aDevices)
- : mRequest(aRequest)
-{
- dom::MediaStreamConstraints constraints;
- mRequest->GetConstraints(constraints);
-
- mAudio = !constraints.mAudio.IsBoolean() || constraints.mAudio.GetAsBoolean();
- mVideo = !constraints.mVideo.IsBoolean() || constraints.mVideo.GetAsBoolean();
-
- for (uint32_t i = 0; i < aDevices.Length(); ++i) {
- nsCOMPtr<nsIMediaDevice> device(aDevices[i]);
- nsAutoString deviceType;
- device->GetType(deviceType);
- if (mAudio && deviceType.EqualsLiteral("audio")) {
- mAudioDevices.AppendElement(device);
- }
- if (mVideo && deviceType.EqualsLiteral("video")) {
- mVideoDevices.AppendElement(device);
- }
- }
-
- nsCOMPtr<nsPIDOMWindowInner> window = GetOwner();
- mRequester = new nsContentPermissionRequester(window);
-}
-
-// nsIContentPermissionRequest methods
-NS_IMETHODIMP
-MediaPermissionRequest::GetTypes(nsIArray** aTypes)
-{
- nsCOMPtr<nsIMutableArray> types = do_CreateInstance(NS_ARRAY_CONTRACTID);
- //XXX append device list
- if (mAudio) {
- nsTArray<nsString> audioDeviceNames;
- CreateDeviceNameList(mAudioDevices, audioDeviceNames);
- nsCOMPtr<nsISupports> AudioType =
- new ContentPermissionType(NS_LITERAL_CSTRING(AUDIO_PERMISSION_NAME),
- NS_LITERAL_CSTRING("unused"),
- audioDeviceNames);
- types->AppendElement(AudioType, false);
- }
- if (mVideo) {
- nsTArray<nsString> videoDeviceNames;
- CreateDeviceNameList(mVideoDevices, videoDeviceNames);
- nsCOMPtr<nsISupports> VideoType =
- new ContentPermissionType(NS_LITERAL_CSTRING(VIDEO_PERMISSION_NAME),
- NS_LITERAL_CSTRING("unused"),
- videoDeviceNames);
- types->AppendElement(VideoType, false);
- }
- NS_IF_ADDREF(*aTypes = types);
-
- return NS_OK;
-}
-
-NS_IMETHODIMP
-MediaPermissionRequest::GetPrincipal(nsIPrincipal **aRequestingPrincipal)
-{
- NS_ENSURE_ARG_POINTER(aRequestingPrincipal);
-
- nsCOMPtr<nsPIDOMWindowInner> window =
- nsGlobalWindow::GetInnerWindowWithId(mRequest->InnerWindowID())->AsInner();
- NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
-
- nsCOMPtr<nsIDocument> doc = window->GetExtantDoc();
- NS_ENSURE_TRUE(doc, NS_ERROR_FAILURE);
-
- NS_ADDREF(*aRequestingPrincipal = doc->NodePrincipal());
- return NS_OK;
-}
-
-NS_IMETHODIMP
-MediaPermissionRequest::GetWindow(mozIDOMWindow** aRequestingWindow)
-{
- NS_ENSURE_ARG_POINTER(aRequestingWindow);
- nsCOMPtr<nsPIDOMWindowInner> window =
- nsGlobalWindow::GetInnerWindowWithId(mRequest->InnerWindowID())->AsInner();
- window.forget(aRequestingWindow);
- return NS_OK;
-}
-
-NS_IMETHODIMP
-MediaPermissionRequest::GetElement(nsIDOMElement** aRequestingElement)
-{
- NS_ENSURE_ARG_POINTER(aRequestingElement);
- *aRequestingElement = nullptr;
- return NS_OK;
-}
-
-NS_IMETHODIMP
-MediaPermissionRequest::Cancel()
-{
- nsString callID;
- mRequest->GetCallID(callID);
- NotifyPermissionDeny(callID, NS_LITERAL_STRING("SecurityError"));
- return NS_OK;
-}
-
-NS_IMETHODIMP
-MediaPermissionRequest::Allow(JS::HandleValue aChoices)
-{
- // check if JS object
- if (!aChoices.isObject()) {
- MOZ_ASSERT(false, "Not a correct format of PermissionChoice");
- return NS_ERROR_INVALID_ARG;
- }
- // iterate through audio-capture and video-capture
- AutoJSAPI jsapi;
- if (!jsapi.Init(&aChoices.toObject())) {
- return NS_ERROR_UNEXPECTED;
- }
- JSContext* cx = jsapi.cx();
- JS::Rooted<JSObject*> obj(cx, &aChoices.toObject());
- JS::Rooted<JS::Value> v(cx);
-
- // get selected audio device name
- nsString audioDevice;
- if (mAudio) {
- if (!JS_GetProperty(cx, obj, AUDIO_PERMISSION_NAME, &v) || !v.isString()) {
- return NS_ERROR_FAILURE;
- }
- nsAutoJSString deviceName;
- if (!deviceName.init(cx, v)) {
- MOZ_ASSERT(false, "Couldn't initialize string from aChoices");
- return NS_ERROR_FAILURE;
- }
- audioDevice = deviceName;
- }
-
- // get selected video device name
- nsString videoDevice;
- if (mVideo) {
- if (!JS_GetProperty(cx, obj, VIDEO_PERMISSION_NAME, &v) || !v.isString()) {
- return NS_ERROR_FAILURE;
- }
- nsAutoJSString deviceName;
- if (!deviceName.init(cx, v)) {
- MOZ_ASSERT(false, "Couldn't initialize string from aChoices");
- return NS_ERROR_FAILURE;
- }
- videoDevice = deviceName;
- }
-
- return DoAllow(audioDevice, videoDevice);
-}
-
-NS_IMETHODIMP
-MediaPermissionRequest::GetRequester(nsIContentPermissionRequester** aRequester)
-{
- NS_ENSURE_ARG_POINTER(aRequester);
-
- nsCOMPtr<nsIContentPermissionRequester> requester = mRequester;
- requester.forget(aRequester);
- return NS_OK;
-}
-
-nsresult
-MediaPermissionRequest::DoAllow(const nsString &audioDevice,
- const nsString &videoDevice)
-{
- nsTArray<nsCOMPtr<nsIMediaDevice> > selectedDevices;
- if (mAudio) {
- nsCOMPtr<nsIMediaDevice> device =
- FindDeviceByName(mAudioDevices, audioDevice);
- if (device) {
- selectedDevices.AppendElement(device);
- }
- }
-
- if (mVideo) {
- nsCOMPtr<nsIMediaDevice> device =
- FindDeviceByName(mVideoDevices, videoDevice);
- if (device) {
- selectedDevices.AppendElement(device);
- }
- }
-
- nsString callID;
- mRequest->GetCallID(callID);
- return NotifyPermissionAllow(callID, selectedDevices);
-}
-
-already_AddRefed<nsPIDOMWindowInner>
-MediaPermissionRequest::GetOwner()
-{
- nsCOMPtr<nsPIDOMWindowInner> window =
- nsGlobalWindow::GetInnerWindowWithId(mRequest->InnerWindowID())->AsInner();
- return window.forget();
-}
-
-// Success callback for MediaManager::GetUserMediaDevices().
-class MediaDeviceSuccessCallback: public nsIGetUserMediaDevicesSuccessCallback
-{
-public:
- NS_DECL_ISUPPORTS
- NS_DECL_NSIGETUSERMEDIADEVICESSUCCESSCALLBACK
-
- explicit MediaDeviceSuccessCallback(RefPtr<dom::GetUserMediaRequest> &aRequest)
- : mRequest(aRequest) {}
-
-protected:
- virtual ~MediaDeviceSuccessCallback() {}
-
-private:
- nsresult DoPrompt(RefPtr<MediaPermissionRequest> &req);
- RefPtr<dom::GetUserMediaRequest> mRequest;
-};
-
-NS_IMPL_ISUPPORTS(MediaDeviceSuccessCallback, nsIGetUserMediaDevicesSuccessCallback)
-
-// nsIGetUserMediaDevicesSuccessCallback method
-NS_IMETHODIMP
-MediaDeviceSuccessCallback::OnSuccess(nsIVariant* aDevices)
-{
- nsIID elementIID;
- uint16_t elementType;
- void* rawArray;
- uint32_t arrayLen;
-
- nsresult rv;
- rv = aDevices->GetAsArray(&elementType, &elementIID, &arrayLen, &rawArray);
- NS_ENSURE_SUCCESS(rv, rv);
-
- if (elementType != nsIDataType::VTYPE_INTERFACE) {
- free(rawArray);
- return NS_ERROR_FAILURE;
- }
-
- // Create array for nsIMediaDevice
- nsTArray<nsCOMPtr<nsIMediaDevice> > devices;
-
- nsISupports **supportsArray = reinterpret_cast<nsISupports **>(rawArray);
- for (uint32_t i = 0; i < arrayLen; ++i) {
- nsCOMPtr<nsIMediaDevice> device(do_QueryInterface(supportsArray[i]));
- devices.AppendElement(device);
- NS_IF_RELEASE(supportsArray[i]); // explicitly decrease reference count for raw pointer
- }
- free(rawArray); // explicitly free for the memory from nsIVariant::GetAsArray
-
- // Send MediaPermissionRequest
- RefPtr<MediaPermissionRequest> req = new MediaPermissionRequest(mRequest, devices);
- rv = DoPrompt(req);
-
- NS_ENSURE_SUCCESS(rv, rv);
- return NS_OK;
-}
-
-// Trigger permission prompt UI
-nsresult
-MediaDeviceSuccessCallback::DoPrompt(RefPtr<MediaPermissionRequest> &req)
-{
- nsCOMPtr<nsPIDOMWindowInner> window(req->GetOwner());
- return dom::nsContentPermissionUtils::AskPermission(req, window);
-}
-
-// Error callback for MediaManager::GetUserMediaDevices()
-class MediaDeviceErrorCallback: public nsIDOMGetUserMediaErrorCallback
-{
-public:
- NS_DECL_ISUPPORTS
- NS_DECL_NSIDOMGETUSERMEDIAERRORCALLBACK
-
- explicit MediaDeviceErrorCallback(const nsAString &aCallID)
- : mCallID(aCallID) {}
-
-protected:
- virtual ~MediaDeviceErrorCallback() {}
-
-private:
- const nsString mCallID;
-};
-
-NS_IMPL_ISUPPORTS(MediaDeviceErrorCallback, nsIDOMGetUserMediaErrorCallback)
-
-// nsIDOMGetUserMediaErrorCallback method
-NS_IMETHODIMP
-MediaDeviceErrorCallback::OnError(nsISupports* aError)
-{
- RefPtr<MediaStreamError> error = do_QueryObject(aError);
- if (!error) {
- return NS_ERROR_NO_INTERFACE;
- }
-
- nsString name;
- error->GetName(name);
- return NotifyPermissionDeny(mCallID, name);
-}
-
-} // namespace anonymous
-
-// MediaPermissionManager
-NS_IMPL_ISUPPORTS(MediaPermissionManager, nsIObserver)
-
-MediaPermissionManager*
-MediaPermissionManager::GetInstance()
-{
- if (!gMediaPermMgr) {
- gMediaPermMgr = new MediaPermissionManager();
- }
-
- return gMediaPermMgr;
-}
-
-MediaPermissionManager::MediaPermissionManager()
-{
- nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
- if (obs) {
- obs->AddObserver(this, "getUserMedia:request", false);
- obs->AddObserver(this, "xpcom-shutdown", false);
- }
-}
-
-MediaPermissionManager::~MediaPermissionManager()
-{
- this->Deinit();
-}
-
-nsresult
-MediaPermissionManager::Deinit()
-{
- nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
- if (obs) {
- obs->RemoveObserver(this, "getUserMedia:request");
- obs->RemoveObserver(this, "xpcom-shutdown");
- }
- return NS_OK;
-}
-
-// nsIObserver method
-NS_IMETHODIMP
-MediaPermissionManager::Observe(nsISupports* aSubject, const char* aTopic,
- const char16_t* aData)
-{
- nsresult rv;
- if (!strcmp(aTopic, "getUserMedia:request")) {
- RefPtr<dom::GetUserMediaRequest> req =
- static_cast<dom::GetUserMediaRequest*>(aSubject);
- rv = HandleRequest(req);
-
- if (NS_FAILED(rv)) {
- nsString callID;
- req->GetCallID(callID);
- NotifyPermissionDeny(callID, NS_LITERAL_STRING("unable to enumerate media device"));
- }
- } else if (!strcmp(aTopic, "xpcom-shutdown")) {
- rv = this->Deinit();
- } else {
- // not reachable
- rv = NS_ERROR_FAILURE;
- }
- return rv;
-}
-
-// Handle GetUserMediaRequest, query available media device first.
-nsresult
-MediaPermissionManager::HandleRequest(RefPtr<dom::GetUserMediaRequest> &req)
-{
- nsString callID;
- req->GetCallID(callID);
- uint64_t innerWindowID = req->InnerWindowID();
-
- nsCOMPtr<nsPIDOMWindowInner> innerWindow =
- nsGlobalWindow::GetInnerWindowWithId(innerWindowID)->AsInner();
- if (!innerWindow) {
- MOZ_ASSERT(false, "No inner window");
- return NS_ERROR_FAILURE;
- }
-
- nsCOMPtr<nsIGetUserMediaDevicesSuccessCallback> onSuccess =
- new MediaDeviceSuccessCallback(req);
- nsCOMPtr<nsIDOMGetUserMediaErrorCallback> onError =
- new MediaDeviceErrorCallback(callID);
-
- dom::MediaStreamConstraints constraints;
- req->GetConstraints(constraints);
-
- RefPtr<MediaManager> MediaMgr = MediaManager::GetInstance();
- nsresult rv = MediaMgr->GetUserMediaDevices(innerWindow, constraints,
- onSuccess, onError,
- innerWindowID, callID);
- NS_ENSURE_SUCCESS(rv, rv);
-
- return NS_OK;
-}
-
-} // namespace mozilla
diff --git a/dom/media/MediaPermissionGonk.h b/dom/media/MediaPermissionGonk.h
deleted file mode 100644
index 0a2fac056a..0000000000
--- a/dom/media/MediaPermissionGonk.h
+++ /dev/null
@@ -1,39 +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/. */
-
-#ifndef DOM_MEDIA_MEDIAPERMISSIONGONK_H
-#define DOM_MEDIA_MEDIAPERMISSIONGONK_H
-
-#include "nsError.h"
-#include "nsIObserver.h"
-#include "nsISupportsImpl.h"
-#include "GetUserMediaRequest.h"
-
-namespace mozilla {
-
-/**
- * The observer to create the MediaPermissionMgr. This is the entry point of
- * permission request on b2g.
- */
-class MediaPermissionManager : public nsIObserver
-{
-public:
- NS_DECL_ISUPPORTS
- NS_DECL_NSIOBSERVER
-
- static MediaPermissionManager* GetInstance();
-
-protected:
- virtual ~MediaPermissionManager();
-
-private:
- MediaPermissionManager();
- nsresult Deinit();
- nsresult HandleRequest(RefPtr<dom::GetUserMediaRequest> &req);
-};
-
-} // namespace mozilla
-
-#endif // DOM_MEDIA_MEDIAPERMISSIONGONK_H
-
diff --git a/dom/media/moz.build b/dom/media/moz.build
index d1885793ba..4d036a5f67 100644
--- a/dom/media/moz.build
+++ b/dom/media/moz.build
@@ -169,11 +169,6 @@ IPDL_SOURCES += [
'webrtc/PWebrtcGlobal.ipdl'
]
-if CONFIG['MOZ_B2G']:
- EXPORTS.mozilla += [
- 'MediaPermissionGonk.h',
- ]
-
EXPORTS.mozilla.dom += [
'AudioStreamTrack.h',
'AudioTrack.h',
@@ -270,11 +265,6 @@ UNIFIED_SOURCES += [
if CONFIG['OS_TARGET'] == 'WINNT':
SOURCES += [ 'ThreadPoolCOMListener.cpp' ]
-if CONFIG['MOZ_B2G']:
- SOURCES += [
- 'MediaPermissionGonk.cpp',
- ]
-
# DecoderTraits.cpp needs to be built separately because of Mac OS X headers.
SOURCES += [
'DecoderTraits.cpp',
@@ -325,9 +315,6 @@ else:
if CONFIG['ANDROID_VERSION'] > '15':
DEFINES['MOZ_OMX_WEBM_DECODER'] = True
-if CONFIG['MOZ_GONK_MEDIACODEC']:
- DEFINES['MOZ_GONK_MEDIACODEC'] = True
-
include('/ipc/chromium/chromium-config.mozbuild')
# Suppress some GCC warnings being treated as errors:
diff --git a/dom/media/platforms/gonk/GonkAudioDecoderManager.cpp b/dom/media/platforms/gonk/GonkAudioDecoderManager.cpp
deleted file mode 100644
index 0bc3fbea9a..0000000000
--- a/dom/media/platforms/gonk/GonkAudioDecoderManager.cpp
+++ /dev/null
@@ -1,268 +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 "MediaCodecProxy.h"
-#include <OMX_IVCommon.h>
-#include <gui/Surface.h>
-#include <ICrypto.h>
-#include "GonkAudioDecoderManager.h"
-#include "MediaDecoderReader.h"
-#include "VideoUtils.h"
-#include "nsTArray.h"
-#include "mozilla/Logging.h"
-#include "stagefright/MediaBuffer.h"
-#include "stagefright/MetaData.h"
-#include "stagefright/MediaErrors.h"
-#include <stagefright/foundation/AMessage.h>
-#include <stagefright/foundation/ALooper.h>
-#include "media/openmax/OMX_Audio.h"
-#include "MediaData.h"
-#include "MediaInfo.h"
-
-#define CODECCONFIG_TIMEOUT_US 10000LL
-#define READ_OUTPUT_BUFFER_TIMEOUT_US 0LL
-
-#include <android/log.h>
-#define GADM_LOG(...) __android_log_print(ANDROID_LOG_DEBUG, "GonkAudioDecoderManager", __VA_ARGS__)
-
-#define LOG(...) MOZ_LOG(sPDMLog, mozilla::LogLevel::Debug, (__VA_ARGS__))
-
-using namespace android;
-typedef android::MediaCodecProxy MediaCodecProxy;
-
-namespace mozilla {
-
-GonkAudioDecoderManager::GonkAudioDecoderManager(const AudioInfo& aConfig)
- : mAudioChannels(aConfig.mChannels)
- , mAudioRate(aConfig.mRate)
- , mAudioProfile(aConfig.mProfile)
- , mAudioCompactor(mAudioQueue)
-{
- MOZ_COUNT_CTOR(GonkAudioDecoderManager);
- MOZ_ASSERT(mAudioChannels);
- mCodecSpecificData = aConfig.mCodecSpecificConfig;
- mMimeType = aConfig.mMimeType;
-}
-
-GonkAudioDecoderManager::~GonkAudioDecoderManager()
-{
- MOZ_COUNT_DTOR(GonkAudioDecoderManager);
-}
-
-RefPtr<MediaDataDecoder::InitPromise>
-GonkAudioDecoderManager::Init()
-{
- if (InitMediaCodecProxy()) {
- return InitPromise::CreateAndResolve(TrackType::kAudioTrack, __func__);
- } else {
- return InitPromise::CreateAndReject(NS_ERROR_DOM_MEDIA_FATAL_ERR, __func__);
- }
-}
-
-bool
-GonkAudioDecoderManager::InitMediaCodecProxy()
-{
- status_t rv = OK;
- if (!InitLoopers(MediaData::AUDIO_DATA)) {
- return false;
- }
-
- mDecoder = MediaCodecProxy::CreateByType(mDecodeLooper, mMimeType.get(), false);
- if (!mDecoder.get()) {
- return false;
- }
- if (!mDecoder->AllocateAudioMediaCodec())
- {
- mDecoder = nullptr;
- return false;
- }
- sp<AMessage> format = new AMessage;
- // Fixed values
- GADM_LOG("Configure audio mime type:%s, chan no:%d, sample-rate:%d, profile:%d",
- mMimeType.get(), mAudioChannels, mAudioRate, mAudioProfile);
- format->setString("mime", mMimeType.get());
- format->setInt32("channel-count", mAudioChannels);
- format->setInt32("sample-rate", mAudioRate);
- format->setInt32("aac-profile", mAudioProfile);
- status_t err = mDecoder->configure(format, nullptr, nullptr, 0);
- if (err != OK || !mDecoder->Prepare()) {
- return false;
- }
-
- if (mMimeType.EqualsLiteral("audio/mp4a-latm")) {
- rv = mDecoder->Input(mCodecSpecificData->Elements(), mCodecSpecificData->Length(), 0,
- android::MediaCodec::BUFFER_FLAG_CODECCONFIG,
- CODECCONFIG_TIMEOUT_US);
- }
-
- if (rv == OK) {
- return true;
- } else {
- GADM_LOG("Failed to input codec specific data!");
- return false;
- }
-}
-
-nsresult
-GonkAudioDecoderManager::CreateAudioData(MediaBuffer* aBuffer, int64_t aStreamOffset)
-{
- if (!(aBuffer != nullptr && aBuffer->data() != nullptr)) {
- GADM_LOG("Audio Buffer is not valid!");
- return NS_ERROR_UNEXPECTED;
- }
-
- int64_t timeUs;
- if (!aBuffer->meta_data()->findInt64(kKeyTime, &timeUs)) {
- return NS_ERROR_UNEXPECTED;
- }
-
- if (aBuffer->range_length() == 0) {
- // Some decoders may return spurious empty buffers that we just want to ignore
- // quoted from Android's AwesomePlayer.cpp
- return NS_ERROR_NOT_AVAILABLE;
- }
-
- if (mLastTime > timeUs) {
- GADM_LOG("Output decoded sample time is revert. time=%lld", timeUs);
- MOZ_ASSERT(false);
- return NS_ERROR_NOT_AVAILABLE;
- }
- mLastTime = timeUs;
-
- const uint8_t *data = static_cast<const uint8_t*>(aBuffer->data());
- size_t dataOffset = aBuffer->range_offset();
- size_t size = aBuffer->range_length();
-
- uint32_t frames = size / (2 * mAudioChannels);
-
- CheckedInt64 duration = FramesToUsecs(frames, mAudioRate);
- if (!duration.isValid()) {
- return NS_ERROR_UNEXPECTED;
- }
-
- typedef AudioCompactor::NativeCopy OmxCopy;
- mAudioCompactor.Push(aStreamOffset,
- timeUs,
- mAudioRate,
- frames,
- mAudioChannels,
- OmxCopy(data+dataOffset,
- size,
- mAudioChannels));
- return NS_OK;
-}
-
-nsresult
-GonkAudioDecoderManager::Output(int64_t aStreamOffset,
- RefPtr<MediaData>& aOutData)
-{
- aOutData = nullptr;
- if (mAudioQueue.GetSize() > 0) {
- aOutData = mAudioQueue.PopFront();
- return mAudioQueue.AtEndOfStream() ? NS_ERROR_ABORT : NS_OK;
- }
-
- status_t err;
- MediaBuffer* audioBuffer = nullptr;
- err = mDecoder->Output(&audioBuffer, READ_OUTPUT_BUFFER_TIMEOUT_US);
- AutoReleaseMediaBuffer a(audioBuffer, mDecoder.get());
-
- switch (err) {
- case OK:
- {
- nsresult rv = CreateAudioData(audioBuffer, aStreamOffset);
- NS_ENSURE_SUCCESS(rv, rv);
- break;
- }
- case android::INFO_FORMAT_CHANGED:
- {
- // If the format changed, update our cached info.
- GADM_LOG("Decoder format changed");
- sp<AMessage> audioCodecFormat;
-
- if (mDecoder->getOutputFormat(&audioCodecFormat) != OK ||
- audioCodecFormat == nullptr) {
- return NS_ERROR_UNEXPECTED;
- }
-
- int32_t codec_channel_count = 0;
- int32_t codec_sample_rate = 0;
-
- if (!audioCodecFormat->findInt32("channel-count", &codec_channel_count) ||
- !audioCodecFormat->findInt32("sample-rate", &codec_sample_rate)) {
- return NS_ERROR_UNEXPECTED;
- }
-
- // Update AudioInfo
- AudioConfig::ChannelLayout layout(codec_channel_count);
- if (!layout.IsValid()) {
- return NS_ERROR_FAILURE;
- }
- mAudioChannels = codec_channel_count;
- mAudioRate = codec_sample_rate;
-
- return Output(aStreamOffset, aOutData);
- }
- case android::INFO_OUTPUT_BUFFERS_CHANGED:
- {
- GADM_LOG("Info Output Buffers Changed");
- if (mDecoder->UpdateOutputBuffers()) {
- return Output(aStreamOffset, aOutData);
- }
- return NS_ERROR_FAILURE;
- }
- case -EAGAIN:
- {
- return NS_ERROR_NOT_AVAILABLE;
- }
- case android::ERROR_END_OF_STREAM:
- {
- GADM_LOG("Got EOS frame!");
- nsresult rv = CreateAudioData(audioBuffer, aStreamOffset);
- NS_ENSURE_SUCCESS(rv, NS_ERROR_ABORT);
- MOZ_ASSERT(mAudioQueue.GetSize() > 0);
- mAudioQueue.Finish();
- break;
- }
- case -ETIMEDOUT:
- {
- GADM_LOG("Timeout. can try again next time");
- return NS_ERROR_UNEXPECTED;
- }
- default:
- {
- GADM_LOG("Decoder failed, err=%d", err);
- return NS_ERROR_UNEXPECTED;
- }
- }
-
- if (mAudioQueue.GetSize() > 0) {
- aOutData = mAudioQueue.PopFront();
- // Return NS_ERROR_ABORT at the last sample.
- return mAudioQueue.AtEndOfStream() ? NS_ERROR_ABORT : NS_OK;
- }
-
- return NS_ERROR_NOT_AVAILABLE;
-}
-
-void
-GonkAudioDecoderManager::ProcessFlush()
-{
- GADM_LOG("FLUSH<<<");
- mAudioQueue.Reset();
- GADM_LOG(">>>FLUSH");
- GonkDecoderManager::ProcessFlush();
-}
-
-void
-GonkAudioDecoderManager::ResetEOS()
-{
- GADM_LOG("ResetEOS(<<<");
- mAudioQueue.Reset();
- GADM_LOG(">>>ResetEOS(");
- GonkDecoderManager::ResetEOS();
-}
-
-} // namespace mozilla
diff --git a/dom/media/platforms/gonk/GonkAudioDecoderManager.h b/dom/media/platforms/gonk/GonkAudioDecoderManager.h
deleted file mode 100644
index aa35d620ec..0000000000
--- a/dom/media/platforms/gonk/GonkAudioDecoderManager.h
+++ /dev/null
@@ -1,59 +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(GonkAudioDecoderManager_h_)
-#define GonkAudioDecoderManager_h_
-
-#include "AudioCompactor.h"
-#include "mozilla/RefPtr.h"
-#include "GonkMediaDataDecoder.h"
-
-using namespace android;
-
-namespace android {
-class MOZ_EXPORT MediaBuffer;
-} // namespace android
-
-namespace mozilla {
-
-class GonkAudioDecoderManager : public GonkDecoderManager {
-typedef android::MediaCodecProxy MediaCodecProxy;
-public:
- GonkAudioDecoderManager(const AudioInfo& aConfig);
-
- virtual ~GonkAudioDecoderManager();
-
- RefPtr<InitPromise> Init() override;
-
- nsresult Output(int64_t aStreamOffset,
- RefPtr<MediaData>& aOutput) override;
-
- void ProcessFlush() override;
- virtual void ResetEOS() override;
-
- const char* GetDescriptionName() const override
- {
- return "gonk audio decoder";
- }
-
-private:
- bool InitMediaCodecProxy();
-
- nsresult CreateAudioData(MediaBuffer* aBuffer, int64_t aStreamOffset);
-
- uint32_t mAudioChannels;
- uint32_t mAudioRate;
- const uint32_t mAudioProfile;
-
- MediaQueue<AudioData> mAudioQueue;
-
- AudioCompactor mAudioCompactor;
-
-};
-
-} // namespace mozilla
-
-#endif // GonkAudioDecoderManager_h_
diff --git a/dom/media/platforms/gonk/GonkDecoderModule.cpp b/dom/media/platforms/gonk/GonkDecoderModule.cpp
deleted file mode 100644
index 537bc299c0..0000000000
--- a/dom/media/platforms/gonk/GonkDecoderModule.cpp
+++ /dev/null
@@ -1,63 +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 "GonkDecoderModule.h"
-#include "GonkVideoDecoderManager.h"
-#include "GonkAudioDecoderManager.h"
-#include "mozilla/DebugOnly.h"
-#include "GonkMediaDataDecoder.h"
-
-namespace mozilla {
-GonkDecoderModule::GonkDecoderModule()
-{
-}
-
-GonkDecoderModule::~GonkDecoderModule()
-{
-}
-
-already_AddRefed<MediaDataDecoder>
-GonkDecoderModule::CreateVideoDecoder(const CreateDecoderParams& aParams)
-{
- RefPtr<MediaDataDecoder> decoder =
- new GonkMediaDataDecoder(new GonkVideoDecoderManager(aParams.mImageContainer, aParams.VideoConfig()),
- aParams.mCallback);
- return decoder.forget();
-}
-
-already_AddRefed<MediaDataDecoder>
-GonkDecoderModule::CreateAudioDecoder(const CreateDecoderParams& aParams)
-{
- RefPtr<MediaDataDecoder> decoder =
- new GonkMediaDataDecoder(new GonkAudioDecoderManager(aParams.AudioConfig()),
- aParams.mCallback);
- return decoder.forget();
-}
-
-PlatformDecoderModule::ConversionRequired
-GonkDecoderModule::DecoderNeedsConversion(const TrackInfo& aConfig) const
-{
- if (aConfig.IsVideo()) {
- return ConversionRequired::kNeedAnnexB;
- } else {
- return ConversionRequired::kNeedNone;
- }
-}
-
-bool
-GonkDecoderModule::SupportsMimeType(const nsACString& aMimeType,
- DecoderDoctorDiagnostics* aDiagnostics) const
-{
- return aMimeType.EqualsLiteral("audio/mp4a-latm") ||
- aMimeType.EqualsLiteral("audio/3gpp") ||
- aMimeType.EqualsLiteral("audio/amr-wb") ||
- aMimeType.EqualsLiteral("audio/mpeg") ||
- aMimeType.EqualsLiteral("video/mp4") ||
- aMimeType.EqualsLiteral("video/mp4v-es") ||
- aMimeType.EqualsLiteral("video/avc") ||
- aMimeType.EqualsLiteral("video/3gpp");
-}
-
-} // namespace mozilla
diff --git a/dom/media/platforms/gonk/GonkDecoderModule.h b/dom/media/platforms/gonk/GonkDecoderModule.h
deleted file mode 100644
index 4f29f0e754..0000000000
--- a/dom/media/platforms/gonk/GonkDecoderModule.h
+++ /dev/null
@@ -1,37 +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(GonkPlatformDecoderModule_h_)
-#define GonkPlatformDecoderModule_h_
-
-#include "PlatformDecoderModule.h"
-
-namespace mozilla {
-
-class GonkDecoderModule : public PlatformDecoderModule {
-public:
- GonkDecoderModule();
- virtual ~GonkDecoderModule();
-
- // Decode thread.
- already_AddRefed<MediaDataDecoder>
- CreateVideoDecoder(const CreateDecoderParams& aParams) override;
-
- // Decode thread.
- already_AddRefed<MediaDataDecoder>
- CreateAudioDecoder(const CreateDecoderParams& aParams) override;
-
- ConversionRequired
- DecoderNeedsConversion(const TrackInfo& aConfig) const override;
-
- bool SupportsMimeType(const nsACString& aMimeType,
- DecoderDoctorDiagnostics* aDiagnostics) const override;
-
-};
-
-} // namespace mozilla
-
-#endif
diff --git a/dom/media/platforms/gonk/GonkMediaDataDecoder.cpp b/dom/media/platforms/gonk/GonkMediaDataDecoder.cpp
deleted file mode 100644
index 6d59d72e11..0000000000
--- a/dom/media/platforms/gonk/GonkMediaDataDecoder.cpp
+++ /dev/null
@@ -1,385 +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 "GonkMediaDataDecoder.h"
-#include "VideoUtils.h"
-#include "nsTArray.h"
-#include "MediaCodecProxy.h"
-
-#include <stagefright/foundation/ADebug.h>
-
-#include "mozilla/Logging.h"
-#include <android/log.h>
-#define GMDD_LOG(...) __android_log_print(ANDROID_LOG_DEBUG, "GonkMediaDataDecoder", __VA_ARGS__)
-#define INPUT_TIMEOUT_US 0LL // Don't wait for buffer if none is available.
-#define MIN_QUEUED_SAMPLES 2
-
-#ifdef DEBUG
-#include <utils/AndroidThreads.h>
-#endif
-
-#define LOG(...) MOZ_LOG(sPDMLog, mozilla::LogLevel::Debug, (__VA_ARGS__))
-
-using namespace android;
-
-namespace mozilla {
-
-bool
-GonkDecoderManager::InitLoopers(MediaData::Type aType)
-{
- MOZ_ASSERT(mDecodeLooper.get() == nullptr && mTaskLooper.get() == nullptr);
- MOZ_ASSERT(aType == MediaData::VIDEO_DATA || aType == MediaData::AUDIO_DATA);
-
- const char* suffix = (aType == MediaData::VIDEO_DATA ? "video" : "audio");
- mDecodeLooper = new ALooper;
- android::AString name("MediaCodecProxy/");
- name.append(suffix);
- mDecodeLooper->setName(name.c_str());
-
- mTaskLooper = new ALooper;
- name.setTo("GonkDecoderManager/");
- name.append(suffix);
- mTaskLooper->setName(name.c_str());
- mTaskLooper->registerHandler(this);
-
-#ifdef DEBUG
- sp<AMessage> findThreadId(new AMessage(kNotifyFindLooperId, id()));
- findThreadId->post();
-#endif
-
- return mDecodeLooper->start() == OK && mTaskLooper->start() == OK;
-}
-
-nsresult
-GonkDecoderManager::Input(MediaRawData* aSample)
-{
- RefPtr<MediaRawData> sample;
-
- if (aSample) {
- sample = aSample;
- } else {
- // It means EOS with empty sample.
- sample = new MediaRawData();
- }
- {
- MutexAutoLock lock(mMutex);
- mQueuedSamples.AppendElement(sample);
- }
-
- sp<AMessage> input = new AMessage(kNotifyProcessInput, id());
- if (!aSample) {
- input->setInt32("input-eos", 1);
- }
- input->post();
- return NS_OK;
-}
-
-int32_t
-GonkDecoderManager::ProcessQueuedSamples()
-{
- MOZ_ASSERT(OnTaskLooper());
-
- MutexAutoLock lock(mMutex);
- status_t rv;
- while (mQueuedSamples.Length()) {
- RefPtr<MediaRawData> data = mQueuedSamples.ElementAt(0);
- rv = mDecoder->Input(reinterpret_cast<const uint8_t*>(data->Data()),
- data->Size(),
- data->mTime,
- 0,
- INPUT_TIMEOUT_US);
- if (rv == OK) {
- mQueuedSamples.RemoveElementAt(0);
- mWaitOutput.AppendElement(WaitOutputInfo(data->mOffset, data->mTime,
- /* eos */ data->Data() == nullptr));
- } else if (rv == -EAGAIN || rv == -ETIMEDOUT) {
- // In most cases, EAGAIN or ETIMEOUT are safe because OMX can't fill
- // buffer on time.
- break;
- } else {
- return rv;
- }
- }
- return mQueuedSamples.Length();
-}
-
-nsresult
-GonkDecoderManager::Flush()
-{
- if (mDecoder == nullptr) {
- GMDD_LOG("Decoder is not initialized");
- return NS_ERROR_UNEXPECTED;
- }
-
- if (!mInitPromise.IsEmpty()) {
- return NS_OK;
- }
-
- {
- MutexAutoLock lock(mMutex);
- mQueuedSamples.Clear();
- }
-
- MonitorAutoLock lock(mFlushMonitor);
- mIsFlushing = true;
- sp<AMessage> flush = new AMessage(kNotifyProcessFlush, id());
- flush->post();
- while (mIsFlushing) {
- lock.Wait();
- }
- return NS_OK;
-}
-
-nsresult
-GonkDecoderManager::Shutdown()
-{
- if (mDecoder.get()) {
- mDecoder->stop();
- mDecoder->ReleaseMediaResources();
- mDecoder = nullptr;
- }
-
- mInitPromise.RejectIfExists(NS_ERROR_DOM_MEDIA_CANCELED, __func__);
-
- return NS_OK;
-}
-
-size_t
-GonkDecoderManager::NumQueuedSamples()
-{
- MutexAutoLock lock(mMutex);
- return mQueuedSamples.Length();
-}
-
-void
-GonkDecoderManager::ProcessInput(bool aEndOfStream)
-{
- MOZ_ASSERT(OnTaskLooper());
-
- status_t rv = ProcessQueuedSamples();
- if (rv >= 0) {
- if (!aEndOfStream && rv <= MIN_QUEUED_SAMPLES) {
- mDecodeCallback->InputExhausted();
- }
-
- if (mToDo.get() == nullptr) {
- mToDo = new AMessage(kNotifyDecoderActivity, id());
- if (aEndOfStream) {
- mToDo->setInt32("input-eos", 1);
- }
- mDecoder->requestActivityNotification(mToDo);
- } else if (aEndOfStream) {
- mToDo->setInt32("input-eos", 1);
- }
- } else {
- GMDD_LOG("input processed: error#%d", rv);
- mDecodeCallback->Error(MediaResult(NS_ERROR_DOM_MEDIA_FATAL_ERR,
- __func__));
- }
-}
-
-void
-GonkDecoderManager::ProcessFlush()
-{
- MOZ_ASSERT(OnTaskLooper());
-
- mLastTime = INT64_MIN;
- MonitorAutoLock lock(mFlushMonitor);
- mWaitOutput.Clear();
- if (mDecoder->flush() != OK) {
- GMDD_LOG("flush error");
- mDecodeCallback->Error(MediaResult(NS_ERROR_DOM_MEDIA_FATAL_ERR,
- __func__));
- }
- mIsFlushing = false;
- lock.NotifyAll();
-}
-
-// Use output timestamp to determine which output buffer is already returned
-// and remove corresponding info, except for EOS, from the waiting list.
-// This method handles the cases that audio decoder sends multiple output
-// buffers for one input.
-void
-GonkDecoderManager::UpdateWaitingList(int64_t aForgetUpTo)
-{
- MOZ_ASSERT(OnTaskLooper());
-
- size_t i;
- for (i = 0; i < mWaitOutput.Length(); i++) {
- const auto& item = mWaitOutput.ElementAt(i);
- if (item.mEOS || item.mTimestamp > aForgetUpTo) {
- break;
- }
- }
- if (i > 0) {
- mWaitOutput.RemoveElementsAt(0, i);
- }
-}
-
-void
-GonkDecoderManager::ProcessToDo(bool aEndOfStream)
-{
- MOZ_ASSERT(OnTaskLooper());
-
- MOZ_ASSERT(mToDo.get() != nullptr);
- mToDo.clear();
-
- if (NumQueuedSamples() > 0 && ProcessQueuedSamples() < 0) {
- mDecodeCallback->Error(MediaResult(NS_ERROR_DOM_MEDIA_FATAL_ERR,
- __func__));
- return;
- }
-
- while (mWaitOutput.Length() > 0) {
- RefPtr<MediaData> output;
- WaitOutputInfo wait = mWaitOutput.ElementAt(0);
- nsresult rv = Output(wait.mOffset, output);
- if (rv == NS_OK) {
- MOZ_ASSERT(output);
- mDecodeCallback->Output(output);
- UpdateWaitingList(output->mTime);
- } else if (rv == NS_ERROR_ABORT) {
- // EOS
- MOZ_ASSERT(mQueuedSamples.IsEmpty());
- if (output) {
- mDecodeCallback->Output(output);
- UpdateWaitingList(output->mTime);
- }
- MOZ_ASSERT(mWaitOutput.Length() == 1);
- mWaitOutput.RemoveElementAt(0);
- mDecodeCallback->DrainComplete();
- ResetEOS();
- return;
- } else if (rv == NS_ERROR_NOT_AVAILABLE) {
- break;
- } else {
- mDecodeCallback->Error(MediaResult(NS_ERROR_DOM_MEDIA_FATAL_ERR,
- __func__));
- return;
- }
- }
-
- if (!aEndOfStream && NumQueuedSamples() <= MIN_QUEUED_SAMPLES) {
- mDecodeCallback->InputExhausted();
- // No need to shedule todo task this time because InputExhausted() will
- // cause Input() to be invoked and do it for us.
- return;
- }
-
- if (NumQueuedSamples() || mWaitOutput.Length() > 0) {
- mToDo = new AMessage(kNotifyDecoderActivity, id());
- if (aEndOfStream) {
- mToDo->setInt32("input-eos", 1);
- }
- mDecoder->requestActivityNotification(mToDo);
- }
-}
-
-void
-GonkDecoderManager::ResetEOS()
-{
- // After eos, android::MediaCodec needs to be flushed to receive next input
- mWaitOutput.Clear();
- if (mDecoder->flush() != OK) {
- GMDD_LOG("flush error");
- mDecodeCallback->Error(MediaResult(NS_ERROR_DOM_MEDIA_FATAL_ERR,
- __func__));
- }
-}
-
-void
-GonkDecoderManager::onMessageReceived(const sp<AMessage> &aMessage)
-{
- switch (aMessage->what()) {
- case kNotifyProcessInput:
- {
- int32_t eos = 0;
- ProcessInput(aMessage->findInt32("input-eos", &eos) && eos);
- break;
- }
- case kNotifyProcessFlush:
- {
- ProcessFlush();
- break;
- }
- case kNotifyDecoderActivity:
- {
- int32_t eos = 0;
- ProcessToDo(aMessage->findInt32("input-eos", &eos) && eos);
- break;
- }
-#ifdef DEBUG
- case kNotifyFindLooperId:
- {
- mTaskLooperId = androidGetThreadId();
- MOZ_ASSERT(mTaskLooperId);
- break;
- }
-#endif
- default:
- {
- TRESPASS();
- break;
- }
- }
-}
-
-#ifdef DEBUG
-bool
-GonkDecoderManager::OnTaskLooper()
-{
- return androidGetThreadId() == mTaskLooperId;
-}
-#endif
-
-GonkMediaDataDecoder::GonkMediaDataDecoder(GonkDecoderManager* aManager,
- MediaDataDecoderCallback* aCallback)
- : mManager(aManager)
-{
- MOZ_COUNT_CTOR(GonkMediaDataDecoder);
- mManager->SetDecodeCallback(aCallback);
-}
-
-GonkMediaDataDecoder::~GonkMediaDataDecoder()
-{
- MOZ_COUNT_DTOR(GonkMediaDataDecoder);
-}
-
-RefPtr<MediaDataDecoder::InitPromise>
-GonkMediaDataDecoder::Init()
-{
- return mManager->Init();
-}
-
-void
-GonkMediaDataDecoder::Shutdown()
-{
- mManager->Shutdown();
-
- // Because codec allocated runnable and init promise is at reader TaskQueue,
- // so manager needs to be destroyed at reader TaskQueue to prevent racing.
- mManager = nullptr;
-}
-
-// Inserts data into the decoder's pipeline.
-void
-GonkMediaDataDecoder::Input(MediaRawData* aSample)
-{
- mManager->Input(aSample);
-}
-
-void
-GonkMediaDataDecoder::Flush()
-{
- mManager->Flush();
-}
-
-void
-GonkMediaDataDecoder::Drain()
-{
- mManager->Input(nullptr);
-}
-
-} // namespace mozilla
diff --git a/dom/media/platforms/gonk/GonkMediaDataDecoder.h b/dom/media/platforms/gonk/GonkMediaDataDecoder.h
deleted file mode 100644
index bba2a8645d..0000000000
--- a/dom/media/platforms/gonk/GonkMediaDataDecoder.h
+++ /dev/null
@@ -1,214 +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(GonkMediaDataDecoder_h_)
-#define GonkMediaDataDecoder_h_
-#include "PlatformDecoderModule.h"
-#include <stagefright/foundation/AHandler.h>
-
-namespace android {
-struct ALooper;
-class MediaBuffer;
-class MediaCodecProxy;
-} // namespace android
-
-namespace mozilla {
-class MediaRawData;
-
-// Manage the data flow from inputting encoded data and outputting decode data.
-class GonkDecoderManager : public android::AHandler {
-public:
- typedef TrackInfo::TrackType TrackType;
- typedef MediaDataDecoder::InitPromise InitPromise;
-
- virtual ~GonkDecoderManager() {}
-
- virtual RefPtr<InitPromise> Init() = 0;
- virtual const char* GetDescriptionName() const = 0;
-
- // Asynchronously send sample into mDecoder. If out of input buffer, aSample
- // will be queued for later re-send.
- nsresult Input(MediaRawData* aSample);
-
- // Flush the queued samples and signal decoder to throw all pending input/output away.
- nsresult Flush();
-
- // Shutdown decoder and rejects the init promise.
- virtual nsresult Shutdown();
-
- // How many samples are waiting for processing.
- size_t NumQueuedSamples();
-
- // Set callback for decoder events, such as requesting more input,
- // returning output, or reporting error.
- void SetDecodeCallback(MediaDataDecoderCallback* aCallback)
- {
- mDecodeCallback = aCallback;
- }
-
-protected:
- GonkDecoderManager()
- : mMutex("GonkDecoderManager")
- , mLastTime(INT64_MIN)
- , mFlushMonitor("GonkDecoderManager::Flush")
- , mIsFlushing(false)
- , mDecodeCallback(nullptr)
- {}
-
- bool InitLoopers(MediaData::Type aType);
-
- void onMessageReceived(const android::sp<android::AMessage> &aMessage) override;
-
- // Produces decoded output. It returns NS_OK on success, or NS_ERROR_NOT_AVAILABLE
- // when output is not produced yet.
- // If this returns a failure code other than NS_ERROR_NOT_AVAILABLE, an error
- // will be reported through mDecodeCallback.
- virtual nsresult Output(int64_t aStreamOffset,
- RefPtr<MediaData>& aOutput) = 0;
-
- // Send queued samples to OMX. It returns how many samples are still in
- // queue after processing, or negative error code if failed.
- int32_t ProcessQueuedSamples();
-
- void ProcessInput(bool aEndOfStream);
- virtual void ProcessFlush();
- void ProcessToDo(bool aEndOfStream);
- virtual void ResetEOS();
-
- RefPtr<MediaByteBuffer> mCodecSpecificData;
-
- nsAutoCString mMimeType;
-
- // MediaCodedc's wrapper that performs the decoding.
- android::sp<android::MediaCodecProxy> mDecoder;
- // Looper for mDecoder to run on.
- android::sp<android::ALooper> mDecodeLooper;
- // Looper to run decode tasks such as processing input, output, flush, and
- // recycling output buffers.
- android::sp<android::ALooper> mTaskLooper;
- // Message codes for tasks running on mTaskLooper.
- enum {
- // Decoder will send this to indicate internal state change such as input or
- // output buffers availability. Used to run pending input & output tasks.
- kNotifyDecoderActivity = 'nda ',
- // Signal the decoder to flush.
- kNotifyProcessFlush = 'npf ',
- // Used to process queued samples when there is new input.
- kNotifyProcessInput = 'npi ',
-#ifdef DEBUG
- kNotifyFindLooperId = 'nfli',
-#endif
- };
-
- MozPromiseHolder<InitPromise> mInitPromise;
-
- Mutex mMutex; // Protects mQueuedSamples.
- // A queue that stores the samples waiting to be sent to mDecoder.
- // Empty element means EOS and there shouldn't be any sample be queued after it.
- // Samples are queued in caller's thread and dequeued in mTaskLooper.
- nsTArray<RefPtr<MediaRawData>> mQueuedSamples;
-
- // The last decoded frame presentation time. Only accessed on mTaskLooper.
- int64_t mLastTime;
-
- Monitor mFlushMonitor; // Waits for flushing to complete.
- bool mIsFlushing; // Protected by mFlushMonitor.
-
- // Remembers the notification that is currently waiting for the decoder event
- // to avoid requesting more than one notification at the time, which is
- // forbidden by mDecoder.
- android::sp<android::AMessage> mToDo;
-
- // Stores sample info for output buffer processing later.
- struct WaitOutputInfo {
- WaitOutputInfo(int64_t aOffset, int64_t aTimestamp, bool aEOS)
- : mOffset(aOffset)
- , mTimestamp(aTimestamp)
- , mEOS(aEOS)
- {}
- const int64_t mOffset;
- const int64_t mTimestamp;
- const bool mEOS;
- };
-
- nsTArray<WaitOutputInfo> mWaitOutput;
-
- MediaDataDecoderCallback* mDecodeCallback; // Reports decoder output or error.
-
-private:
- void UpdateWaitingList(int64_t aForgetUpTo);
-
-#ifdef DEBUG
- typedef void* LooperId;
-
- bool OnTaskLooper();
- LooperId mTaskLooperId;
-#endif
-};
-
-class AutoReleaseMediaBuffer
-{
-public:
- AutoReleaseMediaBuffer(android::MediaBuffer* aBuffer, android::MediaCodecProxy* aCodec)
- : mBuffer(aBuffer)
- , mCodec(aCodec)
- {}
-
- ~AutoReleaseMediaBuffer()
- {
- MOZ_ASSERT(mCodec.get());
- if (mBuffer) {
- mCodec->ReleaseMediaBuffer(mBuffer);
- }
- }
-
- android::MediaBuffer* forget()
- {
- android::MediaBuffer* tmp = mBuffer;
- mBuffer = nullptr;
- return tmp;
- }
-
-private:
- android::MediaBuffer* mBuffer;
- android::sp<android::MediaCodecProxy> mCodec;
-};
-
-// Samples are decoded using the GonkDecoder (MediaCodec)
-// created by the GonkDecoderManager. This class implements
-// the higher-level logic that drives mapping the Gonk to the async
-// MediaDataDecoder interface. The specifics of decoding the exact stream
-// type are handled by GonkDecoderManager and the GonkDecoder it creates.
-class GonkMediaDataDecoder : public MediaDataDecoder {
-public:
- GonkMediaDataDecoder(GonkDecoderManager* aDecoderManager,
- MediaDataDecoderCallback* aCallback);
-
- ~GonkMediaDataDecoder();
-
- RefPtr<InitPromise> Init() override;
-
- void Input(MediaRawData* aSample) override;
-
- void Flush() override;
-
- void Drain() override;
-
- void Shutdown() override;
-
- const char* GetDescriptionName() const override
- {
- return "gonk decoder";
- }
-
-private:
-
- android::sp<GonkDecoderManager> mManager;
-};
-
-} // namespace mozilla
-
-#endif // GonkMediaDataDecoder_h_
diff --git a/dom/media/platforms/gonk/GonkVideoDecoderManager.cpp b/dom/media/platforms/gonk/GonkVideoDecoderManager.cpp
deleted file mode 100644
index 0c7b3b6af9..0000000000
--- a/dom/media/platforms/gonk/GonkVideoDecoderManager.cpp
+++ /dev/null
@@ -1,772 +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 "MediaCodecProxy.h"
-#include <OMX_IVCommon.h>
-#include <gui/Surface.h>
-#include <ICrypto.h>
-#include "GonkVideoDecoderManager.h"
-#include "GrallocImages.h"
-#include "MediaDecoderReader.h"
-#include "ImageContainer.h"
-#include "VideoUtils.h"
-#include "nsThreadUtils.h"
-#include "Layers.h"
-#include "mozilla/Logging.h"
-#include <stagefright/MediaBuffer.h>
-#include <stagefright/MetaData.h>
-#include <stagefright/MediaErrors.h>
-#include <stagefright/foundation/AString.h>
-#include "GonkNativeWindow.h"
-#include "mozilla/layers/GrallocTextureClient.h"
-#include "mozilla/layers/ImageBridgeChild.h"
-#include "mozilla/layers/TextureClient.h"
-#include "mozilla/layers/TextureClientRecycleAllocator.h"
-#include <cutils/properties.h>
-
-#define CODECCONFIG_TIMEOUT_US 10000LL
-#define READ_OUTPUT_BUFFER_TIMEOUT_US 0LL
-
-#include <android/log.h>
-#define GVDM_LOG(...) __android_log_print(ANDROID_LOG_DEBUG, "GonkVideoDecoderManager", __VA_ARGS__)
-
-#define LOG(...) MOZ_LOG(sPDMLog, mozilla::LogLevel::Debug, (__VA_ARGS__))
-using namespace mozilla::layers;
-using namespace android;
-typedef android::MediaCodecProxy MediaCodecProxy;
-
-namespace mozilla {
-
-class GonkTextureClientAllocationHelper : public layers::ITextureClientAllocationHelper
-{
-public:
- GonkTextureClientAllocationHelper(uint32_t aGrallocFormat,
- gfx::IntSize aSize)
- : ITextureClientAllocationHelper(gfx::SurfaceFormat::UNKNOWN,
- aSize,
- BackendSelector::Content,
- TextureFlags::DEALLOCATE_CLIENT,
- ALLOC_DISALLOW_BUFFERTEXTURECLIENT)
- , mGrallocFormat(aGrallocFormat)
- {}
-
- already_AddRefed<TextureClient> Allocate(KnowsCompositor* aAllocator) override
- {
- uint32_t usage = android::GraphicBuffer::USAGE_SW_READ_OFTEN |
- android::GraphicBuffer::USAGE_SW_WRITE_OFTEN |
- android::GraphicBuffer::USAGE_HW_TEXTURE;
-
- GrallocTextureData* texData = GrallocTextureData::Create(mSize, mGrallocFormat,
- gfx::BackendType::NONE,
- usage, aAllocator->GetTextureForwarder());
- if (!texData) {
- return nullptr;
- }
- sp<GraphicBuffer> graphicBuffer = texData->GetGraphicBuffer();
- if (!graphicBuffer.get()) {
- return nullptr;
- }
- RefPtr<TextureClient> textureClient =
- TextureClient::CreateWithData(texData, TextureFlags::DEALLOCATE_CLIENT, aAllocator->GetTextureForwarder());
- return textureClient.forget();
- }
-
- bool IsCompatible(TextureClient* aTextureClient) override
- {
- if (!aTextureClient) {
- return false;
- }
- sp<GraphicBuffer> graphicBuffer =
- static_cast<GrallocTextureData*>(aTextureClient->GetInternalData())->GetGraphicBuffer();
- if (!graphicBuffer.get() ||
- static_cast<uint32_t>(graphicBuffer->getPixelFormat()) != mGrallocFormat ||
- aTextureClient->GetSize() != mSize) {
- return false;
- }
- return true;
- }
-
-private:
- uint32_t mGrallocFormat;
-};
-
-GonkVideoDecoderManager::GonkVideoDecoderManager(
- mozilla::layers::ImageContainer* aImageContainer,
- const VideoInfo& aConfig)
- : mConfig(aConfig)
- , mImageContainer(aImageContainer)
- , mColorConverterBufferSize(0)
- , mPendingReleaseItemsLock("GonkVideoDecoderManager::mPendingReleaseItemsLock")
- , mNeedsCopyBuffer(false)
-{
- MOZ_COUNT_CTOR(GonkVideoDecoderManager);
-}
-
-GonkVideoDecoderManager::~GonkVideoDecoderManager()
-{
- MOZ_COUNT_DTOR(GonkVideoDecoderManager);
-}
-
-nsresult
-GonkVideoDecoderManager::Shutdown()
-{
- mVideoCodecRequest.DisconnectIfExists();
- return GonkDecoderManager::Shutdown();
-}
-
-RefPtr<MediaDataDecoder::InitPromise>
-GonkVideoDecoderManager::Init()
-{
- mNeedsCopyBuffer = false;
-
- uint32_t maxWidth, maxHeight;
- char propValue[PROPERTY_VALUE_MAX];
- property_get("ro.moz.omx.hw.max_width", propValue, "-1");
- maxWidth = -1 == atoi(propValue) ? MAX_VIDEO_WIDTH : atoi(propValue);
- property_get("ro.moz.omx.hw.max_height", propValue, "-1");
- maxHeight = -1 == atoi(propValue) ? MAX_VIDEO_HEIGHT : atoi(propValue) ;
-
- if (uint32_t(mConfig.mImage.width * mConfig.mImage.height) > maxWidth * maxHeight) {
- GVDM_LOG("Video resolution exceeds hw codec capability");
- return InitPromise::CreateAndReject(NS_ERROR_DOM_MEDIA_FATAL_ERR, __func__);
- }
-
- // Validate the container-reported frame and pictureRect sizes. This ensures
- // that our video frame creation code doesn't overflow.
- if (!IsValidVideoRegion(mConfig.mImage, mConfig.ImageRect(), mConfig.mDisplay)) {
- GVDM_LOG("It is not a valid region");
- return InitPromise::CreateAndReject(NS_ERROR_DOM_MEDIA_FATAL_ERR, __func__);
- }
-
- mReaderTaskQueue = AbstractThread::GetCurrent()->AsTaskQueue();
- MOZ_ASSERT(mReaderTaskQueue);
-
- if (mDecodeLooper.get() != nullptr) {
- return InitPromise::CreateAndReject(NS_ERROR_DOM_MEDIA_FATAL_ERR, __func__);
- }
-
- if (!InitLoopers(MediaData::VIDEO_DATA)) {
- return InitPromise::CreateAndReject(NS_ERROR_DOM_MEDIA_FATAL_ERR, __func__);
- }
-
- RefPtr<InitPromise> p = mInitPromise.Ensure(__func__);
- android::sp<GonkVideoDecoderManager> self = this;
- mDecoder = MediaCodecProxy::CreateByType(mDecodeLooper,
- mConfig.mMimeType.get(),
- false);
-
- uint32_t capability = MediaCodecProxy::kEmptyCapability;
- if (mDecoder->getCapability(&capability) == OK && (capability &
- MediaCodecProxy::kCanExposeGraphicBuffer)) {
-#if ANDROID_VERSION >= 21
- sp<IGonkGraphicBufferConsumer> consumer;
- GonkBufferQueue::createBufferQueue(&mGraphicBufferProducer, &consumer);
- mNativeWindow = new GonkNativeWindow(consumer);
-#else
- mNativeWindow = new GonkNativeWindow();
-#endif
- }
-
- mVideoCodecRequest.Begin(mDecoder->AsyncAllocateVideoMediaCodec()
- ->Then(mReaderTaskQueue, __func__,
- [self] (bool) -> void {
- self->mVideoCodecRequest.Complete();
- self->codecReserved();
- }, [self] (bool) -> void {
- self->mVideoCodecRequest.Complete();
- self->codecCanceled();
- }));
-
- return p;
-}
-
-nsresult
-GonkVideoDecoderManager::CreateVideoData(MediaBuffer* aBuffer,
- int64_t aStreamOffset,
- VideoData **v)
-{
- *v = nullptr;
- RefPtr<VideoData> data;
- int64_t timeUs;
- int32_t keyFrame;
-
- if (aBuffer == nullptr) {
- GVDM_LOG("Video Buffer is not valid!");
- return NS_ERROR_UNEXPECTED;
- }
-
- AutoReleaseMediaBuffer autoRelease(aBuffer, mDecoder.get());
-
- if (!aBuffer->meta_data()->findInt64(kKeyTime, &timeUs)) {
- GVDM_LOG("Decoder did not return frame time");
- return NS_ERROR_UNEXPECTED;
- }
-
- if (mLastTime > timeUs) {
- GVDM_LOG("Output decoded sample time is revert. time=%lld", timeUs);
- return NS_ERROR_NOT_AVAILABLE;
- }
- mLastTime = timeUs;
-
- if (aBuffer->range_length() == 0) {
- // Some decoders may return spurious empty buffers that we just want to ignore
- // quoted from Android's AwesomePlayer.cpp
- return NS_ERROR_NOT_AVAILABLE;
- }
-
- if (!aBuffer->meta_data()->findInt32(kKeyIsSyncFrame, &keyFrame)) {
- keyFrame = 0;
- }
-
- gfx::IntRect picture =
- mConfig.ScaledImageRect(mFrameInfo.mWidth, mFrameInfo.mHeight);
- if (aBuffer->graphicBuffer().get()) {
- data = CreateVideoDataFromGraphicBuffer(aBuffer, picture);
- if (data && !mNeedsCopyBuffer) {
- // RecycleCallback() will be responsible for release the buffer.
- autoRelease.forget();
- }
- mNeedsCopyBuffer = false;
- } else {
- data = CreateVideoDataFromDataBuffer(aBuffer, picture);
- }
-
- if (!data) {
- return NS_ERROR_UNEXPECTED;
- }
- // Fill necessary info.
- data->mOffset = aStreamOffset;
- data->mTime = timeUs;
- data->mKeyframe = keyFrame;
-
- data.forget(v);
- return NS_OK;
-}
-
-// Copy pixels from one planar YUV to another.
-static void
-CopyYUV(PlanarYCbCrData& aSource, PlanarYCbCrData& aDestination)
-{
- // Fill Y plane.
- uint8_t* srcY = aSource.mYChannel;
- gfx::IntSize ySize = aSource.mYSize;
- uint8_t* destY = aDestination.mYChannel;
- // Y plane.
- for (int i = 0; i < ySize.height; i++) {
- memcpy(destY, srcY, ySize.width);
- srcY += aSource.mYStride;
- destY += aDestination.mYStride;
- }
-
- // Fill UV plane.
- // Line start
- uint8_t* srcU = aSource.mCbChannel;
- uint8_t* srcV = aSource.mCrChannel;
- uint8_t* destU = aDestination.mCbChannel;
- uint8_t* destV = aDestination.mCrChannel;
-
- gfx::IntSize uvSize = aSource.mCbCrSize;
- for (int i = 0; i < uvSize.height; i++) {
- uint8_t* su = srcU;
- uint8_t* sv = srcV;
- uint8_t* du = destU;
- uint8_t* dv =destV;
- for (int j = 0; j < uvSize.width; j++) {
- *du++ = *su++;
- *dv++ = *sv++;
- // Move to next pixel.
- su += aSource.mCbSkip;
- sv += aSource.mCrSkip;
- du += aDestination.mCbSkip;
- dv += aDestination.mCrSkip;
- }
- // Move to next line.
- srcU += aSource.mCbCrStride;
- srcV += aSource.mCbCrStride;
- destU += aDestination.mCbCrStride;
- destV += aDestination.mCbCrStride;
- }
-}
-
-inline static int
-Align(int aX, int aAlign)
-{
- return (aX + aAlign - 1) & ~(aAlign - 1);
-}
-
-// Venus formats are doucmented in kernel/include/media/msm_media_info.h:
-// * Y_Stride : Width aligned to 128
-// * UV_Stride : Width aligned to 128
-// * Y_Scanlines: Height aligned to 32
-// * UV_Scanlines: Height/2 aligned to 16
-// * Total size = align((Y_Stride * Y_Scanlines
-// * + UV_Stride * UV_Scanlines + 4096), 4096)
-static void
-CopyVenus(uint8_t* aSrc, uint8_t* aDest, uint32_t aWidth, uint32_t aHeight)
-{
- size_t yStride = Align(aWidth, 128);
- uint8_t* s = aSrc;
- uint8_t* d = aDest;
- for (size_t i = 0; i < aHeight; i++) {
- memcpy(d, s, aWidth);
- s += yStride;
- d += yStride;
- }
- size_t uvStride = yStride;
- size_t uvLines = (aHeight + 1) / 2;
- size_t ySize = yStride * Align(aHeight, 32);
- s = aSrc + ySize;
- d = aDest + ySize;
- for (size_t i = 0; i < uvLines; i++) {
- memcpy(d, s, aWidth);
- s += uvStride;
- d += uvStride;
- }
-}
-
-static void
-CopyGraphicBuffer(sp<GraphicBuffer>& aSource, sp<GraphicBuffer>& aDestination)
-{
- void* srcPtr = nullptr;
- aSource->lock(GraphicBuffer::USAGE_SW_READ_OFTEN, &srcPtr);
- void* destPtr = nullptr;
- aDestination->lock(GraphicBuffer::USAGE_SW_WRITE_OFTEN, &destPtr);
- MOZ_ASSERT(srcPtr && destPtr);
-
- // Build PlanarYCbCrData for source buffer.
- PlanarYCbCrData srcData;
- switch (aSource->getPixelFormat()) {
- case HAL_PIXEL_FORMAT_YV12: {
- // Android YV12 format is defined in system/core/include/system/graphics.h
- srcData.mYChannel = static_cast<uint8_t*>(srcPtr);
- srcData.mYSkip = 0;
- srcData.mYSize.width = aSource->getWidth();
- srcData.mYSize.height = aSource->getHeight();
- srcData.mYStride = aSource->getStride();
- // 4:2:0.
- srcData.mCbCrSize.width = srcData.mYSize.width / 2;
- srcData.mCbCrSize.height = srcData.mYSize.height / 2;
- srcData.mCrChannel = srcData.mYChannel + (srcData.mYStride * srcData.mYSize.height);
- // Aligned to 16 bytes boundary.
- srcData.mCbCrStride = Align(srcData.mYStride / 2, 16);
- srcData.mCrSkip = 0;
- srcData.mCbChannel = srcData.mCrChannel + (srcData.mCbCrStride * srcData.mCbCrSize.height);
- srcData.mCbSkip = 0;
-
- // Build PlanarYCbCrData for destination buffer.
- PlanarYCbCrData destData;
- destData.mYChannel = static_cast<uint8_t*>(destPtr);
- destData.mYSkip = 0;
- destData.mYSize.width = aDestination->getWidth();
- destData.mYSize.height = aDestination->getHeight();
- destData.mYStride = aDestination->getStride();
- // 4:2:0.
- destData.mCbCrSize.width = destData.mYSize.width / 2;
- destData.mCbCrSize.height = destData.mYSize.height / 2;
- destData.mCrChannel = destData.mYChannel + (destData.mYStride * destData.mYSize.height);
- // Aligned to 16 bytes boundary.
- destData.mCbCrStride = Align(destData.mYStride / 2, 16);
- destData.mCrSkip = 0;
- destData.mCbChannel = destData.mCrChannel + (destData.mCbCrStride * destData.mCbCrSize.height);
- destData.mCbSkip = 0;
-
- CopyYUV(srcData, destData);
- break;
- }
- case GrallocImage::HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
- CopyVenus(static_cast<uint8_t*>(srcPtr),
- static_cast<uint8_t*>(destPtr),
- aSource->getWidth(),
- aSource->getHeight());
- break;
- default:
- NS_ERROR("Unsupported input gralloc image type. Should never be here.");
- }
-
-
- aSource->unlock();
- aDestination->unlock();
-}
-
-already_AddRefed<VideoData>
-GonkVideoDecoderManager::CreateVideoDataFromGraphicBuffer(MediaBuffer* aSource,
- gfx::IntRect& aPicture)
-{
- sp<GraphicBuffer> srcBuffer(aSource->graphicBuffer());
- RefPtr<TextureClient> textureClient;
-
- if (mNeedsCopyBuffer) {
- // Copy buffer contents for bug 1199809.
- if (!mCopyAllocator) {
- RefPtr<layers::ImageBridgeChild> bridge = layers::ImageBridgeChild::GetSingleton();
- mCopyAllocator = new TextureClientRecycleAllocator(bridge);
- }
- if (!mCopyAllocator) {
- GVDM_LOG("Create buffer allocator failed!");
- return nullptr;
- }
-
- gfx::IntSize size(srcBuffer->getWidth(), srcBuffer->getHeight());
- GonkTextureClientAllocationHelper helper(srcBuffer->getPixelFormat(), size);
- textureClient = mCopyAllocator->CreateOrRecycle(helper);
- if (!textureClient) {
- GVDM_LOG("Copy buffer allocation failed!");
- return nullptr;
- }
-
- sp<GraphicBuffer> destBuffer =
- static_cast<GrallocTextureData*>(textureClient->GetInternalData())->GetGraphicBuffer();
-
- CopyGraphicBuffer(srcBuffer, destBuffer);
- } else {
- textureClient = mNativeWindow->getTextureClientFromBuffer(srcBuffer.get());
- textureClient->SetRecycleCallback(GonkVideoDecoderManager::RecycleCallback, this);
- static_cast<GrallocTextureData*>(textureClient->GetInternalData())->SetMediaBuffer(aSource);
- }
-
- RefPtr<VideoData> data =
- VideoData::CreateAndCopyIntoTextureClient(mConfig,
- 0, // Filled later by caller.
- 0, // Filled later by caller.
- 1, // No way to pass sample duration from muxer to
- // OMX codec, so we hardcode the duration here.
- textureClient,
- false, // Filled later by caller.
- -1,
- aPicture);
- return data.forget();
-}
-
-already_AddRefed<VideoData>
-GonkVideoDecoderManager::CreateVideoDataFromDataBuffer(MediaBuffer* aSource, gfx::IntRect& aPicture)
-{
- if (!aSource->data()) {
- GVDM_LOG("No data in Video Buffer!");
- return nullptr;
- }
- uint8_t *yuv420p_buffer = (uint8_t *)aSource->data();
- int32_t stride = mFrameInfo.mStride;
- int32_t slice_height = mFrameInfo.mSliceHeight;
-
- // Converts to OMX_COLOR_FormatYUV420Planar
- if (mFrameInfo.mColorFormat != OMX_COLOR_FormatYUV420Planar) {
- ARect crop;
- crop.top = 0;
- crop.bottom = mFrameInfo.mHeight;
- crop.left = 0;
- crop.right = mFrameInfo.mWidth;
- yuv420p_buffer = GetColorConverterBuffer(mFrameInfo.mWidth, mFrameInfo.mHeight);
- if (mColorConverter.convertDecoderOutputToI420(aSource->data(),
- mFrameInfo.mWidth, mFrameInfo.mHeight, crop, yuv420p_buffer) != OK) {
- GVDM_LOG("Color conversion failed!");
- return nullptr;
- }
- stride = mFrameInfo.mWidth;
- slice_height = mFrameInfo.mHeight;
- }
-
- size_t yuv420p_y_size = stride * slice_height;
- size_t yuv420p_u_size = ((stride + 1) / 2) * ((slice_height + 1) / 2);
- uint8_t *yuv420p_y = yuv420p_buffer;
- uint8_t *yuv420p_u = yuv420p_y + yuv420p_y_size;
- uint8_t *yuv420p_v = yuv420p_u + yuv420p_u_size;
-
- VideoData::YCbCrBuffer b;
- b.mPlanes[0].mData = yuv420p_y;
- b.mPlanes[0].mWidth = mFrameInfo.mWidth;
- b.mPlanes[0].mHeight = mFrameInfo.mHeight;
- b.mPlanes[0].mStride = stride;
- b.mPlanes[0].mOffset = 0;
- b.mPlanes[0].mSkip = 0;
-
- b.mPlanes[1].mData = yuv420p_u;
- b.mPlanes[1].mWidth = (mFrameInfo.mWidth + 1) / 2;
- b.mPlanes[1].mHeight = (mFrameInfo.mHeight + 1) / 2;
- b.mPlanes[1].mStride = (stride + 1) / 2;
- b.mPlanes[1].mOffset = 0;
- b.mPlanes[1].mSkip = 0;
-
- b.mPlanes[2].mData = yuv420p_v;
- b.mPlanes[2].mWidth =(mFrameInfo.mWidth + 1) / 2;
- b.mPlanes[2].mHeight = (mFrameInfo.mHeight + 1) / 2;
- b.mPlanes[2].mStride = (stride + 1) / 2;
- b.mPlanes[2].mOffset = 0;
- b.mPlanes[2].mSkip = 0;
-
- RefPtr<VideoData> data =
- VideoData::CreateAndCopyData(mConfig,
- mImageContainer,
- 0, // Filled later by caller.
- 0, // Filled later by caller.
- 1, // We don't know the duration.
- b,
- 0, // Filled later by caller.
- -1,
- aPicture);
-
- return data.forget();
-}
-
-bool
-GonkVideoDecoderManager::SetVideoFormat()
-{
- // read video metadata from MediaCodec
- sp<AMessage> codecFormat;
- if (mDecoder->getOutputFormat(&codecFormat) == OK) {
- AString mime;
- int32_t width = 0;
- int32_t height = 0;
- int32_t stride = 0;
- int32_t slice_height = 0;
- int32_t color_format = 0;
- int32_t crop_left = 0;
- int32_t crop_top = 0;
- int32_t crop_right = 0;
- int32_t crop_bottom = 0;
- if (!codecFormat->findString("mime", &mime) ||
- !codecFormat->findInt32("width", &width) ||
- !codecFormat->findInt32("height", &height) ||
- !codecFormat->findInt32("stride", &stride) ||
- !codecFormat->findInt32("slice-height", &slice_height) ||
- !codecFormat->findInt32("color-format", &color_format) ||
- !codecFormat->findRect("crop", &crop_left, &crop_top, &crop_right, &crop_bottom)) {
- GVDM_LOG("Failed to find values");
- return false;
- }
- mFrameInfo.mWidth = width;
- mFrameInfo.mHeight = height;
- mFrameInfo.mStride = stride;
- mFrameInfo.mSliceHeight = slice_height;
- mFrameInfo.mColorFormat = color_format;
-
- nsIntSize displaySize(width, height);
- if (!IsValidVideoRegion(mConfig.mDisplay,
- mConfig.ScaledImageRect(width, height),
- displaySize)) {
- GVDM_LOG("It is not a valid region");
- return false;
- }
- return true;
- }
- GVDM_LOG("Fail to get output format");
- return false;
-}
-
-// Blocks until decoded sample is produced by the deoder.
-nsresult
-GonkVideoDecoderManager::Output(int64_t aStreamOffset,
- RefPtr<MediaData>& aOutData)
-{
- aOutData = nullptr;
- status_t err;
- if (mDecoder == nullptr) {
- GVDM_LOG("Decoder is not inited");
- return NS_ERROR_UNEXPECTED;
- }
- MediaBuffer* outputBuffer = nullptr;
- err = mDecoder->Output(&outputBuffer, READ_OUTPUT_BUFFER_TIMEOUT_US);
-
- switch (err) {
- case OK:
- {
- RefPtr<VideoData> data;
- nsresult rv = CreateVideoData(outputBuffer, aStreamOffset, getter_AddRefs(data));
- if (rv == NS_ERROR_NOT_AVAILABLE) {
- // Decoder outputs a empty video buffer, try again
- return NS_ERROR_NOT_AVAILABLE;
- } else if (rv != NS_OK || data == nullptr) {
- GVDM_LOG("Failed to create VideoData");
- return NS_ERROR_UNEXPECTED;
- }
- aOutData = data;
- return NS_OK;
- }
- case android::INFO_FORMAT_CHANGED:
- {
- // If the format changed, update our cached info.
- GVDM_LOG("Decoder format changed");
- if (!SetVideoFormat()) {
- return NS_ERROR_UNEXPECTED;
- }
- return Output(aStreamOffset, aOutData);
- }
- case android::INFO_OUTPUT_BUFFERS_CHANGED:
- {
- if (mDecoder->UpdateOutputBuffers()) {
- return Output(aStreamOffset, aOutData);
- }
- GVDM_LOG("Fails to update output buffers!");
- return NS_ERROR_FAILURE;
- }
- case -EAGAIN:
- {
-// GVDM_LOG("Need to try again!");
- return NS_ERROR_NOT_AVAILABLE;
- }
- case android::ERROR_END_OF_STREAM:
- {
- GVDM_LOG("Got the EOS frame!");
- RefPtr<VideoData> data;
- nsresult rv = CreateVideoData(outputBuffer, aStreamOffset, getter_AddRefs(data));
- if (rv == NS_ERROR_NOT_AVAILABLE) {
- // For EOS, no need to do any thing.
- return NS_ERROR_ABORT;
- }
- if (rv != NS_OK || data == nullptr) {
- GVDM_LOG("Failed to create video data");
- return NS_ERROR_UNEXPECTED;
- }
- aOutData = data;
- return NS_ERROR_ABORT;
- }
- case -ETIMEDOUT:
- {
- GVDM_LOG("Timeout. can try again next time");
- return NS_ERROR_UNEXPECTED;
- }
- default:
- {
- GVDM_LOG("Decoder failed, err=%d", err);
- return NS_ERROR_UNEXPECTED;
- }
- }
-
- return NS_OK;
-}
-
-void
-GonkVideoDecoderManager::codecReserved()
-{
- if (mInitPromise.IsEmpty()) {
- return;
- }
- GVDM_LOG("codecReserved");
- sp<AMessage> format = new AMessage;
- sp<Surface> surface;
- status_t rv = OK;
- // Fixed values
- GVDM_LOG("Configure video mime type: %s, width:%d, height:%d", mConfig.mMimeType.get(), mConfig.mImage.width, mConfig.mImage.height);
- format->setString("mime", mConfig.mMimeType.get());
- format->setInt32("width", mConfig.mImage.width);
- format->setInt32("height", mConfig.mImage.height);
- // Set the "moz-use-undequeued-bufs" to use the undeque buffers to accelerate
- // the video decoding.
- format->setInt32("moz-use-undequeued-bufs", 1);
- if (mNativeWindow != nullptr) {
-#if ANDROID_VERSION >= 21
- surface = new Surface(mGraphicBufferProducer);
-#else
- surface = new Surface(mNativeWindow->getBufferQueue());
-#endif
- }
- mDecoder->configure(format, surface, nullptr, 0);
- mDecoder->Prepare();
-
- if (mConfig.mMimeType.EqualsLiteral("video/mp4v-es")) {
- rv = mDecoder->Input(mConfig.mCodecSpecificConfig->Elements(),
- mConfig.mCodecSpecificConfig->Length(), 0,
- android::MediaCodec::BUFFER_FLAG_CODECCONFIG,
- CODECCONFIG_TIMEOUT_US);
- }
-
- if (rv != OK) {
- GVDM_LOG("Failed to configure codec!!!!");
- mInitPromise.Reject(NS_ERROR_DOM_MEDIA_FATAL_ERR, __func__);
- return;
- }
-
- mInitPromise.Resolve(TrackType::kVideoTrack, __func__);
-}
-
-void
-GonkVideoDecoderManager::codecCanceled()
-{
- GVDM_LOG("codecCanceled");
- mInitPromise.RejectIfExists(NS_ERROR_DOM_MEDIA_CANCELED, __func__);
-}
-
-// Called on GonkDecoderManager::mTaskLooper thread.
-void
-GonkVideoDecoderManager::onMessageReceived(const sp<AMessage> &aMessage)
-{
- switch (aMessage->what()) {
- case kNotifyPostReleaseBuffer:
- {
- ReleaseAllPendingVideoBuffers();
- break;
- }
-
- default:
- {
- GonkDecoderManager::onMessageReceived(aMessage);
- break;
- }
- }
-}
-
-uint8_t *
-GonkVideoDecoderManager::GetColorConverterBuffer(int32_t aWidth, int32_t aHeight)
-{
- // Allocate a temporary YUV420Planer buffer.
- size_t yuv420p_y_size = aWidth * aHeight;
- size_t yuv420p_u_size = ((aWidth + 1) / 2) * ((aHeight + 1) / 2);
- size_t yuv420p_v_size = yuv420p_u_size;
- size_t yuv420p_size = yuv420p_y_size + yuv420p_u_size + yuv420p_v_size;
- if (mColorConverterBufferSize != yuv420p_size) {
- mColorConverterBuffer = MakeUnique<uint8_t[]>(yuv420p_size);
- mColorConverterBufferSize = yuv420p_size;
- }
- return mColorConverterBuffer.get();
-}
-
-/* static */
-void
-GonkVideoDecoderManager::RecycleCallback(TextureClient* aClient, void* aClosure)
-{
- MOZ_ASSERT(aClient && !aClient->IsDead());
- GonkVideoDecoderManager* videoManager = static_cast<GonkVideoDecoderManager*>(aClosure);
- GrallocTextureData* client = static_cast<GrallocTextureData*>(aClient->GetInternalData());
- aClient->ClearRecycleCallback();
- FenceHandle handle = aClient->GetAndResetReleaseFenceHandle();
- videoManager->PostReleaseVideoBuffer(client->GetMediaBuffer(), handle);
-}
-
-void GonkVideoDecoderManager::PostReleaseVideoBuffer(
- android::MediaBuffer *aBuffer,
- FenceHandle aReleaseFence)
-{
- {
- MutexAutoLock autoLock(mPendingReleaseItemsLock);
- if (aBuffer) {
- mPendingReleaseItems.AppendElement(ReleaseItem(aBuffer, aReleaseFence));
- }
- }
- sp<AMessage> notify =
- new AMessage(kNotifyPostReleaseBuffer, id());
- notify->post();
-
-}
-
-void GonkVideoDecoderManager::ReleaseAllPendingVideoBuffers()
-{
- nsTArray<ReleaseItem> releasingItems;
- {
- MutexAutoLock autoLock(mPendingReleaseItemsLock);
- releasingItems.AppendElements(mPendingReleaseItems);
- mPendingReleaseItems.Clear();
- }
-
- // Free all pending video buffers without holding mPendingReleaseItemsLock.
- size_t size = releasingItems.Length();
- for (size_t i = 0; i < size; i++) {
- RefPtr<FenceHandle::FdObj> fdObj = releasingItems[i].mReleaseFence.GetAndResetFdObj();
- sp<Fence> fence = new Fence(fdObj->GetAndResetFd());
- fence->waitForever("GonkVideoDecoderManager");
- mDecoder->ReleaseMediaBuffer(releasingItems[i].mBuffer);
- }
- releasingItems.Clear();
-}
-
-} // namespace mozilla
diff --git a/dom/media/platforms/gonk/GonkVideoDecoderManager.h b/dom/media/platforms/gonk/GonkVideoDecoderManager.h
deleted file mode 100644
index 343bb2a5ce..0000000000
--- a/dom/media/platforms/gonk/GonkVideoDecoderManager.h
+++ /dev/null
@@ -1,149 +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(GonkVideoDecoderManager_h_)
-#define GonkVideoDecoderManager_h_
-
-#include "nsRect.h"
-#include "GonkMediaDataDecoder.h"
-#include "mozilla/RefPtr.h"
-#include "I420ColorConverterHelper.h"
-#include "MediaCodecProxy.h"
-#include "GonkNativeWindow.h"
-#include "mozilla/layers/FenceUtils.h"
-#include "mozilla/UniquePtr.h"
-#include <ui/Fence.h>
-
-using namespace android;
-
-namespace android {
-class MediaBuffer;
-struct MOZ_EXPORT AString;
-class GonkNativeWindow;
-} // namespace android
-
-namespace mozilla {
-
-namespace layers {
-class TextureClient;
-class TextureClientRecycleAllocator;
-} // namespace mozilla::layers
-
-class GonkVideoDecoderManager : public GonkDecoderManager {
-typedef android::MediaCodecProxy MediaCodecProxy;
-typedef mozilla::layers::TextureClient TextureClient;
-
-public:
- GonkVideoDecoderManager(mozilla::layers::ImageContainer* aImageContainer,
- const VideoInfo& aConfig);
-
- virtual ~GonkVideoDecoderManager();
-
- RefPtr<InitPromise> Init() override;
-
- nsresult Output(int64_t aStreamOffset,
- RefPtr<MediaData>& aOutput) override;
-
- nsresult Shutdown() override;
-
- const char* GetDescriptionName() const override
- {
- return "gonk video decoder";
- }
-
- static void RecycleCallback(TextureClient* aClient, void* aClosure);
-
-protected:
- // Bug 1199809: workaround to avoid sending the graphic buffer by making a
- // copy of output buffer after calling flush(). Bug 1203859 was created to
- // reimplementing Gonk PDM on top of OpenMax IL directly. Its buffer
- // management will work better with Gecko and solve problems like this.
- void ProcessFlush() override
- {
- mNeedsCopyBuffer = true;
- GonkDecoderManager::ProcessFlush();
- }
-
-private:
- struct FrameInfo
- {
- int32_t mWidth = 0;
- int32_t mHeight = 0;
- int32_t mStride = 0;
- int32_t mSliceHeight = 0;
- int32_t mColorFormat = 0;
- int32_t mCropLeft = 0;
- int32_t mCropTop = 0;
- int32_t mCropRight = 0;
- int32_t mCropBottom = 0;
- };
-
- void onMessageReceived(const android::sp<android::AMessage> &aMessage) override;
-
- bool SetVideoFormat();
-
- nsresult CreateVideoData(MediaBuffer* aBuffer, int64_t aStreamOffset, VideoData** aOutData);
- already_AddRefed<VideoData> CreateVideoDataFromGraphicBuffer(android::MediaBuffer* aSource,
- gfx::IntRect& aPicture);
- already_AddRefed<VideoData> CreateVideoDataFromDataBuffer(android::MediaBuffer* aSource,
- gfx::IntRect& aPicture);
-
- uint8_t* GetColorConverterBuffer(int32_t aWidth, int32_t aHeight);
-
- // For codec resource management
- void codecReserved();
- void codecCanceled();
-
- void ReleaseAllPendingVideoBuffers();
- void PostReleaseVideoBuffer(android::MediaBuffer *aBuffer,
- layers::FenceHandle mReleaseFence);
-
- VideoInfo mConfig;
-
- RefPtr<layers::ImageContainer> mImageContainer;
- RefPtr<layers::TextureClientRecycleAllocator> mCopyAllocator;
-
- MozPromiseRequestHolder<android::MediaCodecProxy::CodecPromise> mVideoCodecRequest;
- FrameInfo mFrameInfo;
-
- // color converter
- android::I420ColorConverterHelper mColorConverter;
- UniquePtr<uint8_t[]> mColorConverterBuffer;
- size_t mColorConverterBufferSize;
-
- android::sp<android::GonkNativeWindow> mNativeWindow;
-#if ANDROID_VERSION >= 21
- android::sp<android::IGraphicBufferProducer> mGraphicBufferProducer;
-#endif
-
- enum {
- kNotifyPostReleaseBuffer = 'nprb',
- };
-
- struct ReleaseItem {
- ReleaseItem(android::MediaBuffer* aBuffer, layers::FenceHandle& aFence)
- : mBuffer(aBuffer)
- , mReleaseFence(aFence) {}
- android::MediaBuffer* mBuffer;
- layers::FenceHandle mReleaseFence;
- };
- nsTArray<ReleaseItem> mPendingReleaseItems;
-
- // The lock protects mPendingReleaseItems.
- Mutex mPendingReleaseItemsLock;
-
- // This TaskQueue should be the same one in mDecodeCallback->OnReaderTaskQueue().
- // It is for codec resource mangement, decoding task should not dispatch to it.
- RefPtr<TaskQueue> mReaderTaskQueue;
-
- // Bug 1199809: do we need to make a copy of output buffer? Used only when
- // the decoder outputs graphic buffers.
- bool mNeedsCopyBuffer;
-};
-
-} // namespace mozilla
-
-#endif // GonkVideoDecoderManager_h_
diff --git a/dom/media/platforms/gonk/moz.build b/dom/media/platforms/gonk/moz.build
deleted file mode 100644
index 014594977c..0000000000
--- a/dom/media/platforms/gonk/moz.build
+++ /dev/null
@@ -1,39 +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 += [
- 'GonkAudioDecoderManager.h',
- 'GonkDecoderModule.h',
- 'GonkMediaDataDecoder.h',
- 'GonkVideoDecoderManager.h',
-]
-UNIFIED_SOURCES += [
- 'GonkAudioDecoderManager.cpp',
- 'GonkDecoderModule.cpp',
- 'GonkMediaDataDecoder.cpp',
- 'GonkVideoDecoderManager.cpp',
-]
-LOCAL_INCLUDES += [
- '/dom/media/omx/',
-]
-include('/ipc/chromium/chromium-config.mozbuild')
-
-# 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'
- ]
-
-FINAL_LIBRARY = 'xul'
-
-LOCAL_INCLUDES += [
- '%' + '%s/%s' % (CONFIG['ANDROID_SOURCE'], d) for d in [
- 'frameworks/native/opengl/include',]
-]
diff --git a/dom/media/platforms/moz.build b/dom/media/platforms/moz.build
index 310820c912..3fb0cc842a 100644
--- a/dom/media/platforms/moz.build
+++ b/dom/media/platforms/moz.build
@@ -70,10 +70,6 @@ if CONFIG['MOZ_APPLEMEDIA']:
'-framework AudioToolbox',
]
-if CONFIG['MOZ_GONK_MEDIACODEC']:
- DEFINES['MOZ_GONK_MEDIACODEC'] = True
- DIRS += ['gonk']
-
include('/ipc/chromium/chromium-config.mozbuild')
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'android':
diff --git a/dom/secureelement/SEUtils.jsm b/dom/secureelement/SEUtils.jsm
deleted file mode 100644
index d5980b19cc..0000000000
--- a/dom/secureelement/SEUtils.jsm
+++ /dev/null
@@ -1,116 +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/. */
-
-/* Copyright © 2015, Deutsche Telekom, Inc. */
-
-"use strict";
-
-this.SEUtils = {
- byteArrayToHexString: function byteArrayToHexString(array) {
- let hexStr = "";
-
- let len = array ? array.length : 0;
- for (let i = 0; i < len; i++) {
- let hex = (array[i] & 0xff).toString(16);
- hex = (hex.length === 1) ? "0" + hex : hex;
- hexStr += hex;
- }
-
- return hexStr.toUpperCase();
- },
-
- hexStringToByteArray: function hexStringToByteArray(hexStr) {
- if (typeof hexStr !== "string" || hexStr.length % 2 !== 0) {
- return [];
- }
-
- let array = [];
- for (let i = 0, len = hexStr.length; i < len; i += 2) {
- array.push(parseInt(hexStr.substr(i, 2), 16));
- }
-
- return array;
- },
-
- arraysEqual: function arraysEqual(a1, a2) {
- if (!a1 || !a2) {
- return false;
- }
-
- if (a1.length !== a2.length) {
- return false;
- }
-
- for (let i = 0, len = a1.length; i < len; i++) {
- if (a1[i] !== a2[i]) {
- return false;
- }
- }
-
- return true;
- },
-
- ensureIsArray: function ensureIsArray(obj) {
- return Array.isArray(obj) ? obj : [obj];
- },
-
- /**
- * parseTLV is intended primarily to be used to parse Global Platform Device
- * Technology secure element access control data.
- *
- * The parsed result value is an internal format only.
- *
- * All tags will be treated as simple Tag Length Values (TLV), (i.e. with a
- * plain value, not subject to further unpacking), unless those tags are
- * listed in the containerTags array.
- *
- * @param bytes - byte array
- * @param containerTags - byte array of tags
- */
- parseTLV: function parseTLV(bytes, containerTags) {
- let result = {};
-
- if (typeof bytes === "string") {
- bytes = this.hexStringToByteArray(bytes);
- }
-
- if (!Array.isArray(bytes)) {
- debug("Passed value is not an array nor a string.");
- return null;
- }
-
- for (let pos = 0; pos < bytes.length; ) {
- let tag = bytes[pos],
- length = bytes[pos + 1],
- value = bytes.slice(pos + 2, pos + 2 + length),
- parsed = null;
-
- // Support for 0xFF padded files (GPD 7.1.2)
- if (tag === 0xFF) {
- break;
- }
-
- if (containerTags.indexOf(tag) >= 0) {
- parsed = this.parseTLV(value, containerTags);
- } else {
- parsed = value;
- }
-
- // Internal parsed format.
- if (!result[tag]) {
- result[tag] = parsed;
- } else if (Array.isArray(result[tag])) {
- result[tag].push(parsed);
- } else {
- result[tag] = [result[tag], parsed];
- }
-
- pos = pos + 2 + length;
- }
-
- return result;
- }
-};
-
-this.EXPORTED_SYMBOLS = ["SEUtils"];
diff --git a/dom/secureelement/gonk/ACEService.js b/dom/secureelement/gonk/ACEService.js
deleted file mode 100644
index b52ba5faba..0000000000
--- a/dom/secureelement/gonk/ACEService.js
+++ /dev/null
@@ -1,139 +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/. */
-
-/* Copyright © 2015, Deutsche Telekom, Inc. */
-
-"use strict";
-
-const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-Cu.import("resource://gre/modules/Promise.jsm");
-Cu.import("resource://gre/modules/Services.jsm");
-
-XPCOMUtils.defineLazyModuleGetter(this, "SEUtils",
- "resource://gre/modules/SEUtils.jsm");
-
-XPCOMUtils.defineLazyGetter(this, "SE", function() {
- let obj = {};
- Cu.import("resource://gre/modules/se_consts.js", obj);
- return obj;
-});
-
-var DEBUG = SE.DEBUG_ACE;
-function debug(msg) {
- if (DEBUG) {
- dump("ACEservice: " + msg + "\n");
- }
-}
-
-/**
- * Implements decision making algorithm as described in GPD specification,
- * mostly in 3.1, 3.2 and 4.2.3.
- *
- * TODO: Bug 1137533: Implement GPAccessRulesManager APDU filters
- */
-function GPAccessDecision(rules, certHash, aid) {
- this.rules = rules;
- this.certHash = certHash;
- this.aid = aid;
-}
-
-GPAccessDecision.prototype = {
- isAccessAllowed: function isAccessAllowed() {
- // GPD SE Access Control v1.1, 3.4.1, Table 3-2: (Conflict resolution)
- // If a specific rule allows, all other non-specific access is denied.
- // Conflicting specific rules will resolve to the first Allowed == "true"
- // match. Given no specific rule, the global "All" rules will determine
- // access. "Some", skips further processing if access Allowed == "true".
- //
- // Access must be decided before the SE connector openChannel, and the
- // exchangeAPDU call.
- //
- // NOTE: This implementation may change with the introduction of APDU
- // filters.
- let decision = this.rules.some(this._decideAppAccess.bind(this));
- return decision;
- },
-
- _decideAppAccess: function _decideAppAccess(rule) {
- let appMatched, appletMatched;
-
- // GPD SE AC 4.2.3: Algorithm for Applying Rules
- // Specific rule overrides global rule.
- //
- // DeviceAppID is the application hash, and the AID is SE Applet ID:
- //
- // GPD SE AC 4.2.3 A:
- // SearchRuleFor(DeviceAppID, AID)
- // GPD SE AC 4.2.3 B: If no rule fits A:
- // SearchRuleFor(<AllDeviceApplications>, AID)
- // GPD SE AC 4.2.3 C: If no rule fits A or B:
- // SearchRuleFor(DeviceAppID, <AllSEApplications>)
- // GPD SE AC 4.2.3 D: If no rule fits A, B, or C:
- // SearchRuleFor(<AllDeviceApplications>, <AllSEApplications>)
-
- // Device App
- appMatched = Array.isArray(rule.application) ?
- // GPD SE AC 4.2.3 A and 4.2.3 C (DeviceAppID rule)
- this._appCertHashMatches(rule.application) :
- // GPD SE AC 4.2.3 B and 4.2.3 D (All Device Applications)
- rule.application === Ci.nsIAccessRulesManager.ALLOW_ALL;
-
- if (!appMatched) {
- return false; // bail out early.
- }
-
- // SE Applet
- appletMatched = Array.isArray(rule.applet) ?
- // GPD SE AC 4.2.3 A and 4.2.3 B (AID rule)
- SEUtils.arraysEqual(rule.applet, this.aid) :
- // GPD SE AC 4.2.3 C and 4.2.3 D (All AID)
- rule.applet === Ci.nsIAccessRulesManager.ALL_APPLET;
-
- return appletMatched;
- },
-
- _appCertHashMatches: function _appCertHashMatches(hashArray) {
- if (!Array.isArray(hashArray)) {
- return false;
- }
-
- return !!(hashArray.find((hash) => {
- return SEUtils.arraysEqual(hash, this.certHash);
- }));
- }
-};
-
-function ACEService() {
- this._rulesManagers = new Map();
-
- this._rulesManagers.set(
- SE.TYPE_UICC,
- Cc["@mozilla.org/secureelement/access-control/rules-manager;1"]
- .createInstance(Ci.nsIAccessRulesManager));
-}
-
-ACEService.prototype = {
- _rulesManagers: null,
-
- isAccessAllowed: function isAccessAllowed(localId, seType, aid) {
- if(!Services.prefs.getBoolPref("devtools.debugger.forbid-certified-apps")) {
- debug("Certified apps debug enabled, allowing access");
- return Promise.resolve(true);
- }
-
- throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
- },
-
- _getDevCertHashForApp: function getDevCertHashForApp(manifestURL) {
- throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
- },
-
- classID: Components.ID("{882a7463-2ca7-4d61-a89a-10eb6fd70478}"),
- contractID: "@mozilla.org/secureelement/access-control/ace;1",
- QueryInterface: XPCOMUtils.generateQI([Ci.nsIAccessControlEnforcer])
-};
-
-this.NSGetFactory = XPCOMUtils.generateNSGetFactory([ACEService]);
-
diff --git a/dom/secureelement/gonk/ACEService.manifest b/dom/secureelement/gonk/ACEService.manifest
deleted file mode 100644
index 40949c83d9..0000000000
--- a/dom/secureelement/gonk/ACEService.manifest
+++ /dev/null
@@ -1,2 +0,0 @@
-component {882a7463-2ca7-4d61-a89a-10eb6fd70478} ACEService.js
-contract @mozilla.org/secureelement/access-control/ace;1 {882a7463-2ca7-4d61-a89a-10eb6fd70478} \ No newline at end of file
diff --git a/dom/secureelement/gonk/GPAccessRulesManager.js b/dom/secureelement/gonk/GPAccessRulesManager.js
deleted file mode 100644
index dce11ec096..0000000000
--- a/dom/secureelement/gonk/GPAccessRulesManager.js
+++ /dev/null
@@ -1,436 +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/. */
-
-/* Copyright © 2015, Deutsche Telekom, Inc. */
-
-"use strict";
-
-const Ci = Components.interfaces;
-const Cu = Components.utils;
-
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-Cu.import("resource://gre/modules/Promise.jsm");
-Cu.import("resource://gre/modules/Task.jsm");
-Cu.import("resource://gre/modules/systemlibs.js");
-
-XPCOMUtils.defineLazyServiceGetter(this, "UiccConnector",
- "@mozilla.org/secureelement/connector/uicc;1",
- "nsISecureElementConnector");
-
-XPCOMUtils.defineLazyModuleGetter(this, "SEUtils",
- "resource://gre/modules/SEUtils.jsm");
-
-XPCOMUtils.defineLazyGetter(this, "SE", function() {
- let obj = {};
- Cu.import("resource://gre/modules/se_consts.js", obj);
- return obj;
-});
-
-XPCOMUtils.defineLazyGetter(this, "GP", function() {
- let obj = {};
- Cu.import("resource://gre/modules/gp_consts.js", obj);
- return obj;
-});
-
-var DEBUG = SE.DEBUG_ACE;
-function debug(msg) {
- if (DEBUG) {
- dump("-*- GPAccessRulesManager " + msg);
- }
-}
-
-/**
- * Based on [1] - "GlobalPlatform Device Technology
- * Secure Element Access Control Version 1.0".
- * GPAccessRulesManager reads and parses access rules from SE file system
- * as defined in section #7 of [1]: "Structure of Access Rule Files (ARF)".
- * Rules retrieval from ARA-M applet is not implmented due to lack of
- * commercial implemenations of ARA-M.
- * @todo Bug 1137537: Implement ARA-M support according to section #4 of [1]
- */
-function GPAccessRulesManager() {}
-
-GPAccessRulesManager.prototype = {
- // source [1] section 7.1.3 PKCS#15 Selection
- PKCS_AID: "a000000063504b43532d3135",
-
- // APDUs (ISO 7816-4) for accessing rules on SE file system
- // see for more details: http://www.cardwerk.com/smartcards/
- // smartcard_standard_ISO7816-4_6_basic_interindustry_commands.aspx
- READ_BINARY: [GP.CLA_SM, GP.INS_RB, GP.P1_RB, GP.P2_RB],
- GET_RESPONSE: [GP.CLA_SM, GP.INS_GR, GP.P1_GR, GP.P2_GR],
- SELECT_BY_DF: [GP.CLA_SM, GP.INS_SF, GP.P1_SF_DF, GP.P2_SF_FCP],
-
- // Non-null if there is a channel open
- channel: null,
-
- // Refresh tag path in the acMain file as described in GPD spec,
- // sections 7.1.5 and C.1.
- REFRESH_TAG_PATH: [GP.TAG_SEQUENCE, GP.TAG_OCTETSTRING],
- refreshTag: null,
-
- // Contains rules as read from the SE
- rules: [],
-
- // Returns the latest rules. Results are cached.
- getAccessRules: function getAccessRules() {
- debug("getAccessRules");
-
- return new Promise((resolve, reject) => {
- this._readAccessRules(() => resolve(this.rules));
- });
- },
-
- _readAccessRules: Task.async(function*(done) {
- try {
- yield this._openChannel(this.PKCS_AID);
-
- let odf = yield this._readODF();
- let dodf = yield this._readDODF(odf);
-
- let acmf = yield this._readACMF(dodf);
- let refreshTag = acmf[this.REFRESH_TAG_PATH[0]]
- [this.REFRESH_TAG_PATH[1]];
-
- // Update cached rules based on refreshTag.
- if (SEUtils.arraysEqual(this.refreshTag, refreshTag)) {
- debug("_readAccessRules: refresh tag equals to the one saved.");
- yield this._closeChannel();
- return done();
- }
-
- this.refreshTag = refreshTag;
- debug("_readAccessRules: refresh tag saved: " + this.refreshTag);
-
- let acrf = yield this._readACRules(acmf);
- let accf = yield this._readACConditions(acrf);
- this.rules = yield this._parseRules(acrf, accf);
-
- DEBUG && debug("_readAccessRules: " + JSON.stringify(this.rules, 0, 2));
-
- yield this._closeChannel();
- done();
- } catch (error) {
- debug("_readAccessRules: " + error);
- this.rules = [];
- yield this._closeChannel();
- done();
- }
- }),
-
- _openChannel: function _openChannel(aid) {
- if (this.channel !== null) {
- debug("_openChannel: Channel already opened, rejecting.");
- return Promise.reject();
- }
-
- return new Promise((resolve, reject) => {
- UiccConnector.openChannel(aid, {
- notifyOpenChannelSuccess: (channel, openResponse) => {
- debug("_openChannel/notifyOpenChannelSuccess: Channel " + channel +
- " opened, open response: " + openResponse);
- this.channel = channel;
- resolve();
- },
- notifyError: (error) => {
- debug("_openChannel/notifyError: failed to open channel, error: " +
- error);
- reject(error);
- }
- });
- });
- },
-
- _closeChannel: function _closeChannel() {
- if (this.channel === null) {
- debug("_closeChannel: Channel not opened, rejecting.");
- return Promise.reject();
- }
-
- return new Promise((resolve, reject) => {
- UiccConnector.closeChannel(this.channel, {
- notifyCloseChannelSuccess: () => {
- debug("_closeChannel/notifyCloseChannelSuccess: chanel " +
- this.channel + " closed");
- this.channel = null;
- resolve();
- },
- notifyError: (error) => {
- debug("_closeChannel/notifyError: error closing channel, error" +
- error);
- reject(error);
- }
- });
- });
- },
-
- _exchangeAPDU: function _exchangeAPDU(bytes) {
- DEBUG && debug("apdu " + JSON.stringify(bytes));
-
- let apdu = this._bytesToAPDU(bytes);
- return new Promise((resolve, reject) => {
- UiccConnector.exchangeAPDU(this.channel, apdu.cla,
- apdu.ins, apdu.p1, apdu.p2, apdu.data, apdu.le,
- {
- notifyExchangeAPDUResponse: (sw1, sw2, data) => {
- debug("APDU response is " + sw1.toString(16) + sw2.toString(16) +
- " data: " + data);
-
- // 90 00 is "success"
- if (sw1 !== 0x90 && sw2 !== 0x00) {
- debug("rejecting APDU response");
- reject(new Error("Response " + sw1 + "," + sw2));
- return;
- }
-
- resolve(this._parseTLV(data));
- },
-
- notifyError: (error) => {
- debug("_exchangeAPDU/notifyError " + error);
- reject(error);
- }
- }
- );
- });
- },
-
- _readBinaryFile: function _readBinaryFile(selectResponse) {
- DEBUG && debug("Select response: " + JSON.stringify(selectResponse));
- // 0x80 tag parameter - get the elementary file (EF) length
- // without structural information.
- let fileLength = selectResponse[GP.TAG_FCP][0x80];
-
- // If file is empty, no need to attempt to read it.
- if (fileLength[0] === 0 && fileLength[1] === 0) {
- return Promise.resolve(null);
- }
-
- // TODO READ BINARY with filelength not supported
- // let readApdu = this.READ_BINARY.concat(fileLength);
- return this._exchangeAPDU(this.READ_BINARY);
- },
-
- _selectAndRead: function _selectAndRead(df) {
- return this._exchangeAPDU(this.SELECT_BY_DF.concat(df.length & 0xFF, df))
- .then((resp) => this._readBinaryFile(resp));
- },
-
- _readODF: function _readODF() {
- debug("_readODF");
- return this._selectAndRead(GP.ODF_DF);
- },
-
- _readDODF: function _readDODF(odfFile) {
- debug("_readDODF, ODF file: " + odfFile);
-
- // Data Object Directory File (DODF) is used as an entry point to the
- // Access Control data. It is specified in PKCS#15 section 6.7.6.
- // DODF is referenced by the ODF file, which looks as follows:
- // A7 06
- // 30 04
- // 04 02 XY WZ
- // where [0xXY, 0xWZ] is a DF of DODF file.
- let DODF_DF = odfFile[GP.TAG_EF_ODF][GP.TAG_SEQUENCE][GP.TAG_OCTETSTRING];
- return this._selectAndRead(DODF_DF);
- },
-
- _readACMF: function _readACMF(dodfFile) {
- debug("_readACMF, DODF file: " + dodfFile);
-
- // ACMF file DF is referenced in DODF file, which looks like this:
- //
- // A1 29
- // 30 00
- // 30 0F
- // 0C 0D 47 50 20 53 45 20 41 63 63 20 43 74 6C
- // A1 14
- // 30 12
- // 06 0A 2A 86 48 86 FC 6B 81 48 01 01 <-- GPD registered OID
- // 30 04
- // 04 02 AB CD <-- ACMF DF
- // A1 2B
- // 30 00
- // 30 0F
- // 0C 0D 53 41 54 53 41 20 47 54 4F 20 31 2E 31
- // A1 16
- // 30 14
- // 06 0C 2B 06 01 04 01 2A 02 6E 03 01 01 01 <-- some other OID
- // 30 04
- // 04 02 XY WZ <-- some other file's DF
- //
- // DODF file consists of DataTypes with oidDO entries. Entry with OID
- // equal to "1.2.840.114283.200.1.1" ("2A 86 48 86 FC 6B 81 48 01 01")
- // contains DF of the ACMF. In the file above, it means that ACMF DF
- // equals to [0xAB, 0xCD], and not [0xXY, 0xWZ].
- //
- // Algorithm used to encode OID to an byte array:
- // http://www.snmpsharpnet.com/?p=153
-
- let gpdOid = [0x2A, // 1.2
- 0x86, 0x48, // 840
- 0x86, 0xFC, 0x6B, // 114283
- 0x81, 0x48, // 129
- 0x01, // 1
- 0x01]; // 1
-
- let records = SEUtils.ensureIsArray(dodfFile[GP.TAG_EXTERNALDO]);
-
- // Look for the OID registered for GPD SE.
- let gpdRecords = records.filter((record) => {
- let oid = record[GP.TAG_EXTERNALDO][GP.TAG_SEQUENCE][GP.TAG_OID];
- return SEUtils.arraysEqual(oid, gpdOid);
- });
-
- // [1] 7.1.5: "There shall be only one ACMF file per Secure Element.
- // If a Secure Element contains several ACMF files, then the security shall
- // be considered compromised and the Access Control enforcer shall forbid
- // access to all (...) apps."
- if (gpdRecords.length !== 1) {
- return Promise.reject(new Error(gpdRecords.length + " ACMF files found"));
- }
-
- let ACMain_DF = gpdRecords[0][GP.TAG_EXTERNALDO][GP.TAG_SEQUENCE]
- [GP.TAG_SEQUENCE][GP.TAG_OCTETSTRING];
- return this._selectAndRead(ACMain_DF);
- },
-
- _readACRules: function _readACRules(acMainFile) {
- debug("_readACRules, ACMain file: " + acMainFile);
-
- // ACMF looks like this:
- //
- // 30 10
- // 04 08 XX XX XX XX XX XX XX XX
- // 30 04
- // 04 02 XY WZ
- //
- // where [XY, WZ] is a DF of ACRF, and XX XX XX XX XX XX XX XX is a refresh
- // tag.
-
- let ACRules_DF = acMainFile[GP.TAG_SEQUENCE][GP.TAG_SEQUENCE][GP.TAG_OCTETSTRING];
- return this._selectAndRead(ACRules_DF);
- },
-
- _readACConditions: function _readACConditions(acRulesFile) {
- debug("_readACCondition, ACRules file: " + acRulesFile);
-
- let acRules = SEUtils.ensureIsArray(acRulesFile[GP.TAG_SEQUENCE]);
- if (acRules.length === 0) {
- debug("No rules found in ACRules file.");
- return Promise.reject(new Error("No rules found in ACRules file"));
- }
-
- // We first read all the condition files referenced in the ACRules file,
- // because ACRules file might reference one ACCondition file more than
- // once. Since reading it isn't exactly fast, we optimize here.
- let acReadQueue = Promise.resolve({});
-
- acRules.forEach((ruleEntry) => {
- let df = ruleEntry[GP.TAG_SEQUENCE][GP.TAG_OCTETSTRING];
-
- // Promise chain read condition entries:
- let readAcCondition = (acConditionFiles) => {
- if (acConditionFiles[df] !== undefined) {
- debug("Skipping previously read acCondition df: " + df);
- return acConditionFiles;
- }
-
- return this._selectAndRead(df)
- .then((acConditionFileContents) => {
- acConditionFiles[df] = acConditionFileContents;
- return acConditionFiles;
- });
- }
-
- acReadQueue = acReadQueue.then(readAcCondition);
- });
-
- return acReadQueue;
- },
-
- _parseRules: function _parseRules(acRulesFile, acConditionFiles) {
- DEBUG && debug("_parseRules: acConditionFiles " + JSON.stringify(acConditionFiles));
- let rules = [];
-
- let acRules = SEUtils.ensureIsArray(acRulesFile[GP.TAG_SEQUENCE]);
- acRules.forEach((ruleEntry) => {
- DEBUG && debug("Parsing one rule: " + JSON.stringify(ruleEntry));
- let rule = {};
-
- // 0xA0 and 0x82 tags as per GPD spec sections C.1 - C.3. 0xA0 means
- // that rule describes access to one SE applet only (and its AID is
- // given). 0x82 means that rule describes acccess to all SE applets.
- let oneApplet = ruleEntry[GP.TAG_GPD_AID];
- let allApplets = ruleEntry[GP.TAG_GPD_ALL];
-
- if (oneApplet) {
- rule.applet = oneApplet[GP.TAG_OCTETSTRING];
- } else if (allApplets) {
- rule.applet = Ci.nsIAccessRulesManager.ALL_APPLET;
- } else {
- throw Error("Unknown applet definition");
- }
-
- let df = ruleEntry[GP.TAG_SEQUENCE][GP.TAG_OCTETSTRING];
- let condition = acConditionFiles[df];
- if (condition === null) {
- rule.application = Ci.nsIAccessRulesManager.DENY_ALL;
- } else if (condition[GP.TAG_SEQUENCE]) {
- if (!Array.isArray(condition[GP.TAG_SEQUENCE]) &&
- !condition[GP.TAG_SEQUENCE][GP.TAG_OCTETSTRING]) {
- rule.application = Ci.nsIAccessRulesManager.ALLOW_ALL;
- } else {
- rule.application = SEUtils.ensureIsArray(condition[GP.TAG_SEQUENCE])
- .map((conditionEntry) => {
- return conditionEntry[GP.TAG_OCTETSTRING];
- });
- }
- } else {
- throw Error("Unknown application definition");
- }
-
- DEBUG && debug("Rule parsed, adding to the list: " + JSON.stringify(rule));
- rules.push(rule);
- });
-
- DEBUG && debug("All rules parsed, we have those in total: " + JSON.stringify(rules));
- return rules;
- },
-
- _parseTLV: function _parseTLV(bytes) {
- let containerTags = [
- GP.TAG_SEQUENCE,
- GP.TAG_FCP,
- GP.TAG_GPD_AID,
- GP.TAG_EXTERNALDO,
- GP.TAG_INDIRECT,
- GP.TAG_EF_ODF
- ];
- return SEUtils.parseTLV(bytes, containerTags);
- },
-
- // TODO consider removing if better format for storing
- // APDU consts will be introduced
- _bytesToAPDU: function _bytesToAPDU(arr) {
- let apdu = {
- cla: arr[0] & 0xFF,
- ins: arr[1] & 0xFF,
- p1: arr[2] & 0xFF,
- p2: arr[3] & 0xFF,
- p3: arr[4] & 0xFF,
- le: 0
- };
-
- let data = (apdu.p3 > 0) ? (arr.slice(5)) : [];
- apdu.data = (data.length) ? SEUtils.byteArrayToHexString(data) : null;
- return apdu;
- },
-
- classID: Components.ID("{3e046b4b-9e66-439a-97e0-98a69f39f55f}"),
- contractID: "@mozilla.org/secureelement/access-control/rules-manager;1",
- QueryInterface: XPCOMUtils.generateQI([Ci.nsIAccessRulesManager])
-};
-
-this.NSGetFactory = XPCOMUtils.generateNSGetFactory([GPAccessRulesManager]);
diff --git a/dom/secureelement/gonk/GPAccessRulesManager.manifest b/dom/secureelement/gonk/GPAccessRulesManager.manifest
deleted file mode 100644
index 2d7ea038b1..0000000000
--- a/dom/secureelement/gonk/GPAccessRulesManager.manifest
+++ /dev/null
@@ -1,2 +0,0 @@
-component {3e046b4b-9e66-439a-97e0-98a69f39f55f} GPAccessRulesManager.js
-contract @mozilla.org/secureelement/access-control/rules-manager;1 {3e046b4b-9e66-439a-97e0-98a69f39f55f}
diff --git a/dom/secureelement/gonk/SecureElement.js b/dom/secureelement/gonk/SecureElement.js
deleted file mode 100644
index 144c6d8d6e..0000000000
--- a/dom/secureelement/gonk/SecureElement.js
+++ /dev/null
@@ -1,514 +0,0 @@
-/* Copyright 2012 Mozilla Foundation and Mozilla contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* Copyright © 2014, Deutsche Telekom, Inc. */
-
-"use strict";
-
-/* globals dump, Components, XPCOMUtils, SE, Services, UiccConnector,
- SEUtils, ppmm, gMap, UUIDGenerator */
-
-const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
-
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-Cu.import("resource://gre/modules/Services.jsm");
-Cu.import("resource://gre/modules/systemlibs.js");
-
-XPCOMUtils.defineLazyGetter(this, "SE", () => {
- let obj = {};
- Cu.import("resource://gre/modules/se_consts.js", obj);
- return obj;
-});
-
-// set to true in se_consts.js to see debug messages
-var DEBUG = SE.DEBUG_SE;
-function debug(s) {
- if (DEBUG) {
- dump("-*- SecureElement: " + s + "\n");
- }
-}
-
-const SE_IPC_SECUREELEMENT_MSG_NAMES = [
- "SE:GetSEReaders",
- "SE:OpenChannel",
- "SE:CloseChannel",
- "SE:TransmitAPDU"
-];
-
-const SECUREELEMENTMANAGER_CONTRACTID =
- "@mozilla.org/secureelement/parent-manager;1";
-const SECUREELEMENTMANAGER_CID =
- Components.ID("{48f4e650-28d2-11e4-8c21-0800200c9a66}");
-const NS_XPCOM_SHUTDOWN_OBSERVER_ID = "xpcom-shutdown";
-
-XPCOMUtils.defineLazyServiceGetter(this, "ppmm",
- "@mozilla.org/parentprocessmessagemanager;1",
- "nsIMessageBroadcaster");
-
-XPCOMUtils.defineLazyServiceGetter(this, "UUIDGenerator",
- "@mozilla.org/uuid-generator;1",
- "nsIUUIDGenerator");
-
-XPCOMUtils.defineLazyModuleGetter(this, "SEUtils",
- "resource://gre/modules/SEUtils.jsm");
-
-XPCOMUtils.defineLazyGetter(this, "UiccConnector", () => {
- let uiccClass = Cc["@mozilla.org/secureelement/connector/uicc;1"];
- return uiccClass ? uiccClass.getService(Ci.nsISecureElementConnector) : null;
-});
-
-function getConnector(type) {
- switch (type) {
- case SE.TYPE_UICC:
- return UiccConnector;
- case SE.TYPE_ESE:
- default:
- debug("Unsupported SEConnector : " + type);
- return null;
- }
-}
-
-/**
- * 'gMap' is a nested dictionary object that manages all the information
- * pertaining to channels for a given application (appId). It manages the
- * relationship between given application and its opened channels.
- */
-XPCOMUtils.defineLazyGetter(this, "gMap", function() {
- return {
- // example structure of AppInfoMap
- // {
- // "appId1": {
- // target: target1,
- // channels: {
- // "channelToken1": {
- // seType: "uicc",
- // aid: "aid1",
- // channelNumber: 1
- // },
- // "channelToken2": { ... }
- // }
- // },
- // "appId2": { ... }
- // }
- appInfoMap: {},
-
- registerSecureElementTarget: function(appId, target) {
- if (this.isAppIdRegistered(appId)) {
- debug("AppId: " + appId + "already registered");
- return;
- }
-
- this.appInfoMap[appId] = {
- target: target,
- channels: {}
- };
-
- debug("Registered a new SE target " + appId);
- },
-
- unregisterSecureElementTarget: function(target) {
- let appId = Object.keys(this.appInfoMap).find((id) => {
- return this.appInfoMap[id].target === target;
- });
-
- if (!appId) {
- return;
- }
-
- debug("Unregistered SE Target for AppId: " + appId);
- delete this.appInfoMap[appId];
- },
-
- isAppIdRegistered: function(appId) {
- return this.appInfoMap[appId] !== undefined;
- },
-
- getChannelCountByAppIdType: function(appId, type) {
- return Object.keys(this.appInfoMap[appId].channels)
- .reduce((cnt, ch) => ch.type === type ? ++cnt : cnt, 0);
- },
-
- // Add channel to the appId. Upon successfully adding the entry
- // this function will return the 'token'
- addChannel: function(appId, type, aid, channelNumber) {
- let token = UUIDGenerator.generateUUID().toString();
- this.appInfoMap[appId].channels[token] = {
- seType: type,
- aid: aid,
- channelNumber: channelNumber
- };
- return token;
- },
-
- removeChannel: function(appId, channelToken) {
- if (this.appInfoMap[appId].channels[channelToken]) {
- debug("Deleting channel with token : " + channelToken);
- delete this.appInfoMap[appId].channels[channelToken];
- }
- },
-
- getChannel: function(appId, channelToken) {
- if (!this.appInfoMap[appId].channels[channelToken]) {
- return null;
- }
-
- return this.appInfoMap[appId].channels[channelToken];
- },
-
- getChannelsByTarget: function(target) {
- let appId = Object.keys(this.appInfoMap).find((id) => {
- return this.appInfoMap[id].target === target;
- });
-
- if (!appId) {
- return [];
- }
-
- return Object.keys(this.appInfoMap[appId].channels)
- .map(token => this.appInfoMap[appId].channels[token]);
- },
-
- getTargets: function() {
- return Object.keys(this.appInfoMap)
- .map(appId => this.appInfoMap[appId].target);
- },
- };
-});
-
-/**
- * 'SecureElementManager' is the main object that handles IPC messages from
- * child process. It interacts with other objects such as 'gMap' & 'Connector
- * instances (UiccConnector, eSEConnector)' to perform various
- * SE-related (open, close, transmit) operations.
- * @TODO: Bug 1118097 Support slot based SE/reader names
- * @TODO: Bug 1118101 Introduce SE type specific permissions
- */
-function SecureElementManager() {
- this._registerMessageListeners();
- this._registerSEListeners();
- Services.obs.addObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, false);
- this._acEnforcer =
- Cc["@mozilla.org/secureelement/access-control/ace;1"]
- .getService(Ci.nsIAccessControlEnforcer);
-}
-
-SecureElementManager.prototype = {
- QueryInterface: XPCOMUtils.generateQI([
- Ci.nsIMessageListener,
- Ci.nsISEListener,
- Ci.nsIObserver]),
- classID: SECUREELEMENTMANAGER_CID,
- classInfo: XPCOMUtils.generateCI({
- classID: SECUREELEMENTMANAGER_CID,
- classDescription: "SecureElementManager",
- interfaces: [Ci.nsIMessageListener,
- Ci.nsISEListener,
- Ci.nsIObserver]
- }),
-
- // Stores information about supported SE types and their presence.
- // key: secure element type, value: (Boolean) is present/accessible
- _sePresence: {},
-
- _acEnforcer: null,
-
- _shutdown: function() {
- this._acEnforcer = null;
- this.secureelement = null;
- Services.obs.removeObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID);
- this._unregisterMessageListeners();
- this._unregisterSEListeners();
- },
-
- _registerMessageListeners: function() {
- ppmm.addMessageListener("child-process-shutdown", this);
- for (let msgname of SE_IPC_SECUREELEMENT_MSG_NAMES) {
- ppmm.addMessageListener(msgname, this);
- }
- },
-
- _unregisterMessageListeners: function() {
- ppmm.removeMessageListener("child-process-shutdown", this);
- for (let msgname of SE_IPC_SECUREELEMENT_MSG_NAMES) {
- ppmm.removeMessageListener(msgname, this);
- }
- ppmm = null;
- },
-
- _registerSEListeners: function() {
- let connector = getConnector(SE.TYPE_UICC);
- if (!connector) {
- return;
- }
-
- this._sePresence[SE.TYPE_UICC] = false;
- connector.registerListener(this);
- },
-
- _unregisterSEListeners: function() {
- Object.keys(this._sePresence).forEach((type) => {
- let connector = getConnector(type);
- if (connector) {
- connector.unregisterListener(this);
- }
- });
-
- this._sePresence = {};
- },
-
- notifySEPresenceChanged: function(type, isPresent) {
- // we need to notify all targets, even those without open channels,
- // app could've stored the reader without actually using it
- debug("notifying DOM about SE state change");
- this._sePresence[type] = isPresent;
- gMap.getTargets().forEach(target => {
- let result = { type: type, isPresent: isPresent };
- target.sendAsyncMessage("SE:ReaderPresenceChanged", { result: result });
- });
- },
-
- _canOpenChannel: function(appId, type) {
- let opened = gMap.getChannelCountByAppIdType(appId, type);
- let limit = SE.MAX_CHANNELS_ALLOWED_PER_SESSION;
- // UICC basic channel is not accessible see comment in se_consts.js
- limit = type === SE.TYPE_UICC ? limit - 1 : limit;
- return opened < limit;
- },
-
- _handleOpenChannel: function(msg, callback) {
- if (!this._canOpenChannel(msg.appId, msg.type)) {
- debug("Max channels per session exceed");
- callback({ error: SE.ERROR_GENERIC });
- return;
- }
-
- let connector = getConnector(msg.type);
- if (!connector) {
- debug("No SE connector available");
- callback({ error: SE.ERROR_NOTPRESENT });
- return;
- }
-
- this._acEnforcer.isAccessAllowed(msg.appId, msg.type, msg.aid)
- .then((allowed) => {
- if (!allowed) {
- callback({ error: SE.ERROR_SECURITY });
- return;
- }
- connector.openChannel(SEUtils.byteArrayToHexString(msg.aid), {
-
- notifyOpenChannelSuccess: (channelNumber, openResponse) => {
- // Add the new 'channel' to the map upon success
- let channelToken =
- gMap.addChannel(msg.appId, msg.type, msg.aid, channelNumber);
- if (channelToken) {
- callback({
- error: SE.ERROR_NONE,
- channelToken: channelToken,
- isBasicChannel: (channelNumber === SE.BASIC_CHANNEL),
- openResponse: SEUtils.hexStringToByteArray(openResponse)
- });
- } else {
- callback({ error: SE.ERROR_GENERIC });
- }
- },
-
- notifyError: (reason) => {
- debug("Failed to open the channel to AID : " +
- SEUtils.byteArrayToHexString(msg.aid) +
- ", Rejected with Reason : " + reason);
- callback({ error: SE.ERROR_GENERIC, reason: reason, response: [] });
- }
- });
- })
- .catch((error) => {
- debug("Failed to get info from accessControlEnforcer " + error);
- callback({ error: SE.ERROR_SECURITY });
- });
- },
-
- _handleTransmit: function(msg, callback) {
- let channel = gMap.getChannel(msg.appId, msg.channelToken);
- if (!channel) {
- debug("Invalid token:" + msg.channelToken + ", appId: " + msg.appId);
- callback({ error: SE.ERROR_GENERIC });
- return;
- }
-
- let connector = getConnector(channel.seType);
- if (!connector) {
- debug("No SE connector available");
- callback({ error: SE.ERROR_NOTPRESENT });
- return;
- }
-
- // Bug 1137533 - ACE GPAccessRulesManager APDU filters
- connector.exchangeAPDU(channel.channelNumber, msg.apdu.cla, msg.apdu.ins,
- msg.apdu.p1, msg.apdu.p2,
- SEUtils.byteArrayToHexString(msg.apdu.data),
- msg.apdu.le, {
- notifyExchangeAPDUResponse: (sw1, sw2, response) => {
- callback({
- error: SE.ERROR_NONE,
- sw1: sw1,
- sw2: sw2,
- response: SEUtils.hexStringToByteArray(response)
- });
- },
-
- notifyError: (reason) => {
- debug("Transmit failed, rejected with Reason : " + reason);
- callback({ error: SE.ERROR_INVALIDAPPLICATION, reason: reason });
- }
- });
- },
-
- _handleCloseChannel: function(msg, callback) {
- let channel = gMap.getChannel(msg.appId, msg.channelToken);
- if (!channel) {
- debug("Invalid token:" + msg.channelToken + ", appId:" + msg.appId);
- callback({ error: SE.ERROR_GENERIC });
- return;
- }
-
- let connector = getConnector(channel.seType);
- if (!connector) {
- debug("No SE connector available");
- callback({ error: SE.ERROR_NOTPRESENT });
- return;
- }
-
- connector.closeChannel(channel.channelNumber, {
- notifyCloseChannelSuccess: () => {
- gMap.removeChannel(msg.appId, msg.channelToken);
- callback({ error: SE.ERROR_NONE });
- },
-
- notifyError: (reason) => {
- debug("Failed to close channel with token: " + msg.channelToken +
- ", reason: "+ reason);
- callback({ error: SE.ERROR_BADSTATE, reason: reason });
- }
- });
- },
-
- _handleGetSEReadersRequest: function(msg, target, callback) {
- gMap.registerSecureElementTarget(msg.appId, target);
- let readers = Object.keys(this._sePresence).map(type => {
- return { type: type, isPresent: this._sePresence[type] };
- });
- callback({ readers: readers, error: SE.ERROR_NONE });
- },
-
- _handleChildProcessShutdown: function(target) {
- let channels = gMap.getChannelsByTarget(target);
-
- let createCb = (seType, channelNumber) => {
- return {
- notifyCloseChannelSuccess: () => {
- debug("closed " + seType + ", channel " + channelNumber);
- },
-
- notifyError: (reason) => {
- debug("Failed to close " + seType + " channel " +
- channelNumber + ", reason: " + reason);
- }
- };
- };
-
- channels.forEach((channel) => {
- let connector = getConnector(channel.seType);
- if (!connector) {
- return;
- }
-
- connector.closeChannel(channel.channelNumber,
- createCb(channel.seType, channel.channelNumber));
- });
-
- gMap.unregisterSecureElementTarget(target);
- },
-
- _sendSEResponse: function(msg, result) {
- let promiseStatus = (result.error === SE.ERROR_NONE) ? "Resolved" : "Rejected";
- result.resolverId = msg.data.resolverId;
- msg.target.sendAsyncMessage(msg.name + promiseStatus, {result: result});
- },
-
- _isValidMessage: function(msg) {
- let appIdValid = gMap.isAppIdRegistered(msg.data.appId);
- return msg.name === "SE:GetSEReaders" ? true : appIdValid;
- },
-
- /**
- * nsIMessageListener interface methods.
- */
-
- receiveMessage: function(msg) {
- DEBUG && debug("Received '" + msg.name + "' message from content process" +
- ": " + JSON.stringify(msg.data));
-
- if (msg.name === "child-process-shutdown") {
- this._handleChildProcessShutdown(msg.target);
- return null;
- }
-
- if (SE_IPC_SECUREELEMENT_MSG_NAMES.indexOf(msg.name) !== -1) {
- if (!msg.target.assertPermission("secureelement-manage")) {
- debug("SecureElement message " + msg.name + " from a content process " +
- "with no 'secureelement-manage' privileges.");
- return null;
- }
- } else {
- debug("Ignoring unknown message type: " + msg.name);
- return null;
- }
-
- let callback = (result) => this._sendSEResponse(msg, result);
- if (!this._isValidMessage(msg)) {
- debug("Message not valid");
- callback({ error: SE.ERROR_GENERIC });
- return null;
- }
-
- switch (msg.name) {
- case "SE:GetSEReaders":
- this._handleGetSEReadersRequest(msg.data, msg.target, callback);
- break;
- case "SE:OpenChannel":
- this._handleOpenChannel(msg.data, callback);
- break;
- case "SE:CloseChannel":
- this._handleCloseChannel(msg.data, callback);
- break;
- case "SE:TransmitAPDU":
- this._handleTransmit(msg.data, callback);
- break;
- }
- return null;
- },
-
- /**
- * nsIObserver interface methods.
- */
-
- observe: function(subject, topic, data) {
- if (topic === NS_XPCOM_SHUTDOWN_OBSERVER_ID) {
- this._shutdown();
- }
- }
-};
-
-this.NSGetFactory = XPCOMUtils.generateNSGetFactory([SecureElementManager]);
diff --git a/dom/secureelement/gonk/SecureElement.manifest b/dom/secureelement/gonk/SecureElement.manifest
deleted file mode 100644
index a76fcfc11f..0000000000
--- a/dom/secureelement/gonk/SecureElement.manifest
+++ /dev/null
@@ -1,18 +0,0 @@
-# Copyright 2012 Mozilla Foundation and Mozilla contributors
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-# SecureElementManager
-component {48f4e650-28d2-11e4-8c21-0800200c9a66} SecureElement.js
-contract @mozilla.org/secureelement/parent-manager;1 {48f4e650-28d2-11e4-8c21-0800200c9a66}
-category profile-after-change SecureElementManager @mozilla.org/secureelement/parent-manager;1
diff --git a/dom/secureelement/gonk/UiccConnector.js b/dom/secureelement/gonk/UiccConnector.js
deleted file mode 100644
index 517303de29..0000000000
--- a/dom/secureelement/gonk/UiccConnector.js
+++ /dev/null
@@ -1,360 +0,0 @@
-/* Copyright 2012 Mozilla Foundation and Mozilla contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* Copyright © 2014, Deutsche Telekom, Inc. */
-
-"use strict";
-
-/* globals Components, XPCOMUtils, SE, dump, libcutils, Services,
- iccService, SEUtils */
-
-const { 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");
-
-XPCOMUtils.defineLazyGetter(this, "SE", function() {
- let obj = {};
- Cu.import("resource://gre/modules/se_consts.js", obj);
- return obj;
-});
-
-// set to true in se_consts.js to see debug messages
-var DEBUG = SE.DEBUG_CONNECTOR;
-function debug(s) {
- if (DEBUG) {
- dump("-*- UiccConnector: " + s + "\n");
- }
-}
-
-XPCOMUtils.defineLazyModuleGetter(this, "SEUtils",
- "resource://gre/modules/SEUtils.jsm");
-
-XPCOMUtils.defineLazyServiceGetter(this, "iccService",
- "@mozilla.org/icc/iccservice;1",
- "nsIIccService");
-
-const UICCCONNECTOR_CONTRACTID =
- "@mozilla.org/secureelement/connector/uicc;1";
-const UICCCONNECTOR_CID =
- Components.ID("{8e040e5d-c8c3-4c1b-ac82-c00d25d8c4a4}");
-const NS_XPCOM_SHUTDOWN_OBSERVER_ID = "xpcom-shutdown";
-
-// TODO: Bug 1118099 - Add multi-sim support.
-// In the Multi-sim, there is more than one client.
-// For now, use default clientID as 0. Ideally, SE parent process would like to
-// know which clients (uicc slot) are connected to CLF over SWP interface.
-const PREFERRED_UICC_CLIENTID =
- libcutils.property_get("ro.moz.se.def_client_id", "0");
-
-/**
- * 'UiccConnector' object is a wrapper over iccService's channel management
- * related interfaces that implements nsISecureElementConnector interface.
- */
-function UiccConnector() {
- this._init();
-}
-
-UiccConnector.prototype = {
- QueryInterface: XPCOMUtils.generateQI([Ci.nsISecureElementConnector,
- Ci.nsIIccListener]),
- classID: UICCCONNECTOR_CID,
- classInfo: XPCOMUtils.generateCI({
- classID: UICCCONNECTOR_CID,
- contractID: UICCCONNECTOR_CONTRACTID,
- classDescription: "UiccConnector",
- interfaces: [Ci.nsISecureElementConnector,
- Ci.nsIIccListener,
- Ci.nsIObserver]
- }),
-
- _SEListeners: [],
- _isPresent: false,
-
- _init: function() {
- Services.obs.addObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, false);
- let icc = iccService.getIccByServiceId(PREFERRED_UICC_CLIENTID);
- icc.registerListener(this);
-
- // Update the state in order to avoid race condition.
- // By this time, 'notifyCardStateChanged (with proper card state)'
- // may have occurred already before this module initialization.
- this._updatePresenceState();
- },
-
- _shutdown: function() {
- Services.obs.removeObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID);
- let icc = iccService.getIccByServiceId(PREFERRED_UICC_CLIENTID);
- icc.unregisterListener(this);
- },
-
- _updatePresenceState: function() {
- let uiccNotReadyStates = [
- Ci.nsIIcc.CARD_STATE_UNKNOWN,
- Ci.nsIIcc.CARD_STATE_ILLEGAL,
- Ci.nsIIcc.CARD_STATE_PERSONALIZATION_IN_PROGRESS,
- Ci.nsIIcc.CARD_STATE_PERMANENT_BLOCKED,
- Ci.nsIIcc.CARD_STATE_UNDETECTED
- ];
-
- let cardState = iccService.getIccByServiceId(PREFERRED_UICC_CLIENTID).cardState;
- let uiccPresent = cardState !== null &&
- uiccNotReadyStates.indexOf(cardState) == -1;
-
- if (this._isPresent === uiccPresent) {
- return;
- }
-
- debug("Uicc presence changed " + this._isPresent + " -> " + uiccPresent);
- this._isPresent = uiccPresent;
- this._SEListeners.forEach((listener) => {
- listener.notifySEPresenceChanged(SE.TYPE_UICC, this._isPresent);
- });
- },
-
- // See GP Spec, 11.1.4 Class Byte Coding
- _setChannelToCLAByte: function(cla, channel) {
- if (channel < SE.LOGICAL_CHANNEL_NUMBER_LIMIT) {
- // b7 = 0 indicates the first interindustry class byte coding
- cla = (cla & 0x9C) & 0xFF | channel;
- } else if (channel < SE.SUPPLEMENTARY_LOGICAL_CHANNEL_NUMBER_LIMIT) {
- // b7 = 1 indicates the further interindustry class byte coding
- cla = (cla & 0xB0) & 0xFF | 0x40 | (channel - SE.LOGICAL_CHANNEL_NUMBER_LIMIT);
- } else {
- debug("Channel number must be within [0..19]");
- return SE.ERROR_GENERIC;
- }
- return cla;
- },
-
- _doGetOpenResponse: function(channel, length, callback) {
- // Le value is set. It means that this is a request for all available
- // response bytes.
- let cla = this._setChannelToCLAByte(SE.CLA_GET_RESPONSE, channel);
- this.exchangeAPDU(channel, cla, SE.INS_GET_RESPONSE, 0x00, 0x00,
- null, length, {
- notifyExchangeAPDUResponse: function(sw1, sw2, response) {
- debug("GET Response : " + response);
- if (callback) {
- callback({
- error: SE.ERROR_NONE,
- sw1: sw1,
- sw2: sw2,
- response: response
- });
- }
- },
-
- notifyError: function(reason) {
- debug("Failed to get open response: " +
- ", Rejected with Reason : " + reason);
- if (callback) {
- callback({ error: SE.ERROR_INVALIDAPPLICATION, reason: reason });
- }
- }
- });
- },
-
- _doIccExchangeAPDU: function(channel, cla, ins, p1, p2, p3,
- data, appendResp, callback) {
- let icc = iccService.getIccByServiceId(PREFERRED_UICC_CLIENTID);
- icc.iccExchangeAPDU(channel, cla & 0xFC, ins, p1, p2, p3, data, {
- notifyExchangeAPDUResponse: (sw1, sw2, response) => {
- debug("sw1 : " + sw1 + ", sw2 : " + sw2 + ", response : " + response);
-
- // According to ETSI TS 102 221 , Section 7.2.2.3.1,
- // Enforce 'Procedure bytes' checks before notifying the callback.
- // Note that 'Procedure bytes'are special cases.
- // There is no need to handle '0x60' procedure byte as it implies
- // no-action from SE stack perspective. This procedure byte is not
- // notified to application layer.
- if (sw1 === 0x6C) {
- // Use the previous command header with length as second procedure
- // byte (SW2) as received and repeat the procedure.
-
- // Recursive! and Pass empty response '' as args, since '0x6C'
- // procedure does not have to deal with appended responses.
- this._doIccExchangeAPDU(channel, cla, ins, p1, p2,
- sw2, data, "", callback);
- } else if (sw1 === 0x61) {
- // Since the terminal waited for a second procedure byte and
- // received it (sw2), send a GET RESPONSE command header to the UICC
- // with a maximum length of 'XX', where 'XX' is the value of the
- // second procedure byte (SW2).
-
- let claWithChannel = this._setChannelToCLAByte(SE.CLA_GET_RESPONSE,
- channel);
-
- // Recursive, with GET RESPONSE bytes and '0x61' procedure IS interested
- // in appended responses. Pass appended response and note that p3=sw2.
- this._doIccExchangeAPDU(channel, claWithChannel, SE.INS_GET_RESPONSE,
- 0x00, 0x00, sw2, null,
- (response ? response + appendResp : appendResp),
- callback);
- } else if (callback) {
- callback.notifyExchangeAPDUResponse(sw1, sw2, response);
- }
- },
-
- notifyError: (reason) => {
- debug("Failed to trasmit C-APDU over the channel # : " + channel +
- ", Rejected with Reason : " + reason);
- if (callback) {
- callback.notifyError(reason);
- }
- }
- });
- },
-
- /**
- * nsISecureElementConnector interface methods.
- */
-
- /**
- * Opens a channel on a default clientId
- */
- openChannel: function(aid, callback) {
- if (!this._isPresent) {
- callback.notifyError(SE.ERROR_NOTPRESENT);
- return;
- }
-
- // TODO: Bug 1118106: Handle Resource management / leaks by persisting
- // the newly opened channel in some persistent storage so that when this
- // module gets restarted (say after opening a channel) in the event of
- // some erroneous conditions such as gecko restart /, crash it can read
- // the persistent storage to check if there are any held resources
- // (opened channels) and close them.
- let icc = iccService.getIccByServiceId(PREFERRED_UICC_CLIENTID);
- icc.iccOpenChannel(aid, {
- notifyOpenChannelSuccess: (channel) => {
- this._doGetOpenResponse(channel, 0x00, function(result) {
- if (callback) {
- callback.notifyOpenChannelSuccess(channel, result.response);
- }
- });
- },
-
- notifyError: (reason) => {
- debug("Failed to open the channel to AID : " + aid +
- ", Rejected with Reason : " + reason);
- if (callback) {
- callback.notifyError(reason);
- }
- }
- });
- },
-
- /**
- * Transmit the C-APDU (command) on default clientId.
- */
- exchangeAPDU: function(channel, cla, ins, p1, p2, data, le, callback) {
- if (!this._isPresent) {
- callback.notifyError(SE.ERROR_NOTPRESENT);
- return;
- }
-
- if (data && data.length % 2 !== 0) {
- callback.notifyError("Data should be a hex string with length % 2 === 0");
- return;
- }
-
- cla = this._setChannelToCLAByte(cla, channel);
- let lc = data ? data.length / 2 : 0;
- let p3 = lc || le;
-
- if (lc && (le !== -1)) {
- data += SEUtils.byteArrayToHexString([le]);
- }
-
- // Pass empty response '' as args as we are not interested in appended
- // responses yet!
- debug("exchangeAPDU on Channel # " + channel);
- this._doIccExchangeAPDU(channel, cla, ins, p1, p2, p3, data, "",
- callback);
- },
-
- /**
- * Closes the channel on default clientId.
- */
- closeChannel: function(channel, callback) {
- if (!this._isPresent) {
- callback.notifyError(SE.ERROR_NOTPRESENT);
- return;
- }
-
- let icc = iccService.getIccByServiceId(PREFERRED_UICC_CLIENTID);
- icc.iccCloseChannel(channel, {
- notifyCloseChannelSuccess: function() {
- debug("closeChannel successfully closed the channel # : " + channel);
- if (callback) {
- callback.notifyCloseChannelSuccess();
- }
- },
-
- notifyError: function(reason) {
- debug("Failed to close the channel # : " + channel +
- ", Rejected with Reason : " + reason);
- if (callback) {
- callback.notifyError(reason);
- }
- }
- });
- },
-
- registerListener: function(listener) {
- if (this._SEListeners.indexOf(listener) !== -1) {
- throw Cr.NS_ERROR_UNEXPECTED;
- }
-
- this._SEListeners.push(listener);
- // immediately notify listener about the current state
- listener.notifySEPresenceChanged(SE.TYPE_UICC, this._isPresent);
- },
-
- unregisterListener: function(listener) {
- let idx = this._SEListeners.indexOf(listener);
- if (idx !== -1) {
- this._SEListeners.splice(idx, 1);
- }
- },
-
- /**
- * nsIIccListener interface methods.
- */
- notifyStkCommand: function() {},
-
- notifyStkSessionEnd: function() {},
-
- notifyIccInfoChanged: function() {},
-
- notifyCardStateChanged: function() {
- debug("Card state changed, updating UICC presence.");
- this._updatePresenceState();
- },
-
- /**
- * nsIObserver interface methods.
- */
-
- observe: function(subject, topic, data) {
- if (topic === NS_XPCOM_SHUTDOWN_OBSERVER_ID) {
- this._shutdown();
- }
- }
-};
-
-this.NSGetFactory = XPCOMUtils.generateNSGetFactory([UiccConnector]);
diff --git a/dom/secureelement/gonk/UiccConnector.manifest b/dom/secureelement/gonk/UiccConnector.manifest
deleted file mode 100644
index 5ac8b3b7bb..0000000000
--- a/dom/secureelement/gonk/UiccConnector.manifest
+++ /dev/null
@@ -1,17 +0,0 @@
-# Copyright 2012 Mozilla Foundation and Mozilla contributors
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-# UiccConnector
-component {8e040e5d-c8c3-4c1b-ac82-c00d25d8c4a4} UiccConnector.js
-contract @mozilla.org/secureelement/connector/uicc;1 {8e040e5d-c8c3-4c1b-ac82-c00d25d8c4a4}
diff --git a/dom/secureelement/gonk/gp_consts.js b/dom/secureelement/gonk/gp_consts.js
deleted file mode 100644
index 7c3bc71658..0000000000
--- a/dom/secureelement/gonk/gp_consts.js
+++ /dev/null
@@ -1,62 +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/. */
-
-/* Copyright © 2015, Deutsche Telekom, Inc. */
-
-/* Object Directory File (ODF) is an elementary file which contain
- pointers to other EFs. It is specified in PKCS#15 section 6.7. */
-this.ODF_DF = [0x50, 0x31];
-
-/* ISO 7816-4: secure messaging */
-this.CLA_SM = 0x00;
-
-/* ISO 7816-4, 5.4.1 table 11 */
-this.INS_SF = 0xA4; // select file
-this.INS_GR = 0xC0; // get response
-this.INS_RB = 0xB0; // read binary
-
-/* ISO 7816-4: select file, see 6.11.3, table 58 & 59 */
-this.P1_SF_DF = 0x00; // select DF
-this.P2_SF_FCP = 0x04; // return FCP
-
-/* ISO 7816-4: read binary, 6.1.3. P1 and P2 describe offset of the first byte
- to be read. We always read the whole files at the moment. */
-this.P1_RB = 0x00;
-this.P2_RB = 0x00;
-
-/* ISO 7816-4: get response, 7.1.3 table 74, P1-P2 '0000' (other values RFU) */
-this.P1_GR = 0x00;
-this.P2_GR = 0x00;
-
-/* ISO 7816-4: 5.1.5 File Control Information, Table 1. For FCP and FMD. */
-this.TAG_PROPRIETARY = 0x00;
-this.TAG_NON_TLV = 0x53;
-this.TAG_BER_TLV = 0x73;
-
-/* ASN.1 tags */
-this.TAG_SEQUENCE = 0x30;
-this.TAG_OCTETSTRING = 0x04;
-this.TAG_OID = 0x06; // Object Identifier
-
-/* ISO 7816-4: 5.1.5 File Control Information, Templates. */
-this.TAG_FCP = 0x62; // File control parameters template
-this.TAG_FMD = 0x64; // File management data template
-this.TAG_FCI = 0x6F; // File control information template
-
-/* EF_DIR tags */
-this.TAG_APPLTEMPLATE = 0x61;
-this.TAG_APPLIDENTIFIER = 0x4F;
-this.TAG_APPLLABEL = 0x50;
-this.TAG_APPLPATH = 0x51;
-
-this.TAG_GPD_ALL = 0x82; // EF-ACRules - GPD spec. "all applets"
-
-/* Generic TLVs that are parsed */
-this.TAG_GPD_AID = 0xA0; // AID in the EF-ACRules - GPD spec, "one applet"
-this.TAG_EXTERNALDO = 0xA1; // External data objects - PKCS#15
-this.TAG_INDIRECT = 0xA5; // Indirect value.
-this.TAG_EF_ODF = 0xA7; // Elemenetary File Object Directory File
-
-// Allow this file to be imported via Components.utils.import().
-this.EXPORTED_SYMBOLS = Object.keys(this);
diff --git a/dom/secureelement/gonk/nsIAccessControlEnforcer.idl b/dom/secureelement/gonk/nsIAccessControlEnforcer.idl
deleted file mode 100644
index 7ad1a97f60..0000000000
--- a/dom/secureelement/gonk/nsIAccessControlEnforcer.idl
+++ /dev/null
@@ -1,32 +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/. */
-
-/* Copyright © 2015, Deutsche Telekom, Inc. */
-
-#include "nsISupports.idl"
-
-interface nsIVariant;
-
-[scriptable, uuid(4994a960-26d9-4d71-82dd-4505bd97bf2a)]
-interface nsIAccessControlEnforcer : nsISupports
-{
- /**
- * Determines whether application identified by its ID should be allowed
- * to access Secure Element's applet identified by its AID. Decision
- * is made according to the GPD specification.
- *
- * @param localId
- * ID of an application accessing SE
- * @param seType
- * Type of the SE.
- * @param aid
- * AID of a SE applet
- * @return Promise which is resolved to true if access should be allowed,
- * false otherwise, and rejected if the application contains
- * no developer certificate.
- */
- jsval isAccessAllowed(in unsigned long localId,
- in DOMString seType,
- in DOMString aid);
-};
diff --git a/dom/secureelement/gonk/nsIAccessRulesManager.idl b/dom/secureelement/gonk/nsIAccessRulesManager.idl
deleted file mode 100644
index 173f57c906..0000000000
--- a/dom/secureelement/gonk/nsIAccessRulesManager.idl
+++ /dev/null
@@ -1,50 +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/. */
-
-/* Copyright © 2015, Deutsche Telekom, Inc. */
-
-#include "nsISupports.idl"
-
-[scriptable, uuid(7baedd2a-3189-4b03-b2a3-34016043b5e2)]
-interface nsIAccessRulesManager : nsISupports
-{
- /* Wildcard: rule allows all applications to access an SE applet */
- const unsigned short ALLOW_ALL = 1;
- /* Wildcard: rule denies all applications to access an SE applet */
- const unsigned short DENY_ALL = 2;
- /* Wildcard: rule allows application(s) access to all SE applets */
- const unsigned short ALL_APPLET = 3;
-
- /**
- * Initiates Access Rules Manager, this should perform the initial
- * reading of rules from access rule source
- * @return Promise which is resolved if init is successful or rejected
- * otherwise
- */
- jsval init();
-
- /**
- * Retrieves all access rules.
- *
- * Rules are stored in an array. Each rule contains the following properties:
- * - applet - describes an SE applet referenced by this rule. Might equal
- * to an applet AID (as a byte array), or to a wildcard "all"
- * meaning all applets.
- * - application - describes an application referenced by this rule. Might
- * be an array of developer certificate hashes (each as
- * a byte array) in which case it lists all applications
- * allowed access. Alternatively, might equal to wildcard
- * "allowed-all" or "denied-all".
- *
- * Example rule format:
- * [{ applet: ALL_APPLET,
- * application: [[0x01, 0x02, ..., 0x20],
- * [0x20, 0x19, ...., 0x01]],
- * { applet: [0x00, 0x01, ..., 0x05],
- * application: ALLOW_ALL}}]
- *
- * @return Promise which resolves with Array containing parsed access rules
- */
- jsval getAccessRules();
-};
diff --git a/dom/secureelement/gonk/nsISecureElementConnector.idl b/dom/secureelement/gonk/nsISecureElementConnector.idl
deleted file mode 100644
index 92cc1eb2b8..0000000000
--- a/dom/secureelement/gonk/nsISecureElementConnector.idl
+++ /dev/null
@@ -1,124 +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(1ff3f35a-1b6f-4e65-a89e-a363b8604cd7)]
-interface nsISEChannelCallback : nsISupports
-{
- /**
- * Callback function to notify on successfully opening a logical channel.
- *
- * @param channel
- * The Channel Number/Handle that is successfully opened.
- * @param openResponse
- * Response from SE for OpenChannel operation.
- */
- void notifyOpenChannelSuccess(in long channel, in DOMString openResponse);
-
- /**
- * Callback function to notify on successfully closing the logical channel.
- *
- */
- void notifyCloseChannelSuccess();
-
- /**
- * Callback function to notify the status of 'seExchangeAPDU' command.
- *
- * @param sw1
- * Response's First Status Byte
- * @param sw2
- * Response's Second Status Byte
- * @param data
- * Response's data
- */
- void notifyExchangeAPDUResponse(in octet sw1,
- in octet sw2,
- in DOMString data);
-
- /**
- * Callback function to notify error
- *
- * @param error
- * Error describing the reason for failure.
- */
- void notifyError(in DOMString error);
-};
-
-[scriptable, uuid(417f59ee-f582-45b9-9a4e-e9dcefecb4f7)]
-interface nsISEListener : nsISupports
-{
- void notifySEPresenceChanged(in DOMString seType, in boolean isPresent);
-};
-
-[scriptable, uuid(3cef313a-1d01-432d-9cd2-6610a80911f3)]
-interface nsISecureElementConnector : nsISupports
-{
- /**
- * Open a logical communication channel with the specific secure element type
- *
- * @param aid
- * Application Identifier of the Card Applet on the secure element.
- * @param callback
- * callback to notify the result of the operation.
- */
- void openChannel(in DOMString aid,
- in nsISEChannelCallback callback);
-
- /**
- * Exchanges APDU channel with the specific secure element type
- *
- * @param channel
- * Channel on which C-APDU to be transmitted.
- * @param cla
- Class Byte.
- * @param ins
- Instruction Byte
- * @param p1
- Reference parameter first byte
- * @param p2
- Reference parameter second byte
- * Refer to 3G TS 31.101 , 10.2 'Command APDU Structure' for all the cases.
- * @param data
- Sequence of C-APDU data octets
- * @param le [optional]
- * le is the length of expected response. If the response is not expected,
- it should be explicitly set to -1.
- * @param callback
- * callback to notify the result of the operation.
- */
- void exchangeAPDU(in long channel,
- in octet cla,
- in octet ins,
- in octet p1,
- in octet p2,
- in DOMString data,
- in short le,
- in nsISEChannelCallback callback);
-
- /**
- * Closes the logical communication channel to the specific secure element type
- *
- * @param channel
- * Channel to be closed.
- * @param callback
- * callback to notify the result of the operation.
- */
- void closeChannel(in long channel,
- in nsISEChannelCallback callback);
-
- /**
- * Register a Secure Element listener
- *
- * @param listener
- */
- void registerListener(in nsISEListener listener);
-
- /**
- * Unregister a Secure Element listener
- *
- * @param listener
- */
- void unregisterListener(in nsISEListener listener);
-};
diff --git a/dom/secureelement/gonk/se_consts.js b/dom/secureelement/gonk/se_consts.js
deleted file mode 100644
index 13489b7aed..0000000000
--- a/dom/secureelement/gonk/se_consts.js
+++ /dev/null
@@ -1,68 +0,0 @@
-/* Copyright 2012 Mozilla Foundation and Mozilla contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* Copyright © 2014, Deutsche Telekom, Inc. */
-
-// Set to true to debug SecureElement (SE) stack
-this.DEBUG_ALL = false;
-
-// Set individually to debug specific layers
-this.DEBUG_CONNECTOR = DEBUG_ALL || false;
-this.DEBUG_ACE = DEBUG_ALL || false ;
-this.DEBUG_SE = DEBUG_ALL || false ;
-
-// Maximun logical channels per session.
-// For 'uicc' SE type this value is 3, as opening a basic channel' : 0
-// is not allowed for security reasons. In such scenarios, possible
-// supplementary logical channels available are : [1, 2, or 3].
-// However,Other SE types may support upto max 4 (including '0').
-this.MAX_CHANNELS_ALLOWED_PER_SESSION = 4;
-
-this.BASIC_CHANNEL = 0;
-
-// According GPCardSpec 2.2
-this.MAX_APDU_LEN = 255; // including APDU header
-
-// CLA (1 byte) + INS (1 byte) + P1 (1 byte) + P2 (1 byte)
-this.APDU_HEADER_LEN = 4;
-
-this.LOGICAL_CHANNEL_NUMBER_LIMIT = 4;
-this.SUPPLEMENTARY_LOGICAL_CHANNEL_NUMBER_LIMIT = 20;
-
-this.MIN_AID_LEN = 5;
-this.MAX_AID_LEN = 16;
-
-this.CLA_GET_RESPONSE = 0x00;
-
-this.INS_SELECT = 0xA4;
-this.INS_MANAGE_CHANNEL = 0x70;
-this.INS_GET_RESPONSE = 0xC0;
-
-// Match the following errors with SecureElement.webidl's SEError enum values
-this.ERROR_NONE = "";
-this.ERROR_SECURITY = "SESecurityError";
-this.ERROR_IO = "SEIoError";
-this.ERROR_BADSTATE = "SEBadStateError";
-this.ERROR_INVALIDCHANNEL = "SEInvalidChannelError";
-this.ERROR_INVALIDAPPLICATION = "SEInvalidApplicationError";
-this.ERROR_GENERIC = "SEGenericError";
-this.ERROR_NOTPRESENT = "SENotPresentError";
-this.ERROR_ILLEGALPARAMETER = "SEIllegalParameterError";
-
-this.TYPE_UICC = "uicc";
-this.TYPE_ESE = "eSE";
-
-// Allow this file to be imported via Components.utils.import().
-this.EXPORTED_SYMBOLS = Object.keys(this);
diff --git a/dom/secureelement/moz.build b/dom/secureelement/moz.build
index a2c87b0140..973000512f 100644
--- a/dom/secureelement/moz.build
+++ b/dom/secureelement/moz.build
@@ -11,30 +11,6 @@ if CONFIG['MOZ_SECUREELEMENT']:
'DOMSecureElement.manifest',
]
-if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk' and CONFIG['MOZ_SECUREELEMENT']:
- EXTRA_COMPONENTS += [
- 'gonk/ACEService.js',
- 'gonk/ACEService.manifest',
- 'gonk/GPAccessRulesManager.js',
- 'gonk/GPAccessRulesManager.manifest',
- 'gonk/SecureElement.js',
- 'gonk/SecureElement.manifest',
- ]
- XPIDL_MODULE = 'dom_secureelement'
- XPIDL_SOURCES += [
- 'gonk/nsIAccessControlEnforcer.idl',
- 'gonk/nsIAccessRulesManager.idl',
- 'gonk/nsISecureElementConnector.idl',
- ]
- EXTRA_JS_MODULES += [
- 'gonk/gp_consts.js',
- 'gonk/se_consts.js',
- 'SEUtils.jsm'
- ]
- XPCSHELL_TESTS_MANIFESTS += [
- 'tests/unit/xpcshell.ini'
- ]
-
include('/ipc/chromium/chromium-config.mozbuild')
FINAL_LIBRARY = 'xul'
diff --git a/dom/system/gonk/AudioChannelManager.cpp b/dom/system/gonk/AudioChannelManager.cpp
deleted file mode 100644
index 977715a29e..0000000000
--- a/dom/system/gonk/AudioChannelManager.cpp
+++ /dev/null
@@ -1,181 +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 "nsIDocument.h"
-#include "nsIDOMClassInfo.h"
-#include "nsIDOMEvent.h"
-#include "nsIDOMEventListener.h"
-#include "nsPIDOMWindow.h"
-#include "nsIDocShell.h"
-#include "nsIPermissionManager.h"
-#include "nsIInterfaceRequestorUtils.h"
-#include "AudioChannelManager.h"
-#include "mozilla/dom/AudioChannelManagerBinding.h"
-#include "mozilla/dom/nsBrowserElement.h"
-#include "mozilla/Services.h"
-
-namespace mozilla {
-namespace dom {
-namespace system {
-
-NS_IMPL_QUERY_INTERFACE_INHERITED(AudioChannelManager, DOMEventTargetHelper,
- nsIDOMEventListener)
-NS_IMPL_ADDREF_INHERITED(AudioChannelManager, DOMEventTargetHelper)
-NS_IMPL_RELEASE_INHERITED(AudioChannelManager, DOMEventTargetHelper)
-
-AudioChannelManager::AudioChannelManager()
- : mVolumeChannel(-1)
-{
- hal::RegisterSwitchObserver(hal::SWITCH_HEADPHONES, this);
-}
-
-AudioChannelManager::~AudioChannelManager()
-{
- hal::UnregisterSwitchObserver(hal::SWITCH_HEADPHONES, this);
-
- nsCOMPtr<EventTarget> target = do_QueryInterface(GetOwner());
- NS_ENSURE_TRUE_VOID(target);
-
- target->RemoveSystemEventListener(NS_LITERAL_STRING("visibilitychange"),
- this,
- /* useCapture = */ true);
-}
-
-void
-AudioChannelManager::Init(nsPIDOMWindowInner* aWindow)
-{
- BindToOwner(aWindow);
-
- nsCOMPtr<nsIDOMEventTarget> target = do_QueryInterface(GetOwner());
- NS_ENSURE_TRUE_VOID(target);
-
- target->AddSystemEventListener(NS_LITERAL_STRING("visibilitychange"),
- this,
- /* useCapture = */ true,
- /* wantsUntrusted = */ false);
-}
-
-JSObject*
-AudioChannelManager::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
-{
- return AudioChannelManagerBinding::Wrap(aCx, this, aGivenProto);
-}
-
-void
-AudioChannelManager::Notify(const hal::SwitchEvent& aEvent)
-{
- mState = Some(aEvent.status());
-
- DispatchTrustedEvent(NS_LITERAL_STRING("headphoneschange"));
-}
-
-bool
-AudioChannelManager::SetVolumeControlChannel(const nsAString& aChannel)
-{
- if (aChannel.EqualsASCII("publicnotification")) {
- return false;
- }
-
- AudioChannel newChannel = AudioChannelService::GetAudioChannel(aChannel);
-
- // Only normal channel doesn't need permission.
- if (newChannel != AudioChannel::Normal) {
- nsCOMPtr<nsIPermissionManager> permissionManager =
- services::GetPermissionManager();
- if (!permissionManager) {
- return false;
- }
- uint32_t perm = nsIPermissionManager::UNKNOWN_ACTION;
- permissionManager->TestPermissionFromWindow(GetOwner(),
- nsCString(NS_LITERAL_CSTRING("audio-channel-") +
- NS_ConvertUTF16toUTF8(aChannel)).get(), &perm);
- if (perm != nsIPermissionManager::ALLOW_ACTION) {
- return false;
- }
- }
-
- if (mVolumeChannel == (int32_t)newChannel) {
- return true;
- }
-
- mVolumeChannel = (int32_t)newChannel;
-
- NotifyVolumeControlChannelChanged();
- return true;
-}
-
-bool
-AudioChannelManager::GetVolumeControlChannel(nsAString & aChannel)
-{
- if (mVolumeChannel >= 0) {
- AudioChannelService::GetAudioChannelString(
- static_cast<AudioChannel>(mVolumeChannel),
- aChannel);
- } else {
- aChannel.AssignASCII("");
- }
-
- return true;
-}
-
-void
-AudioChannelManager::NotifyVolumeControlChannelChanged()
-{
- nsCOMPtr<nsIDocShell> docshell = do_GetInterface(GetOwner());
- NS_ENSURE_TRUE_VOID(docshell);
-
- bool isActive = false;
- docshell->GetIsActive(&isActive);
-
- RefPtr<AudioChannelService> service = AudioChannelService::GetOrCreate();
- if (!service) {
- return;
- }
-
- if (isActive) {
- service->SetDefaultVolumeControlChannel(mVolumeChannel, isActive);
- } else {
- service->SetDefaultVolumeControlChannel(-1, isActive);
- }
-}
-
-NS_IMETHODIMP
-AudioChannelManager::HandleEvent(nsIDOMEvent* aEvent)
-{
- nsAutoString type;
- aEvent->GetType(type);
-
- if (type.EqualsLiteral("visibilitychange")) {
- NotifyVolumeControlChannelChanged();
- }
- return NS_OK;
-}
-
-void
-AudioChannelManager::GetAllowedAudioChannels(
- nsTArray<RefPtr<BrowserElementAudioChannel>>& aAudioChannels,
- ErrorResult& aRv)
-{
- MOZ_ASSERT(aAudioChannels.IsEmpty());
-
- // Only main process is supported.
- if (XRE_GetProcessType() != GeckoProcessType_Default) {
- aRv.Throw(NS_ERROR_FAILURE);
- return;
- }
-
- nsCOMPtr<nsPIDOMWindowInner> window = GetOwner();
- if (NS_WARN_IF(!window)) {
- aRv.Throw(NS_ERROR_FAILURE);
- return;
- }
-
- nsBrowserElement::GenerateAllowedAudioChannels(window, nullptr, nullptr,
- aAudioChannels, aRv);
- NS_WARNING_ASSERTION(!aRv.Failed(), "GenerateAllowedAudioChannels failed");
-}
-
-} // namespace system
-} // namespace dom
-} // namespace mozilla
diff --git a/dom/system/gonk/AudioChannelManager.h b/dom/system/gonk/AudioChannelManager.h
deleted file mode 100644
index a460651e78..0000000000
--- a/dom/system/gonk/AudioChannelManager.h
+++ /dev/null
@@ -1,87 +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/. */
-
-#ifndef mozilla_dom_system_AudioChannelManager_h
-#define mozilla_dom_system_AudioChannelManager_h
-
-#include "mozilla/dom/BrowserElementAudioChannel.h"
-#include "mozilla/DOMEventTargetHelper.h"
-#include "mozilla/Hal.h"
-#include "mozilla/HalTypes.h"
-#include "mozilla/Maybe.h"
-#include "AudioChannelService.h"
-
-namespace mozilla {
-namespace hal {
-class SwitchEvent;
-typedef Observer<SwitchEvent> SwitchObserver;
-} // namespace hal
-
-namespace dom {
-namespace system {
-
-class AudioChannelManager final
- : public DOMEventTargetHelper
- , public hal::SwitchObserver
- , public nsIDOMEventListener
-{
-public:
- AudioChannelManager();
-
- NS_DECL_ISUPPORTS_INHERITED
- NS_DECL_NSIDOMEVENTLISTENER
-
- void Notify(const hal::SwitchEvent& aEvent);
-
- void Init(nsPIDOMWindowInner* aWindow);
-
- /**
- * WebIDL Interface
- */
-
- nsPIDOMWindowInner* GetParentObject() const
- {
- return GetOwner();
- }
-
- virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
-
- bool Headphones()
- {
- // Bug 929139 - Remove the assert check for SWITCH_STATE_UNKNOWN.
- // If any devices (ex: emulator) didn't have the corresponding sys node for
- // headset switch state then GonkSwitch will report the unknown state.
- // So it is possible to get unknown state here.
- if (mState.isNothing()) {
- mState = Some(hal::GetCurrentSwitchState(hal::SWITCH_HEADPHONES));
- }
- return mState.value() != hal::SWITCH_STATE_OFF &&
- mState.value() != hal::SWITCH_STATE_UNKNOWN;
- }
-
- bool SetVolumeControlChannel(const nsAString& aChannel);
-
- bool GetVolumeControlChannel(nsAString& aChannel);
-
- IMPL_EVENT_HANDLER(headphoneschange)
-
- void GetAllowedAudioChannels(
- nsTArray<RefPtr<mozilla::dom::BrowserElementAudioChannel>>& aAudioChannels,
- mozilla::ErrorResult& aRv);
-
-protected:
- virtual ~AudioChannelManager();
-
-private:
- void NotifyVolumeControlChannelChanged();
-
- Maybe<hal::SwitchState> mState;
- int32_t mVolumeChannel;
-};
-
-} // namespace system
-} // namespace dom
-} // namespace mozilla
-
-#endif // mozilla_dom_system_AudioChannelManager_h
diff --git a/dom/system/gonk/AudioManager.cpp b/dom/system/gonk/AudioManager.cpp
deleted file mode 100644
index 88dff13f7d..0000000000
--- a/dom/system/gonk/AudioManager.cpp
+++ /dev/null
@@ -1,1412 +0,0 @@
-/* Copyright 2012 Mozilla Foundation and Mozilla contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <android/log.h>
-#include <cutils/properties.h>
-#include <binder/IServiceManager.h>
-
-#include "AudioChannelService.h"
-#include "AudioManager.h"
-
-#include "nsIObserverService.h"
-#include "nsISettingsService.h"
-#include "nsPrintfCString.h"
-
-#include "mozilla/Hal.h"
-#include "mozilla/Services.h"
-#include "mozilla/StaticPtr.h"
-#include "mozilla/ClearOnShutdown.h"
-#include "mozilla/MozPromise.h"
-#include "mozilla/dom/ScriptSettings.h"
-#include "base/message_loop.h"
-
-#include "BluetoothCommon.h"
-#include "BluetoothHfpManagerBase.h"
-
-#include "nsJSUtils.h"
-#include "nsThreadUtils.h"
-#include "nsServiceManagerUtils.h"
-#include "nsComponentManagerUtils.h"
-#include "nsContentUtils.h"
-#include "nsXULAppAPI.h"
-#include "mozilla/dom/BindingUtils.h"
-#include "mozilla/dom/SettingChangeNotificationBinding.h"
-
-using namespace mozilla::dom;
-using namespace mozilla::dom::gonk;
-using namespace android;
-using namespace mozilla;
-using namespace mozilla::dom::bluetooth;
-
-#undef LOG
-#define LOG(args...) __android_log_print(ANDROID_LOG_INFO, "AudioManager" , ## args)
-
-#define HEADPHONES_STATUS_HEADSET u"headset"
-#define HEADPHONES_STATUS_HEADPHONE u"headphone"
-#define HEADPHONES_STATUS_OFF u"off"
-#define HEADPHONES_STATUS_UNKNOWN u"unknown"
-#define HEADPHONES_STATUS_CHANGED "headphones-status-changed"
-#define MOZ_SETTINGS_CHANGE_ID "mozsettings-changed"
-#define AUDIO_CHANNEL_PROCESS_CHANGED "audio-channel-process-changed"
-#define AUDIO_POLICY_SERVICE_NAME "media.audio_policy"
-#define SETTINGS_SERVICE "@mozilla.org/settingsService;1"
-
-// Refer AudioService.java from Android
-static const uint32_t sMaxStreamVolumeTbl[AUDIO_STREAM_CNT] = {
- 5, // voice call
- 15, // system
- 15, // ring
- 15, // music
- 15, // alarm
- 15, // notification
- 15, // BT SCO
- 15, // enforced audible
- 15, // DTMF
- 15, // TTS
-#if ANDROID_VERSION < 19
- 15, // FM
-#endif
-};
-
-static const uint32_t sDefaultStreamVolumeTbl[AUDIO_STREAM_CNT] = {
- 3, // voice call
- 8, // system
- 8, // ring
- 8, // music
- 8, // alarm
- 8, // notification
- 8, // BT SCO
- 15, // enforced audible // XXX Handle as fixed maximum audio setting
- 8, // DTMF
- 8, // TTS
-#if ANDROID_VERSION < 19
- 8, // FM
-#endif
-};
-
-static const int32_t sStreamVolumeAliasTbl[AUDIO_STREAM_CNT] = {
- AUDIO_STREAM_VOICE_CALL, // voice call
- AUDIO_STREAM_NOTIFICATION, // system
- AUDIO_STREAM_NOTIFICATION, // ring
- AUDIO_STREAM_MUSIC, // music
- AUDIO_STREAM_ALARM, // alarm
- AUDIO_STREAM_NOTIFICATION, // notification
- AUDIO_STREAM_BLUETOOTH_SCO, // BT SCO
- AUDIO_STREAM_ENFORCED_AUDIBLE,// enforced audible
- AUDIO_STREAM_DTMF, // DTMF
- AUDIO_STREAM_TTS, // TTS
-#if ANDROID_VERSION < 19
- AUDIO_STREAM_MUSIC, // FM
-#endif
-};
-
-static const uint32_t sChannelStreamTbl[NUMBER_OF_AUDIO_CHANNELS] = {
- AUDIO_STREAM_MUSIC, // AudioChannel::Normal
- AUDIO_STREAM_MUSIC, // AudioChannel::Content
- AUDIO_STREAM_NOTIFICATION, // AudioChannel::Notification
- AUDIO_STREAM_ALARM, // AudioChannel::Alarm
- AUDIO_STREAM_VOICE_CALL, // AudioChannel::Telephony
- AUDIO_STREAM_RING, // AudioChannel::Ringer
- AUDIO_STREAM_ENFORCED_AUDIBLE,// AudioChannel::Publicnotification
- AUDIO_STREAM_SYSTEM, // AudioChannel::System
-};
-
-
-struct AudioDeviceInfo {
- /** The string the value maps to */
- const char* tag;
- /** The enum value that maps to this string */
- uint32_t value;
-};
-
-// Mappings audio output devices to strings.
-static const AudioDeviceInfo kAudioDeviceInfos[] = {
- { "earpiece", AUDIO_DEVICE_OUT_EARPIECE },
- { "speaker", AUDIO_DEVICE_OUT_SPEAKER },
- { "wired_headset", AUDIO_DEVICE_OUT_WIRED_HEADSET },
- { "wired_headphone", AUDIO_DEVICE_OUT_WIRED_HEADPHONE },
- { "bt_scoheadset", AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET },
- { "bt_a2dp", AUDIO_DEVICE_OUT_BLUETOOTH_A2DP },
-};
-
-static const int kBtSampleRate = 8000;
-
-typedef MozPromise<bool, const char*, true> VolumeInitPromise;
-
-namespace mozilla {
-namespace dom {
-namespace gonk {
-
-/**
- * We have five sound volume settings from UX spec,
- * You can see more informations in Bug1068219.
- * (1) Media : music, video, FM ...
- * (2) Notification : ringer, notification ...
- * (3) Alarm : alarm
- * (4) Telephony : GSM call, WebRTC call
- * (5) Bluetooth SCO : SCO call
- **/
-struct VolumeData {
- const char* mChannelName;
- int32_t mStreamType;
-};
-
-static const VolumeData gVolumeData[] = {
- {"audio.volume.content", AUDIO_STREAM_MUSIC},
- {"audio.volume.notification", AUDIO_STREAM_NOTIFICATION},
- {"audio.volume.alarm", AUDIO_STREAM_ALARM},
- {"audio.volume.telephony", AUDIO_STREAM_VOICE_CALL},
- {"audio.volume.bt_sco", AUDIO_STREAM_BLUETOOTH_SCO}
-};
-
-class RunnableCallTask : public Runnable
-{
-public:
- explicit RunnableCallTask(nsIRunnable* aRunnable)
- : mRunnable(aRunnable) {}
-
- NS_IMETHOD Run() override
- {
- return mRunnable->Run();
- }
-protected:
- nsCOMPtr<nsIRunnable> mRunnable;
-};
-
-nsCOMPtr<nsISettingsServiceLock>
-GetSettingServiceLock()
-{
- nsresult rv;
- nsCOMPtr<nsISettingsService> service = do_GetService(SETTINGS_SERVICE, &rv);
- if (NS_WARN_IF(NS_FAILED(rv))) {
- return nullptr;
- }
-
- nsCOMPtr<nsISettingsServiceLock> lock;
- rv = service->CreateLock(nullptr, getter_AddRefs(lock));
- if (NS_WARN_IF(NS_FAILED(rv))) {
- return nullptr;
- }
- return lock.forget();
-}
-
-#if ANDROID_VERSION >= 21
-class GonkAudioPortCallback : public AudioSystem::AudioPortCallback
-{
-public:
- virtual void onAudioPortListUpdate()
- {
- nsCOMPtr<nsIRunnable> runnable =
- NS_NewRunnableFunction([]() {
- MOZ_ASSERT(NS_IsMainThread());
- RefPtr<AudioManager> audioManager = AudioManager::GetInstance();
- NS_ENSURE_TRUE(audioManager.get(), );
- audioManager->UpdateCachedActiveDevicesForStreams();
- audioManager->MaybeUpdateVolumeSettingToDatabase();
- });
- NS_DispatchToMainThread(runnable);
- }
- virtual void onAudioPatchListUpdate() { }
- virtual void onServiceDied() { }
-};
-#endif
-
-void
-AudioManager::HandleAudioFlingerDied()
-{
- //Disable volume change notification
- mIsVolumeInited = false;
-
- uint32_t attempt;
- for (attempt = 0; attempt < 50; attempt++) {
- if (defaultServiceManager()->checkService(String16(AUDIO_POLICY_SERVICE_NAME)) != 0) {
- break;
- }
- LOG("AudioPolicyService is dead! attempt=%d", attempt);
- usleep(1000 * 200);
- }
-
- MOZ_RELEASE_ASSERT(attempt < 50);
-
- // Indicate to audio HAL that we start the reconfiguration phase after a media
- // server crash
- AudioSystem::setParameters(0, String8("restarting=true"));
-
- // Restore device connection states
- SetAllDeviceConnectionStates();
-
- // Restore call state
-#if ANDROID_VERSION < 17
- AudioSystem::setPhoneState(mPhoneState);
-#else
- AudioSystem::setPhoneState(static_cast<audio_mode_t>(mPhoneState));
-#endif
-
- // Restore master volume
- AudioSystem::setMasterVolume(1.0);
-
- // Restore stream volumes
- for (uint32_t streamType = 0; streamType < AUDIO_STREAM_CNT; ++streamType) {
- mStreamStates[streamType]->InitStreamVolume();
- mStreamStates[streamType]->RestoreVolumeIndexToAllDevices();
- }
-
- // Indicate the end of reconfiguration phase to audio HAL
- AudioSystem::setParameters(0, String8("restarting=true"));
-
- // Enable volume change notification
- mIsVolumeInited = true;
- mAudioOutDevicesUpdated = 0;
- MaybeUpdateVolumeSettingToDatabase(true);
-}
-
-class VolumeInitCallback final : public nsISettingsServiceCallback
-{
-public:
- NS_DECL_ISUPPORTS
-
- VolumeInitCallback()
- : mInitCounter(0)
- {
- mPromise = mPromiseHolder.Ensure(__func__);
- }
-
- RefPtr<VolumeInitPromise> GetPromise() const
- {
- return mPromise;
- }
-
- NS_IMETHOD Handle(const nsAString& aName, JS::Handle<JS::Value> aResult)
- {
- RefPtr<AudioManager> audioManager = AudioManager::GetInstance();
- MOZ_ASSERT(audioManager);
- for (uint32_t idx = 0; idx < MOZ_ARRAY_LENGTH(gVolumeData); ++idx) {
- NS_ConvertASCIItoUTF16 volumeType(gVolumeData[idx].mChannelName);
- if (StringBeginsWith(aName, volumeType)) {
- uint32_t device = GetDeviceFromSettingName(aName);
- MOZ_ASSERT(device != AUDIO_DEVICE_NONE);
- if (aResult.isInt32()) {
- int32_t stream = gVolumeData[idx].mStreamType;
- uint32_t volIndex = aResult.toInt32();
- nsresult rv = audioManager->ValidateVolumeIndex(stream, volIndex);
- if (NS_WARN_IF(NS_FAILED(rv))) {
- mPromiseHolder.Reject("Error : invalid volume index.", __func__);
- return rv;
- }
- audioManager->SetStreamVolumeForDevice(stream, volIndex, device);
- }
-
- if (++mInitCounter == MOZ_ARRAY_LENGTH(kAudioDeviceInfos) * MOZ_ARRAY_LENGTH(gVolumeData)) {
- mPromiseHolder.Resolve(true, __func__);
- }
- return NS_OK;
- }
- }
- mPromiseHolder.Reject("Error : unexpected audio init event.", __func__);
- return NS_OK;
- }
-
- NS_IMETHOD HandleError(const nsAString& aName)
- {
- mPromiseHolder.Reject(NS_ConvertUTF16toUTF8(aName).get(), __func__);
- return NS_OK;
- }
-
-protected:
- ~VolumeInitCallback() {}
-
- uint32_t GetDeviceFromSettingName(const nsAString& aName) const
- {
- for (uint32_t idx = 0; idx < MOZ_ARRAY_LENGTH(kAudioDeviceInfos); ++idx) {
- NS_ConvertASCIItoUTF16 device(kAudioDeviceInfos[idx].tag);
- if (StringEndsWith(aName, device)) {
- return kAudioDeviceInfos[idx].value;
- }
- }
- return AUDIO_DEVICE_NONE;
- }
-
- RefPtr<VolumeInitPromise> mPromise;
- MozPromiseHolder<VolumeInitPromise> mPromiseHolder;
- uint32_t mInitCounter;
-};
-
-NS_IMPL_ISUPPORTS(VolumeInitCallback, nsISettingsServiceCallback)
-
-static void
-BinderDeadCallback(status_t aErr)
-{
- if (aErr != DEAD_OBJECT) {
- return;
- }
-
- nsCOMPtr<nsIRunnable> runnable =
- NS_NewRunnableFunction([]() {
- MOZ_ASSERT(NS_IsMainThread());
- RefPtr<AudioManager> audioManager = AudioManager::GetInstance();
- NS_ENSURE_TRUE(audioManager.get(), );
- audioManager->HandleAudioFlingerDied();
- });
-
- NS_DispatchToMainThread(runnable);
-}
-
-bool
-AudioManager::IsFmOutConnected()
-{
- return mConnectedDevices.Get(AUDIO_DEVICE_OUT_FM, nullptr);
-}
-
-NS_IMPL_ISUPPORTS(AudioManager, nsIAudioManager, nsIObserver)
-
-void
-AudioManager::AudioOutDeviceUpdated(uint32_t aDevice)
-{
- MOZ_ASSERT(audio_is_output_device(aDevice));
- mAudioOutDevicesUpdated |= aDevice;
-}
-
-void
-AudioManager::UpdateHeadsetConnectionState(hal::SwitchState aState)
-{
- bool headphoneConnected = mConnectedDevices.Get(AUDIO_DEVICE_OUT_WIRED_HEADPHONE,
- nullptr);
- bool headsetConnected = mConnectedDevices.Get(AUDIO_DEVICE_OUT_WIRED_HEADSET,
- nullptr);
- if (aState == hal::SWITCH_STATE_HEADSET) {
- UpdateDeviceConnectionState(true,
- AUDIO_DEVICE_OUT_WIRED_HEADSET,
- NS_LITERAL_CSTRING(""));
- } else if (aState == hal::SWITCH_STATE_HEADPHONE) {
- UpdateDeviceConnectionState(true,
- AUDIO_DEVICE_OUT_WIRED_HEADPHONE,
- NS_LITERAL_CSTRING(""));
- } else if (aState == hal::SWITCH_STATE_OFF) {
- if (headsetConnected) {
- UpdateDeviceConnectionState(false,
- AUDIO_DEVICE_OUT_WIRED_HEADSET,
- NS_LITERAL_CSTRING(""));
- }
- if (headphoneConnected) {
- UpdateDeviceConnectionState(false,
- AUDIO_DEVICE_OUT_WIRED_HEADPHONE,
- NS_LITERAL_CSTRING(""));
- }
- }
-}
-
-void
-AudioManager::UpdateDeviceConnectionState(bool aIsConnected, uint32_t aDevice, const nsCString& aDeviceName)
-{
-#if ANDROID_VERSION >= 15
- bool isConnected = mConnectedDevices.Get(aDevice, nullptr);
- if (isConnected && !aIsConnected) {
- AudioSystem::setDeviceConnectionState(static_cast<audio_devices_t>(aDevice),
- AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
- aDeviceName.get());
- mConnectedDevices.Remove(aDevice);
- } else if(!isConnected && aIsConnected) {
- AudioSystem::setDeviceConnectionState(static_cast<audio_devices_t>(aDevice),
- AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
- aDeviceName.get());
- mConnectedDevices.Put(aDevice, aDeviceName);
- }
-#if ANDROID_VERSION < 21
- // Manually call it, since AudioPortCallback is not supported.
- // Current volumes might be changed by updating active devices in android
- // AudioPolicyManager.
- MaybeUpdateVolumeSettingToDatabase();
-#endif
-#else
- NS_NOTREACHED("Doesn't support audio routing on GB version");
-#endif
-}
-
-void
-AudioManager::SetAllDeviceConnectionStates()
-{
- for (auto iter = mConnectedDevices.Iter(); !iter.Done(); iter.Next()) {
- const uint32_t& device = iter.Key();
- nsCString& deviceAddress = iter.Data();
- AudioSystem::setDeviceConnectionState(static_cast<audio_devices_t>(device),
- AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
- deviceAddress.get());
- }
-#if ANDROID_VERSION < 21
- // Manually call it, since AudioPortCallback is not supported.
- // Current volumes might be changed by updating active devices in android
- // AudioPolicyManager.
- MaybeUpdateVolumeSettingToDatabase(true);
-#endif
-}
-
-void
-AudioManager::HandleBluetoothStatusChanged(nsISupports* aSubject,
- const char* aTopic,
- const nsCString aAddress)
-{
-#ifdef MOZ_B2G_BT
- bool isConnected = false;
- if (!strcmp(aTopic, BLUETOOTH_SCO_STATUS_CHANGED_ID)) {
- BluetoothHfpManagerBase* hfp =
- static_cast<BluetoothHfpManagerBase*>(aSubject);
- isConnected = hfp->IsScoConnected();
- } else {
- BluetoothProfileManagerBase* profile =
- static_cast<BluetoothProfileManagerBase*>(aSubject);
- isConnected = profile->IsConnected();
- }
-
- if (!strcmp(aTopic, BLUETOOTH_SCO_STATUS_CHANGED_ID)) {
- if (isConnected) {
- String8 cmd;
- cmd.appendFormat("bt_samplerate=%d", kBtSampleRate);
- AudioSystem::setParameters(0, cmd);
- SetForceForUse(nsIAudioManager::USE_COMMUNICATION, nsIAudioManager::FORCE_BT_SCO);
- } else {
- int32_t force;
- GetForceForUse(nsIAudioManager::USE_COMMUNICATION, &force);
- if (force == nsIAudioManager::FORCE_BT_SCO) {
- SetForceForUse(nsIAudioManager::USE_COMMUNICATION, nsIAudioManager::FORCE_NONE);
- }
- }
- } else if (!strcmp(aTopic, BLUETOOTH_A2DP_STATUS_CHANGED_ID)) {
- if (!isConnected && mA2dpSwitchDone) {
- RefPtr<AudioManager> self = this;
- nsCOMPtr<nsIRunnable> runnable =
- NS_NewRunnableFunction([self, isConnected, aAddress]() {
- if (self->mA2dpSwitchDone) {
- return;
- }
- self->UpdateDeviceConnectionState(isConnected,
- AUDIO_DEVICE_OUT_BLUETOOTH_A2DP,
- aAddress);
-
- String8 cmd("bluetooth_enabled=false");
- AudioSystem::setParameters(0, cmd);
- cmd.setTo("A2dpSuspended=true");
- AudioSystem::setParameters(0, cmd);
- self->mA2dpSwitchDone = true;
- });
- MessageLoop::current()->PostDelayedTask(
- MakeAndAddRef<RunnableCallTask>(runnable), 1000);
-
- mA2dpSwitchDone = false;
- } else {
- UpdateDeviceConnectionState(isConnected,
- AUDIO_DEVICE_OUT_BLUETOOTH_A2DP,
- aAddress);
- String8 cmd("bluetooth_enabled=true");
- AudioSystem::setParameters(0, cmd);
- cmd.setTo("A2dpSuspended=false");
- AudioSystem::setParameters(0, cmd);
- mA2dpSwitchDone = true;
-#if ANDROID_VERSION >= 17
- if (AudioSystem::getForceUse(AUDIO_POLICY_FORCE_FOR_MEDIA) == AUDIO_POLICY_FORCE_NO_BT_A2DP) {
- SetForceForUse(AUDIO_POLICY_FORCE_FOR_MEDIA, AUDIO_POLICY_FORCE_NONE);
- }
-#endif
- }
- mBluetoothA2dpEnabled = isConnected;
- } else if (!strcmp(aTopic, BLUETOOTH_HFP_STATUS_CHANGED_ID)) {
- UpdateDeviceConnectionState(isConnected,
- AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET,
- aAddress);
- UpdateDeviceConnectionState(isConnected,
- AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET,
- aAddress);
- } else if (!strcmp(aTopic, BLUETOOTH_HFP_NREC_STATUS_CHANGED_ID)) {
- String8 cmd;
- BluetoothHfpManagerBase* hfp =
- static_cast<BluetoothHfpManagerBase*>(aSubject);
- if (hfp->IsNrecEnabled()) {
- cmd.setTo("bt_headset_name=<unknown>;bt_headset_nrec=on");
- AudioSystem::setParameters(0, cmd);
- } else {
- cmd.setTo("bt_headset_name=<unknown>;bt_headset_nrec=off");
- AudioSystem::setParameters(0, cmd);
- }
- }
-#endif
-}
-
-void
-AudioManager::HandleAudioChannelProcessChanged()
-{
- // Note: If the user answers a VoIP call (e.g. WebRTC calls) during the
- // telephony call (GSM/CDMA calls) the audio manager won't set the
- // PHONE_STATE_IN_COMMUNICATION audio state. Once the telephony call finishes
- // the RIL plumbing sets the PHONE_STATE_NORMAL audio state. This seems to be
- // an issue for the VoIP call but it is not. Once the RIL plumbing sets the
- // the PHONE_STATE_NORMAL audio state the AudioManager::mPhoneAudioAgent
- // member will call the NotifyStoppedPlaying() method causing that this function will
- // be called again and therefore the audio manager sets the
- // PHONE_STATE_IN_COMMUNICATION audio state.
-
- if ((mPhoneState == PHONE_STATE_IN_CALL) ||
- (mPhoneState == PHONE_STATE_RINGTONE)) {
- return;
- }
-
- RefPtr<AudioChannelService> service = AudioChannelService::GetOrCreate();
- bool telephonyChannelIsActive = service && service->TelephonyChannelIsActive();
- telephonyChannelIsActive ? SetPhoneState(PHONE_STATE_IN_COMMUNICATION) :
- SetPhoneState(PHONE_STATE_NORMAL);
-}
-
-nsresult
-AudioManager::Observe(nsISupports* aSubject,
- const char* aTopic,
- const char16_t* aData)
-{
- if ((strcmp(aTopic, BLUETOOTH_SCO_STATUS_CHANGED_ID) == 0) ||
- (strcmp(aTopic, BLUETOOTH_HFP_STATUS_CHANGED_ID) == 0) ||
- (strcmp(aTopic, BLUETOOTH_HFP_NREC_STATUS_CHANGED_ID) == 0) ||
- (strcmp(aTopic, BLUETOOTH_A2DP_STATUS_CHANGED_ID) == 0)) {
- nsCString address = NS_ConvertUTF16toUTF8(nsDependentString(aData));
- if (address.IsEmpty()) {
- NS_WARNING(nsPrintfCString("Invalid address of %s", aTopic).get());
- return NS_ERROR_FAILURE;
- }
-
- HandleBluetoothStatusChanged(aSubject, aTopic, address);
- return NS_OK;
- }
-
- else if (!strcmp(aTopic, AUDIO_CHANNEL_PROCESS_CHANGED)) {
- HandleAudioChannelProcessChanged();
- return NS_OK;
- }
-
- // To process the volume control on each volume categories according to
- // change of settings
- else if (!strcmp(aTopic, MOZ_SETTINGS_CHANGE_ID)) {
- RootedDictionary<dom::SettingChangeNotification> setting(RootingCx());
- if (!WrappedJSToDictionary(aSubject, setting)) {
- return NS_OK;
- }
- if (!StringBeginsWith(setting.mKey, NS_LITERAL_STRING("audio.volume."))) {
- return NS_OK;
- }
- if (!setting.mValue.isNumber()) {
- return NS_OK;
- }
-
- uint32_t volIndex = setting.mValue.toNumber();
- for (uint32_t idx = 0; idx < MOZ_ARRAY_LENGTH(gVolumeData); ++idx) {
- if (setting.mKey.EqualsASCII(gVolumeData[idx].mChannelName)) {
- SetStreamVolumeIndex(gVolumeData[idx].mStreamType, volIndex);
- return NS_OK;
- }
- }
- }
-
- NS_WARNING("Unexpected topic in AudioManager");
- return NS_ERROR_FAILURE;
-}
-
-static void
-NotifyHeadphonesStatus(hal::SwitchState aState)
-{
- nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
- if (obs) {
- if (aState == hal::SWITCH_STATE_HEADSET) {
- obs->NotifyObservers(nullptr, HEADPHONES_STATUS_CHANGED, HEADPHONES_STATUS_HEADSET);
- } else if (aState == hal::SWITCH_STATE_HEADPHONE) {
- obs->NotifyObservers(nullptr, HEADPHONES_STATUS_CHANGED, HEADPHONES_STATUS_HEADPHONE);
- } else if (aState == hal::SWITCH_STATE_OFF) {
- obs->NotifyObservers(nullptr, HEADPHONES_STATUS_CHANGED, HEADPHONES_STATUS_OFF);
- } else {
- obs->NotifyObservers(nullptr, HEADPHONES_STATUS_CHANGED, HEADPHONES_STATUS_UNKNOWN);
- }
- }
-}
-
-class HeadphoneSwitchObserver : public hal::SwitchObserver
-{
-public:
- void Notify(const hal::SwitchEvent& aEvent) {
- RefPtr<AudioManager> audioManager = AudioManager::GetInstance();
- MOZ_ASSERT(audioManager);
- audioManager->HandleHeadphoneSwitchEvent(aEvent);
- }
-};
-
-void
-AudioManager::HandleHeadphoneSwitchEvent(const hal::SwitchEvent& aEvent)
-{
- NotifyHeadphonesStatus(aEvent.status());
- // When user pulled out the headset, a delay of routing here can avoid the leakage of audio from speaker.
- if (aEvent.status() == hal::SWITCH_STATE_OFF && mSwitchDone) {
-
- RefPtr<AudioManager> self = this;
- nsCOMPtr<nsIRunnable> runnable =
- NS_NewRunnableFunction([self]() {
- if (self->mSwitchDone) {
- return;
- }
- self->UpdateHeadsetConnectionState(hal::SWITCH_STATE_OFF);
- self->mSwitchDone = true;
- });
- MessageLoop::current()->PostDelayedTask(
- MakeAndAddRef<RunnableCallTask>(runnable), 1000);
- mSwitchDone = false;
- } else if (aEvent.status() != hal::SWITCH_STATE_OFF) {
- UpdateHeadsetConnectionState(aEvent.status());
- mSwitchDone = true;
- }
- // Handle the coexistence of a2dp / headset device, latest one wins.
-#if ANDROID_VERSION >= 17
- int32_t forceUse = 0;
- GetForceForUse(AUDIO_POLICY_FORCE_FOR_MEDIA, &forceUse);
- if (aEvent.status() != hal::SWITCH_STATE_OFF && mBluetoothA2dpEnabled) {
- SetForceForUse(AUDIO_POLICY_FORCE_FOR_MEDIA, AUDIO_POLICY_FORCE_NO_BT_A2DP);
- } else if (forceUse == AUDIO_POLICY_FORCE_NO_BT_A2DP) {
- SetForceForUse(AUDIO_POLICY_FORCE_FOR_MEDIA, AUDIO_POLICY_FORCE_NONE);
- }
-#endif
-}
-
-AudioManager::AudioManager()
- : mPhoneState(PHONE_STATE_CURRENT)
- , mIsVolumeInited(false)
- , mAudioOutDevicesUpdated(0)
- , mSwitchDone(true)
-#if defined(MOZ_B2G_BT) || ANDROID_VERSION >= 17
- , mBluetoothA2dpEnabled(false)
-#endif
-#ifdef MOZ_B2G_BT
- , mA2dpSwitchDone(true)
-#endif
- , mObserver(new HeadphoneSwitchObserver())
-{
- for (uint32_t idx = 0; idx < MOZ_ARRAY_LENGTH(kAudioDeviceInfos); ++idx) {
- mAudioDeviceTableIdMaps.Put(kAudioDeviceInfos[idx].value, idx);
- }
-
- AudioSystem::setErrorCallback(BinderDeadCallback);
-#if ANDROID_VERSION >= 21
- android::sp<GonkAudioPortCallback> callback = new GonkAudioPortCallback();
- AudioSystem::setAudioPortCallback(callback);
-#endif
-
- // Create VolumeStreamStates
- for (uint32_t loop = 0; loop < AUDIO_STREAM_CNT; ++loop) {
- VolumeStreamState* streamState =
- new VolumeStreamState(*this, static_cast<audio_stream_type_t>(loop));
- mStreamStates.AppendElement(streamState);
- }
- // Initialize stream volumes with default values
- for (int32_t streamType = 0; streamType < AUDIO_STREAM_MAX; streamType++) {
- uint32_t volIndex = sDefaultStreamVolumeTbl[streamType];
- SetStreamVolumeForDevice(streamType, volIndex, AUDIO_DEVICE_OUT_DEFAULT);
- }
- UpdateCachedActiveDevicesForStreams();
-
- RegisterSwitchObserver(hal::SWITCH_HEADPHONES, mObserver);
- // Initialize headhone/heaset status
- UpdateHeadsetConnectionState(hal::GetCurrentSwitchState(hal::SWITCH_HEADPHONES));
- NotifyHeadphonesStatus(hal::GetCurrentSwitchState(hal::SWITCH_HEADPHONES));
-
- // Get the initial volume index from settings DB during boot up.
- InitVolumeFromDatabase();
-
- // Gecko only control stream volume not master so set to default value
- // directly.
- AudioSystem::setMasterVolume(1.0);
-
- nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
- NS_ENSURE_TRUE_VOID(obs);
- if (NS_FAILED(obs->AddObserver(this, BLUETOOTH_SCO_STATUS_CHANGED_ID, false))) {
- NS_WARNING("Failed to add bluetooth sco status changed observer!");
- }
- if (NS_FAILED(obs->AddObserver(this, BLUETOOTH_A2DP_STATUS_CHANGED_ID, false))) {
- NS_WARNING("Failed to add bluetooth a2dp status changed observer!");
- }
- if (NS_FAILED(obs->AddObserver(this, BLUETOOTH_HFP_STATUS_CHANGED_ID, false))) {
- NS_WARNING("Failed to add bluetooth hfp status changed observer!");
- }
- if (NS_FAILED(obs->AddObserver(this, BLUETOOTH_HFP_NREC_STATUS_CHANGED_ID, false))) {
- NS_WARNING("Failed to add bluetooth hfp NREC status changed observer!");
- }
- if (NS_FAILED(obs->AddObserver(this, MOZ_SETTINGS_CHANGE_ID, false))) {
- NS_WARNING("Failed to add mozsettings-changed observer!");
- }
- if (NS_FAILED(obs->AddObserver(this, AUDIO_CHANNEL_PROCESS_CHANGED, false))) {
- NS_WARNING("Failed to add audio-channel-process-changed observer!");
- }
-
-}
-
-AudioManager::~AudioManager() {
- AudioSystem::setErrorCallback(nullptr);
-#if ANDROID_VERSION >= 21
- AudioSystem::setAudioPortCallback(nullptr);
-#endif
- hal::UnregisterSwitchObserver(hal::SWITCH_HEADPHONES, mObserver);
-
- nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
- NS_ENSURE_TRUE_VOID(obs);
- if (NS_FAILED(obs->RemoveObserver(this, BLUETOOTH_SCO_STATUS_CHANGED_ID))) {
- NS_WARNING("Failed to remove bluetooth sco status changed observer!");
- }
- if (NS_FAILED(obs->RemoveObserver(this, BLUETOOTH_A2DP_STATUS_CHANGED_ID))) {
- NS_WARNING("Failed to remove bluetooth a2dp status changed observer!");
- }
- if (NS_FAILED(obs->RemoveObserver(this, BLUETOOTH_HFP_STATUS_CHANGED_ID))) {
- NS_WARNING("Failed to remove bluetooth hfp status changed observer!");
- }
- if (NS_FAILED(obs->RemoveObserver(this, BLUETOOTH_HFP_NREC_STATUS_CHANGED_ID))) {
- NS_WARNING("Failed to remove bluetooth hfp NREC status changed observer!");
- }
- if (NS_FAILED(obs->RemoveObserver(this, MOZ_SETTINGS_CHANGE_ID))) {
- NS_WARNING("Failed to remove mozsettings-changed observer!");
- }
- if (NS_FAILED(obs->RemoveObserver(this, AUDIO_CHANNEL_PROCESS_CHANGED))) {
- NS_WARNING("Failed to remove audio-channel-process-changed!");
- }
-}
-
-static StaticRefPtr<AudioManager> sAudioManager;
-
-already_AddRefed<AudioManager>
-AudioManager::GetInstance()
-{
- // Avoid createing AudioManager from content process.
- if (!XRE_IsParentProcess()) {
- MOZ_CRASH("Non-chrome processes should not get here.");
- }
-
- // Avoid createing multiple AudioManager instance inside main process.
- if (!sAudioManager) {
- sAudioManager = new AudioManager();
- ClearOnShutdown(&sAudioManager);
- }
-
- RefPtr<AudioManager> audioMgr = sAudioManager.get();
- return audioMgr.forget();
-}
-
-NS_IMETHODIMP
-AudioManager::GetMicrophoneMuted(bool* aMicrophoneMuted)
-{
-
- if (AudioSystem::isMicrophoneMuted(aMicrophoneMuted)) {
- return NS_ERROR_FAILURE;
- }
- return NS_OK;
-}
-
-NS_IMETHODIMP
-AudioManager::SetMicrophoneMuted(bool aMicrophoneMuted)
-{
- if (!AudioSystem::muteMicrophone(aMicrophoneMuted)) {
- return NS_OK;
- }
- return NS_ERROR_FAILURE;
-}
-
-NS_IMETHODIMP
-AudioManager::GetPhoneState(int32_t* aState)
-{
- *aState = mPhoneState;
- return NS_OK;
-}
-
-NS_IMETHODIMP
-AudioManager::SetPhoneState(int32_t aState)
-{
- if (mPhoneState == aState) {
- return NS_OK;
- }
-
- nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
- if (obs) {
- nsString state;
- state.AppendInt(aState);
- obs->NotifyObservers(nullptr, "phone-state-changed", state.get());
- }
-
-#if ANDROID_VERSION < 17
- if (AudioSystem::setPhoneState(aState)) {
-#else
- if (AudioSystem::setPhoneState(static_cast<audio_mode_t>(aState))) {
-#endif
- return NS_ERROR_FAILURE;
- }
-
-#if ANDROID_VERSION < 21
- // Manually call it, since AudioPortCallback is not supported.
- // Current volumes might be changed by updating active devices in android
- // AudioPolicyManager.
- MaybeUpdateVolumeSettingToDatabase();
-#endif
- mPhoneState = aState;
- return NS_OK;
-}
-
-NS_IMETHODIMP
-AudioManager::SetForceForUse(int32_t aUsage, int32_t aForce)
-{
-#if ANDROID_VERSION >= 15
- status_t status = AudioSystem::setForceUse(
- (audio_policy_force_use_t)aUsage,
- (audio_policy_forced_cfg_t)aForce);
-#if ANDROID_VERSION < 21
- // Manually call it, since AudioPortCallback is not supported.
- // Current volumes might be changed by updating active devices in android
- // AudioPolicyManager.
- MaybeUpdateVolumeSettingToDatabase();
-#endif
- return status ? NS_ERROR_FAILURE : NS_OK;
-#else
- NS_NOTREACHED("Doesn't support force routing on GB version");
- return NS_ERROR_UNEXPECTED;
-#endif
-}
-
-NS_IMETHODIMP
-AudioManager::GetForceForUse(int32_t aUsage, int32_t* aForce) {
-#if ANDROID_VERSION >= 15
- *aForce = AudioSystem::getForceUse((audio_policy_force_use_t)aUsage);
- return NS_OK;
-#else
- NS_NOTREACHED("Doesn't support force routing on GB version");
- return NS_ERROR_UNEXPECTED;
-#endif
-}
-
-NS_IMETHODIMP
-AudioManager::SetAudioChannelVolume(uint32_t aChannel, uint32_t aIndex)
-{
- if (aChannel >= NUMBER_OF_AUDIO_CHANNELS) {
- return NS_ERROR_INVALID_ARG;
- }
-
- return SetStreamVolumeIndex(sChannelStreamTbl[aChannel], aIndex);
-}
-
-NS_IMETHODIMP
-AudioManager::GetAudioChannelVolume(uint32_t aChannel, uint32_t* aIndex)
-{
- if (aChannel >= NUMBER_OF_AUDIO_CHANNELS) {
- return NS_ERROR_INVALID_ARG;
- }
-
- if (!aIndex) {
- return NS_ERROR_NULL_POINTER;
- }
-
- return GetStreamVolumeIndex(sChannelStreamTbl[aChannel], aIndex);
-}
-
-NS_IMETHODIMP
-AudioManager::GetMaxAudioChannelVolume(uint32_t aChannel, uint32_t* aMaxIndex)
-{
- if (aChannel >= NUMBER_OF_AUDIO_CHANNELS) {
- return NS_ERROR_INVALID_ARG;
- }
-
- if (!aMaxIndex) {
- return NS_ERROR_NULL_POINTER;
- }
-
- *aMaxIndex = mStreamStates[sChannelStreamTbl[aChannel]]->GetMaxIndex();
- return NS_OK;
-}
-
-nsresult
-AudioManager::ValidateVolumeIndex(int32_t aStream, uint32_t aIndex) const
-{
- if (aStream <= AUDIO_STREAM_DEFAULT || aStream >= AUDIO_STREAM_MAX) {
- return NS_ERROR_INVALID_ARG;
- }
-
- uint32_t maxIndex = mStreamStates[aStream]->GetMaxIndex();
- if (aIndex > maxIndex) {
- return NS_ERROR_FAILURE;
- }
- return NS_OK;
-}
-
-nsresult
-AudioManager::SetStreamVolumeForDevice(int32_t aStream,
- uint32_t aIndex,
- uint32_t aDevice)
-{
- if (aStream <= AUDIO_STREAM_DEFAULT || aStream >= AUDIO_STREAM_MAX) {
- return NS_ERROR_INVALID_ARG;
- }
-
- int32_t streamAlias = sStreamVolumeAliasTbl[aStream];
- VolumeStreamState* streamState = mStreamStates[streamAlias].get();
- return streamState->SetVolumeIndexToAliasStreams(aIndex, aDevice);
-}
-
-nsresult
-AudioManager::SetStreamVolumeIndex(int32_t aStream, uint32_t aIndex)
-{
- if (aStream <= AUDIO_STREAM_DEFAULT || aStream >= AUDIO_STREAM_MAX) {
- return NS_ERROR_INVALID_ARG;
- }
-
- int32_t streamAlias = sStreamVolumeAliasTbl[aStream];
-
- nsresult rv;
- for (int32_t streamType = 0; streamType < AUDIO_STREAM_MAX; streamType++) {
- if (streamAlias == sStreamVolumeAliasTbl[streamType]) {
- rv = mStreamStates[streamType]->SetVolumeIndexToActiveDevices(aIndex);
- if (NS_WARN_IF(NS_FAILED(rv))) {
- return rv;
- }
- }
- }
-
- // AUDIO_STREAM_FM is not used on recent gonk.
- // AUDIO_STREAM_MUSIC is used for FM radio volume control.
-#if ANDROID_VERSION < 19
- if (streamAlias == AUDIO_STREAM_MUSIC && IsFmOutConnected()) {
- rv = mStreamStates[AUDIO_STREAM_FM]->
- SetVolumeIndex(aIndex, AUDIO_DEVICE_OUT_FM);
- if (NS_WARN_IF(NS_FAILED(rv))) {
- return rv;
- }
- }
-#endif
-
- MaybeUpdateVolumeSettingToDatabase();
- return NS_OK;
-}
-
-nsresult
-AudioManager::GetStreamVolumeIndex(int32_t aStream, uint32_t *aIndex)
-{
- if (!aIndex) {
- return NS_ERROR_INVALID_ARG;
- }
-
- if (aStream <= AUDIO_STREAM_DEFAULT || aStream >= AUDIO_STREAM_MAX) {
- return NS_ERROR_INVALID_ARG;
- }
-
- *aIndex = mStreamStates[aStream]->GetVolumeIndex();
- return NS_OK;
-}
-
-nsAutoCString
-AudioManager::AppendDeviceToVolumeSetting(const char* aName, uint32_t aDevice)
-{
- nsAutoCString topic;
- topic.Assign(aName);
- topic.Append(".");
- uint32_t index = 0;
- DebugOnly<bool> exist = mAudioDeviceTableIdMaps.Get(aDevice, &index);
- MOZ_ASSERT(exist);
- topic.Append(kAudioDeviceInfos[index].tag);
- return topic;
-}
-
-void
-AudioManager::InitVolumeFromDatabase()
-{
- nsresult rv;
- nsCOMPtr<nsISettingsService> service = do_GetService(SETTINGS_SERVICE, &rv);
- if (NS_WARN_IF(NS_FAILED(rv))) {
- return;
- }
-
- nsCOMPtr<nsISettingsServiceLock> lock;
- rv = service->CreateLock(nullptr, getter_AddRefs(lock));
- if (NS_WARN_IF(NS_FAILED(rv))) {
- return;
- }
-
- RefPtr<VolumeInitCallback> callback = new VolumeInitCallback();
- MOZ_ASSERT(callback);
- callback->GetPromise()->Then(AbstractThread::MainThread(), __func__, this,
- &AudioManager::InitDeviceVolumeSucceeded,
- &AudioManager::InitDeviceVolumeFailed);
-
- for (uint32_t idx = 0; idx < MOZ_ARRAY_LENGTH(gVolumeData); ++idx) {
- for (uint32_t idx2 = 0; idx2 < MOZ_ARRAY_LENGTH(kAudioDeviceInfos); ++idx2) {
- lock->Get(AppendDeviceToVolumeSetting(gVolumeData[idx].mChannelName,
- kAudioDeviceInfos[idx2].value).get(),
- callback);
- }
- }
-}
-
-void
-AudioManager::InitDeviceVolumeSucceeded()
-{
- mIsVolumeInited = true;
- MaybeUpdateVolumeSettingToDatabase(true);
-}
-
-void
-AudioManager::InitDeviceVolumeFailed(const char* aError)
-{
- // Default volume of AUDIO_DEVICE_OUT_DEFAULT is already set.
- mIsVolumeInited = true;
- MaybeUpdateVolumeSettingToDatabase(true);
- NS_WARNING(aError);
-}
-
-void
-AudioManager::MaybeUpdateVolumeSettingToDatabase(bool aForce)
-{
- if (!mIsVolumeInited) {
- return;
- }
-
- nsCOMPtr<nsISettingsServiceLock> lock = GetSettingServiceLock();
- if (NS_WARN_IF(!lock)) {
- return;
- }
-
- // Send events to update the Gaia volumes
- JS::Rooted<JS::Value> value(RootingCx());
- uint32_t volume = 0;
- for (uint32_t idx = 0; idx < MOZ_ARRAY_LENGTH(gVolumeData); ++idx) {
- int32_t streamType = gVolumeData[idx].mStreamType;
- VolumeStreamState* streamState = mStreamStates[streamType].get();
- if(!aForce && !streamState->IsDevicesChanged()) {
- continue;
- }
- // Get volume index of active device.
- volume = streamState->GetVolumeIndex();
- value.setInt32(volume);
- lock->Set(gVolumeData[idx].mChannelName, value, nullptr, nullptr);
- }
-
- // For reducing the code dependency, Gaia doesn't need to know the
- // device volume, it only need to care about different volume categories.
- // However, we need to send the setting volume to the permanent database,
- // so that we can store the volume setting even if the phone reboots.
-
- for (uint32_t idx = 0; idx < MOZ_ARRAY_LENGTH(gVolumeData); ++idx) {
- int32_t streamType = gVolumeData[idx].mStreamType;
- VolumeStreamState* streamState = mStreamStates[streamType].get();
-
- if(!streamState->IsVolumeIndexesChanged()) {
- continue;
- }
-
- uint32_t remainingDevices = mAudioOutDevicesUpdated;
- for (uint32_t i = 0; remainingDevices != 0; i++) {
- uint32_t device = (1 << i);
- if ((device & remainingDevices) == 0) {
- continue;
- }
- remainingDevices &= ~device;
- if (!mAudioDeviceTableIdMaps.Get(device, nullptr)) {
- continue;
- }
- volume = streamState->GetVolumeIndex(device);
- value.setInt32(volume);
- lock->Set(AppendDeviceToVolumeSetting(gVolumeData[idx].mChannelName,
- device).get(),
- value, nullptr, nullptr);
- }
- }
-
- // Clear changed flags
- for (uint32_t idx = 0; idx < MOZ_ARRAY_LENGTH(gVolumeData); ++idx) {
- int32_t streamType = gVolumeData[idx].mStreamType;
- mStreamStates[streamType]->ClearDevicesChanged();
- mStreamStates[streamType]->ClearVolumeIndexesChanged();
- }
- // Clear mAudioOutDevicesUpdated
- mAudioOutDevicesUpdated = 0;
-}
-
-void
-AudioManager::UpdateCachedActiveDevicesForStreams()
-{
- // This function updates cached active devices for streams.
- // It is used for optimization of GetDevicesForStream() since L.
- // AudioManager could know when active devices
- // are changed in AudioPolicyManager by onAudioPortListUpdate().
- // Except it, AudioManager normally do not need to ask AuidoPolicyManager
- // about current active devices of streams and could use cached values.
- // Before L, onAudioPortListUpdate() does not exist and GetDevicesForStream()
- // does not use the cache. Therefore this function do nothing.
-#if ANDROID_VERSION >= 21
- for (int32_t streamType = 0; streamType < AUDIO_STREAM_MAX; streamType++) {
- // Update cached active devices of stream
- mStreamStates[streamType]->IsDevicesChanged(false /* aFromCache */);
- }
-#endif
-}
-
-uint32_t
-AudioManager::GetDevicesForStream(int32_t aStream, bool aFromCache)
-{
-#if ANDROID_VERSION >= 21
- // Since Lollipop, devices update could be notified by AudioPortCallback.
- // Cached values can be used if there is no update.
- if (aFromCache) {
- return mStreamStates[aStream]->GetLastDevices();
- }
-#endif
-
-#if ANDROID_VERSION >= 17
- audio_devices_t devices =
- AudioSystem::getDevicesForStream(static_cast<audio_stream_type_t>(aStream));
-
- return static_cast<uint32_t>(devices);
-#else
- // Per audio out device volume is not supported.
- // Use AUDIO_DEVICE_OUT_SPEAKER just to store audio volume to DB.
- return AUDIO_DEVICE_OUT_SPEAKER;
-#endif
-}
-
-uint32_t
-AudioManager::GetDeviceForStream(int32_t aStream)
-{
- uint32_t devices =
- GetDevicesForStream(static_cast<audio_stream_type_t>(aStream));
- uint32_t device = SelectDeviceFromDevices(devices);
- return device;
-}
-
-/* static */ uint32_t
-AudioManager::SelectDeviceFromDevices(uint32_t aOutDevices)
-{
- uint32_t device = aOutDevices;
-
- // See android AudioService.getDeviceForStream().
- // AudioPolicyManager expects it.
- // See also android AudioPolicyManager::getDeviceForVolume().
- if ((device & (device - 1)) != 0) {
- // Multiple device selection.
- if ((device & AUDIO_DEVICE_OUT_SPEAKER) != 0) {
- device = AUDIO_DEVICE_OUT_SPEAKER;
-#if ANDROID_VERSION >= 21
- } else if ((device & AUDIO_DEVICE_OUT_HDMI_ARC) != 0) {
- device = AUDIO_DEVICE_OUT_HDMI_ARC;
- } else if ((device & AUDIO_DEVICE_OUT_SPDIF) != 0) {
- device = AUDIO_DEVICE_OUT_SPDIF;
- } else if ((device & AUDIO_DEVICE_OUT_AUX_LINE) != 0) {
- device = AUDIO_DEVICE_OUT_AUX_LINE;
-#endif
- } else {
- device &= AUDIO_DEVICE_OUT_ALL_A2DP;
- }
- }
- MOZ_ASSERT(audio_is_output_device(device));
- return device;
-}
-AudioManager::VolumeStreamState::VolumeStreamState(AudioManager& aManager,
- int32_t aStreamType)
- : mManager(aManager)
- , mStreamType(aStreamType)
- , mLastDevices(0)
- , mIsDevicesChanged(true)
- , mIsVolumeIndexesChanged(true)
-{
- InitStreamVolume();
-}
-
-bool
-AudioManager::VolumeStreamState::IsDevicesChanged(bool aFromCache)
-{
- uint32_t devices = mManager.GetDevicesForStream(mStreamType, aFromCache);
- if (devices != mLastDevices) {
- mLastDevices = devices;
- mIsDevicesChanged = true;
- }
- return mIsDevicesChanged;
-}
-
-void
-AudioManager::VolumeStreamState::ClearDevicesChanged()
-{
- mIsDevicesChanged = false;
-}
-
-bool
-AudioManager::VolumeStreamState::IsVolumeIndexesChanged()
-{
- return mIsVolumeIndexesChanged;
-}
-
-void
-AudioManager::VolumeStreamState::ClearVolumeIndexesChanged()
-{
- mIsVolumeIndexesChanged = false;
-}
-
-void
-AudioManager::VolumeStreamState::InitStreamVolume()
-{
- AudioSystem::initStreamVolume(static_cast<audio_stream_type_t>(mStreamType),
- 0,
- GetMaxIndex());
-}
-
-uint32_t
-AudioManager::VolumeStreamState::GetMaxIndex()
-{
- return sMaxStreamVolumeTbl[mStreamType];
-}
-
-uint32_t
-AudioManager::VolumeStreamState::GetDefaultIndex()
-{
- return sDefaultStreamVolumeTbl[mStreamType];
-}
-
-uint32_t
-AudioManager::VolumeStreamState::GetVolumeIndex()
-{
- uint32_t device = mManager.GetDeviceForStream(mStreamType);
- return GetVolumeIndex(device);
-}
-
-uint32_t
-AudioManager::VolumeStreamState::GetVolumeIndex(uint32_t aDevice)
-{
- uint32_t index = 0;
- bool ret = mVolumeIndexes.Get(aDevice, &index);
- if (!ret) {
- index = mVolumeIndexes.Get(AUDIO_DEVICE_OUT_DEFAULT);
- }
- return index;
-}
-
-nsresult
-AudioManager::VolumeStreamState::SetVolumeIndexToActiveDevices(uint32_t aIndex)
-{
- uint32_t device = mManager.GetDeviceForStream(mStreamType);
-
- // Update volume index for device
- uint32_t oldVolumeIndex = 0;
- bool exist = mVolumeIndexes.Get(device, &oldVolumeIndex);
- if (exist && aIndex == oldVolumeIndex) {
- // No update
- return NS_OK;
- }
-
- // AudioPolicyManager::setStreamVolumeIndex() set volumes of all active
- // devices for stream.
- nsresult rv;
- rv = SetVolumeIndexToConsistentDeviceIfNeeded(aIndex, device);
- if (NS_WARN_IF(NS_FAILED(rv))) {
- return rv;
- }
-
- return NS_OK;
-}
-
-nsresult
-AudioManager::VolumeStreamState::SetVolumeIndexToAliasStreams(uint32_t aIndex,
- uint32_t aDevice)
-{
- uint32_t oldVolumeIndex = 0;
- bool exist = mVolumeIndexes.Get(aDevice, &oldVolumeIndex);
- if (exist && aIndex == oldVolumeIndex) {
- // No update
- return NS_OK;
- }
-
- nsresult rv = SetVolumeIndexToConsistentDeviceIfNeeded(aIndex, aDevice);
- if (NS_WARN_IF(NS_FAILED(rv))) {
- return rv;
- }
-
- for (int32_t streamType = 0; streamType < AUDIO_STREAM_MAX; streamType++) {
- if ((streamType != mStreamType) &&
- sStreamVolumeAliasTbl[streamType] == mStreamType) {
- // Rescaling of index is not necessary.
- rv = mManager.mStreamStates[streamType]->
- SetVolumeIndexToAliasStreams(aIndex, aDevice);
- if (NS_WARN_IF(NS_FAILED(rv))) {
- return rv;
- }
- }
- }
-
- return NS_OK;
-}
-
-nsresult
-AudioManager::VolumeStreamState::SetVolumeIndexToConsistentDeviceIfNeeded(uint32_t aIndex, uint32_t aDevice)
-{
- nsresult rv;
- if (aDevice == AUDIO_DEVICE_OUT_SPEAKER || aDevice == AUDIO_DEVICE_OUT_EARPIECE) {
- // Set AUDIO_DEVICE_OUT_SPEAKER and AUDIO_DEVICE_OUT_EARPIECE to same volume.
- rv = SetVolumeIndex(aIndex, AUDIO_DEVICE_OUT_SPEAKER);
- if (NS_WARN_IF(NS_FAILED(rv))) {
- return rv;
- }
- rv = SetVolumeIndex(aIndex, AUDIO_DEVICE_OUT_EARPIECE);
- if (NS_WARN_IF(NS_FAILED(rv))) {
- return rv;
- }
- } else {
- // No alias device
- rv = SetVolumeIndex(aIndex, aDevice);
- }
- return rv;
-}
-
-nsresult
-AudioManager::VolumeStreamState::SetVolumeIndex(uint32_t aIndex,
- uint32_t aDevice,
- bool aUpdateCache)
-{
- status_t rv;
-#if ANDROID_VERSION >= 17
- if (aUpdateCache) {
- mVolumeIndexes.Put(aDevice, aIndex);
- mIsVolumeIndexesChanged = true;
- mManager.AudioOutDeviceUpdated(aDevice);
- }
-
- rv = AudioSystem::setStreamVolumeIndex(
- static_cast<audio_stream_type_t>(mStreamType),
- aIndex,
- aDevice);
- return rv ? NS_ERROR_FAILURE : NS_OK;
-#else
- if (aUpdateCache) {
- // Per audio out device volume is not supported.
- // Use AUDIO_DEVICE_OUT_SPEAKER just to store audio volume to DB.
- mVolumeIndexes.Put(AUDIO_DEVICE_OUT_SPEAKER, aIndex);
- mIsVolumeIndexesChanged = true;
- mManager.AudioOutDeviceUpdated(AUDIO_DEVICE_OUT_SPEAKER);
- }
- rv = AudioSystem::setStreamVolumeIndex(
- static_cast<audio_stream_type_t>(mStreamType),
- aIndex);
- return rv ? NS_ERROR_FAILURE : NS_OK;
-#endif
-}
-
-void
-AudioManager::VolumeStreamState::RestoreVolumeIndexToAllDevices()
-{
- for (auto iter = mVolumeIndexes.Iter(); !iter.Done(); iter.Next()) {
- const uint32_t& key = iter.Key();
- uint32_t& index = iter.Data();
- SetVolumeIndex(key, index, /* aUpdateCache */ false);
- }
-}
-
-} /* namespace gonk */
-} /* namespace dom */
-} /* namespace mozilla */
diff --git a/dom/system/gonk/AudioManager.h b/dom/system/gonk/AudioManager.h
deleted file mode 100644
index f56eaad6cf..0000000000
--- a/dom/system/gonk/AudioManager.h
+++ /dev/null
@@ -1,180 +0,0 @@
-/* Copyright 2012 Mozilla Foundation and Mozilla contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef mozilla_dom_system_b2g_audiomanager_h__
-#define mozilla_dom_system_b2g_audiomanager_h__
-
-#include "mozilla/HalTypes.h"
-#include "mozilla/Observer.h"
-#include "mozilla/UniquePtr.h"
-#include "nsAutoPtr.h"
-#include "nsDataHashtable.h"
-#include "nsIAudioManager.h"
-#include "nsIObserver.h"
-#include "android_audio/AudioSystem.h"
-
-// {b2b51423-502d-4d77-89b3-7786b562b084}
-#define NS_AUDIOMANAGER_CID {0x94f6fd70, 0x7615, 0x4af9, \
- {0x89, 0x10, 0xf9, 0x3c, 0x55, 0xe6, 0x62, 0xec}}
-#define NS_AUDIOMANAGER_CONTRACTID "@mozilla.org/telephony/audiomanager;1"
-
-class nsISettingsServiceLock;
-
-namespace mozilla {
-namespace hal {
-class SwitchEvent;
-typedef Observer<SwitchEvent> SwitchObserver;
-} // namespace hal
-
-namespace dom {
-namespace gonk {
-
-class VolumeInitCallback;
-
-class AudioManager final : public nsIAudioManager
- , public nsIObserver
-{
-public:
- static already_AddRefed<AudioManager> GetInstance();
-
- NS_DECL_ISUPPORTS
- NS_DECL_NSIAUDIOMANAGER
- NS_DECL_NSIOBSERVER
-
- // Validate whether the volume index is within the range
- nsresult ValidateVolumeIndex(int32_t aStream, uint32_t aIndex) const;
-
- // Called when android AudioFlinger in mediaserver is died
- void HandleAudioFlingerDied();
-
- void HandleHeadphoneSwitchEvent(const hal::SwitchEvent& aEvent);
-
- class VolumeStreamState {
- public:
- explicit VolumeStreamState(AudioManager& aManager, int32_t aStreamType);
- int32_t GetStreamType()
- {
- return mStreamType;
- }
- bool IsDevicesChanged(bool aFromCache = true);
- void ClearDevicesChanged();
- uint32_t GetLastDevices()
- {
- return mLastDevices;
- }
- bool IsVolumeIndexesChanged();
- void ClearVolumeIndexesChanged();
- void InitStreamVolume();
- uint32_t GetMaxIndex();
- uint32_t GetDefaultIndex();
- uint32_t GetVolumeIndex();
- uint32_t GetVolumeIndex(uint32_t aDevice);
- void ClearCurrentVolumeUpdated();
- // Set volume index to all active devices.
- // Active devices are chosen by android AudioPolicyManager.
- nsresult SetVolumeIndexToActiveDevices(uint32_t aIndex);
- // Set volume index to all alias streams for device. Alias streams have same volume.
- nsresult SetVolumeIndexToAliasStreams(uint32_t aIndex, uint32_t aDevice);
- nsresult SetVolumeIndexToConsistentDeviceIfNeeded(uint32_t aIndex, uint32_t aDevice);
- nsresult SetVolumeIndex(uint32_t aIndex, uint32_t aDevice, bool aUpdateCache = true);
- // Restore volume index to all devices. Called when AudioFlinger is restarted.
- void RestoreVolumeIndexToAllDevices();
- private:
- AudioManager& mManager;
- const int32_t mStreamType;
- uint32_t mLastDevices;
- bool mIsDevicesChanged;
- bool mIsVolumeIndexesChanged;
- nsDataHashtable<nsUint32HashKey, uint32_t> mVolumeIndexes;
- };
-
-protected:
- int32_t mPhoneState;
-
- bool mIsVolumeInited;
-
- // A bitwise variable for volume update of audio output devices,
- // clear it after store the value into database.
- uint32_t mAudioOutDevicesUpdated;
-
- // Connected devices that are controlled by setDeviceConnectionState()
- nsDataHashtable<nsUint32HashKey, nsCString> mConnectedDevices;
-
- nsDataHashtable<nsUint32HashKey, uint32_t> mAudioDeviceTableIdMaps;
-
- bool mSwitchDone;
-
-#if defined(MOZ_B2G_BT) || ANDROID_VERSION >= 17
- bool mBluetoothA2dpEnabled;
-#endif
-#ifdef MOZ_B2G_BT
- bool mA2dpSwitchDone;
-#endif
- nsTArray<UniquePtr<VolumeStreamState> > mStreamStates;
- uint32_t mLastChannelVolume[AUDIO_STREAM_CNT];
-
- bool IsFmOutConnected();
-
- nsresult SetStreamVolumeForDevice(int32_t aStream,
- uint32_t aIndex,
- uint32_t aDevice);
- nsresult SetStreamVolumeIndex(int32_t aStream, uint32_t aIndex);
- nsresult GetStreamVolumeIndex(int32_t aStream, uint32_t* aIndex);
-
- void UpdateCachedActiveDevicesForStreams();
- uint32_t GetDevicesForStream(int32_t aStream, bool aFromCache = true);
- uint32_t GetDeviceForStream(int32_t aStream);
- // Choose one device as representative of active devices.
- static uint32_t SelectDeviceFromDevices(uint32_t aOutDevices);
-
-private:
- nsAutoPtr<mozilla::hal::SwitchObserver> mObserver;
-
- void HandleBluetoothStatusChanged(nsISupports* aSubject,
- const char* aTopic,
- const nsCString aAddress);
- void HandleAudioChannelProcessChanged();
-
- // Append the audio output device to the volume setting string.
- nsAutoCString AppendDeviceToVolumeSetting(const char* aName,
- uint32_t aDevice);
-
- // We store the volume setting in the database, these are related functions.
- void InitVolumeFromDatabase();
- void MaybeUpdateVolumeSettingToDatabase(bool aForce = false);
-
- // Promise functions.
- void InitDeviceVolumeSucceeded();
- void InitDeviceVolumeFailed(const char* aError);
-
- void AudioOutDeviceUpdated(uint32_t aDevice);
-
- void UpdateHeadsetConnectionState(hal::SwitchState aState);
- void UpdateDeviceConnectionState(bool aIsConnected, uint32_t aDevice, const nsCString& aDeviceName);
- void SetAllDeviceConnectionStates();
-
- AudioManager();
- ~AudioManager();
-
- friend class VolumeInitCallback;
- friend class VolumeStreamState;
- friend class GonkAudioPortCallback;
-};
-
-} /* namespace gonk */
-} /* namespace dom */
-} /* namespace mozilla */
-
-#endif // mozilla_dom_system_b2g_audiomanager_h__
diff --git a/dom/system/gonk/AutoMounter.cpp b/dom/system/gonk/AutoMounter.cpp
deleted file mode 100644
index 52c4554fb8..0000000000
--- a/dom/system/gonk/AutoMounter.cpp
+++ /dev/null
@@ -1,1496 +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 <errno.h>
-#include <fcntl.h>
-#include <pthread.h>
-#include <signal.h>
-#include <string.h>
-#include <strings.h>
-#include <unistd.h>
-#include <sys/statfs.h>
-
-#include <arpa/inet.h>
-#include <linux/types.h>
-#include <linux/netlink.h>
-#include <netinet/in.h>
-#include <sys/socket.h>
-#include <android/log.h>
-#include <cutils/properties.h>
-
-#include "AutoMounter.h"
-#include "nsVolumeService.h"
-#include "AutoMounterSetting.h"
-#include "base/message_loop.h"
-#include "base/task.h"
-#include "mozilla/AutoRestore.h"
-#include "mozilla/FileUtils.h"
-#include "mozilla/Hal.h"
-#include "mozilla/StaticPtr.h"
-#include "MozMtpServer.h"
-#include "MozMtpStorage.h"
-#include "nsCharSeparatedTokenizer.h"
-#include "nsMemory.h"
-#include "nsString.h"
-#include "nsThreadUtils.h"
-#include "nsXULAppAPI.h"
-#include "OpenFileFinder.h"
-#include "Volume.h"
-#include "VolumeManager.h"
-#include "nsIStatusReporter.h"
-
-USING_MTP_NAMESPACE
-
-/**************************************************************************
-*
-* The following "switch" files are available for monitoring usb
-* connections:
-*
-* /sys/devices/virtual/switch/usb_connected/state
-* /sys/devices/virtual/switch/usb_configuration/state
-*
-* Under gingerbread, only the usb_configuration seems to be available.
-* Starting with honeycomb, usb_connected was also added.
-*
-* When a cable insertion/removal occurs, then a uevent similar to the
-* following will be generted:
-*
-* change@/devices/virtual/switch/usb_configuration
-* ACTION=change
-* DEVPATH=/devices/virtual/switch/usb_configuration
-* SUBSYSTEM=switch
-* SWITCH_NAME=usb_configuration
-* SWITCH_STATE=0
-* SEQNUM=5038
-*
-* SWITCH_STATE will be 0 after a removal and 1 after an insertion
-*
-**************************************************************************/
-
-#define USB_CONFIGURATION_SWITCH_NAME NS_LITERAL_STRING("usb_configuration")
-
-#define GB_SYS_UMS_ENABLE "/sys/devices/virtual/usb_composite/usb_mass_storage/enable"
-#define GB_SYS_USB_CONFIGURED "/sys/devices/virtual/switch/usb_configuration/state"
-
-#define ICS_SYS_USB_FUNCTIONS "/sys/devices/virtual/android_usb/android0/functions"
-#define ICS_SYS_UMS_DIRECTORY "/sys/devices/virtual/android_usb/android0/f_mass_storage"
-#define ICS_SYS_MTP_DIRECTORY "/sys/devices/virtual/android_usb/android0/f_mtp"
-#define ICS_SYS_USB_STATE "/sys/devices/virtual/android_usb/android0/state"
-
-#undef USE_DEBUG // MozMtpDatabase.h also defines USE_DEBUG
-#define USE_DEBUG 0
-
-#undef LOG
-#undef LOGW
-#undef ERR
-#define LOG(args...) __android_log_print(ANDROID_LOG_INFO, "AutoMounter", ## args)
-#define LOGW(args...) __android_log_print(ANDROID_LOG_WARN, "AutoMounter", ## args)
-#define ERR(args...) __android_log_print(ANDROID_LOG_ERROR, "AutoMounter", ## args)
-
-#undef DBG
-#if USE_DEBUG
-#define DBG(args...) __android_log_print(ANDROID_LOG_DEBUG, "AutoMounter" , ## args)
-#else
-#define DBG(args...)
-#endif
-
-namespace mozilla {
-namespace system {
-
-#define SYS_USB_CONFIG "sys.usb.config"
-#define PERSIST_SYS_USB_CONFIG "persist.sys.usb.config"
-
-#define USB_FUNC_ADB "adb"
-#define USB_FUNC_MTP "mtp"
-#define USB_FUNC_NONE "none"
-#define USB_FUNC_RNDIS "rndis"
-#define USB_FUNC_UMS "mass_storage"
-#define USB_FUNC_DEFAULT "default"
-
-class AutoMounter;
-
-static void SetAutoMounterStatus(int32_t aStatus);
-
-/***************************************************************************/
-
-inline const char* SwitchStateStr(const hal::SwitchEvent& aEvent)
-{
- return aEvent.status() == hal::SWITCH_STATE_ON ? "plugged" : "unplugged";
-}
-
-/***************************************************************************/
-
-static bool
-IsUsbCablePluggedIn()
-{
-#if 0
- // Use this code when bug 745078 gets fixed (or use whatever the
- // appropriate method is)
- return GetCurrentSwitchEvent(SWITCH_USB) == hal::SWITCH_STATE_ON;
-#else
- // Until then, just go read the file directly
- if (access(ICS_SYS_USB_STATE, F_OK) == 0) {
- char usbState[20];
- if (ReadSysFile(ICS_SYS_USB_STATE, usbState, sizeof(usbState))) {
- DBG("IsUsbCablePluggedIn: state = '%s'", usbState);
- return strcmp(usbState, "CONFIGURED") == 0 ||
- strcmp(usbState, "CONNECTED") == 0;
- }
- ERR("Error reading file '%s': %s", ICS_SYS_USB_STATE, strerror(errno));
- return false;
- }
- bool configured;
- if (ReadSysFile(GB_SYS_USB_CONFIGURED, &configured)) {
- return configured;
- }
- ERR("Error reading file '%s': %s", GB_SYS_USB_CONFIGURED, strerror(errno));
- return false;
-#endif
-}
-
-static bool
-IsUsbConfigured()
-{
- if (access(ICS_SYS_USB_STATE, F_OK) == 0) {
- char usbState[20];
- if (ReadSysFile(ICS_SYS_USB_STATE, usbState, sizeof(usbState))) {
- DBG("IsUsbConfigured: state = '%s'", usbState);
- return strcmp(usbState, "CONFIGURED") == 0;
- }
- ERR("Error reading file '%s': %s", ICS_SYS_USB_STATE, strerror(errno));
- return false;
- }
- bool configured;
- if (ReadSysFile(GB_SYS_USB_CONFIGURED, &configured)) {
- return configured;
- }
- ERR("Error reading file '%s': %s", GB_SYS_USB_CONFIGURED, strerror(errno));
- return false;
-}
-
-/***************************************************************************/
-
-// The AutoVolumeManagerStateObserver allows the AutoMounter to know when
-// the volume manager changes state (i.e. it has finished initialization)
-class AutoVolumeManagerStateObserver : public VolumeManager::StateObserver
-{
-public:
- virtual void Notify(const VolumeManager::StateChangedEvent& aEvent);
-};
-
-// The AutoVolumeEventObserver allows the AutoMounter to know about card
-// insertion and removal, as well as state changes in the volume.
-class AutoVolumeEventObserver : public Volume::EventObserver
-{
-public:
- virtual void Notify(Volume* const& aEvent);
-};
-
-class AutoMounterResponseCallback : public VolumeResponseCallback
-{
-public:
- AutoMounterResponseCallback()
- : mErrorCount(0)
- {
- }
-
-protected:
- virtual void ResponseReceived(const VolumeCommand* aCommand);
-
-private:
- const static int kMaxErrorCount = 3; // Max number of errors before we give up
-
- int mErrorCount;
-};
-
-/***************************************************************************/
-
-class AutoMounter
-{
-public:
- NS_INLINE_DECL_REFCOUNTING(AutoMounter)
-
- typedef nsTArray<RefPtr<Volume>> VolumeArray;
-
- AutoMounter()
- : mState(STATE_IDLE),
- mResponseCallback(new AutoMounterResponseCallback),
- mMode(AUTOMOUNTER_DISABLE)
- {
- VolumeManager::RegisterStateObserver(&mVolumeManagerStateObserver);
- Volume::RegisterVolumeObserver(&mVolumeEventObserver, "AutoMounter");
-
- // It's possible that the VolumeManager is already in the READY state,
- // so we call CheckVolumeSettings here to cover that case. Otherwise,
- // we'll pick it up when the VolumeManage state changes to VOLUMES_READY.
- CheckVolumeSettings();
-
- DBG("Calling UpdateState from constructor");
- UpdateState();
- }
-
- void CheckVolumeSettings()
- {
- if (VolumeManager::State() != VolumeManager::VOLUMES_READY) {
- DBG("CheckVolumeSettings: VolumeManager is NOT READY yet");
- return;
- }
- DBG("CheckVolumeSettings: VolumeManager is READY");
-
- // The VolumeManager knows about all of the volumes from vold. We now
- // know the names of all of the volumes, so we can find out what the
- // initial sharing settings are set to.
-
- VolumeManager::VolumeArray::size_type numVolumes = VolumeManager::NumVolumes();
- VolumeManager::VolumeArray::index_type i;
- for (i = 0; i < numVolumes; i++) {
- RefPtr<Volume> vol = VolumeManager::GetVolume(i);
- if (vol) {
- // We need to pick up the intial value of the
- // ums.volume.NAME.enabled setting.
- AutoMounterSetting::CheckVolumeSettings(vol->Name());
-
- // Note: eventually CheckVolumeSettings will call
- // AutoMounter::SetSharingMode, which will in turn call
- // UpdateState if needed.
- }
- }
- }
-
- void UpdateState();
- void GetStatus(bool& umsAvail, bool& umsConfigured, bool& umsEnabled, bool& mtpAvail,
- bool& mtpConfigured, bool& mtpEnabled, bool& rndisConfigured);
-
- nsresult Dump(nsACString& desc);
-
- void ConfigureUsbFunction(const char* aUsbFunc);
-
- bool StartMtpServer();
- void StopMtpServer();
-
- void StartUmsSharing();
- void StopUmsSharing();
-
-
- const char* ModeStr(int32_t aMode)
- {
- switch (aMode) {
- case AUTOMOUNTER_DISABLE: return "Disable";
- case AUTOMOUNTER_ENABLE_UMS: return "Enable-UMS";
- case AUTOMOUNTER_DISABLE_WHEN_UNPLUGGED: return "DisableWhenUnplugged";
- case AUTOMOUNTER_ENABLE_MTP: return "Enable-MTP";
- }
- return "??? Unknown ???";
- }
-
- bool IsModeEnabled(int32_t aMode)
- {
- return aMode == AUTOMOUNTER_ENABLE_MTP ||
- aMode == AUTOMOUNTER_ENABLE_UMS;
- }
-
- void SetMode(int32_t aMode)
- {
- if ((aMode == AUTOMOUNTER_DISABLE_WHEN_UNPLUGGED) &&
- (mMode == AUTOMOUNTER_DISABLE)) {
- // If it's already disabled, then leave it as disabled.
- // AUTOMOUNTER_DISABLE_WHEN_UNPLUGGED implies "enabled until unplugged"
- aMode = AUTOMOUNTER_DISABLE;
- }
-
- if (aMode == AUTOMOUNTER_DISABLE &&
- mMode == AUTOMOUNTER_ENABLE_UMS && IsUsbCablePluggedIn()) {
- // On many devices (esp non-Samsung), we can't force the disable, so we
- // need to defer until the USB cable is actually unplugged.
- // See bug 777043.
- //
- // Otherwise our attempt to disable it will fail, and we'll wind up in a bad
- // state where the AutoMounter thinks that Sharing has been turned off, but
- // the files are actually still being Shared because the attempt to unshare
- // failed.
- LOG("Attempting to disable UMS. Deferring until USB cable is unplugged.");
- aMode = AUTOMOUNTER_DISABLE_WHEN_UNPLUGGED;
- }
-
- if (aMode != mMode) {
- LOG("Changing mode from '%s' to '%s'", ModeStr(mMode), ModeStr(aMode));
- mMode = aMode;
- DBG("Calling UpdateState due to mode set to %d", mMode);
- UpdateState();
- }
- }
-
- void SetSharingMode(const nsACString& aVolumeName, bool aAllowSharing)
- {
- RefPtr<Volume> vol = VolumeManager::FindVolumeByName(aVolumeName);
- if (!vol) {
- return;
- }
- if (vol->IsSharingEnabled() == aAllowSharing) {
- return;
- }
- vol->SetUnmountRequested(false);
- vol->SetMountRequested(false);
- vol->SetSharingEnabled(aAllowSharing);
- DBG("Calling UpdateState due to volume %s sharing set to %d",
- vol->NameStr(), (int)aAllowSharing);
- UpdateState();
- }
-
- void FormatVolume(const nsACString& aVolumeName)
- {
- RefPtr<Volume> vol = VolumeManager::FindVolumeByName(aVolumeName);
- if (!vol) {
- return;
- }
- if (vol->IsFormatRequested()) {
- return;
- }
- vol->SetUnmountRequested(false);
- vol->SetMountRequested(false);
- vol->SetFormatRequested(true);
- DBG("Calling UpdateState due to volume %s formatting set to %d",
- vol->NameStr(), (int)vol->IsFormatRequested());
- UpdateState();
- }
-
- void MountVolume(const nsACString& aVolumeName)
- {
- RefPtr<Volume> vol = VolumeManager::FindVolumeByName(aVolumeName);
- if (!vol) {
- return;
- }
- vol->SetUnmountRequested(false);
- if (vol->IsMountRequested() || vol->mState == nsIVolume::STATE_MOUNTED) {
- return;
- }
- vol->SetMountRequested(true);
- DBG("Calling UpdateState due to volume %s mounting set to %d",
- vol->NameStr(), (int)vol->IsMountRequested());
- UpdateState();
- }
-
- void UnmountVolume(const nsACString& aVolumeName)
- {
- RefPtr<Volume> vol = VolumeManager::FindVolumeByName(aVolumeName);
- if (!vol) {
- return;
- }
- if (vol->IsUnmountRequested()) {
- return;
- }
- vol->SetMountRequested(false);
- vol->SetUnmountRequested(true);
- DBG("Calling UpdateState due to volume %s unmounting set to %d",
- vol->NameStr(), (int)vol->IsUnmountRequested());
- UpdateState();
- }
-
-protected:
- ~AutoMounter()
- {
- Volume::UnregisterVolumeObserver(&mVolumeEventObserver, "AutoMounter");
- VolumeManager::UnregisterStateObserver(&mVolumeManagerStateObserver);
- }
-
-private:
-
- enum STATE
- {
- // IDLE - Nothing is being shared
- STATE_IDLE,
-
- // We've detected that conditions are right to enable mtp. So we've
- // set sys.usb.config to include mtp, and we're waiting for the USB
- // subsystem to be "configured". Once mtp shows up in
- // then we know
- // that its been configured and we can open /dev/mtp_usb
- STATE_MTP_CONFIGURING,
-
- // mtp has been configured (i.e. mtp now shows up in
- // /sys/devices/virtual/android_usb/android0/functions so we can start
- // the mtp server.
- STATE_MTP_STARTED,
-
- // The mtp server has reported sessionStarted. We'll leave this state
- // when we receive sessionEnded.
- STATE_MTP_CONNECTED,
-
- // We've added mass_storage (aka UMS) to sys.usb.config and we're waiting for
- // mass_storage to appear in /sys/devices/virtual/android_usb/android0/functions
- STATE_UMS_CONFIGURING,
-
- // mass_storage has been configured and we can start sharing once the user
- // enables it.
- STATE_UMS_CONFIGURED,
-
- // USB Tethering is enabled
- STATE_RNDIS_CONFIGURED,
- };
-
- const char *StateStr(STATE aState)
- {
- switch (aState) {
- case STATE_IDLE: return "IDLE";
- case STATE_MTP_CONFIGURING: return "MTP_CONFIGURING";
- case STATE_MTP_CONNECTED: return "MTP_CONNECTED";
- case STATE_MTP_STARTED: return "MTP_STARTED";
- case STATE_UMS_CONFIGURING: return "UMS_CONFIGURING";
- case STATE_UMS_CONFIGURED: return "UMS_CONFIGURED";
- case STATE_RNDIS_CONFIGURED: return "RNDIS_CONFIGURED";
- }
- return "STATE_???";
- }
-
- void SetState(STATE aState)
- {
- const char *oldStateStr = StateStr(mState);
- mState = aState;
- const char *newStateStr = StateStr(mState);
- LOG("AutoMounter state changed from %s to %s", oldStateStr, newStateStr);
- }
-
- STATE mState;
-
- AutoVolumeEventObserver mVolumeEventObserver;
- AutoVolumeManagerStateObserver mVolumeManagerStateObserver;
- RefPtr<VolumeResponseCallback> mResponseCallback;
- int32_t mMode;
- MozMtpStorage::Array mMozMtpStorage;
-};
-
-static StaticRefPtr<AutoMounter> sAutoMounter;
-static StaticRefPtr<MozMtpServer> sMozMtpServer;
-
-// The following is for status reporter
-enum STATE_REPORTER_STATE
-{
- REPORTER_UNREGISTERED,
- REPORTER_REGISTERED
-};
-
-static int status_reporter_progress = REPORTER_UNREGISTERED;
-nsresult getState(nsACString &desc)
-{
- sAutoMounter->Dump(desc);
- return NS_OK;
-}
-NS_STATUS_REPORTER_IMPLEMENT(AutoMounter, "AutoMounter", getState);
-
-/***************************************************************************/
-
-void
-AutoVolumeManagerStateObserver::Notify(const VolumeManager::StateChangedEvent &)
-{
- LOG("VolumeManager state changed event: %s", VolumeManager::StateStr());
-
- if (!sAutoMounter) {
- return;
- }
-
- // In the event that the VolumeManager just entered the VOLUMES_READY state,
- // we call CheckVolumeSettings here (it's possible that this method never
- // gets called if the VolumeManager was already in the VOLUMES_READY state
- // by the time the AutoMounter was constructed).
- sAutoMounter->CheckVolumeSettings();
-
- DBG("Calling UpdateState due to VolumeManagerStateObserver");
- sAutoMounter->UpdateState();
-}
-
-void
-AutoVolumeEventObserver::Notify(Volume * const &)
-{
- if (!sAutoMounter) {
- return;
- }
- DBG("Calling UpdateState due to VolumeEventStateObserver");
- sAutoMounter->UpdateState();
-}
-
-void
-AutoMounterResponseCallback::ResponseReceived(const VolumeCommand* aCommand)
-{
-
- if (WasSuccessful()) {
- DBG("Calling UpdateState due to Volume::OnSuccess");
- mErrorCount = 0;
- sAutoMounter->UpdateState();
- return;
- }
- ERR("Command '%s' failed: %d '%s'",
- aCommand->CmdStr(), ResponseCode(), ResponseStr().get());
-
- if (++mErrorCount < kMaxErrorCount) {
- DBG("Calling UpdateState due to VolumeResponseCallback::OnError");
- sAutoMounter->UpdateState();
- }
-}
-
-static bool
-IsUsbFunctionEnabled(const char* aConfig, const char* aUsbFunc)
-{
- nsAutoCString config(aConfig);
- nsCCharSeparatedTokenizer tokenizer(config, ',');
-
- while (tokenizer.hasMoreTokens()) {
- nsAutoCString token(tokenizer.nextToken());
- if (token.Equals(aUsbFunc)) {
- DBG("IsUsbFunctionEnabled('%s', '%s'): returning true", aConfig, aUsbFunc);
- return true;
- }
- }
- DBG("IsUsbFunctionEnabled('%s', '%s'): returning false", aConfig, aUsbFunc);
- return false;
-}
-
-static void
-SetUsbFunction(const char* aUsbFunc)
-{
- char oldSysUsbConfig[PROPERTY_VALUE_MAX];
- property_get(SYS_USB_CONFIG, oldSysUsbConfig, "");
-
- if (strcmp(oldSysUsbConfig, USB_FUNC_NONE) == 0) {
- // It's quite possible that sys.usb.config may have the value "none". We
- // convert that to an empty string here, and at the end we convert the
- // empty string back to "none".
- oldSysUsbConfig[0] = '\0';
- }
-
- if (IsUsbFunctionEnabled(oldSysUsbConfig, aUsbFunc)) {
- // The function is already configured. Nothing else to do.
- DBG("SetUsbFunction('%s') - already set - nothing to do", aUsbFunc);
- return;
- }
-
- char newSysUsbConfig[PROPERTY_VALUE_MAX];
-
- if (strcmp(aUsbFunc, USB_FUNC_MTP) == 0) {
- // We're enabling MTP. For this we'll wind up using mtp, or mtp,adb
- strlcpy(newSysUsbConfig, USB_FUNC_MTP, sizeof(newSysUsbConfig));
- } else if (strcmp(aUsbFunc, USB_FUNC_UMS) == 0) {
- // We're enabling UMS. For this we make the assumption that the persisted
- // property has mass_storage enabled.
- property_get(PERSIST_SYS_USB_CONFIG, newSysUsbConfig, "");
- } else if (strcmp(aUsbFunc, USB_FUNC_DEFAULT) == 0) {
- // Set the property as PERSIST_SYS_USB_CONFIG
- property_get(PERSIST_SYS_USB_CONFIG, newSysUsbConfig, "");
- } else {
- printf_stderr("AutoMounter::SetUsbFunction Unrecognized aUsbFunc '%s'\n", aUsbFunc);
- MOZ_ASSERT(0);
- return;
- }
-
- // Make sure the new value that we write into sys.usb.config keeps the adb
- // (or non-adb) of the current string.
-
- if (IsUsbFunctionEnabled(oldSysUsbConfig, USB_FUNC_ADB)) {
- // ADB was turned on - keep it on.
- if (!IsUsbFunctionEnabled(newSysUsbConfig, USB_FUNC_ADB)) {
- // Add adb to the new string
- strlcat(newSysUsbConfig, ",", sizeof(newSysUsbConfig));
- strlcat(newSysUsbConfig, USB_FUNC_ADB, sizeof(newSysUsbConfig));
- }
- } else {
- // ADB was turned off - keep it off
- if (IsUsbFunctionEnabled(newSysUsbConfig, USB_FUNC_ADB)) {
- // Remove ADB from the new string.
- if (strcmp(newSysUsbConfig, USB_FUNC_ADB) == 0) {
- newSysUsbConfig[0] = '\0';
- } else {
- nsAutoCString withoutAdb(newSysUsbConfig);
- withoutAdb.ReplaceSubstring( "," USB_FUNC_ADB, "");
- strlcpy(newSysUsbConfig, withoutAdb.get(), sizeof(newSysUsbConfig));
- }
- }
- }
-
- // If the persisted function didn't have mass_storage (this happens on
- // the nexus 4/5, then we can get to here and have oldSysUsbConfig equal
- // to newSysUsbConfig. So we need to check for that.
-
- if (strcmp(oldSysUsbConfig, newSysUsbConfig) == 0) {
- DBG("SetUsbFunction('%s') %s is already set to '%s' - nothing to do",
- aUsbFunc, SYS_USB_CONFIG, newSysUsbConfig);
- return;
- }
-
- if (newSysUsbConfig[0] == '\0') {
- // Convert the empty string back to the string "none"
- strlcpy(newSysUsbConfig, USB_FUNC_NONE, sizeof(newSysUsbConfig));
- }
- LOG("SetUsbFunction(%s) %s from '%s' to '%s'", aUsbFunc, SYS_USB_CONFIG,
- oldSysUsbConfig, newSysUsbConfig);
- property_set(SYS_USB_CONFIG, newSysUsbConfig);
-}
-
-bool
-AutoMounter::StartMtpServer()
-{
- if (sMozMtpServer) {
- // Mtp Server is already running - nothing to do
- return true;
- }
- LOG("Starting MtpServer");
-
- // For debugging, Change the #if 0 to #if 1, and then attach gdb during
- // the 5 second interval below. Otherwise, configuring MTP will cause adb
- // (and thus gdb) to get bounced.
-#if 0
- LOG("Sleeping");
- PRTime now = PR_Now();
- PRTime stopTime = now + 5000000;
- while (PR_Now() < stopTime) {
- LOG("Sleeping...");
- sleep(1);
- }
- LOG("Sleep done");
-#endif
-
- sMozMtpServer = new MozMtpServer();
- if (!sMozMtpServer->Init()) {
- sMozMtpServer = nullptr;
- return false;
- }
-
- VolumeArray::index_type volIndex;
- VolumeArray::size_type numVolumes = VolumeManager::NumVolumes();
- for (volIndex = 0; volIndex < numVolumes; volIndex++) {
- RefPtr<Volume> vol = VolumeManager::GetVolume(volIndex);
- RefPtr<MozMtpStorage> storage = new MozMtpStorage(vol, sMozMtpServer);
- mMozMtpStorage.AppendElement(storage);
- }
-
- sMozMtpServer->Run();
- return true;
-}
-
-void
-AutoMounter::StopMtpServer()
-{
- LOG("Stopping MtpServer");
-
- mMozMtpStorage.Clear();
- sMozMtpServer = nullptr;
-}
-
-/***************************************************************************/
-
-void
-AutoMounter::UpdateState()
-{
- static bool inUpdateState = false;
- if (inUpdateState) {
- // When UpdateState calls SetISharing, this causes a volume state
- // change to occur, which would normally cause UpdateState to be called
- // again. We want the volume state change to go out (so that device
- // storage will see the change in sharing state), but since we're
- // already in UpdateState we just want to prevent recursion from screwing
- // things up.
- return;
- }
- AutoRestore<bool> inUpdateStateDetector(inUpdateState);
- inUpdateState = true;
-
- MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
-
- // If the following preconditions are met:
- // - UMS is available (i.e. compiled into the kernel)
- // - UMS is enabled
- // - AutoMounter is enabled
- // - USB cable is plugged in
- // then we will try to unmount and share
- // otherwise we will try to unshare and mount.
-
- if (VolumeManager::State() != VolumeManager::VOLUMES_READY) {
- // The volume manager isn't in a ready state, so there
- // isn't anything else that we can do.
- LOG("UpdateState: VolumeManager not ready yet");
- return;
- }
-
- if (mResponseCallback->IsPending()) {
- // We only deal with one outstanding volume command at a time,
- // so we need to wait for it to finish.
- return;
- }
-
- // Calling setprop sys.usb.config mtp,adb (or adding mass_storage) will
- // cause /sys/devices/virtual/android_usb/android0/state to go:
- // CONFIGURED -> DISCONNECTED -> CONNECTED -> CONFIGURED
- //
- // Since IsUsbCablePluggedIn returns state == CONFIGURED, it will look
- // like a cable pull and replugin.
- bool umsAvail, umsConfigured, umsEnabled;
- bool mtpAvail, mtpConfigured, mtpEnabled;
- bool rndisConfigured;
- bool usbCablePluggedIn = IsUsbCablePluggedIn();
- GetStatus(umsAvail, umsConfigured, umsEnabled, mtpAvail,
- mtpConfigured, mtpEnabled, rndisConfigured);
- bool enabled = mtpEnabled || umsEnabled;
-
- if (mMode == AUTOMOUNTER_DISABLE_WHEN_UNPLUGGED) {
- // DISABLE_WHEN_UNPLUGGED implies already enabled.
- enabled = usbCablePluggedIn;
- if (!usbCablePluggedIn) {
- mMode = AUTOMOUNTER_DISABLE;
- mtpEnabled = false;
- umsEnabled = false;
- }
- }
-
- DBG("UpdateState: ums:A%dC%dE%d mtp:A%dC%dE%d rndis:%d mode:%d usb:%d mState:%s",
- umsAvail, umsConfigured, umsEnabled,
- mtpAvail, mtpConfigured, mtpEnabled, rndisConfigured,
- mMode, usbCablePluggedIn, StateStr(mState));
-
- switch (mState) {
-
- case STATE_IDLE:
- if (!usbCablePluggedIn) {
- // Stay in the IDLE state. We'll get a CONNECTED or CONFIGURED
- // UEvent when the usb cable is plugged in.
- break;
- }
- if (rndisConfigured) {
- // USB Tethering uses RNDIS. We'll just wait until its turned off.
- SetState(STATE_RNDIS_CONFIGURED);
- break;
- }
- if (mtpEnabled) {
- if (mtpConfigured) {
- // The USB layer has already been configured. Now we can go ahead
- // and start the MTP server. This particular codepath will not
- // normally be taken, but it could happen if you stop and restart
- // b2g while sys.usb.config is set to enable mtp.
- if (StartMtpServer()) {
- SetState(STATE_MTP_STARTED);
- } else {
- if (umsAvail) {
- // Unable to start MTP. Go back to UMS.
- LOG("UpdateState: StartMtpServer failed, switch to UMS");
- SetUsbFunction(USB_FUNC_UMS);
- SetState(STATE_UMS_CONFIGURING);
- } else {
- LOG("UpdateState: StartMtpServer failed, keep idle state");
- SetUsbFunction(USB_FUNC_DEFAULT);
- }
- }
- } else {
- // We need to configure USB to use mtp. Wait for it to be configured
- // before we start the MTP server.
- SetUsbFunction(USB_FUNC_MTP);
- SetState(STATE_MTP_CONFIGURING);
- }
- } else if (umsConfigured) {
- // UMS is already configured.
- SetState(STATE_UMS_CONFIGURED);
- } else if (umsAvail) {
- // We do this whether or not UMS is enabled. With UMS, it's the
- // sharing of the volume which is significant. What is important
- // is that we don't leave it in MTP mode when MTP isn't enabled.
- SetUsbFunction(USB_FUNC_UMS);
- SetState(STATE_UMS_CONFIGURING);
- }
- break;
-
- case STATE_MTP_CONFIGURING:
- // While configuring, the USB configuration state will change from
- // CONFIGURED -> CONNECTED -> DISCONNECTED -> CONNECTED -> CONFIGURED
- // so we don't check for cable unplugged here.
- if (mtpEnabled && mtpConfigured) {
- // The USB layer has been configured. Now we can go ahead and start
- // the MTP server.
- if (StartMtpServer()) {
- SetState(STATE_MTP_STARTED);
- } else {
- // Unable to start MTP. Go back to UMS.
- SetUsbFunction(USB_FUNC_UMS);
- SetState(STATE_UMS_CONFIGURING);
- }
- break;
- }
- if (rndisConfigured) {
- SetState(STATE_RNDIS_CONFIGURED);
- break;
- }
- break;
-
- case STATE_MTP_STARTED:
- if (usbCablePluggedIn && mtpConfigured && mtpEnabled) {
- // Everything is still good. Leave the MTP server running
- break;
- }
- DBG("STATE_MTP_STARTED: About to StopMtpServer "
- "mtpConfigured = %d mtpEnabled = %d usbCablePluggedIn: %d",
- mtpConfigured, mtpEnabled, usbCablePluggedIn);
- StopMtpServer();
- if (rndisConfigured) {
- SetState(STATE_RNDIS_CONFIGURED);
- break;
- }
- if (umsAvail) {
- // Switch back to UMS
- SetUsbFunction(USB_FUNC_UMS);
- SetState(STATE_UMS_CONFIGURING);
- break;
- }
-
- // if ums/rndis is not available and mtp is disable,
- // restore the usb function as PERSIST_SYS_USB_CONFIG.
- SetUsbFunction(USB_FUNC_DEFAULT);
- SetState(STATE_IDLE);
- break;
-
- case STATE_UMS_CONFIGURING:
- if (mtpEnabled) {
- // MTP was enabled. Start reconfiguring.
- SetState(STATE_MTP_CONFIGURING);
- SetUsbFunction(USB_FUNC_MTP);
- break;
- }
- if (rndisConfigured) {
- SetState(STATE_RNDIS_CONFIGURED);
- break;
- }
- // While configuring, the USB configuration state will change from
- // CONFIGURED -> CONNECTED -> DISCONNECTED -> CONNECTED -> CONFIGURED
- // so we don't check for cable unplugged here. However, having said
- // that, we'll often sit in this state while the cable is unplugged,
- // since we might not get any events until the cable gets plugged back
- // in. This is why we need to check for mtpEnabled once we get the
- // configured event.
- if (umsConfigured) {
- SetState(STATE_UMS_CONFIGURED);
- }
- break;
-
- case STATE_UMS_CONFIGURED:
- if (usbCablePluggedIn) {
- if (mtpEnabled) {
- // MTP was enabled. Start reconfiguring.
- SetState(STATE_MTP_CONFIGURING);
- SetUsbFunction(USB_FUNC_MTP);
- break;
- }
- if (umsConfigured && umsEnabled) {
- // This is the normal state when UMS is enabled.
- break;
- }
- }
- if (rndisConfigured) {
- SetState(STATE_RNDIS_CONFIGURED);
- break;
- }
- SetState(STATE_IDLE);
- break;
-
- case STATE_RNDIS_CONFIGURED:
- if (usbCablePluggedIn && rndisConfigured) {
- // Normal state when RNDIS is enabled.
- break;
- }
- SetState(STATE_IDLE);
- break;
-
- default:
- SetState(STATE_IDLE);
- break;
- }
-
- bool tryToShare = umsEnabled && usbCablePluggedIn;
- LOG("UpdateState: ums:A%dC%dE%d mtp:A%dC%dE%d mode:%d usb:%d tryToShare:%d state:%s",
- umsAvail, umsConfigured, umsEnabled,
- mtpAvail, mtpConfigured, mtpEnabled,
- mMode, usbCablePluggedIn, tryToShare, StateStr(mState));
-
- bool filesOpen = false;
- static unsigned filesOpenDelayCount = 0;
- VolumeArray::index_type volIndex;
- VolumeArray::size_type numVolumes = VolumeManager::NumVolumes();
- for (volIndex = 0; volIndex < numVolumes; volIndex++) {
- RefPtr<Volume> vol = VolumeManager::GetVolume(volIndex);
- Volume::STATE volState = vol->State();
-
- if (vol->State() == nsIVolume::STATE_MOUNTED) {
- LOG("UpdateState: Volume %s is %s and %s @ %s gen %d locked %d sharing %s",
- vol->NameStr(), vol->StateStr(),
- vol->MediaPresent() ? "inserted" : "missing",
- vol->MountPoint().get(), vol->MountGeneration(),
- (int)vol->IsMountLocked(),
- vol->CanBeShared() ? (vol->IsSharingEnabled() ?
- (vol->IsSharing() ? "en-y" : "en-n") : "dis") : "x");
- if (vol->IsSharing() && !usbCablePluggedIn) {
- // We call SetIsSharing(true) below to indicate intent to share. This
- // causes a state change which notifys apps, and they'll close any
- // open files, which will initiate the change away from the mounted
- // state and into the sharing state. Normally, when the volume
- // transitions back to the mounted state, then vol->mIsSharing gets set
- // to false. However, if the user pulls the USB cable before we
- // actually start sharing, then the volume never actually leaves
- // the mounted state (and hence never transitions from
- // sharing -> mounted), and mIsSharing never gets set back to false.
- // So we clear mIsSharing here.
- vol->SetIsSharing(false);
- }
- } else {
- LOG("UpdateState: Volume %s is %s and %s", vol->NameStr(), vol->StateStr(),
- vol->MediaPresent() ? "inserted" : "missing");
- }
- if (!vol->MediaPresent()) {
- // No media - nothing we can do
- continue;
- }
-
- if (vol->State() == nsIVolume::STATE_CHECKMNT) {
- // vold reports the volume is "Mounted". Need to check if the volume is
- // accessible by statfs(). Once it can be accessed, set the volume as
- // STATE_MOUNTED, otherwise, post a delay task of UpdateState to check it
- // again.
- struct statfs fsbuf;
- int rc = MOZ_TEMP_FAILURE_RETRY(statfs(vol->MountPoint().get(), &fsbuf));
- if (rc == -1) {
- // statfs() failed. Stay in STATE_CHECKMNT. Any failures here
- // are probably non-recoverable, so we need to wait until
- // something else changes the state back to IDLE/UNMOUNTED, etc.
- ERR("statfs failed for '%s': errno = %d (%s)", vol->NameStr(), errno, strerror(errno));
- continue;
- }
- static int delay = 250;
- if (fsbuf.f_blocks == 0) {
- if (delay <= 4000) {
- LOG("UpdateState: Volume '%s' is inaccessible, checking again in %d msec", vol->NameStr(), delay);
- MessageLoopForIO::current()->
- PostDelayedTask(NewRunnableMethod(this, &AutoMounter::UpdateState),
- delay);
- delay *= 2;
- } else {
- LOG("UpdateState: Volume '%s' is inaccessible, giving up", vol->NameStr());
- }
- continue;
- } else {
- delay = 250;
- vol->SetState(nsIVolume::STATE_MOUNTED);
- }
- }
-
- if ((tryToShare && vol->IsSharingEnabled()) ||
- vol->IsFormatRequested() ||
- vol->IsUnmountRequested()) {
- switch (volState) {
- // We're going to try to unmount the volume
- case nsIVolume::STATE_MOUNTED: {
- if (vol->IsMountLocked()) {
- // The volume is currently locked, so leave it in the mounted
- // state.
- LOGW("UpdateState: Mounted volume %s is locked, not sharing or formatting",
- vol->NameStr());
- break;
- }
-
- // Mark the volume as if we've started sharing/formatting/unmmounting.
- // This will cause apps which watch device storage notifications to see
- // the volume go into the different state, and prompt them to close any
- // open files that they might have.
- if (tryToShare && vol->IsSharingEnabled()) {
- vol->SetIsSharing(true);
- } else if (vol->IsFormatRequested()){
- vol->SetIsFormatting(true);
- } else if (vol->IsUnmountRequested()){
- vol->SetIsUnmounting(true);
- }
-
- // Check to see if there are any open files on the volume and
- // don't initiate the unmount while there are open files.
- OpenFileFinder::Info fileInfo;
- OpenFileFinder fileFinder(vol->MountPoint());
- if (fileFinder.First(&fileInfo)) {
- LOGW("The following files are open under '%s'",
- vol->MountPoint().get());
- do {
- LOGW(" PID: %d file: '%s' app: '%s' comm: '%s' exe: '%s'\n",
- fileInfo.mPid,
- fileInfo.mFileName.get(),
- fileInfo.mAppName.get(),
- fileInfo.mComm.get(),
- fileInfo.mExe.get());
- } while (fileFinder.Next(&fileInfo));
- LOGW("UpdateState: Mounted volume %s has open files, not sharing or formatting",
- vol->NameStr());
-
- // Check again in a few seconds to see if the files are closed.
- // Since we're trying to share the volume, this implies that we're
- // plugged into the PC via USB and this in turn implies that the
- // battery is charging, so we don't need to be too concerned about
- // wasting battery here.
- //
- // If we just detected that there were files open, then we use
- // a short timer. We will have told the apps that we're trying
- // trying to share, and they'll be closing their files. This makes
- // the sharing more responsive. If after a few seconds, the apps
- // haven't closed their files, then we back off.
-
- int delay = 1000;
- if (filesOpenDelayCount > 10) {
- delay = 5000;
- }
- MessageLoopForIO::current()->
- PostDelayedTask(NewRunnableMethod(this, &AutoMounter::UpdateState),
- delay);
- filesOpen = true;
- break;
- }
-
- // Volume is mounted, we need to unmount before
- // we can share.
- LOG("UpdateState: Unmounting %s", vol->NameStr());
- vol->StartUnmount(mResponseCallback);
- return; // UpdateState will be called again when the Unmount command completes
- }
- case nsIVolume::STATE_IDLE:
- case nsIVolume::STATE_MOUNT_FAIL: {
- LOG("UpdateState: Volume %s is %s", vol->NameStr(), vol->StateStr());
- if (vol->IsFormatting() && !vol->IsFormatRequested()) {
- vol->SetFormatRequested(false);
- if (!(tryToShare && vol->IsSharingEnabled()) && volState == nsIVolume::STATE_IDLE) {
- LOG("UpdateState: Mounting %s", vol->NameStr());
- vol->StartMount(mResponseCallback);
- break;
- }
- }
-
- // If there are format and share requests in the same time,
- // we should do format first then share.
- if (vol->IsFormatRequested()) {
- // Volume is unmounted. We can go ahead and format.
- LOG("UpdateState: Formatting %s", vol->NameStr());
- vol->StartFormat(mResponseCallback);
- } else if (tryToShare && vol->IsSharingEnabled() && volState == nsIVolume::STATE_IDLE) {
- // Volume is unmounted. We can go ahead and share.
- LOG("UpdateState: Sharing %s", vol->NameStr());
- vol->StartShare(mResponseCallback);
- }
- return; // UpdateState will be called again when the Share/Format command completes
- }
- default: {
- // Not in a state that we can do anything about.
- break;
- }
- }
- } else {
- // We're going to try and unshare and remount the volumes
- switch (volState) {
- case nsIVolume::STATE_SHARED: {
- // Volume is shared. We can go ahead and unshare.
- LOG("UpdateState: Unsharing %s", vol->NameStr());
- vol->StartUnshare(mResponseCallback);
- return; // UpdateState will be called again when the Unshare command completes
- }
- case nsIVolume::STATE_IDLE: {
- if (!vol->IsUnmountRequested()) {
- // Volume is unmounted and mount-requested, try to mount.
-
- LOG("UpdateState: Mounting %s", vol->NameStr());
- vol->StartMount(mResponseCallback);
- }
- return; // UpdateState will be called again when Mount command completes
- }
- default: {
- // Not in a state that we can do anything about.
- break;
- }
- }
- }
- }
-
- int32_t status = AUTOMOUNTER_STATUS_DISABLED;
- if (filesOpen) {
- filesOpenDelayCount++;
- status = AUTOMOUNTER_STATUS_FILES_OPEN;
- } else if (enabled) {
- filesOpenDelayCount = 0;
- status = AUTOMOUNTER_STATUS_ENABLED;
- }
- SetAutoMounterStatus(status);
-}
-
-/***************************************************************************/
-
-void AutoMounter::GetStatus(bool& umsAvail, bool& umsConfigured, bool& umsEnabled,
- bool& mtpAvail, bool& mtpConfigured, bool& mtpEnabled,
- bool& rndisConfigured)
-{
- umsAvail = false;
- umsConfigured = false;
- umsEnabled = false;
- mtpAvail = false;
- mtpConfigured = false;
- mtpEnabled = false;
- rndisConfigured = false;
-
- if (access(ICS_SYS_USB_FUNCTIONS, F_OK) != 0) {
- return;
- }
-
- char functionsStr[60];
- if (!ReadSysFile(ICS_SYS_USB_FUNCTIONS, functionsStr, sizeof(functionsStr))) {
- ERR("Error reading file '%s': %s", ICS_SYS_USB_FUNCTIONS, strerror(errno));
- functionsStr[0] = '\0';
- }
- DBG("GetStatus: USB functions: '%s'", functionsStr);
-
- bool usbConfigured = IsUsbConfigured();
-
- // On the Nexus 4/5, it advertises that the UMS usb function is available,
- // but we have a further requirement that mass_storage be in the
- // persist.sys.usb.config property.
- char persistSysUsbConfig[PROPERTY_VALUE_MAX];
- property_get(PERSIST_SYS_USB_CONFIG, persistSysUsbConfig, "");
- if (IsUsbFunctionEnabled(persistSysUsbConfig, USB_FUNC_UMS)) {
- umsAvail = (access(ICS_SYS_UMS_DIRECTORY, F_OK) == 0);
- }
- if (umsAvail) {
- umsConfigured = usbConfigured && strstr(functionsStr, USB_FUNC_UMS) != nullptr;
- umsEnabled = (mMode == AUTOMOUNTER_ENABLE_UMS) ||
- ((mMode == AUTOMOUNTER_DISABLE_WHEN_UNPLUGGED) && umsConfigured);
- } else {
- umsConfigured = false;
- umsEnabled = false;
- }
-
- mtpAvail = (access(ICS_SYS_MTP_DIRECTORY, F_OK) == 0);
- if (mtpAvail) {
- mtpConfigured = usbConfigured && strstr(functionsStr, USB_FUNC_MTP) != nullptr;
- mtpEnabled = (mMode == AUTOMOUNTER_ENABLE_MTP) ||
- ((mMode == AUTOMOUNTER_DISABLE_WHEN_UNPLUGGED) && mtpConfigured);
- } else {
- mtpConfigured = false;
- mtpEnabled = false;
- }
-
- rndisConfigured = strstr(functionsStr, USB_FUNC_RNDIS) != nullptr;
-}
-
-
-nsresult AutoMounter::Dump(nsACString& desc)
-{
- DBG("GetState!");
- bool umsAvail, umsConfigured, umsEnabled;
- bool mtpAvail, mtpConfigured, mtpEnabled;
- bool rndisConfigured;
- GetStatus(umsAvail, umsConfigured, umsEnabled, mtpAvail,
- mtpConfigured, mtpEnabled, rndisConfigured);
- if (mMode == AUTOMOUNTER_DISABLE_WHEN_UNPLUGGED) {
- // DISABLE_WHEN_UNPLUGGED implies already enabled.
- if (!IsUsbCablePluggedIn()) {
- mMode = AUTOMOUNTER_DISABLE;
- mtpEnabled = false;
- umsEnabled = false;
- }
- }
-
- // Automounter information
- desc += "Current Mode:";
- desc += ModeStr(mMode);
- desc += "|";
-
-
- desc += "Current State:";
- desc += StateStr(mState);
- desc += "|";
-
- desc += "UMS Status:";
- if (umsAvail) {
- desc += "Available";
- } else {
- desc += "UnAvailable";
- }
- desc += ",";
- if (umsConfigured) {
- desc += "Configured";
- } else {
- desc += "Un-Configured";
- }
- desc += ",";
- if (umsEnabled) {
- desc += "Enabled";
- } else {
- desc += "Disabled";
- }
- desc += "|";
-
-
- desc += "MTP Status:";
- if (mtpAvail) {
- desc += "Available";
- } else {
- desc += "UnAvailable";
- }
- desc += ",";
- if (mtpConfigured) {
- desc += "Configured";
- } else {
- desc += "Un-Configured";
- }
- desc += ",";
- if (mtpEnabled) {
- desc += "Enabled";
- } else {
- desc += "Disabled";
- }
-
-
- // Volume information
- VolumeArray::index_type volIndex;
- VolumeArray::size_type numVolumes = VolumeManager::NumVolumes();
- for (volIndex = 0; volIndex < numVolumes; volIndex++) {
- RefPtr<Volume> vol = VolumeManager::GetVolume(volIndex);
-
- desc += "|";
- desc += vol->NameStr();
- desc += ":";
- desc += vol->StateStr();
- desc += "@";
- desc += vol->MountPoint().get();
-
- if (!vol->MediaPresent()) {
- continue;
- }
-
- if (vol->CanBeShared()) {
- desc += ",CanBeShared";
- }
- if (vol->CanBeFormatted()) {
- desc += ",CanBeFormatted";
- }
- if (vol->CanBeMounted()) {
- desc += ",CanBeMounted";
- }
- if (vol->IsRemovable()) {
- desc += ",Removable";
- }
- if (vol->IsHotSwappable()) {
- desc += ",HotSwappable";
- }
- }
-
- return NS_OK;
-}
-
-
-static void
-InitAutoMounterIOThread()
-{
- MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
- MOZ_ASSERT(!sAutoMounter);
-
- sAutoMounter = new AutoMounter();
-}
-
-static void
-ShutdownAutoMounterIOThread()
-{
- MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
-
- sAutoMounter = nullptr;
- ShutdownVolumeManager();
-}
-
-static void
-SetAutoMounterModeIOThread(const int32_t& aMode)
-{
- MOZ_ASSERT(XRE_IsParentProcess());
- MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
- MOZ_ASSERT(sAutoMounter);
-
- sAutoMounter->SetMode(aMode);
-}
-
-static void
-SetAutoMounterSharingModeIOThread(const nsCString& aVolumeName, const bool& aAllowSharing)
-{
- MOZ_ASSERT(XRE_IsParentProcess());
- MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
- MOZ_ASSERT(sAutoMounter);
-
- sAutoMounter->SetSharingMode(aVolumeName, aAllowSharing);
-}
-
-static void
-AutoMounterFormatVolumeIOThread(const nsCString& aVolumeName)
-{
- MOZ_ASSERT(XRE_IsParentProcess());
- MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
- MOZ_ASSERT(sAutoMounter);
-
- sAutoMounter->FormatVolume(aVolumeName);
-}
-
-static void
-AutoMounterMountVolumeIOThread(const nsCString& aVolumeName)
-{
- MOZ_ASSERT(XRE_IsParentProcess());
- MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
- MOZ_ASSERT(sAutoMounter);
-
- sAutoMounter->MountVolume(aVolumeName);
-}
-
-static void
-AutoMounterUnmountVolumeIOThread(const nsCString& aVolumeName)
-{
- MOZ_ASSERT(XRE_IsParentProcess());
- MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
- MOZ_ASSERT(sAutoMounter);
-
- sAutoMounter->UnmountVolume(aVolumeName);
-}
-
-static void
-UsbCableEventIOThread()
-{
- MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
-
- if (!sAutoMounter) {
- return;
- }
- DBG("Calling UpdateState due to USBCableEvent");
- sAutoMounter->UpdateState();
-}
-
-/**************************************************************************
-*
-* Public API
-*
-* Since the AutoMounter runs in IO Thread context, we need to switch
-* to IOThread context before we can do anything.
-*
-**************************************************************************/
-
-class UsbCableObserver final : public hal::SwitchObserver
-{
- ~UsbCableObserver()
- {
- hal::UnregisterSwitchObserver(hal::SWITCH_USB, this);
- }
-
-public:
- NS_INLINE_DECL_REFCOUNTING(UsbCableObserver)
-
- UsbCableObserver()
- {
- hal::RegisterSwitchObserver(hal::SWITCH_USB, this);
- }
-
- virtual void Notify(const hal::SwitchEvent& aEvent)
- {
- DBG("UsbCable switch device: %d state: %s\n",
- aEvent.device(), SwitchStateStr(aEvent));
- XRE_GetIOMessageLoop()->PostTask(
- NewRunnableFunction(UsbCableEventIOThread));
- }
-};
-
-static StaticRefPtr<UsbCableObserver> sUsbCableObserver;
-static StaticRefPtr<AutoMounterSetting> sAutoMounterSetting;
-
-void
-InitAutoMounter()
-{
- InitVolumeManager();
- sAutoMounterSetting = new AutoMounterSetting();
-
- XRE_GetIOMessageLoop()->PostTask(
- NewRunnableFunction(InitAutoMounterIOThread));
-
- // Switch Observers need to run on the main thread, so we need to
- // start it here and have it send events to the AutoMounter running
- // on the IO Thread.
- sUsbCableObserver = new UsbCableObserver();
-
- // Register status reporter into reporter manager
- if(status_reporter_progress == REPORTER_UNREGISTERED) {
- NS_RegisterStatusReporter(new NS_STATUS_REPORTER_NAME(AutoMounter));
- }
- status_reporter_progress = REPORTER_REGISTERED;
-}
-
-int32_t
-GetAutoMounterStatus()
-{
- if (sAutoMounterSetting) {
- return sAutoMounterSetting->GetStatus();
- }
- return AUTOMOUNTER_STATUS_DISABLED;
-}
-
-//static
-void
-SetAutoMounterStatus(int32_t aStatus)
-{
- if (sAutoMounterSetting) {
- sAutoMounterSetting->SetStatus(aStatus);
- }
-}
-
-void
-SetAutoMounterMode(int32_t aMode)
-{
- XRE_GetIOMessageLoop()->PostTask(
- NewRunnableFunction(SetAutoMounterModeIOThread, aMode));
-}
-
-void
-SetAutoMounterSharingMode(const nsCString& aVolumeName, bool aAllowSharing)
-{
- XRE_GetIOMessageLoop()->PostTask(
- NewRunnableFunction(SetAutoMounterSharingModeIOThread,
- aVolumeName, aAllowSharing));
-}
-
-void
-AutoMounterFormatVolume(const nsCString& aVolumeName)
-{
- XRE_GetIOMessageLoop()->PostTask(
- NewRunnableFunction(AutoMounterFormatVolumeIOThread,
- aVolumeName));
-}
-
-void
-AutoMounterMountVolume(const nsCString& aVolumeName)
-{
- XRE_GetIOMessageLoop()->PostTask(
- NewRunnableFunction(AutoMounterMountVolumeIOThread,
- aVolumeName));
-}
-
-void
-AutoMounterUnmountVolume(const nsCString& aVolumeName)
-{
- XRE_GetIOMessageLoop()->PostTask(
- NewRunnableFunction(AutoMounterUnmountVolumeIOThread,
- aVolumeName));
-}
-
-void
-ShutdownAutoMounter()
-{
- if (sAutoMounter) {
- DBG("ShutdownAutoMounter: About to StopMtpServer");
- sAutoMounter->StopMtpServer();
- // Unregister status reporter into reporter manager
- if(status_reporter_progress == REPORTER_REGISTERED) {
- NS_UnregisterStatusReporter(new NS_STATUS_REPORTER_NAME(AutoMounter));
- }
- status_reporter_progress = REPORTER_UNREGISTERED;
- }
- sAutoMounterSetting = nullptr;
- sUsbCableObserver = nullptr;
-
- XRE_GetIOMessageLoop()->PostTask(
- NewRunnableFunction(ShutdownAutoMounterIOThread));
-}
-
-} // system
-} // mozilla
diff --git a/dom/system/gonk/AutoMounter.h b/dom/system/gonk/AutoMounter.h
deleted file mode 100644
index ea98cadf1d..0000000000
--- a/dom/system/gonk/AutoMounter.h
+++ /dev/null
@@ -1,101 +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/. */
-
-#ifndef mozilla_system_automounter_h__
-#define mozilla_system_automounter_h__
-
-#include <stdint.h>
-
-class nsCString;
-
-namespace mozilla {
-namespace system {
-
-// AutoMounter modes
-#define AUTOMOUNTER_DISABLE 0
-#define AUTOMOUNTER_ENABLE_UMS 1
-#define AUTOMOUNTER_DISABLE_WHEN_UNPLUGGED 2
-#define AUTOMOUNTER_ENABLE_MTP 3
-
-// Automounter statuses
-#define AUTOMOUNTER_STATUS_DISABLED 0
-#define AUTOMOUNTER_STATUS_ENABLED 1
-#define AUTOMOUNTER_STATUS_FILES_OPEN 2
-
-/**
- * Initialize the automounter. This causes some of the phone's
- * directories to show up on the host when the phone is plugged
- * into the host via USB.
- *
- * When the AutoMounter starts, it will poll the current state
- * of affairs (usb cable plugged in, automounter enabled, etc)
- * and try to make the state of the volumes match.
- */
-void
-InitAutoMounter();
-
-/**
- * Sets the enabled state of the automounter.
- *
- * This will in turn cause the automounter to re-evaluate
- * whether it should mount/unmount/share/unshare volumes.
- */
-void
-SetAutoMounterMode(int32_t aMode);
-
-/**
- * Reports the status of the automounter.
- */
-int32_t
-GetAutoMounterStatus();
-
-/**
- * Sets the sharing mode of an individual volume.
- *
- * If a volume is enabled for sharing, and the autmounter
- * is in a state to share, then the volume will be shared
- * with the PC.
- */
-void
-SetAutoMounterSharingMode(const nsCString& aVolumeName, bool aAllowSharing);
-
-/**
- * Formats the volume with specified volume name.
- *
- * If the volume is ready to format, automounter
- * will unmount it, format it and then mount it again.
- */
-void
-AutoMounterFormatVolume(const nsCString& aVolumeName);
-
-/**
- * Mounts the volume with specified volume name.
- *
- * If the volume is already unmounted, automounter
- * will mount it. Otherwise automounter will skip this.
- */
-void
-AutoMounterMountVolume(const nsCString& aVolumeName);
-
-/**
- * Unmounts the volume with specified volume name.
- *
- * If the volume is already mounted, automounter
- * will unmount it. Otherwise automounter will skip this.
- */
-void
-AutoMounterUnmountVolume(const nsCString& aVolumeName);
-
-/**
- * Shuts down the automounter.
- *
- * This leaves the volumes in whatever state they're in.
- */
-void
-ShutdownAutoMounter();
-
-} // system
-} // mozilla
-
-#endif // mozilla_system_automounter_h__
diff --git a/dom/system/gonk/AutoMounterSetting.cpp b/dom/system/gonk/AutoMounterSetting.cpp
deleted file mode 100644
index 606bcce04d..0000000000
--- a/dom/system/gonk/AutoMounterSetting.cpp
+++ /dev/null
@@ -1,284 +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 "AutoMounter.h"
-#include "AutoMounterSetting.h"
-
-#include "base/message_loop.h"
-#include "jsapi.h"
-#include "mozilla/Services.h"
-#include "nsCOMPtr.h"
-#include "nsContentUtils.h"
-#include "nsDebug.h"
-#include "nsIObserverService.h"
-#include "nsISettingsService.h"
-#include "nsJSUtils.h"
-#include "nsPrintfCString.h"
-#include "nsServiceManagerUtils.h"
-#include "nsString.h"
-#include "nsThreadUtils.h"
-#include "xpcpublic.h"
-#include "mozilla/dom/ScriptSettings.h"
-#include "mozilla/Attributes.h"
-#include "mozilla/dom/BindingUtils.h"
-#include "mozilla/dom/SettingChangeNotificationBinding.h"
-
-#undef LOG
-#undef ERR
-#define LOG(args...) __android_log_print(ANDROID_LOG_INFO, "AutoMounterSetting" , ## args)
-#define ERR(args...) __android_log_print(ANDROID_LOG_ERROR, "AutoMounterSetting" , ## args)
-
-#define UMS_MODE "ums.mode"
-#define UMS_STATUS "ums.status"
-#define UMS_VOLUME_ENABLED_PREFIX "ums.volume."
-#define UMS_VOLUME_ENABLED_SUFFIX ".enabled"
-#define MOZSETTINGS_CHANGED "mozsettings-changed"
-
-using namespace mozilla::dom;
-
-namespace mozilla {
-namespace system {
-
-class SettingsServiceCallback final : public nsISettingsServiceCallback
-{
-public:
- NS_DECL_THREADSAFE_ISUPPORTS
-
- SettingsServiceCallback() {}
-
- NS_IMETHOD Handle(const nsAString& aName, JS::Handle<JS::Value> aResult)
- {
- if (aResult.isInt32()) {
- int32_t mode = aResult.toInt32();
- SetAutoMounterMode(mode);
- }
- return NS_OK;
- }
-
- NS_IMETHOD HandleError(const nsAString& aName)
- {
- ERR("SettingsCallback::HandleError: %s\n", NS_LossyConvertUTF16toASCII(aName).get());
- return NS_OK;
- }
-
-protected:
- ~SettingsServiceCallback() {}
-};
-
-NS_IMPL_ISUPPORTS(SettingsServiceCallback, nsISettingsServiceCallback)
-
-class CheckVolumeSettingsCallback final : public nsISettingsServiceCallback
-{
-public:
- NS_DECL_THREADSAFE_ISUPPORTS
-
- CheckVolumeSettingsCallback(const nsACString& aVolumeName)
- : mVolumeName(aVolumeName) {}
-
- NS_IMETHOD Handle(const nsAString& aName, JS::Handle<JS::Value> aResult)
- {
- if (aResult.isBoolean()) {
- bool isSharingEnabled = aResult.toBoolean();
- SetAutoMounterSharingMode(mVolumeName, isSharingEnabled);
- }
- return NS_OK;
- }
-
- NS_IMETHOD HandleError(const nsAString& aName)
- {
- ERR("CheckVolumeSettingsCallback::HandleError: %s\n", NS_LossyConvertUTF16toASCII(aName).get());
- return NS_OK;
- }
-
-protected:
- ~CheckVolumeSettingsCallback() {}
-
-private:
- nsCString mVolumeName;
-};
-
-NS_IMPL_ISUPPORTS(CheckVolumeSettingsCallback, nsISettingsServiceCallback)
-
-AutoMounterSetting::AutoMounterSetting()
- : mStatus(AUTOMOUNTER_STATUS_DISABLED)
-{
- MOZ_ASSERT(NS_IsMainThread());
-
- // Setup an observer to watch changes to the setting
- nsCOMPtr<nsIObserverService> observerService =
- mozilla::services::GetObserverService();
- if (!observerService) {
- ERR("GetObserverService failed");
- return;
- }
- nsresult rv;
- rv = observerService->AddObserver(this, MOZSETTINGS_CHANGED, false);
- if (NS_FAILED(rv)) {
- ERR("AddObserver failed");
- return;
- }
-
- // Force ums.mode to be 0 initially. We do this because settings are persisted.
- // We don't want UMS to be enabled until such time as the phone is unlocked,
- // and gaia/apps/system/js/storage.js takes care of detecting when the phone
- // becomes unlocked and changes ums.mode appropriately.
- nsCOMPtr<nsISettingsService> settingsService =
- do_GetService("@mozilla.org/settingsService;1");
- if (!settingsService) {
- ERR("Failed to get settingsLock service!");
- return;
- }
- nsCOMPtr<nsISettingsServiceLock> lock;
- settingsService->CreateLock(nullptr, getter_AddRefs(lock));
- nsCOMPtr<nsISettingsServiceCallback> callback = new SettingsServiceCallback();
- JS::Rooted<JS::Value> value(RootingCx());
- value.setInt32(AUTOMOUNTER_DISABLE);
- lock->Set(UMS_MODE, value, callback, nullptr);
- value.setInt32(mStatus);
- lock->Set(UMS_STATUS, value, nullptr, nullptr);
-}
-
-AutoMounterSetting::~AutoMounterSetting()
-{
- nsCOMPtr<nsIObserverService> observerService =
- mozilla::services::GetObserverService();
- if (observerService) {
- observerService->RemoveObserver(this, MOZSETTINGS_CHANGED);
- }
-}
-
-NS_IMPL_ISUPPORTS(AutoMounterSetting, nsIObserver)
-
-const char *
-AutoMounterSetting::StatusStr(int32_t aStatus)
-{
- switch (aStatus) {
- case AUTOMOUNTER_STATUS_DISABLED: return "Disabled";
- case AUTOMOUNTER_STATUS_ENABLED: return "Enabled";
- case AUTOMOUNTER_STATUS_FILES_OPEN: return "FilesOpen";
- }
- return "??? Unknown ???";
-}
-
-class CheckVolumeSettingsRunnable : public Runnable
-{
-public:
- CheckVolumeSettingsRunnable(const nsACString& aVolumeName)
- : mVolumeName(aVolumeName) {}
-
- NS_IMETHOD Run() override
- {
- MOZ_ASSERT(NS_IsMainThread());
- nsCOMPtr<nsISettingsService> settingsService =
- do_GetService("@mozilla.org/settingsService;1");
- NS_ENSURE_TRUE(settingsService, NS_ERROR_FAILURE);
- nsCOMPtr<nsISettingsServiceLock> lock;
- settingsService->CreateLock(nullptr, getter_AddRefs(lock));
- nsCOMPtr<nsISettingsServiceCallback> callback =
- new CheckVolumeSettingsCallback(mVolumeName);
- nsPrintfCString setting(UMS_VOLUME_ENABLED_PREFIX "%s" UMS_VOLUME_ENABLED_SUFFIX,
- mVolumeName.get());
- lock->Get(setting.get(), callback);
- return NS_OK;
- }
-
-private:
- nsCString mVolumeName;
-};
-
-//static
-void
-AutoMounterSetting::CheckVolumeSettings(const nsACString& aVolumeName)
-{
- NS_DispatchToMainThread(new CheckVolumeSettingsRunnable(aVolumeName));
-}
-
-class SetStatusRunnable : public Runnable
-{
-public:
- SetStatusRunnable(int32_t aStatus) : mStatus(aStatus) {}
-
- NS_IMETHOD Run() override
- {
- MOZ_ASSERT(NS_IsMainThread());
- nsCOMPtr<nsISettingsService> settingsService =
- do_GetService("@mozilla.org/settingsService;1");
- NS_ENSURE_TRUE(settingsService, NS_ERROR_FAILURE);
- nsCOMPtr<nsISettingsServiceLock> lock;
- settingsService->CreateLock(nullptr, getter_AddRefs(lock));
- // lock may be null if this gets called during shutdown.
- if (lock) {
- JS::Rooted<JS::Value> value(RootingCx(),
- JS::Int32Value(mStatus));
- lock->Set(UMS_STATUS, value, nullptr, nullptr);
- }
- return NS_OK;
- }
-
-private:
- int32_t mStatus;
-};
-
-//static
-void
-AutoMounterSetting::SetStatus(int32_t aStatus)
-{
- if (aStatus != mStatus) {
- LOG("Changing status from '%s' to '%s'",
- StatusStr(mStatus), StatusStr(aStatus));
- mStatus = aStatus;
- NS_DispatchToMainThread(new SetStatusRunnable(aStatus));
- }
-}
-
-NS_IMETHODIMP
-AutoMounterSetting::Observe(nsISupports* aSubject,
- const char* aTopic,
- const char16_t* aData)
-{
- if (strcmp(aTopic, MOZSETTINGS_CHANGED) != 0) {
- return NS_OK;
- }
-
- // Note that this function gets called for any and all settings changes,
- // so we need to carefully check if we have the one we're interested in.
- //
- // The string that we're interested in will be a JSON string that looks like:
- // {"key":"ums.autoMount","value":true}
-
- RootedDictionary<SettingChangeNotification> setting(RootingCx());
- if (!WrappedJSToDictionary(aSubject, setting)) {
- return NS_OK;
- }
-
- // Check for ums.mode changes
- if (setting.mKey.EqualsASCII(UMS_MODE)) {
- if (!setting.mValue.isInt32()) {
- return NS_OK;
- }
- int32_t mode = setting.mValue.toInt32();
- SetAutoMounterMode(mode);
- return NS_OK;
- }
-
- // Check for ums.volume.NAME.enabled
- if (StringBeginsWith(setting.mKey, NS_LITERAL_STRING(UMS_VOLUME_ENABLED_PREFIX)) &&
- StringEndsWith(setting.mKey, NS_LITERAL_STRING(UMS_VOLUME_ENABLED_SUFFIX))) {
- if (!setting.mValue.isBoolean()) {
- return NS_OK;
- }
- const size_t prefixLen = sizeof(UMS_VOLUME_ENABLED_PREFIX) - 1;
- const size_t suffixLen = sizeof(UMS_VOLUME_ENABLED_SUFFIX) - 1;
- nsDependentSubstring volumeName =
- Substring(setting.mKey, prefixLen, setting.mKey.Length() - prefixLen - suffixLen);
- bool isSharingEnabled = setting.mValue.toBoolean();
- SetAutoMounterSharingMode(NS_LossyConvertUTF16toASCII(volumeName), isSharingEnabled);
- return NS_OK;
- }
-
- return NS_OK;
-}
-
-} // namespace system
-} // namespace mozilla
diff --git a/dom/system/gonk/AutoMounterSetting.h b/dom/system/gonk/AutoMounterSetting.h
deleted file mode 100644
index 7972de379e..0000000000
--- a/dom/system/gonk/AutoMounterSetting.h
+++ /dev/null
@@ -1,38 +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/. */
-
-#ifndef mozilla_system_automountersetting_h__
-#define mozilla_system_automountersetting_h__
-
-#include "nsIObserver.h"
-
-namespace mozilla {
-namespace system {
-
-class AutoMounterSetting : public nsIObserver
-{
-public:
- NS_DECL_ISUPPORTS
- NS_DECL_NSIOBSERVER
-
- AutoMounterSetting();
-
- static void CheckVolumeSettings(const nsACString& aVolumeName);
-
- int32_t GetStatus() { return mStatus; }
- void SetStatus(int32_t aStatus);
- const char *StatusStr(int32_t aStatus);
-
-protected:
- virtual ~AutoMounterSetting();
-
-private:
- int32_t mStatus;
-};
-
-} // namespace system
-} // namespace mozilla
-
-#endif // mozilla_system_automountersetting_h__
-
diff --git a/dom/system/gonk/DataCallInterfaceService.js b/dom/system/gonk/DataCallInterfaceService.js
deleted file mode 100644
index 0f0e7101ce..0000000000
--- a/dom/system/gonk/DataCallInterfaceService.js
+++ /dev/null
@@ -1,276 +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/Services.jsm");
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-
-const DATACALLINTERFACE_CONTRACTID = "@mozilla.org/datacall/interface;1";
-const DATACALLINTERFACESERVICE_CONTRACTID =
- "@mozilla.org/datacall/interfaceservice;1";
-const DATACALLINTERFACE_CID =
- Components.ID("{ff669306-4390-462a-989b-ba37fc42153f}");
-const DATACALLINTERFACESERVICE_CID =
- Components.ID("{e23e9337-592d-40b9-8cef-7bd47c28b72e}");
-
-const TOPIC_XPCOM_SHUTDOWN = "xpcom-shutdown";
-const TOPIC_PREF_CHANGED = "nsPref:changed";
-const PREF_RIL_DEBUG_ENABLED = "ril.debugging.enabled";
-
-XPCOMUtils.defineLazyGetter(this, "RIL", function () {
- let obj = {};
- Cu.import("resource://gre/modules/ril_consts.js", obj);
- return obj;
-});
-
-XPCOMUtils.defineLazyServiceGetter(this, "gRil",
- "@mozilla.org/ril;1",
- "nsIRadioInterfaceLayer");
-
-XPCOMUtils.defineLazyServiceGetter(this, "gMobileConnectionService",
- "@mozilla.org/mobileconnection/mobileconnectionservice;1",
- "nsIMobileConnectionService");
-
-var DEBUG = RIL.DEBUG_RIL;
-
-function updateDebugFlag() {
- // Read debug setting from pref
- let debugPref;
- try {
- debugPref = Services.prefs.getBoolPref(PREF_RIL_DEBUG_ENABLED);
- } catch (e) {
- debugPref = false;
- }
- DEBUG = debugPref || RIL.DEBUG_RIL;
-}
-updateDebugFlag();
-
-function DataCall(aAttributes) {
- for (let key in aAttributes) {
- if (key === "pdpType") {
- // Convert pdp type into constant int value.
- this[key] = RIL.RIL_DATACALL_PDP_TYPES.indexOf(aAttributes[key]);
- continue;
- }
-
- this[key] = aAttributes[key];
- }
-}
-DataCall.prototype = {
- QueryInterface: XPCOMUtils.generateQI([Ci.nsIDataCall]),
-
- failCause: Ci.nsIDataCallInterface.DATACALL_FAIL_NONE,
- suggestedRetryTime: -1,
- cid: -1,
- active: -1,
- pdpType: -1,
- ifname: null,
- addreses: null,
- dnses: null,
- gateways: null,
- pcscf: null,
- mtu: -1
-};
-
-function DataCallInterfaceService() {
- this._dataCallInterfaces = [];
-
- let numClients = gRil.numRadioInterfaces;
- for (let i = 0; i < numClients; i++) {
- this._dataCallInterfaces.push(new DataCallInterface(i));
- }
-
- Services.obs.addObserver(this, TOPIC_XPCOM_SHUTDOWN, false);
- Services.prefs.addObserver(PREF_RIL_DEBUG_ENABLED, this, false);
-}
-DataCallInterfaceService.prototype = {
- classID: DATACALLINTERFACESERVICE_CID,
- classInfo: XPCOMUtils.generateCI({
- classID: DATACALLINTERFACESERVICE_CID,
- contractID: DATACALLINTERFACESERVICE_CONTRACTID,
- classDescription: "Data Call Interface Service",
- interfaces: [Ci.nsIDataCallInterfaceService,
- Ci.nsIGonkDataCallInterfaceService]
- }),
- QueryInterface: XPCOMUtils.generateQI([Ci.nsIDataCallInterfaceService,
- Ci.nsIGonkDataCallInterfaceService],
- Ci.nsIObserver),
-
- // An array of DataCallInterface instances.
- _dataCallInterfaces: null,
-
- debug: function(aMessage) {
- dump("-*- DataCallInterfaceService: " + aMessage + "\n");
- },
-
- // nsIDataCallInterfaceService
-
- getDataCallInterface: function(aClientId) {
- let dataCallInterface = this._dataCallInterfaces[aClientId];
- if (!dataCallInterface) {
- throw Cr.NS_ERROR_UNEXPECTED;
- }
-
- return dataCallInterface;
- },
-
- // nsIGonkDataCallInterfaceService
-
- notifyDataCallListChanged: function(aClientId, aCount, aDataCalls) {
- let dataCallInterface = this.getDataCallInterface(aClientId);
- dataCallInterface.handleDataCallListChanged(aCount, aDataCalls);
- },
-
- // nsIObserver
-
- observe: function(aSubject, aTopic, aData) {
- switch (aTopic) {
- case TOPIC_PREF_CHANGED:
- if (aData === PREF_RIL_DEBUG_ENABLED) {
- updateDebugFlag();
- }
- break;
- case TOPIC_XPCOM_SHUTDOWN:
- Services.prefs.removeObserver(PREF_RIL_DEBUG_ENABLED, this);
- Services.obs.removeObserver(this, TOPIC_XPCOM_SHUTDOWN);
- break;
- }
- },
-};
-
-function DataCallInterface(aClientId) {
- this._clientId = aClientId;
- this._radioInterface = gRil.getRadioInterface(aClientId);
- this._listeners = [];
-
- if (DEBUG) this.debug("DataCallInterface: " + aClientId);
-}
-DataCallInterface.prototype = {
- classID: DATACALLINTERFACE_CID,
- classInfo: XPCOMUtils.generateCI({classID: DATACALLINTERFACE_CID,
- contractID: DATACALLINTERFACE_CONTRACTID,
- classDescription: "Data Call Interface",
- interfaces: [Ci.nsIDataCallInterface]}),
- QueryInterface: XPCOMUtils.generateQI([Ci.nsIDataCallInterface]),
-
- debug: function(aMessage) {
- dump("-*- DataCallInterface[" + this._clientId + "]: " + aMessage + "\n");
- },
-
- _clientId: -1,
-
- _radioInterface: null,
-
- _listeners: null,
-
- // nsIDataCallInterface
-
- setupDataCall: function(aApn, aUsername, aPassword, aAuthType, aPdpType,
- aCallback) {
- let connection =
- gMobileConnectionService.getItemByServiceId(this._clientId);
- let dataInfo = connection && connection.data;
- let radioTechType = dataInfo.type;
- let radioTechnology = RIL.GECKO_RADIO_TECH.indexOf(radioTechType);
- // Convert pdp type into string value.
- let pdpType = RIL.RIL_DATACALL_PDP_TYPES[aPdpType];
-
- this._radioInterface.sendWorkerMessage("setupDataCall", {
- radioTech: radioTechnology,
- apn: aApn,
- user: aUsername,
- passwd: aPassword,
- chappap: aAuthType,
- pdptype: pdpType
- }, (aResponse) => {
- if (aResponse.errorMsg) {
- aCallback.notifyError(aResponse.errorMsg);
- } else {
- let dataCall = new DataCall(aResponse);
- aCallback.notifySetupDataCallSuccess(dataCall);
- }
- });
- },
-
- deactivateDataCall: function(aCid, aReason, aCallback) {
- this._radioInterface.sendWorkerMessage("deactivateDataCall", {
- cid: aCid,
- reason: aReason
- }, (aResponse) => {
- if (aResponse.errorMsg) {
- aCallback.notifyError(aResponse.errorMsg);
- } else {
- aCallback.notifySuccess();
- }
- });
- },
-
- getDataCallList: function(aCallback) {
- this._radioInterface.sendWorkerMessage("getDataCallList", null,
- (aResponse) => {
- if (aResponse.errorMsg) {
- aCallback.notifyError(aResponse.errorMsg);
- } else {
- let dataCalls = aResponse.datacalls.map(
- dataCall => new DataCall(dataCall));
- aCallback.notifyGetDataCallListSuccess(dataCalls.length, dataCalls);
- }
- });
- },
-
- setDataRegistration: function(aAttach, aCallback) {
- this._radioInterface.sendWorkerMessage("setDataRegistration", {
- attach: aAttach
- }, (aResponse) => {
- if (aResponse.errorMsg) {
- aCallback.notifyError(aResponse.errorMsg);
- } else {
- aCallback.notifySuccess();
- }
- });
- },
-
- handleDataCallListChanged: function(aCount, aDataCalls) {
- this._notifyAllListeners("notifyDataCallListChanged", [aCount, aDataCalls]);
- },
-
- _notifyAllListeners: function(aMethodName, aArgs) {
- let listeners = this._listeners.slice();
- for (let listener of listeners) {
- if (this._listeners.indexOf(listener) == -1) {
- // Listener has been unregistered in previous run.
- continue;
- }
-
- let handler = listener[aMethodName];
- try {
- handler.apply(listener, aArgs);
- } catch (e) {
- if (DEBUG) {
- this.debug("listener for " + aMethodName + " threw an exception: " + e);
- }
- }
- }
- },
-
- registerListener: function(aListener) {
- if (this._listeners.indexOf(aListener) >= 0) {
- return;
- }
-
- this._listeners.push(aListener);
- },
-
- unregisterListener: function(aListener) {
- let index = this._listeners.indexOf(aListener);
- if (index >= 0) {
- this._listeners.splice(index, 1);
- }
- },
-};
-
-this.NSGetFactory = XPCOMUtils.generateNSGetFactory([DataCallInterfaceService]); \ No newline at end of file
diff --git a/dom/system/gonk/DataCallInterfaceService.manifest b/dom/system/gonk/DataCallInterfaceService.manifest
deleted file mode 100644
index bf062c7e92..0000000000
--- a/dom/system/gonk/DataCallInterfaceService.manifest
+++ /dev/null
@@ -1,6 +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/.
-
-component {e23e9337-592d-40b9-8cef-7bd47c28b72e} DataCallInterfaceService.js
-contract @mozilla.org/datacall/interfaceservice;1 {e23e9337-592d-40b9-8cef-7bd47c28b72e} \ No newline at end of file
diff --git a/dom/system/gonk/DataCallManager.js b/dom/system/gonk/DataCallManager.js
deleted file mode 100644
index 5411987cdc..0000000000
--- a/dom/system/gonk/DataCallManager.js
+++ /dev/null
@@ -1,1726 +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/systemlibs.js");
-
-XPCOMUtils.defineLazyServiceGetter(this, "gSettingsService",
- "@mozilla.org/settingsService;1",
- "nsISettingsService");
-
-XPCOMUtils.defineLazyServiceGetter(this, "gNetworkManager",
- "@mozilla.org/network/manager;1",
- "nsINetworkManager");
-
-XPCOMUtils.defineLazyServiceGetter(this, "gMobileConnectionService",
- "@mozilla.org/mobileconnection/mobileconnectionservice;1",
- "nsIMobileConnectionService");
-
-XPCOMUtils.defineLazyServiceGetter(this, "gIccService",
- "@mozilla.org/icc/iccservice;1",
- "nsIIccService");
-
-XPCOMUtils.defineLazyServiceGetter(this, "gDataCallInterfaceService",
- "@mozilla.org/datacall/interfaceservice;1",
- "nsIDataCallInterfaceService");
-
-XPCOMUtils.defineLazyGetter(this, "RIL", function() {
- let obj = {};
- Cu.import("resource://gre/modules/ril_consts.js", obj);
- return obj;
-});
-
-// Ril quirk to attach data registration on demand.
-var RILQUIRKS_DATA_REGISTRATION_ON_DEMAND =
- libcutils.property_get("ro.moz.ril.data_reg_on_demand", "false") == "true";
-
-// Ril quirk to control the uicc/data subscription.
-var RILQUIRKS_SUBSCRIPTION_CONTROL =
- libcutils.property_get("ro.moz.ril.subscription_control", "false") == "true";
-
-// Ril quirk to enable IPv6 protocol/roaming protocol in APN settings.
-var RILQUIRKS_HAVE_IPV6 =
- libcutils.property_get("ro.moz.ril.ipv6", "false") == "true";
-
-const DATACALLMANAGER_CID =
- Components.ID("{35b9efa2-e42c-45ce-8210-0a13e6f4aadc}");
-const DATACALLHANDLER_CID =
- Components.ID("{132b650f-c4d8-4731-96c5-83785cb31dee}");
-const RILNETWORKINTERFACE_CID =
- Components.ID("{9574ee84-5d0d-4814-b9e6-8b279e03dcf4}");
-const RILNETWORKINFO_CID =
- Components.ID("{dd6cf2f0-f0e3-449f-a69e-7c34fdcb8d4b}");
-
-const TOPIC_XPCOM_SHUTDOWN = "xpcom-shutdown";
-const TOPIC_MOZSETTINGS_CHANGED = "mozsettings-changed";
-const TOPIC_PREF_CHANGED = "nsPref:changed";
-const TOPIC_DATA_CALL_ERROR = "data-call-error";
-const PREF_RIL_DEBUG_ENABLED = "ril.debugging.enabled";
-
-const NETWORK_TYPE_UNKNOWN = Ci.nsINetworkInfo.NETWORK_TYPE_UNKNOWN;
-const NETWORK_TYPE_WIFI = Ci.nsINetworkInfo.NETWORK_TYPE_WIFI;
-const NETWORK_TYPE_MOBILE = Ci.nsINetworkInfo.NETWORK_TYPE_MOBILE;
-const NETWORK_TYPE_MOBILE_MMS = Ci.nsINetworkInfo.NETWORK_TYPE_MOBILE_MMS;
-const NETWORK_TYPE_MOBILE_SUPL = Ci.nsINetworkInfo.NETWORK_TYPE_MOBILE_SUPL;
-const NETWORK_TYPE_MOBILE_IMS = Ci.nsINetworkInfo.NETWORK_TYPE_MOBILE_IMS;
-const NETWORK_TYPE_MOBILE_DUN = Ci.nsINetworkInfo.NETWORK_TYPE_MOBILE_DUN;
-const NETWORK_TYPE_MOBILE_FOTA = Ci.nsINetworkInfo.NETWORK_TYPE_MOBILE_FOTA;
-
-const NETWORK_STATE_UNKNOWN = Ci.nsINetworkInfo.NETWORK_STATE_UNKNOWN;
-const NETWORK_STATE_CONNECTING = Ci.nsINetworkInfo.NETWORK_STATE_CONNECTING;
-const NETWORK_STATE_CONNECTED = Ci.nsINetworkInfo.NETWORK_STATE_CONNECTED;
-const NETWORK_STATE_DISCONNECTING = Ci.nsINetworkInfo.NETWORK_STATE_DISCONNECTING;
-const NETWORK_STATE_DISCONNECTED = Ci.nsINetworkInfo.NETWORK_STATE_DISCONNECTED;
-
-const INT32_MAX = 2147483647;
-
-// set to true in ril_consts.js to see debug messages
-var DEBUG = RIL.DEBUG_RIL;
-
-function updateDebugFlag() {
- // Read debug setting from pref
- let debugPref;
- try {
- debugPref = Services.prefs.getBoolPref(PREF_RIL_DEBUG_ENABLED);
- } catch (e) {
- debugPref = false;
- }
- DEBUG = debugPref || RIL.DEBUG_RIL;
-}
-updateDebugFlag();
-
-function DataCallManager() {
- this._connectionHandlers = [];
-
- let numRadioInterfaces = gMobileConnectionService.numItems;
- for (let clientId = 0; clientId < numRadioInterfaces; clientId++) {
- this._connectionHandlers.push(new DataCallHandler(clientId));
- }
-
- let lock = gSettingsService.createLock();
- // Read the APN data from the settings DB.
- lock.get("ril.data.apnSettings", this);
- // Read the data enabled setting from DB.
- lock.get("ril.data.enabled", this);
- lock.get("ril.data.roaming_enabled", this);
- // Read the default client id for data call.
- lock.get("ril.data.defaultServiceId", this);
-
- Services.obs.addObserver(this, TOPIC_XPCOM_SHUTDOWN, false);
- Services.obs.addObserver(this, TOPIC_MOZSETTINGS_CHANGED, false);
- Services.prefs.addObserver(PREF_RIL_DEBUG_ENABLED, this, false);
-}
-DataCallManager.prototype = {
- classID: DATACALLMANAGER_CID,
- classInfo: XPCOMUtils.generateCI({classID: DATACALLMANAGER_CID,
- classDescription: "Data Call Manager",
- interfaces: [Ci.nsIDataCallManager]}),
-
- QueryInterface: XPCOMUtils.generateQI([Ci.nsIDataCallManager,
- Ci.nsIObserver,
- Ci.nsISettingsServiceCallback]),
-
- _connectionHandlers: null,
-
- // Flag to determine the data state to start with when we boot up. It
- // corresponds to the 'ril.data.enabled' setting from the UI.
- _dataEnabled: false,
-
- // Flag to record the default client id for data call. It corresponds to
- // the 'ril.data.defaultServiceId' setting from the UI.
- _dataDefaultClientId: -1,
-
- // Flag to record the current default client id for data call.
- // It differs from _dataDefaultClientId in that it is set only when
- // the switch of client id process is done.
- _currentDataClientId: -1,
-
- // Pending function to execute when we are notified that another data call has
- // been disconnected.
- _pendingDataCallRequest: null,
-
- debug: function(aMsg) {
- dump("-*- DataCallManager: " + aMsg + "\n");
- },
-
- get dataDefaultServiceId() {
- return this._dataDefaultClientId;
- },
-
- getDataCallHandler: function(aClientId) {
- let handler = this._connectionHandlers[aClientId]
- if (!handler) {
- throw Cr.NS_ERROR_UNEXPECTED;
- }
-
- return handler;
- },
-
- _setDataRegistration: function(aDataCallInterface, aAttach) {
- return new Promise(function(aResolve, aReject) {
- let callback = {
- QueryInterface: XPCOMUtils.generateQI([Ci.nsIDataCallCallback]),
- notifySuccess: function() {
- aResolve();
- },
- notifyError: function(aErrorMsg) {
- aReject(aErrorMsg);
- }
- };
-
- aDataCallInterface.setDataRegistration(aAttach, callback);
- });
- },
-
- _handleDataClientIdChange: function(aNewClientId) {
- if (this._dataDefaultClientId === aNewClientId) {
- return;
- }
- this._dataDefaultClientId = aNewClientId;
-
- // This is to handle boot up stage.
- if (this._currentDataClientId == -1) {
- this._currentDataClientId = this._dataDefaultClientId;
- let connHandler = this._connectionHandlers[this._currentDataClientId];
- let dcInterface = connHandler.dataCallInterface;
- if (RILQUIRKS_DATA_REGISTRATION_ON_DEMAND ||
- RILQUIRKS_SUBSCRIPTION_CONTROL) {
- this._setDataRegistration(dcInterface, true);
- }
- if (this._dataEnabled) {
- let settings = connHandler.dataCallSettings;
- settings.oldEnabled = settings.enabled;
- settings.enabled = true;
- connHandler.updateRILNetworkInterface();
- }
- return;
- }
-
- let oldConnHandler = this._connectionHandlers[this._currentDataClientId];
- let oldIface = oldConnHandler.dataCallInterface;
- let oldSettings = oldConnHandler.dataCallSettings;
- let newConnHandler = this._connectionHandlers[this._dataDefaultClientId];
- let newIface = newConnHandler.dataCallInterface;
- let newSettings = newConnHandler.dataCallSettings;
-
- let applyPendingDataSettings = () => {
- if (DEBUG) {
- this.debug("Apply pending data registration and settings.");
- }
-
- if (RILQUIRKS_DATA_REGISTRATION_ON_DEMAND ||
- RILQUIRKS_SUBSCRIPTION_CONTROL) {
- this._setDataRegistration(oldIface, false).then(() => {
- if (this._dataEnabled) {
- newSettings.oldEnabled = newSettings.enabled;
- newSettings.enabled = true;
- }
- this._currentDataClientId = this._dataDefaultClientId;
-
- this._setDataRegistration(newIface, true).then(() => {
- newConnHandler.updateRILNetworkInterface();
- });
- });
- return;
- }
-
- if (this._dataEnabled) {
- newSettings.oldEnabled = newSettings.enabled;
- newSettings.enabled = true;
- }
-
- this._currentDataClientId = this._dataDefaultClientId;
- newConnHandler.updateRILNetworkInterface();
- };
-
- if (this._dataEnabled) {
- oldSettings.oldEnabled = oldSettings.enabled;
- oldSettings.enabled = false;
- }
-
- oldConnHandler.deactivateDataCallsAndWait().then(() => {
- applyPendingDataSettings();
- });
- },
-
- _shutdown: function() {
- for (let handler of this._connectionHandlers) {
- handler.shutdown();
- }
- this._connectionHandlers = null;
- Services.prefs.removeObserver(PREF_RIL_DEBUG_ENABLED, this);
- Services.obs.removeObserver(this, TOPIC_XPCOM_SHUTDOWN);
- Services.obs.removeObserver(this, TOPIC_MOZSETTINGS_CHANGED);
- },
-
- /**
- * nsISettingsServiceCallback
- */
- handle: function(aName, aResult) {
- switch (aName) {
- case "ril.data.apnSettings":
- if (DEBUG) {
- this.debug("'ril.data.apnSettings' is now " +
- JSON.stringify(aResult));
- }
- if (!aResult) {
- break;
- }
- for (let clientId in this._connectionHandlers) {
- let handler = this._connectionHandlers[clientId];
- let apnSetting = aResult[clientId];
- if (handler && apnSetting) {
- handler.updateApnSettings(apnSetting);
- }
- }
- break;
- case "ril.data.enabled":
- if (DEBUG) {
- this.debug("'ril.data.enabled' is now " + aResult);
- }
- if (this._dataEnabled === aResult) {
- break;
- }
- this._dataEnabled = aResult;
-
- if (DEBUG) {
- this.debug("Default id for data call: " + this._dataDefaultClientId);
- }
- if (this._dataDefaultClientId === -1) {
- // We haven't got the default id for data from db.
- break;
- }
-
- let connHandler = this._connectionHandlers[this._dataDefaultClientId];
- let settings = connHandler.dataCallSettings;
- settings.oldEnabled = settings.enabled;
- settings.enabled = aResult;
- connHandler.updateRILNetworkInterface();
- break;
- case "ril.data.roaming_enabled":
- if (DEBUG) {
- this.debug("'ril.data.roaming_enabled' is now " + aResult);
- this.debug("Default id for data call: " + this._dataDefaultClientId);
- }
- for (let clientId = 0; clientId < this._connectionHandlers.length; clientId++) {
- let connHandler = this._connectionHandlers[clientId];
- let settings = connHandler.dataCallSettings;
- settings.roamingEnabled = Array.isArray(aResult) ? aResult[clientId]
- : aResult;
- }
- if (this._dataDefaultClientId === -1) {
- // We haven't got the default id for data from db.
- break;
- }
- this._connectionHandlers[this._dataDefaultClientId].updateRILNetworkInterface();
- break;
- case "ril.data.defaultServiceId":
- aResult = aResult || 0;
- if (DEBUG) {
- this.debug("'ril.data.defaultServiceId' is now " + aResult);
- }
- this._handleDataClientIdChange(aResult);
- break;
- }
- },
-
- handleError: function(aErrorMessage) {
- if (DEBUG) {
- this.debug("There was an error while reading RIL settings.");
- }
- },
-
- /**
- * nsIObserver interface methods.
- */
- observe: function(aSubject, aTopic, aData) {
- switch (aTopic) {
- case TOPIC_MOZSETTINGS_CHANGED:
- if ("wrappedJSObject" in aSubject) {
- aSubject = aSubject.wrappedJSObject;
- }
- this.handle(aSubject.key, aSubject.value);
- break;
- case TOPIC_PREF_CHANGED:
- if (aData === PREF_RIL_DEBUG_ENABLED) {
- updateDebugFlag();
- }
- break;
- case TOPIC_XPCOM_SHUTDOWN:
- this._shutdown();
- break;
- }
- },
-};
-
-function DataCallHandler(aClientId) {
- // Initial owning attributes.
- this.clientId = aClientId;
- this.dataCallSettings = {
- oldEnabled: false,
- enabled: false,
- roamingEnabled: false
- };
- this._dataCalls = [];
- this._listeners = [];
-
- // This map is used to collect all the apn types and its corresponding
- // RILNetworkInterface.
- this.dataNetworkInterfaces = new Map();
-
- this.dataCallInterface = gDataCallInterfaceService.getDataCallInterface(aClientId);
- this.dataCallInterface.registerListener(this);
-
- let mobileConnection = gMobileConnectionService.getItemByServiceId(aClientId);
- mobileConnection.registerListener(this);
-
- this._dataInfo = {
- state: mobileConnection.data.state,
- type: mobileConnection.data.type,
- roaming: mobileConnection.data.roaming
- }
-}
-DataCallHandler.prototype = {
- classID: DATACALLHANDLER_CID,
- classInfo: XPCOMUtils.generateCI({classID: DATACALLHANDLER_CID,
- classDescription: "Data Call Handler",
- interfaces: [Ci.nsIDataCallHandler]}),
-
- QueryInterface: XPCOMUtils.generateQI([Ci.nsIDataCallHandler,
- Ci.nsIDataCallInterfaceListener,
- Ci.nsIMobileConnectionListener]),
-
- clientId: 0,
- dataCallInterface: null,
- dataCallSettings: null,
- dataNetworkInterfaces: null,
- _dataCalls: null,
- _dataInfo: null,
-
- // Apn settings to be setup after data call are cleared.
- _pendingApnSettings: null,
-
- debug: function(aMsg) {
- dump("-*- DataCallHandler[" + this.clientId + "]: " + aMsg + "\n");
- },
-
- shutdown: function() {
- // Shutdown all RIL network interfaces
- this.dataNetworkInterfaces.forEach(function(networkInterface) {
- gNetworkManager.unregisterNetworkInterface(networkInterface);
- networkInterface.shutdown();
- networkInterface = null;
- });
- this.dataNetworkInterfaces.clear();
- this._dataCalls = [];
- this.clientId = null;
-
- this.dataCallInterface.unregisterListener(this);
- this.dataCallInterface = null;
-
- let mobileConnection =
- gMobileConnectionService.getItemByServiceId(this.clientId);
- mobileConnection.unregisterListener(this);
- },
-
- /**
- * Check if we get all necessary APN data.
- */
- _validateApnSetting: function(aApnSetting) {
- return (aApnSetting &&
- aApnSetting.apn &&
- aApnSetting.types &&
- aApnSetting.types.length);
- },
-
- _convertApnType: function(aApnType) {
- switch (aApnType) {
- case "default":
- return NETWORK_TYPE_MOBILE;
- case "mms":
- return NETWORK_TYPE_MOBILE_MMS;
- case "supl":
- return NETWORK_TYPE_MOBILE_SUPL;
- case "ims":
- return NETWORK_TYPE_MOBILE_IMS;
- case "dun":
- return NETWORK_TYPE_MOBILE_DUN;
- case "fota":
- return NETWORK_TYPE_MOBILE_FOTA;
- default:
- return NETWORK_TYPE_UNKNOWN;
- }
- },
-
- _compareDataCallOptions: function(aDataCall, aNewDataCall) {
- return aDataCall.apnProfile.apn == aNewDataCall.apnProfile.apn &&
- aDataCall.apnProfile.user == aNewDataCall.apnProfile.user &&
- aDataCall.apnProfile.password == aNewDataCall.apnProfile.passwd &&
- aDataCall.apnProfile.authType == aNewDataCall.apnProfile.authType &&
- aDataCall.apnProfile.protocol == aNewDataCall.apnProfile.protocol &&
- aDataCall.apnProfile.roaming_protocol == aNewDataCall.apnProfile.roaming_protocol;
- },
-
- /**
- * This function will do the following steps:
- * 1. Clear the cached APN settings in the RIL.
- * 2. Combine APN, user name, and password as the key of |byApn| object to
- * refer to the corresponding APN setting.
- * 3. Use APN type as the index of |byType| object to refer to the
- * corresponding APN setting.
- * 4. Create RilNetworkInterface for each APN setting created at step 2.
- */
- _setupApnSettings: function(aNewApnSettings) {
- if (!aNewApnSettings) {
- return;
- }
- if (DEBUG) this.debug("setupApnSettings: " + JSON.stringify(aNewApnSettings));
-
- // Shutdown all network interfaces and clear data calls.
- this.dataNetworkInterfaces.forEach(function(networkInterface) {
- gNetworkManager.unregisterNetworkInterface(networkInterface);
- networkInterface.shutdown();
- networkInterface = null;
- });
- this.dataNetworkInterfaces.clear();
- this._dataCalls = [];
-
- // Cache the APN settings by APNs and by types in the RIL.
- for (let inputApnSetting of aNewApnSettings) {
- if (!this._validateApnSetting(inputApnSetting)) {
- continue;
- }
-
- // Use APN type as the key of dataNetworkInterfaces to refer to the
- // corresponding RILNetworkInterface.
- for (let i = 0; i < inputApnSetting.types.length; i++) {
- let apnType = inputApnSetting.types[i];
- let networkType = this._convertApnType(apnType);
- if (networkType === NETWORK_TYPE_UNKNOWN) {
- if (DEBUG) this.debug("Invalid apn type: " + apnType);
- continue;
- }
-
- if (DEBUG) this.debug("Preparing RILNetworkInterface for type: " + apnType);
- // Create DataCall for RILNetworkInterface or reuse one that is shareable.
- let dataCall;
- for (let i = 0; i < this._dataCalls.length; i++) {
- if (this._dataCalls[i].canHandleApn(inputApnSetting)) {
- if (DEBUG) this.debug("Found shareable DataCall, reusing it.");
- dataCall = this._dataCalls[i];
- break;
- }
- }
-
- if (!dataCall) {
- if (DEBUG) this.debug("No shareable DataCall found, creating one.");
- dataCall = new DataCall(this.clientId, inputApnSetting, this);
- this._dataCalls.push(dataCall);
- }
-
- try {
- let networkInterface = new RILNetworkInterface(this, networkType,
- inputApnSetting,
- dataCall);
- gNetworkManager.registerNetworkInterface(networkInterface);
- this.dataNetworkInterfaces.set(networkType, networkInterface);
- } catch (e) {
- if (DEBUG) {
- this.debug("Error setting up RILNetworkInterface for type " +
- apnType + ": " + e);
- }
- }
- }
- }
- },
-
- /**
- * Check if all data is disconnected.
- */
- allDataDisconnected: function() {
- for (let i = 0; i < this._dataCalls.length; i++) {
- let dataCall = this._dataCalls[i];
- if (dataCall.state != NETWORK_STATE_UNKNOWN &&
- dataCall.state != NETWORK_STATE_DISCONNECTED) {
- return false;
- }
- }
- return true;
- },
-
- deactivateDataCallsAndWait: function() {
- return new Promise((aResolve, aReject) => {
- this.deactivateDataCalls({
- notifyDataCallsDisconnected: function() {
- aResolve();
- }
- });
- });
- },
-
- updateApnSettings: function(aNewApnSettings) {
- if (!aNewApnSettings) {
- return;
- }
- if (this._pendingApnSettings) {
- // Change of apn settings in process, just update to the newest.
- this._pengingApnSettings = aNewApnSettings;
- return;
- }
-
- this._pendingApnSettings = aNewApnSettings;
- this.deactivateDataCallsAndWait().then(() => {
- this._setupApnSettings(this._pendingApnSettings);
- this._pendingApnSettings = null;
- this.updateRILNetworkInterface();
- });
- },
-
- updateRILNetworkInterface: function() {
- let networkInterface = this.dataNetworkInterfaces.get(NETWORK_TYPE_MOBILE);
- if (!networkInterface) {
- if (DEBUG) {
- this.debug("No network interface for default data.");
- }
- return;
- }
-
- let connection =
- gMobileConnectionService.getItemByServiceId(this.clientId);
-
- // This check avoids data call connection if the radio is not ready
- // yet after toggling off airplane mode.
- let radioState = connection && connection.radioState;
- if (radioState != Ci.nsIMobileConnection.MOBILE_RADIO_STATE_ENABLED) {
- if (DEBUG) {
- this.debug("RIL is not ready for data connection: radio's not ready");
- }
- return;
- }
-
- // We only watch at "ril.data.enabled" flag changes for connecting or
- // disconnecting the data call. If the value of "ril.data.enabled" is
- // true and any of the remaining flags change the setting application
- // should turn this flag to false and then to true in order to reload
- // the new values and reconnect the data call.
- if (this.dataCallSettings.oldEnabled === this.dataCallSettings.enabled) {
- if (DEBUG) {
- this.debug("No changes for ril.data.enabled flag. Nothing to do.");
- }
- return;
- }
-
- let dataInfo = connection && connection.data;
- let isRegistered =
- dataInfo &&
- dataInfo.state == RIL.GECKO_MOBILE_CONNECTION_STATE_REGISTERED;
- let haveDataConnection =
- dataInfo &&
- dataInfo.type != RIL.GECKO_MOBILE_CONNECTION_STATE_UNKNOWN;
- if (!isRegistered || !haveDataConnection) {
- if (DEBUG) {
- this.debug("RIL is not ready for data connection: Phone's not " +
- "registered or doesn't have data connection.");
- }
- return;
- }
- let wifi_active = false;
- if (gNetworkManager.activeNetworkInfo &&
- gNetworkManager.activeNetworkInfo.type == NETWORK_TYPE_WIFI) {
- wifi_active = true;
- }
-
- let defaultDataCallConnected = networkInterface.connected;
-
- // We have moved part of the decision making into DataCall, the rest will be
- // moved after Bug 904514 - [meta] NetworkManager enhancement.
- if (networkInterface.enabled &&
- (!this.dataCallSettings.enabled ||
- (dataInfo.roaming && !this.dataCallSettings.roamingEnabled))) {
- if (DEBUG) {
- this.debug("Data call settings: disconnect data call.");
- }
- networkInterface.disconnect();
- return;
- }
-
- if (networkInterface.enabled && wifi_active) {
- if (DEBUG) {
- this.debug("Disconnect data call when Wifi is connected.");
- }
- networkInterface.disconnect();
- return;
- }
-
- if (!this.dataCallSettings.enabled || defaultDataCallConnected) {
- if (DEBUG) {
- this.debug("Data call settings: nothing to do.");
- }
- return;
- }
- if (dataInfo.roaming && !this.dataCallSettings.roamingEnabled) {
- if (DEBUG) {
- this.debug("We're roaming, but data roaming is disabled.");
- }
- return;
- }
- if (wifi_active) {
- if (DEBUG) {
- this.debug("Don't connect data call when Wifi is connected.");
- }
- return;
- }
- if (this._pendingApnSettings) {
- if (DEBUG) this.debug("We're changing apn settings, ignore any changes.");
- return;
- }
-
- if (this._deactivatingDataCalls) {
- if (DEBUG) this.debug("We're deactivating all data calls, ignore any changes.");
- return;
- }
-
- if (DEBUG) {
- this.debug("Data call settings: connect data call.");
- }
- networkInterface.connect();
- },
-
- _isMobileNetworkType: function(aNetworkType) {
- if (aNetworkType === NETWORK_TYPE_MOBILE ||
- aNetworkType === NETWORK_TYPE_MOBILE_MMS ||
- aNetworkType === NETWORK_TYPE_MOBILE_SUPL ||
- aNetworkType === NETWORK_TYPE_MOBILE_IMS ||
- aNetworkType === NETWORK_TYPE_MOBILE_DUN ||
- aNetworkType === NETWORK_TYPE_MOBILE_FOTA) {
- return true;
- }
-
- return false;
- },
-
- getDataCallStateByType: function(aNetworkType) {
- if (!this._isMobileNetworkType(aNetworkType)) {
- if (DEBUG) this.debug(aNetworkType + " is not a mobile network type!");
- throw Cr.NS_ERROR_INVALID_ARG;
- }
-
- let networkInterface = this.dataNetworkInterfaces.get(aNetworkType);
- if (!networkInterface) {
- return NETWORK_STATE_UNKNOWN;
- }
- return networkInterface.info.state;
- },
-
- setupDataCallByType: function(aNetworkType) {
- if (DEBUG) {
- this.debug("setupDataCallByType: " + aNetworkType);
- }
-
- if (!this._isMobileNetworkType(aNetworkType)) {
- if (DEBUG) this.debug(aNetworkType + " is not a mobile network type!");
- throw Cr.NS_ERROR_INVALID_ARG;
- }
-
- let networkInterface = this.dataNetworkInterfaces.get(aNetworkType);
- if (!networkInterface) {
- if (DEBUG) {
- this.debug("No network interface for type: " + aNetworkType);
- }
- return;
- }
-
- networkInterface.connect();
- },
-
- deactivateDataCallByType: function(aNetworkType) {
- if (DEBUG) {
- this.debug("deactivateDataCallByType: " + aNetworkType);
- }
-
- if (!this._isMobileNetworkType(aNetworkType)) {
- if (DEBUG) this.debug(aNetworkType + " is not a mobile network type!");
- throw Cr.NS_ERROR_INVALID_ARG;
- }
-
- let networkInterface = this.dataNetworkInterfaces.get(aNetworkType);
- if (!networkInterface) {
- if (DEBUG) {
- this.debug("No network interface for type: " + aNetworkType);
- }
- return;
- }
-
- networkInterface.disconnect();
- },
-
- _deactivatingDataCalls: false,
-
- deactivateDataCalls: function(aCallback) {
- let dataDisconnecting = false;
- this.dataNetworkInterfaces.forEach(function(networkInterface) {
- if (networkInterface.enabled) {
- if (networkInterface.info.state != NETWORK_STATE_UNKNOWN &&
- networkInterface.info.state != NETWORK_STATE_DISCONNECTED) {
- dataDisconnecting = true;
- }
- networkInterface.disconnect();
- }
- });
-
- this._deactivatingDataCalls = dataDisconnecting;
- if (!dataDisconnecting) {
- aCallback.notifyDataCallsDisconnected();
- return;
- }
-
- let callback = {
- notifyAllDataDisconnected: () => {
- this._unregisterListener(callback);
- aCallback.notifyDataCallsDisconnected();
- }
- };
- this._registerListener(callback);
- },
-
- _listeners: null,
-
- _notifyListeners: function(aMethodName, aArgs) {
- let listeners = this._listeners.slice();
- for (let listener of listeners) {
- if (this._listeners.indexOf(listener) == -1) {
- // Listener has been unregistered in previous run.
- continue;
- }
-
- let handler = listener[aMethodName];
- try {
- handler.apply(listener, aArgs);
- } catch (e) {
- this.debug("listener for " + aMethodName + " threw an exception: " + e);
- }
- }
- },
-
- _registerListener: function(aListener) {
- if (this._listeners.indexOf(aListener) >= 0) {
- return;
- }
-
- this._listeners.push(aListener);
- },
-
- _unregisterListener: function(aListener) {
- let index = this._listeners.indexOf(aListener);
- if (index >= 0) {
- this._listeners.splice(index, 1);
- }
- },
-
- _findDataCallByCid: function(aCid) {
- if (aCid === undefined || aCid < 0) {
- return -1;
- }
-
- for (let i = 0; i < this._dataCalls.length; i++) {
- let datacall = this._dataCalls[i];
- if (datacall.linkInfo.cid != null &&
- datacall.linkInfo.cid == aCid) {
- return i;
- }
- }
-
- return -1;
- },
-
- /**
- * Notify about data call setup error, called from DataCall.
- */
- notifyDataCallError: function(aDataCall, aErrorMsg) {
- // Notify data call error only for data APN
- let networkInterface = this.dataNetworkInterfaces.get(NETWORK_TYPE_MOBILE);
- if (networkInterface && networkInterface.enabled) {
- let dataCall = networkInterface.dataCall;
- if (this._compareDataCallOptions(dataCall, aDataCall)) {
- Services.obs.notifyObservers(networkInterface.info,
- TOPIC_DATA_CALL_ERROR, aErrorMsg);
- }
- }
- },
-
- /**
- * Notify about data call changed, called from DataCall.
- */
- notifyDataCallChanged: function(aUpdatedDataCall) {
- // Process pending radio power off request after all data calls
- // are disconnected.
- if (aUpdatedDataCall.state == NETWORK_STATE_DISCONNECTED ||
- aUpdatedDataCall.state == NETWORK_STATE_UNKNOWN &&
- this.allDataDisconnected() && this._deactivatingDataCalls) {
- this._deactivatingDataCalls = false;
- this._notifyListeners("notifyAllDataDisconnected", {
- clientId: this.clientId
- });
- }
- },
-
- // nsIDataCallInterfaceListener
-
- notifyDataCallListChanged: function(aCount, aDataCallList) {
- let currentDataCalls = this._dataCalls.slice();
- for (let i = 0; i < aDataCallList.length; i++) {
- let dataCall = aDataCallList[i];
- let index = this._findDataCallByCid(dataCall.cid);
- if (index == -1) {
- if (DEBUG) {
- this.debug("Unexpected new data call: " + JSON.stringify(dataCall));
- }
- continue;
- }
- currentDataCalls[index].onDataCallChanged(dataCall);
- currentDataCalls[index] = null;
- }
-
- // If there is any CONNECTED DataCall left in currentDataCalls, means that
- // it is missing in dataCallList, we should send a DISCONNECTED event to
- // notify about this.
- for (let i = 0; i < currentDataCalls.length; i++) {
- let currentDataCall = currentDataCalls[i];
- if (currentDataCall && currentDataCall.linkInfo.cid != null &&
- currentDataCall.state == NETWORK_STATE_CONNECTED) {
- if (DEBUG) {
- this.debug("Expected data call missing: " + JSON.stringify(
- currentDataCall.apnProfile) + ", must have been DISCONNECTED.");
- }
- currentDataCall.onDataCallChanged({
- state: NETWORK_STATE_DISCONNECTED
- });
- }
- }
- },
-
- // nsIMobileConnectionListener
-
- notifyVoiceChanged: function() {},
-
- notifyDataChanged: function () {
- let connection = gMobileConnectionService.getItemByServiceId(this.clientId);
- let newDataInfo = connection.data;
-
- if (this._dataInfo.state == newDataInfo.state &&
- this._dataInfo.type == newDataInfo.type &&
- this._dataInfo.roaming == newDataInfo.roaming) {
- return;
- }
-
- this._dataInfo.state = newDataInfo.state;
- this._dataInfo.type = newDataInfo.type;
- this._dataInfo.roaming = newDataInfo.roaming;
- this.updateRILNetworkInterface();
- },
-
- notifyDataError: function (aMessage) {},
-
- notifyCFStateChanged: function(aAction, aReason, aNumber, aTimeSeconds, aServiceClass) {},
-
- notifyEmergencyCbModeChanged: function(aActive, aTimeoutMs) {},
-
- notifyOtaStatusChanged: function(aStatus) {},
-
- notifyRadioStateChanged: function() {},
-
- notifyClirModeChanged: function(aMode) {},
-
- notifyLastKnownNetworkChanged: function() {},
-
- notifyLastKnownHomeNetworkChanged: function() {},
-
- notifyNetworkSelectionModeChanged: function() {},
-
- notifyDeviceIdentitiesChanged: function() {}
-};
-
-function DataCall(aClientId, aApnSetting, aDataCallHandler) {
- this.clientId = aClientId;
- this.dataCallHandler = aDataCallHandler;
- this.apnProfile = {
- apn: aApnSetting.apn,
- user: aApnSetting.user,
- password: aApnSetting.password,
- authType: aApnSetting.authtype,
- protocol: aApnSetting.protocol,
- roaming_protocol: aApnSetting.roaming_protocol
- };
- this.linkInfo = {
- cid: null,
- ifname: null,
- addresses: [],
- dnses: [],
- gateways: [],
- pcscf: [],
- mtu: null
- };
- this.state = NETWORK_STATE_UNKNOWN;
- this.requestedNetworkIfaces = [];
-}
-DataCall.prototype = {
- /**
- * Standard values for the APN connection retry process
- * Retry funcion: time(secs) = A * numer_of_retries^2 + B
- */
- NETWORK_APNRETRY_FACTOR: 8,
- NETWORK_APNRETRY_ORIGIN: 3,
- NETWORK_APNRETRY_MAXRETRIES: 10,
-
- dataCallHandler: null,
-
- // Event timer for connection retries
- timer: null,
-
- // APN failed connections. Retry counter
- apnRetryCounter: 0,
-
- // Array to hold RILNetworkInterfaces that requested this DataCall.
- requestedNetworkIfaces: null,
-
- /**
- * @return "deactivate" if <ifname> changes or one of the aCurrentDataCall
- * addresses is missing in updatedDataCall, or "identical" if no
- * changes found, or "changed" otherwise.
- */
- _compareDataCallLink: function(aUpdatedDataCall, aCurrentDataCall) {
- // If network interface is changed, report as "deactivate".
- if (aUpdatedDataCall.ifname != aCurrentDataCall.ifname) {
- return "deactivate";
- }
-
- // If any existing address is missing, report as "deactivate".
- for (let i = 0; i < aCurrentDataCall.addresses.length; i++) {
- let address = aCurrentDataCall.addresses[i];
- if (aUpdatedDataCall.addresses.indexOf(address) < 0) {
- return "deactivate";
- }
- }
-
- if (aCurrentDataCall.addresses.length != aUpdatedDataCall.addresses.length) {
- // Since now all |aCurrentDataCall.addresses| are found in
- // |aUpdatedDataCall.addresses|, this means one or more new addresses are
- // reported.
- return "changed";
- }
-
- let fields = ["gateways", "dnses"];
- for (let i = 0; i < fields.length; i++) {
- // Compare <datacall>.<field>.
- let field = fields[i];
- let lhs = aUpdatedDataCall[field], rhs = aCurrentDataCall[field];
- if (lhs.length != rhs.length) {
- return "changed";
- }
- for (let i = 0; i < lhs.length; i++) {
- if (lhs[i] != rhs[i]) {
- return "changed";
- }
- }
- }
-
- if (aCurrentDataCall.mtu != aUpdatedDataCall.mtu) {
- return "changed";
- }
-
- return "identical";
- },
-
- _getGeckoDataCallState:function (aDataCall) {
- if (aDataCall.active == Ci.nsIDataCallInterface.DATACALL_STATE_ACTIVE_UP ||
- aDataCall.active == Ci.nsIDataCallInterface.DATACALL_STATE_ACTIVE_DOWN) {
- return NETWORK_STATE_CONNECTED;
- }
-
- return NETWORK_STATE_DISCONNECTED;
- },
-
- onSetupDataCallResult: function(aDataCall) {
- this.debug("onSetupDataCallResult: " + JSON.stringify(aDataCall));
- let errorMsg = aDataCall.errorMsg;
- if (aDataCall.failCause &&
- aDataCall.failCause != Ci.nsIDataCallInterface.DATACALL_FAIL_NONE) {
- errorMsg =
- RIL.RIL_DATACALL_FAILCAUSE_TO_GECKO_DATACALL_ERROR[aDataCall.failCause];
- }
-
- if (errorMsg) {
- if (DEBUG) {
- this.debug("SetupDataCall error for apn " + this.apnProfile.apn + ": " +
- errorMsg + " (" + aDataCall.failCause + "), retry time: " +
- aDataCall.suggestedRetryTime);
- }
-
- this.state = NETWORK_STATE_DISCONNECTED;
-
- if (this.requestedNetworkIfaces.length === 0) {
- if (DEBUG) this.debug("This DataCall is not requested anymore.");
- return;
- }
-
- // Let DataCallHandler notify MobileConnectionService
- this.dataCallHandler.notifyDataCallError(this, errorMsg);
-
- // For suggestedRetryTime, the value of INT32_MAX(0x7fffffff) means no retry.
- if (aDataCall.suggestedRetryTime === INT32_MAX ||
- this.isPermanentFail(aDataCall.failCause, errorMsg)) {
- if (DEBUG) this.debug("Data call error: no retry needed.");
- return;
- }
-
- this.retry(aDataCall.suggestedRetryTime);
- return;
- }
-
- this.apnRetryCounter = 0;
- this.linkInfo.cid = aDataCall.cid;
-
- if (this.requestedNetworkIfaces.length === 0) {
- if (DEBUG) {
- this.debug("State is connected, but no network interface requested" +
- " this DataCall");
- }
- this.deactivate();
- return;
- }
-
- this.linkInfo.ifname = aDataCall.ifname;
- this.linkInfo.addresses = aDataCall.addresses ? aDataCall.addresses.split(" ") : [];
- this.linkInfo.gateways = aDataCall.gateways ? aDataCall.gateways.split(" ") : [];
- this.linkInfo.dnses = aDataCall.dnses ? aDataCall.dnses.split(" ") : [];
- this.linkInfo.pcscf = aDataCall.pcscf ? aDataCall.pcscf.split(" ") : [];
- this.linkInfo.mtu = aDataCall.mtu > 0 ? aDataCall.mtu : 0;
- this.state = this._getGeckoDataCallState(aDataCall);
-
- // Notify DataCallHandler about data call connected.
- this.dataCallHandler.notifyDataCallChanged(this);
-
- for (let i = 0; i < this.requestedNetworkIfaces.length; i++) {
- this.requestedNetworkIfaces[i].notifyRILNetworkInterface();
- }
- },
-
- onDeactivateDataCallResult: function() {
- if (DEBUG) this.debug("onDeactivateDataCallResult");
-
- this.reset();
-
- if (this.requestedNetworkIfaces.length > 0) {
- if (DEBUG) {
- this.debug("State is disconnected/unknown, but this DataCall is" +
- " requested.");
- }
- this.setup();
- return;
- }
-
- // Notify DataCallHandler about data call disconnected.
- this.dataCallHandler.notifyDataCallChanged(this);
- },
-
- onDataCallChanged: function(aUpdatedDataCall) {
- if (DEBUG) {
- this.debug("onDataCallChanged: " + JSON.stringify(aUpdatedDataCall));
- }
-
- if (this.state == NETWORK_STATE_CONNECTING ||
- this.state == NETWORK_STATE_DISCONNECTING) {
- if (DEBUG) {
- this.debug("We are in connecting/disconnecting state, ignore any " +
- "unsolicited event for now.");
- }
- return;
- }
-
- let dataCallState = this._getGeckoDataCallState(aUpdatedDataCall);
- if (this.state == dataCallState &&
- dataCallState != NETWORK_STATE_CONNECTED) {
- return;
- }
-
- let newLinkInfo = {
- ifname: aUpdatedDataCall.ifname,
- addresses: aUpdatedDataCall.addresses ? aUpdatedDataCall.addresses.split(" ") : [],
- dnses: aUpdatedDataCall.dnses ? aUpdatedDataCall.dnses.split(" ") : [],
- gateways: aUpdatedDataCall.gateways ? aUpdatedDataCall.gateways.split(" ") : [],
- pcscf: aUpdatedDataCall.pcscf ? aUpdatedDataCall.pcscf.split(" ") : [],
- mtu: aUpdatedDataCall.mtu > 0 ? aUpdatedDataCall.mtu : 0
- };
-
- switch (dataCallState) {
- case NETWORK_STATE_CONNECTED:
- if (this.state == NETWORK_STATE_CONNECTED) {
- let result =
- this._compareDataCallLink(newLinkInfo, this.linkInfo);
-
- if (result == "identical") {
- if (DEBUG) this.debug("No changes in data call.");
- return;
- }
- if (result == "deactivate") {
- if (DEBUG) this.debug("Data link changed, cleanup.");
- this.deactivate();
- return;
- }
- // Minor change, just update and notify.
- if (DEBUG) {
- this.debug("Data link minor change, just update and notify.");
- }
-
- this.linkInfo.addresses = newLinkInfo.addresses.slice();
- this.linkInfo.gateways = newLinkInfo.gateways.slice();
- this.linkInfo.dnses = newLinkInfo.dnses.slice();
- this.linkInfo.pcscf = newLinkInfo.pcscf.slice();
- this.linkInfo.mtu = newLinkInfo.mtu;
- }
- break;
- case NETWORK_STATE_DISCONNECTED:
- case NETWORK_STATE_UNKNOWN:
- if (this.state == NETWORK_STATE_CONNECTED) {
- // Notify first on unexpected data call disconnection.
- this.state = dataCallState;
- for (let i = 0; i < this.requestedNetworkIfaces.length; i++) {
- this.requestedNetworkIfaces[i].notifyRILNetworkInterface();
- }
- }
- this.reset();
-
- if (this.requestedNetworkIfaces.length > 0) {
- if (DEBUG) {
- this.debug("State is disconnected/unknown, but this DataCall is" +
- " requested.");
- }
- this.setup();
- return;
- }
- break;
- }
-
- this.state = dataCallState;
-
- // Notify DataCallHandler about data call changed.
- this.dataCallHandler.notifyDataCallChanged(this);
-
- for (let i = 0; i < this.requestedNetworkIfaces.length; i++) {
- this.requestedNetworkIfaces[i].notifyRILNetworkInterface();
- }
- },
-
- // Helpers
-
- debug: function(aMsg) {
- dump("-*- DataCall[" + this.clientId + ":" + this.apnProfile.apn + "]: " +
- aMsg + "\n");
- },
-
- get connected() {
- return this.state == NETWORK_STATE_CONNECTED;
- },
-
- isPermanentFail: function(aDataFailCause, aErrorMsg) {
- // Check ril.h for 'no retry' data call fail causes.
- if (aErrorMsg === RIL.GECKO_ERROR_RADIO_NOT_AVAILABLE ||
- aErrorMsg === RIL.GECKO_ERROR_INVALID_PARAMETER ||
- aDataFailCause === Ci.nsIDataCallInterface.DATACALL_FAIL_OPERATOR_BARRED ||
- aDataFailCause === Ci.nsIDataCallInterface.DATACALL_FAIL_MISSING_UKNOWN_APN ||
- aDataFailCause === Ci.nsIDataCallInterface.DATACALL_FAIL_UNKNOWN_PDP_ADDRESS_TYPE ||
- aDataFailCause === Ci.nsIDataCallInterface.DATACALL_FAIL_USER_AUTHENTICATION ||
- aDataFailCause === Ci.nsIDataCallInterface.DATACALL_FAIL_ACTIVATION_REJECT_GGSN ||
- aDataFailCause === Ci.nsIDataCallInterface.DATACALL_FAIL_SERVICE_OPTION_NOT_SUPPORTED ||
- aDataFailCause === Ci.nsIDataCallInterface.DATACALL_FAIL_SERVICE_OPTION_NOT_SUBSCRIBED ||
- aDataFailCause === Ci.nsIDataCallInterface.DATACALL_FAIL_NSAPI_IN_USE ||
- aDataFailCause === Ci.nsIDataCallInterface.DATACALL_FAIL_ONLY_IPV4_ALLOWED ||
- aDataFailCause === Ci.nsIDataCallInterface.DATACALL_FAIL_ONLY_IPV6_ALLOWED ||
- aDataFailCause === Ci.nsIDataCallInterface.DATACALL_FAIL_PROTOCOL_ERRORS ||
- aDataFailCause === Ci.nsIDataCallInterface.DATACALL_FAIL_RADIO_POWER_OFF ||
- aDataFailCause === Ci.nsIDataCallInterface.DATACALL_FAIL_TETHERED_CALL_ACTIVE) {
- return true;
- }
-
- return false;
- },
-
- inRequestedTypes: function(aType) {
- for (let i = 0; i < this.requestedNetworkIfaces.length; i++) {
- if (this.requestedNetworkIfaces[i].info.type == aType) {
- return true;
- }
- }
- return false;
- },
-
- canHandleApn: function(aApnSetting) {
- let isIdentical = this.apnProfile.apn == aApnSetting.apn &&
- (this.apnProfile.user || '') == (aApnSetting.user || '') &&
- (this.apnProfile.password || '') == (aApnSetting.password || '') &&
- (this.apnProfile.authType || '') == (aApnSetting.authtype || '');
-
- if (RILQUIRKS_HAVE_IPV6) {
- isIdentical = isIdentical &&
- (this.apnProfile.protocol || '') == (aApnSetting.protocol || '') &&
- (this.apnProfile.roaming_protocol || '') == (aApnSetting.roaming_protocol || '');
- }
-
- return isIdentical;
- },
-
- resetLinkInfo: function() {
- this.linkInfo.cid = null;
- this.linkInfo.ifname = null;
- this.linkInfo.addresses = [];
- this.linkInfo.dnses = [];
- this.linkInfo.gateways = [];
- this.linkInfo.pcscf = [];
- this.linkInfo.mtu = null;
- },
-
- reset: function() {
- this.resetLinkInfo();
-
- this.state = NETWORK_STATE_UNKNOWN;
- },
-
- connect: function(aNetworkInterface) {
- if (DEBUG) this.debug("connect: " + aNetworkInterface.info.type);
-
- if (this.requestedNetworkIfaces.indexOf(aNetworkInterface) == -1) {
- this.requestedNetworkIfaces.push(aNetworkInterface);
- }
-
- if (this.state == NETWORK_STATE_CONNECTING ||
- this.state == NETWORK_STATE_DISCONNECTING) {
- return;
- }
- if (this.state == NETWORK_STATE_CONNECTED) {
- // This needs to run asynchronously, to behave the same way as the case of
- // non-shared apn, see bug 1059110.
- Services.tm.currentThread.dispatch(() => {
- // Do not notify if state changed while this event was being dispatched,
- // the state probably was notified already or need not to be notified.
- if (aNetworkInterface.info.state == RIL.GECKO_NETWORK_STATE_CONNECTED) {
- aNetworkInterface.notifyRILNetworkInterface();
- }
- }, Ci.nsIEventTarget.DISPATCH_NORMAL);
- return;
- }
-
- // If retry mechanism is running on background, stop it since we are going
- // to setup data call now.
- if (this.timer) {
- this.timer.cancel();
- }
-
- this.setup();
- },
-
- setup: function() {
- if (DEBUG) {
- this.debug("Going to set up data connection with APN " +
- this.apnProfile.apn);
- }
-
- let connection =
- gMobileConnectionService.getItemByServiceId(this.clientId);
- let dataInfo = connection && connection.data;
- if (dataInfo == null ||
- dataInfo.state != RIL.GECKO_MOBILE_CONNECTION_STATE_REGISTERED ||
- dataInfo.type == RIL.GECKO_MOBILE_CONNECTION_STATE_UNKNOWN) {
- return;
- }
-
- let radioTechType = dataInfo.type;
- let radioTechnology = RIL.GECKO_RADIO_TECH.indexOf(radioTechType);
- let authType = RIL.RIL_DATACALL_AUTH_TO_GECKO.indexOf(this.apnProfile.authType);
- // Use the default authType if the value in database is invalid.
- // For the case that user might not select the authentication type.
- if (authType == -1) {
- if (DEBUG) {
- this.debug("Invalid authType '" + this.apnProfile.authtype +
- "', using '" + RIL.GECKO_DATACALL_AUTH_DEFAULT + "'");
- }
- authType = RIL.RIL_DATACALL_AUTH_TO_GECKO.indexOf(RIL.GECKO_DATACALL_AUTH_DEFAULT);
- }
-
- let pdpType = Ci.nsIDataCallInterface.DATACALL_PDP_TYPE_IPV4;
- if (RILQUIRKS_HAVE_IPV6) {
- pdpType = !dataInfo.roaming
- ? RIL.RIL_DATACALL_PDP_TYPES.indexOf(this.apnProfile.protocol)
- : RIL.RIL_DATACALL_PDP_TYPES.indexOf(this.apnProfile.roaming_protocol);
- if (pdpType == -1) {
- if (DEBUG) {
- this.debug("Invalid pdpType '" + (!dataInfo.roaming
- ? this.apnProfile.protocol
- : this.apnProfile.roaming_protocol) +
- "', using '" + RIL.GECKO_DATACALL_PDP_TYPE_DEFAULT + "'");
- }
- pdpType = RIL.RIL_DATACALL_PDP_TYPES.indexOf(RIL.GECKO_DATACALL_PDP_TYPE_DEFAULT);
- }
- }
-
- let dcInterface = this.dataCallHandler.dataCallInterface;
- dcInterface.setupDataCall(
- this.apnProfile.apn, this.apnProfile.user, this.apnProfile.password,
- authType, pdpType, {
- QueryInterface: XPCOMUtils.generateQI([Ci.nsIDataCallCallback]),
- notifySetupDataCallSuccess: (aDataCall) => {
- this.onSetupDataCallResult(aDataCall);
- },
- notifyError: (aErrorMsg) => {
- this.onSetupDataCallResult({errorMsg: aErrorMsg});
- }
- });
- this.state = NETWORK_STATE_CONNECTING;
- },
-
- retry: function(aSuggestedRetryTime) {
- let apnRetryTimer;
-
- // We will retry the connection in increasing times
- // based on the function: time = A * numer_of_retries^2 + B
- if (this.apnRetryCounter >= this.NETWORK_APNRETRY_MAXRETRIES) {
- this.apnRetryCounter = 0;
- this.timer = null;
- if (DEBUG) this.debug("Too many APN Connection retries - STOP retrying");
- return;
- }
-
- // If there is a valid aSuggestedRetryTime, override the retry timer.
- if (aSuggestedRetryTime !== undefined && aSuggestedRetryTime >= 0) {
- apnRetryTimer = aSuggestedRetryTime / 1000;
- } else {
- apnRetryTimer = this.NETWORK_APNRETRY_FACTOR *
- (this.apnRetryCounter * this.apnRetryCounter) +
- this.NETWORK_APNRETRY_ORIGIN;
- }
- this.apnRetryCounter++;
- if (DEBUG) {
- this.debug("Data call - APN Connection Retry Timer (secs-counter): " +
- apnRetryTimer + "-" + this.apnRetryCounter);
- }
-
- if (this.timer == null) {
- // Event timer for connection retries
- this.timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
- }
- this.timer.initWithCallback(this, apnRetryTimer * 1000,
- Ci.nsITimer.TYPE_ONE_SHOT);
- },
-
- disconnect: function(aNetworkInterface) {
- if (DEBUG) this.debug("disconnect: " + aNetworkInterface.info.type);
-
- let index = this.requestedNetworkIfaces.indexOf(aNetworkInterface);
- if (index != -1) {
- this.requestedNetworkIfaces.splice(index, 1);
-
- if (this.state == NETWORK_STATE_DISCONNECTED ||
- this.state == NETWORK_STATE_UNKNOWN) {
- if (this.timer) {
- this.timer.cancel();
- }
- this.reset();
- return;
- }
-
- // Notify the DISCONNECTED event immediately after network interface is
- // removed from requestedNetworkIfaces, to make the DataCall, shared or
- // not, to have the same behavior.
- Services.tm.currentThread.dispatch(() => {
- // Do not notify if state changed while this event was being dispatched,
- // the state probably was notified already or need not to be notified.
- if (aNetworkInterface.info.state == RIL.GECKO_NETWORK_STATE_DISCONNECTED) {
- aNetworkInterface.notifyRILNetworkInterface();
-
- // Clear link info after notifying NetworkManager.
- if (this.requestedNetworkIfaces.length === 0) {
- this.resetLinkInfo();
- }
- }
- }, Ci.nsIEventTarget.DISPATCH_NORMAL);
- }
-
- // Only deactivate data call if no more network interface needs this
- // DataCall and if state is CONNECTED, for other states, we simply remove
- // the network interface from requestedNetworkIfaces.
- if (this.requestedNetworkIfaces.length > 0 ||
- this.state != NETWORK_STATE_CONNECTED) {
- return;
- }
-
- this.deactivate();
- },
-
- deactivate: function() {
- let reason = Ci.nsIDataCallInterface.DATACALL_DEACTIVATE_NO_REASON;
- if (DEBUG) {
- this.debug("Going to disconnect data connection cid " + this.linkInfo.cid);
- }
-
- let dcInterface = this.dataCallHandler.dataCallInterface;
- dcInterface.deactivateDataCall(this.linkInfo.cid, reason, {
- QueryInterface: XPCOMUtils.generateQI([Ci.nsIDataCallCallback]),
- notifySuccess: () => {
- this.onDeactivateDataCallResult();
- },
- notifyError: (aErrorMsg) => {
- this.onDeactivateDataCallResult();
- }
- });
-
- this.state = NETWORK_STATE_DISCONNECTING;
- },
-
- // Entry method for timer events. Used to reconnect to a failed APN
- notify: function(aTimer) {
- this.setup();
- },
-
- shutdown: function() {
- if (this.timer) {
- this.timer.cancel();
- this.timer = null;
- }
- }
-};
-
-function RILNetworkInfo(aClientId, aType, aNetworkInterface)
-{
- this.serviceId = aClientId;
- this.type = aType;
-
- this.networkInterface = aNetworkInterface;
-}
-RILNetworkInfo.prototype = {
- classID: RILNETWORKINFO_CID,
- classInfo: XPCOMUtils.generateCI({classID: RILNETWORKINFO_CID,
- classDescription: "RILNetworkInfo",
- interfaces: [Ci.nsINetworkInfo,
- Ci.nsIRilNetworkInfo]}),
- QueryInterface: XPCOMUtils.generateQI([Ci.nsINetworkInfo,
- Ci.nsIRilNetworkInfo]),
-
- networkInterface: null,
-
- getDataCall: function() {
- return this.networkInterface.dataCall;
- },
-
- getApnSetting: function() {
- return this.networkInterface.apnSetting;
- },
-
- debug: function(aMsg) {
- dump("-*- RILNetworkInfo[" + this.serviceId + ":" + this.type + "]: " +
- aMsg + "\n");
- },
-
- /**
- * nsINetworkInfo Implementation
- */
- get state() {
- let dataCall = this.getDataCall();
- if (!dataCall.inRequestedTypes(this.type)) {
- return NETWORK_STATE_DISCONNECTED;
- }
- return dataCall.state;
- },
-
- type: null,
-
- get name() {
- return this.getDataCall().linkInfo.ifname;
- },
-
- getAddresses: function(aIps, aPrefixLengths) {
- let addresses = this.getDataCall().linkInfo.addresses;
-
- let ips = [];
- let prefixLengths = [];
- for (let i = 0; i < addresses.length; i++) {
- let [ip, prefixLength] = addresses[i].split("/");
- ips.push(ip);
- prefixLengths.push(prefixLength);
- }
-
- aIps.value = ips.slice();
- aPrefixLengths.value = prefixLengths.slice();
-
- return ips.length;
- },
-
- getGateways: function(aCount) {
- let linkInfo = this.getDataCall().linkInfo;
-
- if (aCount) {
- aCount.value = linkInfo.gateways.length;
- }
-
- return linkInfo.gateways.slice();
- },
-
- getDnses: function(aCount) {
- let linkInfo = this.getDataCall().linkInfo;
-
- if (aCount) {
- aCount.value = linkInfo.dnses.length;
- }
-
- return linkInfo.dnses.slice();
- },
-
- /**
- * nsIRilNetworkInfo Implementation
- */
-
- serviceId: 0,
-
- get iccId() {
- let icc = gIccService.getIccByServiceId(this.serviceId);
- let iccInfo = icc && icc.iccInfo;
-
- return iccInfo && iccInfo.iccid;
- },
-
- get mmsc() {
- if (this.type != NETWORK_TYPE_MOBILE_MMS) {
- if (DEBUG) this.debug("Error! Only MMS network can get MMSC.");
- throw Cr.NS_ERROR_UNEXPECTED;
- }
-
- return this.getApnSetting().mmsc || "";
- },
-
- get mmsProxy() {
- if (this.type != NETWORK_TYPE_MOBILE_MMS) {
- if (DEBUG) this.debug("Error! Only MMS network can get MMS proxy.");
- throw Cr.NS_ERROR_UNEXPECTED;
- }
-
- return this.getApnSetting().mmsproxy || "";
- },
-
- get mmsPort() {
- if (this.type != NETWORK_TYPE_MOBILE_MMS) {
- if (DEBUG) this.debug("Error! Only MMS network can get MMS port.");
- throw Cr.NS_ERROR_UNEXPECTED;
- }
-
- // Note: Port 0 is reserved, so we treat it as invalid as well.
- // See http://www.iana.org/assignments/port-numbers
- return this.getApnSetting().mmsport || -1;
- },
-
- getPcscf: function(aCount) {
- if (this.type != NETWORK_TYPE_MOBILE_IMS) {
- if (DEBUG) this.debug("Error! Only IMS network can get pcscf.");
- throw Cr.NS_ERROR_UNEXPECTED;
- }
-
- let linkInfo = this.getDataCall().linkInfo;
-
- if (aCount) {
- aCount.value = linkInfo.pcscf.length;
- }
- return linkInfo.pcscf.slice();
- },
-};
-
-function RILNetworkInterface(aDataCallHandler, aType, aApnSetting, aDataCall) {
- if (!aDataCall) {
- throw new Error("No dataCall for RILNetworkInterface: " + type);
- }
-
- this.dataCallHandler = aDataCallHandler;
- this.enabled = false;
- this.dataCall = aDataCall;
- this.apnSetting = aApnSetting;
-
- this.info = new RILNetworkInfo(aDataCallHandler.clientId, aType, this);
-}
-
-RILNetworkInterface.prototype = {
- classID: RILNETWORKINTERFACE_CID,
- classInfo: XPCOMUtils.generateCI({classID: RILNETWORKINTERFACE_CID,
- classDescription: "RILNetworkInterface",
- interfaces: [Ci.nsINetworkInterface]}),
- QueryInterface: XPCOMUtils.generateQI([Ci.nsINetworkInterface]),
-
- // If this RILNetworkInterface type is enabled or not.
- enabled: null,
-
- apnSetting: null,
-
- dataCall: null,
-
- /**
- * nsINetworkInterface Implementation
- */
-
- info: null,
-
- get httpProxyHost() {
- return this.apnSetting.proxy || "";
- },
-
- get httpProxyPort() {
- return this.apnSetting.port || "";
- },
-
- get mtu() {
- // Value provided by network has higher priority than apn settings.
- return this.dataCall.linkInfo.mtu || this.apnSetting.mtu || -1;
- },
-
- // Helpers
-
- debug: function(aMsg) {
- dump("-*- RILNetworkInterface[" + this.dataCallHandler.clientId + ":" +
- this.info.type + "]: " + aMsg + "\n");
- },
-
- get connected() {
- return this.info.state == NETWORK_STATE_CONNECTED;
- },
-
- notifyRILNetworkInterface: function() {
- if (DEBUG) {
- this.debug("notifyRILNetworkInterface type: " + this.info.type +
- ", state: " + this.info.state);
- }
-
- gNetworkManager.updateNetworkInterface(this);
- },
-
- connect: function() {
- this.enabled = true;
-
- this.dataCall.connect(this);
- },
-
- disconnect: function() {
- if (!this.enabled) {
- return;
- }
- this.enabled = false;
-
- this.dataCall.disconnect(this);
- },
-
- shutdown: function() {
- this.dataCall.shutdown();
- this.dataCall = null;
- }
-};
-
-this.NSGetFactory = XPCOMUtils.generateNSGetFactory([DataCallManager]); \ No newline at end of file
diff --git a/dom/system/gonk/DataCallManager.manifest b/dom/system/gonk/DataCallManager.manifest
deleted file mode 100644
index 2a982415ed..0000000000
--- a/dom/system/gonk/DataCallManager.manifest
+++ /dev/null
@@ -1,4 +0,0 @@
-# DataCallManager.js
-component {35b9efa2-e42c-45ce-8210-0a13e6f4aadc} DataCallManager.js
-contract @mozilla.org/datacall/manager;1 {35b9efa2-e42c-45ce-8210-0a13e6f4aadc}
-category profile-after-change DataCallManager @mozilla.org/datacall/manager;1 \ No newline at end of file
diff --git a/dom/system/gonk/GeolocationUtil.cpp b/dom/system/gonk/GeolocationUtil.cpp
deleted file mode 100644
index 99d484a19c..0000000000
--- a/dom/system/gonk/GeolocationUtil.cpp
+++ /dev/null
@@ -1,28 +0,0 @@
-/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
-/* 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/. */
-
-#include "GeolocationUtil.h"
-
-double CalculateDeltaInMeter(double aLat, double aLon, double aLastLat, double aLastLon)
-{
- // Use spherical law of cosines to calculate difference
- // Not quite as correct as the Haversine but simpler and cheaper
- const double radsInDeg = M_PI / 180.0;
- const double rNewLat = aLat * radsInDeg;
- const double rNewLon = aLon * radsInDeg;
- const double rOldLat = aLastLat * radsInDeg;
- const double rOldLon = aLastLon * radsInDeg;
- // WGS84 equatorial radius of earth = 6378137m
- double cosDelta = (sin(rNewLat) * sin(rOldLat)) +
- (cos(rNewLat) * cos(rOldLat) * cos(rOldLon - rNewLon));
- if (cosDelta > 1.0) {
- cosDelta = 1.0;
- } else if (cosDelta < -1.0) {
- cosDelta = -1.0;
- }
- return acos(cosDelta) * 6378137;
-}
-
diff --git a/dom/system/gonk/GeolocationUtil.h b/dom/system/gonk/GeolocationUtil.h
deleted file mode 100644
index fde337fb86..0000000000
--- a/dom/system/gonk/GeolocationUtil.h
+++ /dev/null
@@ -1,13 +0,0 @@
-/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
-/* 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/. */
-
-#ifndef GEOLOCATIONUTIL_H
-#define GEOLOCATIONUTIL_H
-
-double CalculateDeltaInMeter(double aLat, double aLon, double aLastLat, double aLastLon);
-
-#endif
-
diff --git a/dom/system/gonk/GonkGPSGeolocationProvider.cpp b/dom/system/gonk/GonkGPSGeolocationProvider.cpp
deleted file mode 100644
index 9ce6ce2e5a..0000000000
--- a/dom/system/gonk/GonkGPSGeolocationProvider.cpp
+++ /dev/null
@@ -1,706 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* Copyright 2012 Mozilla Foundation and Mozilla contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "GonkGPSGeolocationProvider.h"
-
-#include <cmath>
-#include <pthread.h>
-#include <hardware/gps.h>
-
-#include "base/task.h"
-#include "GeolocationUtil.h"
-#include "mozstumbler/MozStumbler.h"
-#include "mozilla/Preferences.h"
-#include "mozilla/Services.h"
-#include "nsContentUtils.h"
-#include "nsGeoPosition.h"
-#include "nsIInterfaceRequestorUtils.h"
-#include "nsINetworkInterface.h"
-#include "nsIObserverService.h"
-#include "nsJSUtils.h"
-#include "nsPrintfCString.h"
-#include "nsServiceManagerUtils.h"
-#include "nsThreadUtils.h"
-#include "prtime.h"
-#include "mozilla/dom/BindingUtils.h"
-#include "mozilla/dom/ScriptSettings.h"
-#include "mozilla/dom/SettingChangeNotificationBinding.h"
-
-#ifdef AGPS_TYPE_INVALID
-#define AGPS_HAVE_DUAL_APN
-#endif
-
-#define FLUSH_AIDE_DATA 0
-
-#undef LOG
-#undef ERR
-#undef DBG
-#define LOG(args...) __android_log_print(ANDROID_LOG_INFO, "GonkGPSGeolocationProvider", ## args)
-#define ERR(args...) __android_log_print(ANDROID_LOG_ERROR, "GonkGPSGeolocationProvider", ## args)
-#define DBG(args...) __android_log_print(ANDROID_LOG_DEBUG, "GonkGPSGeolocationProvider" , ## args)
-
-using namespace mozilla;
-using namespace mozilla::dom;
-
-static const int kDefaultPeriod = 1000; // ms
-static bool gDebug_isLoggingEnabled = false;
-static bool gDebug_isGPSLocationIgnored = false;
-static const char* kMozSettingsChangedTopic = "mozsettings-changed";
-// Both of these settings can be toggled in the Gaia Developer settings screen.
-static const char* kSettingDebugEnabled = "geolocation.debugging.enabled";
-static const char* kSettingDebugGpsIgnored = "geolocation.debugging.gps-locations-ignored";
-
-// While most methods of GonkGPSGeolocationProvider should only be
-// called from main thread, we deliberately put the Init and ShutdownGPS
-// methods off main thread to avoid blocking.
-NS_IMPL_ISUPPORTS(GonkGPSGeolocationProvider,
- nsIGeolocationProvider,
- nsIObserver,
- nsISettingsServiceCallback)
-
-/* static */ GonkGPSGeolocationProvider* GonkGPSGeolocationProvider::sSingleton = nullptr;
-GpsCallbacks GonkGPSGeolocationProvider::mCallbacks;
-
-
-void
-GonkGPSGeolocationProvider::LocationCallback(GpsLocation* location)
-{
- if (gDebug_isGPSLocationIgnored) {
- return;
- }
-
- class UpdateLocationEvent : public Runnable {
- public:
- UpdateLocationEvent(nsGeoPosition* aPosition)
- : mPosition(aPosition)
- {}
- NS_IMETHOD Run() override {
- RefPtr<GonkGPSGeolocationProvider> provider =
- GonkGPSGeolocationProvider::GetSingleton();
- nsCOMPtr<nsIGeolocationUpdate> callback = provider->mLocationCallback;
- provider->mLastGPSPosition = mPosition;
- if (callback) {
- callback->Update(mPosition);
- }
- return NS_OK;
- }
- private:
- RefPtr<nsGeoPosition> mPosition;
- };
-
- MOZ_ASSERT(location);
-
- const float kImpossibleAccuracy_m = 0.001;
- if (location->accuracy < kImpossibleAccuracy_m) {
- return;
- }
-
- RefPtr<nsGeoPosition> somewhere = new nsGeoPosition(location->latitude,
- location->longitude,
- location->altitude,
- location->accuracy,
- location->accuracy,
- location->bearing,
- location->speed,
- PR_Now() / PR_USEC_PER_MSEC);
- // Note above: Can't use location->timestamp as the time from the satellite is a
- // minimum of 16 secs old (see http://leapsecond.com/java/gpsclock.htm).
- // All code from this point on expects the gps location to be timestamped with the
- // current time, most notably: the geolocation service which respects maximumAge
- // set in the DOM JS.
-
- if (gDebug_isLoggingEnabled) {
- DBG("geo: GPS got a fix (%f, %f). accuracy: %f",
- location->latitude,
- location->longitude,
- location->accuracy);
- }
-
- RefPtr<UpdateLocationEvent> event = new UpdateLocationEvent(somewhere);
- NS_DispatchToMainThread(event);
-
-}
-
-class NotifyObserversGPSTask final : public Runnable
-{
-public:
- explicit NotifyObserversGPSTask(const char16_t* aData)
- : mData(aData)
- {}
- NS_IMETHOD Run() override {
- RefPtr<nsIGeolocationProvider> provider =
- GonkGPSGeolocationProvider::GetSingleton();
- nsCOMPtr<nsIObserverService> obsService = services::GetObserverService();
- obsService->NotifyObservers(provider, "geolocation-device-events", mData);
- return NS_OK;
- }
-private:
- const char16_t* mData;
-};
-
-void
-GonkGPSGeolocationProvider::StatusCallback(GpsStatus* status)
-{
- const char* msgStream=0;
- switch (status->status) {
- case GPS_STATUS_NONE:
- msgStream = "geo: GPS_STATUS_NONE\n";
- break;
- case GPS_STATUS_SESSION_BEGIN:
- msgStream = "geo: GPS_STATUS_SESSION_BEGIN\n";
- break;
- case GPS_STATUS_SESSION_END:
- msgStream = "geo: GPS_STATUS_SESSION_END\n";
- break;
- case GPS_STATUS_ENGINE_ON:
- msgStream = "geo: GPS_STATUS_ENGINE_ON\n";
- NS_DispatchToMainThread(new NotifyObserversGPSTask(u"GPSStarting"));
- break;
- case GPS_STATUS_ENGINE_OFF:
- msgStream = "geo: GPS_STATUS_ENGINE_OFF\n";
- NS_DispatchToMainThread(new NotifyObserversGPSTask(u"GPSShutdown"));
- break;
- default:
- msgStream = "geo: Unknown GPS status\n";
- break;
- }
- if (gDebug_isLoggingEnabled){
- DBG("%s", msgStream);
- }
-}
-
-void
-GonkGPSGeolocationProvider::SvStatusCallback(GpsSvStatus* sv_info)
-{
- if (gDebug_isLoggingEnabled) {
- static int numSvs = 0;
- static uint32_t numEphemeris = 0;
- static uint32_t numAlmanac = 0;
- static uint32_t numUsedInFix = 0;
-
- unsigned int i = 1;
- uint32_t svAlmanacCount = 0;
- for (i = 1; i > 0; i <<= 1) {
- if (i & sv_info->almanac_mask) {
- svAlmanacCount++;
- }
- }
-
- uint32_t svEphemerisCount = 0;
- for (i = 1; i > 0; i <<= 1) {
- if (i & sv_info->ephemeris_mask) {
- svEphemerisCount++;
- }
- }
-
- uint32_t svUsedCount = 0;
- for (i = 1; i > 0; i <<= 1) {
- if (i & sv_info->used_in_fix_mask) {
- svUsedCount++;
- }
- }
-
- // Log the message only if the the status changed.
- if (sv_info->num_svs != numSvs ||
- svAlmanacCount != numAlmanac ||
- svEphemerisCount != numEphemeris ||
- svUsedCount != numUsedInFix) {
-
- LOG(
- "geo: Number of SVs have (visibility, almanac, ephemeris): (%d, %d, %d)."
- " %d of these SVs were used in fix.\n",
- sv_info->num_svs, svAlmanacCount, svEphemerisCount, svUsedCount);
-
- numSvs = sv_info->num_svs;
- numAlmanac = svAlmanacCount;
- numEphemeris = svEphemerisCount;
- numUsedInFix = svUsedCount;
- }
- }
-}
-
-void
-GonkGPSGeolocationProvider::NmeaCallback(GpsUtcTime timestamp, const char* nmea, int length)
-{
- if (gDebug_isLoggingEnabled) {
- DBG("NMEA: timestamp:\t%lld, length: %d, %s", timestamp, length, nmea);
- }
-}
-
-void
-GonkGPSGeolocationProvider::SetCapabilitiesCallback(uint32_t capabilities)
-{
- class UpdateCapabilitiesEvent : public Runnable {
- public:
- UpdateCapabilitiesEvent(uint32_t aCapabilities)
- : mCapabilities(aCapabilities)
- {}
- NS_IMETHOD Run() override {
- RefPtr<GonkGPSGeolocationProvider> provider =
- GonkGPSGeolocationProvider::GetSingleton();
-
- provider->mSupportsScheduling = mCapabilities & GPS_CAPABILITY_SCHEDULING;
- provider->mSupportsSingleShot = mCapabilities & GPS_CAPABILITY_SINGLE_SHOT;
-#ifdef GPS_CAPABILITY_ON_DEMAND_TIME
- provider->mSupportsTimeInjection = mCapabilities & GPS_CAPABILITY_ON_DEMAND_TIME;
-#endif
- return NS_OK;
- }
- private:
- uint32_t mCapabilities;
- };
-
- NS_DispatchToMainThread(new UpdateCapabilitiesEvent(capabilities));
-}
-
-void
-GonkGPSGeolocationProvider::AcquireWakelockCallback()
-{
-}
-
-void
-GonkGPSGeolocationProvider::ReleaseWakelockCallback()
-{
-}
-
-typedef void *(*pthread_func)(void *);
-
-/** Callback for creating a thread that can call into the JS codes.
- */
-pthread_t
-GonkGPSGeolocationProvider::CreateThreadCallback(const char* name, void (*start)(void *), void* arg)
-{
- pthread_t thread;
- pthread_attr_t attr;
-
- pthread_attr_init(&attr);
-
- /* Unfortunately pthread_create and the callback disagreed on what
- * start function should return.
- */
- pthread_create(&thread, &attr, reinterpret_cast<pthread_func>(start), arg);
-
- return thread;
-}
-
-void
-GonkGPSGeolocationProvider::RequestUtcTimeCallback()
-{
-}
-
-GonkGPSGeolocationProvider::GonkGPSGeolocationProvider()
- : mStarted(false)
- , mSupportsScheduling(false)
- , mObservingSettingsChange(false)
- , mSupportsSingleShot(false)
- , mSupportsTimeInjection(false)
- , mGpsInterface(nullptr)
-{
-}
-
-GonkGPSGeolocationProvider::~GonkGPSGeolocationProvider()
-{
- MOZ_ASSERT(NS_IsMainThread());
- MOZ_ASSERT(!mStarted, "Must call Shutdown before destruction");
-
- sSingleton = nullptr;
-}
-
-already_AddRefed<GonkGPSGeolocationProvider>
-GonkGPSGeolocationProvider::GetSingleton()
-{
- MOZ_ASSERT(NS_IsMainThread());
-
- if (!sSingleton)
- sSingleton = new GonkGPSGeolocationProvider();
-
- RefPtr<GonkGPSGeolocationProvider> provider = sSingleton;
- return provider.forget();
-}
-
-const GpsInterface*
-GonkGPSGeolocationProvider::GetGPSInterface()
-{
- hw_module_t* module;
-
- if (hw_get_module(GPS_HARDWARE_MODULE_ID, (hw_module_t const**)&module))
- return nullptr;
-
- hw_device_t* device;
- if (module->methods->open(module, GPS_HARDWARE_MODULE_ID, &device))
- return nullptr;
-
- gps_device_t* gps_device = (gps_device_t *)device;
- const GpsInterface* result = gps_device->get_gps_interface(gps_device);
-
- if (result->size != sizeof(GpsInterface)) {
- return nullptr;
- }
- return result;
-}
-
-void
-GonkGPSGeolocationProvider::RequestSettingValue(const char* aKey)
-{
- MOZ_ASSERT(aKey);
- nsCOMPtr<nsISettingsService> ss = do_GetService("@mozilla.org/settingsService;1");
- if (!ss) {
- MOZ_ASSERT(ss);
- return;
- }
-
- nsCOMPtr<nsISettingsServiceLock> lock;
- nsresult rv = ss->CreateLock(nullptr, getter_AddRefs(lock));
- if (NS_FAILED(rv)) {
- ERR("error while createLock setting '%s': %d\n", aKey, uint32_t(rv));
- return;
- }
-
- rv = lock->Get(aKey, this);
- if (NS_FAILED(rv)) {
- ERR("error while get setting '%s': %d\n", aKey, uint32_t(rv));
- return;
- }
-}
-
-void
-GonkGPSGeolocationProvider::InjectLocation(double latitude,
- double longitude,
- float accuracy)
-{
- if (gDebug_isLoggingEnabled) {
- DBG("injecting location (%f, %f) accuracy: %f", latitude, longitude, accuracy);
- }
-
- MOZ_ASSERT(NS_IsMainThread());
- if (!mGpsInterface) {
- return;
- }
-
- mGpsInterface->inject_location(latitude, longitude, accuracy);
-}
-
-void
-GonkGPSGeolocationProvider::Init()
-{
- // Must not be main thread. Some GPS driver's first init takes very long.
- MOZ_ASSERT(!NS_IsMainThread());
-
- mGpsInterface = GetGPSInterface();
- if (!mGpsInterface) {
- return;
- }
-
- if (!mCallbacks.size) {
- mCallbacks.size = sizeof(GpsCallbacks);
- mCallbacks.location_cb = LocationCallback;
- mCallbacks.status_cb = StatusCallback;
- mCallbacks.sv_status_cb = SvStatusCallback;
- mCallbacks.nmea_cb = NmeaCallback;
- mCallbacks.set_capabilities_cb = SetCapabilitiesCallback;
- mCallbacks.acquire_wakelock_cb = AcquireWakelockCallback;
- mCallbacks.release_wakelock_cb = ReleaseWakelockCallback;
- mCallbacks.create_thread_cb = CreateThreadCallback;
-
-#ifdef GPS_CAPABILITY_ON_DEMAND_TIME
- mCallbacks.request_utc_time_cb = RequestUtcTimeCallback;
-#endif
-
- }
-
- if (mGpsInterface->init(&mCallbacks) != 0) {
- return;
- }
-
- NS_DispatchToMainThread(NewRunnableMethod(this, &GonkGPSGeolocationProvider::StartGPS));
-}
-
-void
-GonkGPSGeolocationProvider::StartGPS()
-{
- MOZ_ASSERT(NS_IsMainThread());
- MOZ_ASSERT(mGpsInterface);
-
- int32_t update = Preferences::GetInt("geo.default.update", kDefaultPeriod);
-
- int positionMode = GPS_POSITION_MODE_STANDALONE;
-
- if (!mSupportsScheduling) {
- update = kDefaultPeriod;
- }
-
- mGpsInterface->set_position_mode(positionMode,
- GPS_POSITION_RECURRENCE_PERIODIC,
- update, 0, 0);
-#if FLUSH_AIDE_DATA
- // Delete cached data
- mGpsInterface->delete_aiding_data(GPS_DELETE_ALL);
-#endif
-
- mGpsInterface->start();
-}
-
-
-NS_IMPL_ISUPPORTS(GonkGPSGeolocationProvider::NetworkLocationUpdate,
- nsIGeolocationUpdate)
-
-NS_IMETHODIMP
-GonkGPSGeolocationProvider::NetworkLocationUpdate::Update(nsIDOMGeoPosition *position)
-{
- RefPtr<GonkGPSGeolocationProvider> provider =
- GonkGPSGeolocationProvider::GetSingleton();
-
- nsCOMPtr<nsIDOMGeoPositionCoords> coords;
- position->GetCoords(getter_AddRefs(coords));
- if (!coords) {
- return NS_ERROR_FAILURE;
- }
-
- double lat, lon, acc;
- coords->GetLatitude(&lat);
- coords->GetLongitude(&lon);
- coords->GetAccuracy(&acc);
-
- double delta = -1.0;
-
- static double sLastMLSPosLat = 0;
- static double sLastMLSPosLon = 0;
-
- if (0 != sLastMLSPosLon || 0 != sLastMLSPosLat) {
- delta = CalculateDeltaInMeter(lat, lon, sLastMLSPosLat, sLastMLSPosLon);
- }
-
- sLastMLSPosLat = lat;
- sLastMLSPosLon = lon;
-
- // if the MLS coord change is smaller than this arbitrarily small value
- // assume the MLS coord is unchanged, and stick with the GPS location
- const double kMinMLSCoordChangeInMeters = 10;
-
- DOMTimeStamp time_ms = 0;
- if (provider->mLastGPSPosition) {
- provider->mLastGPSPosition->GetTimestamp(&time_ms);
- }
- const int64_t diff_ms = (PR_Now() / PR_USEC_PER_MSEC) - time_ms;
-
- // We want to distinguish between the GPS being inactive completely
- // and temporarily inactive. In the former case, we would use a low
- // accuracy network location; in the latter, we only want a network
- // location that appears to updating with movement.
-
- const bool isGPSFullyInactive = diff_ms > 1000 * 60 * 2; // two mins
- const bool isGPSTempInactive = diff_ms > 1000 * 10; // 10 secs
-
- if (provider->mLocationCallback) {
- if (isGPSFullyInactive ||
- (isGPSTempInactive && delta > kMinMLSCoordChangeInMeters))
- {
- if (gDebug_isLoggingEnabled) {
- DBG("Using MLS, GPS age:%fs, MLS Delta:%fm\n", diff_ms / 1000.0, delta);
- }
- provider->mLocationCallback->Update(position);
- } else if (provider->mLastGPSPosition) {
- if (gDebug_isLoggingEnabled) {
- DBG("Using old GPS age:%fs\n", diff_ms / 1000.0);
- }
-
- // This is a fallback case so that the GPS provider responds with its last
- // location rather than waiting for a more recent GPS or network location.
- // The service decides if the location is too old, not the provider.
- provider->mLocationCallback->Update(provider->mLastGPSPosition);
- }
- }
- provider->InjectLocation(lat, lon, acc);
- return NS_OK;
-}
-NS_IMETHODIMP
-GonkGPSGeolocationProvider::NetworkLocationUpdate::NotifyError(uint16_t error)
-{
- return NS_OK;
-}
-NS_IMETHODIMP
-GonkGPSGeolocationProvider::Startup()
-{
- MOZ_ASSERT(NS_IsMainThread());
-
- if (mStarted) {
- return NS_OK;
- }
-
- RequestSettingValue(kSettingDebugEnabled);
- RequestSettingValue(kSettingDebugGpsIgnored);
-
- // Setup an observer to watch changes to the setting.
- nsCOMPtr<nsIObserverService> observerService = services::GetObserverService();
- if (observerService) {
- MOZ_ASSERT(!mObservingSettingsChange);
- nsresult rv = observerService->AddObserver(this, kMozSettingsChangedTopic, false);
- if (NS_FAILED(rv)) {
- NS_WARNING("geo: Gonk GPS AddObserver failed");
- } else {
- mObservingSettingsChange = true;
- }
- }
-
- if (!mInitThread) {
- nsresult rv = NS_NewThread(getter_AddRefs(mInitThread));
- NS_ENSURE_SUCCESS(rv, rv);
- }
-
- mInitThread->Dispatch(NewRunnableMethod(this, &GonkGPSGeolocationProvider::Init),
- NS_DISPATCH_NORMAL);
-
- mNetworkLocationProvider = do_CreateInstance("@mozilla.org/geolocation/mls-provider;1");
- if (mNetworkLocationProvider) {
- nsresult rv = mNetworkLocationProvider->Startup();
- if (NS_SUCCEEDED(rv)) {
- RefPtr<NetworkLocationUpdate> update = new NetworkLocationUpdate();
- mNetworkLocationProvider->Watch(update);
- }
- }
-
- mStarted = true;
- return NS_OK;
-}
-
-NS_IMETHODIMP
-GonkGPSGeolocationProvider::Watch(nsIGeolocationUpdate* aCallback)
-{
- MOZ_ASSERT(NS_IsMainThread());
-
- mLocationCallback = aCallback;
- return NS_OK;
-}
-
-NS_IMETHODIMP
-GonkGPSGeolocationProvider::Shutdown()
-{
- MOZ_ASSERT(NS_IsMainThread());
-
- if (!mStarted) {
- return NS_OK;
- }
-
- mStarted = false;
- if (mNetworkLocationProvider) {
- mNetworkLocationProvider->Shutdown();
- mNetworkLocationProvider = nullptr;
- }
-
- nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
- if (obs) {
- nsresult rv;
- rv = obs->RemoveObserver(this, kMozSettingsChangedTopic);
- if (NS_FAILED(rv)) {
- NS_WARNING("geo: Gonk GPS mozsettings RemoveObserver failed");
- } else {
- mObservingSettingsChange = false;
- }
- }
-
- mInitThread->Dispatch(NewRunnableMethod(this, &GonkGPSGeolocationProvider::ShutdownGPS),
- NS_DISPATCH_NORMAL);
-
- return NS_OK;
-}
-
-void
-GonkGPSGeolocationProvider::ShutdownGPS()
-{
- MOZ_ASSERT(!mStarted, "Should only be called after Shutdown");
-
- if (mGpsInterface) {
- mGpsInterface->stop();
- mGpsInterface->cleanup();
- }
-}
-
-NS_IMETHODIMP
-GonkGPSGeolocationProvider::SetHighAccuracy(bool)
-{
- return NS_OK;
-}
-
-namespace {
-int
-ConvertToGpsNetworkType(int aNetworkInterfaceType)
-{
- switch (aNetworkInterfaceType) {
- case nsINetworkInfo::NETWORK_TYPE_WIFI:
- return AGPS_RIL_NETWORK_TYPE_WIFI;
- case nsINetworkInfo::NETWORK_TYPE_MOBILE:
- return AGPS_RIL_NETWORK_TYPE_MOBILE;
- case nsINetworkInfo::NETWORK_TYPE_MOBILE_MMS:
- return AGPS_RIL_NETWORK_TYPE_MOBILE_MMS;
- case nsINetworkInfo::NETWORK_TYPE_MOBILE_SUPL:
- return AGPS_RIL_NETWORK_TYPE_MOBILE_SUPL;
- case nsINetworkInfo::NETWORK_TYPE_MOBILE_DUN:
- return AGPS_RIL_NETWORK_TTYPE_MOBILE_DUN;
- default:
- NS_WARNING(nsPrintfCString("Unknown network type mapping %d",
- aNetworkInterfaceType).get());
- return -1;
- }
-}
-} // namespace
-
-NS_IMETHODIMP
-GonkGPSGeolocationProvider::Observe(nsISupports* aSubject,
- const char* aTopic,
- const char16_t* aData)
-{
- MOZ_ASSERT(NS_IsMainThread());
-
- if (!strcmp(aTopic, kMozSettingsChangedTopic)) {
- // Read changed setting value
- RootedDictionary<SettingChangeNotification> setting(RootingCx());
- if (!WrappedJSToDictionary(aSubject, setting)) {
- return NS_OK;
- }
-
- if (setting.mKey.EqualsASCII(kSettingDebugGpsIgnored)) {
- LOG("received mozsettings-changed: ignoring\n");
- gDebug_isGPSLocationIgnored =
- setting.mValue.isBoolean() ? setting.mValue.toBoolean() : false;
- if (gDebug_isLoggingEnabled) {
- DBG("GPS ignored %d\n", gDebug_isGPSLocationIgnored);
- }
- return NS_OK;
- } else if (setting.mKey.EqualsASCII(kSettingDebugEnabled)) {
- LOG("received mozsettings-changed: logging\n");
- gDebug_isLoggingEnabled =
- setting.mValue.isBoolean() ? setting.mValue.toBoolean() : false;
- return NS_OK;
- }
- }
-
- return NS_OK;
-}
-
-/** nsISettingsServiceCallback **/
-
-NS_IMETHODIMP
-GonkGPSGeolocationProvider::Handle(const nsAString& aName,
- JS::Handle<JS::Value> aResult)
-{
- return NS_OK;
-}
-
-NS_IMETHODIMP
-GonkGPSGeolocationProvider::HandleError(const nsAString& aErrorMessage)
-{
- return NS_OK;
-}
diff --git a/dom/system/gonk/GonkGPSGeolocationProvider.h b/dom/system/gonk/GonkGPSGeolocationProvider.h
deleted file mode 100644
index 514398edf9..0000000000
--- a/dom/system/gonk/GonkGPSGeolocationProvider.h
+++ /dev/null
@@ -1,103 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* Copyright 2012 Mozilla Foundation and Mozilla contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef GonkGPSGeolocationProvider_h
-#define GonkGPSGeolocationProvider_h
-
-#include <hardware/gps.h> // for GpsInterface
-#include "nsCOMPtr.h"
-#include "nsIGeolocationProvider.h"
-#include "nsIObserver.h"
-#include "nsIDOMGeoPosition.h"
-#include "nsISettingsService.h"
-
-class nsIThread;
-
-#define GONK_GPS_GEOLOCATION_PROVIDER_CID \
-{ 0x48525ec5, 0x5a7f, 0x490a, { 0x92, 0x77, 0xba, 0x66, 0xe0, 0xd2, 0x2c, 0x8b } }
-
-#define GONK_GPS_GEOLOCATION_PROVIDER_CONTRACTID \
-"@mozilla.org/gonk-gps-geolocation-provider;1"
-
-class GonkGPSGeolocationProvider : public nsIGeolocationProvider
- , public nsIObserver
- , public nsISettingsServiceCallback
-{
-public:
- NS_DECL_THREADSAFE_ISUPPORTS
- NS_DECL_NSIGEOLOCATIONPROVIDER
- NS_DECL_NSIOBSERVER
- NS_DECL_NSISETTINGSSERVICECALLBACK
-
- static already_AddRefed<GonkGPSGeolocationProvider> GetSingleton();
-
-private:
-
- /* Client should use GetSingleton() to get the provider instance. */
- GonkGPSGeolocationProvider();
- GonkGPSGeolocationProvider(const GonkGPSGeolocationProvider &);
- GonkGPSGeolocationProvider & operator = (const GonkGPSGeolocationProvider &);
- virtual ~GonkGPSGeolocationProvider();
-
- static void LocationCallback(GpsLocation* location);
- static void StatusCallback(GpsStatus* status);
- static void SvStatusCallback(GpsSvStatus* sv_info);
- static void NmeaCallback(GpsUtcTime timestamp, const char* nmea, int length);
- static void SetCapabilitiesCallback(uint32_t capabilities);
- static void AcquireWakelockCallback();
- static void ReleaseWakelockCallback();
- static pthread_t CreateThreadCallback(const char* name, void (*start)(void*), void* arg);
- static void RequestUtcTimeCallback();
-
- static GpsCallbacks mCallbacks;
-
- void Init();
- void StartGPS();
- void ShutdownGPS();
- void InjectLocation(double latitude, double longitude, float accuracy);
- void RequestSettingValue(const char* aKey);
-
- const GpsInterface* GetGPSInterface();
-
- static GonkGPSGeolocationProvider* sSingleton;
-
- bool mStarted;
-
- bool mSupportsScheduling;
- bool mObservingSettingsChange;
- bool mSupportsSingleShot;
- bool mSupportsTimeInjection;
-
- const GpsInterface* mGpsInterface;
- nsCOMPtr<nsIGeolocationUpdate> mLocationCallback;
- nsCOMPtr<nsIThread> mInitThread;
- nsCOMPtr<nsIGeolocationProvider> mNetworkLocationProvider;
- nsCOMPtr<nsIDOMGeoPosition> mLastGPSPosition;
-
- class NetworkLocationUpdate : public nsIGeolocationUpdate
- {
- public:
- NS_DECL_ISUPPORTS
- NS_DECL_NSIGEOLOCATIONUPDATE
-
- NetworkLocationUpdate() {}
-
- private:
- virtual ~NetworkLocationUpdate() {}
- };
-};
-
-#endif /* GonkGPSGeolocationProvider_h */
diff --git a/dom/system/gonk/MozMtpCommon.h b/dom/system/gonk/MozMtpCommon.h
deleted file mode 100644
index 81c0a3a747..0000000000
--- a/dom/system/gonk/MozMtpCommon.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
-/* 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/. */
-
-#ifndef mozilla_system_mozmtpcommon_h__
-#define mozilla_system_mozmtpcommon_h__
-
-#include "mozilla/Types.h"
-#include <android/log.h>
-
-#define USE_DEBUG 0
-
-#if USE_DEBUG
-#define MTP_DBG(msg, ...) \
- __android_log_print(ANDROID_LOG_DEBUG, "MozMtp", \
- "%s: " msg, __FUNCTION__, ##__VA_ARGS__)
-#else
-#define MTP_DBG(msg, ...)
-#endif
-
-#define MTP_LOG(msg, ...) \
- __android_log_print(ANDROID_LOG_INFO, "MozMtp", \
- "%s: " msg, __FUNCTION__, ##__VA_ARGS__)
-
-#define MTP_ERR(msg, ...) \
- __android_log_print(ANDROID_LOG_ERROR, "MozMtp", \
- "%s: " msg, __FUNCTION__, ##__VA_ARGS__)
-
-#define BEGIN_MTP_NAMESPACE \
- namespace mozilla { namespace system { namespace mtp {
-#define END_MTP_NAMESPACE \
- } /* namespace mtp */ } /* namespace system */ } /* namespace mozilla */
-#define USING_MTP_NAMESPACE \
- using namespace mozilla::system::mtp;
-
-namespace android {
- class MOZ_EXPORT MtpServer;
- class MOZ_EXPORT MtpStorage;
- class MOZ_EXPORT MtpStringBuffer;
- class MOZ_EXPORT MtpDatabase;
- class MOZ_EXPORT MtpDataPacket;
- class MOZ_EXPORT MtpProperty;
-}
-
-#include <mtp.h>
-#include <MtpDatabase.h>
-#include <MtpObjectInfo.h>
-#include <MtpProperty.h>
-#include <MtpServer.h>
-#include <MtpStorage.h>
-#include <MtpStringBuffer.h>
-#include <MtpTypes.h>
-
-#endif // mozilla_system_mtpcommon_h__
diff --git a/dom/system/gonk/MozMtpDatabase.cpp b/dom/system/gonk/MozMtpDatabase.cpp
deleted file mode 100644
index 29fe23e8d0..0000000000
--- a/dom/system/gonk/MozMtpDatabase.cpp
+++ /dev/null
@@ -1,1542 +0,0 @@
-/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
-/* 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/. */
-
-#include "MozMtpDatabase.h"
-#include "MozMtpServer.h"
-
-#include "base/message_loop.h"
-#include "DeviceStorage.h"
-#include "mozilla/ArrayUtils.h"
-#include "mozilla/AutoRestore.h"
-#include "mozilla/Scoped.h"
-#include "mozilla/Services.h"
-#include "nsIFile.h"
-#include "nsIObserverService.h"
-#include "nsPrintfCString.h"
-#include "nsString.h"
-#include "prio.h"
-
-#include <dirent.h>
-#include <libgen.h>
-#include <utime.h>
-#include <sys/stat.h>
-
-using namespace android;
-using namespace mozilla;
-
-namespace mozilla {
-MOZ_TYPE_SPECIFIC_SCOPED_POINTER_TEMPLATE(ScopedCloseDir, PRDir, PR_CloseDir)
-}
-
-BEGIN_MTP_NAMESPACE
-
-static const char* kMtpWatcherNotify = "mtp-watcher-notify";
-
-#if 0
-// Some debug code for figuring out deadlocks, if you happen to run into
-// that scenario
-
-class DebugMutexAutoLock: public MutexAutoLock
-{
-public:
- DebugMutexAutoLock(mozilla::Mutex& aMutex)
- : MutexAutoLock(aMutex)
- {
- MTP_LOG("Mutex acquired");
- }
-
- ~DebugMutexAutoLock()
- {
- MTP_LOG("Releasing mutex");
- }
-};
-#define MutexAutoLock MTP_LOG("About to enter mutex"); DebugMutexAutoLock
-
-#endif
-
-static const char *
-ObjectPropertyAsStr(MtpObjectProperty aProperty)
-{
- switch (aProperty) {
- case MTP_PROPERTY_STORAGE_ID: return "MTP_PROPERTY_STORAGE_ID";
- case MTP_PROPERTY_OBJECT_FORMAT: return "MTP_PROPERTY_OBJECT_FORMAT";
- case MTP_PROPERTY_PROTECTION_STATUS: return "MTP_PROPERTY_PROTECTION_STATUS";
- case MTP_PROPERTY_OBJECT_SIZE: return "MTP_PROPERTY_OBJECT_SIZE";
- case MTP_PROPERTY_OBJECT_FILE_NAME: return "MTP_PROPERTY_OBJECT_FILE_NAME";
- case MTP_PROPERTY_DATE_CREATED: return "MTP_PROPERTY_DATE_CREATED";
- case MTP_PROPERTY_DATE_MODIFIED: return "MTP_PROPERTY_DATE_MODIFIED";
- case MTP_PROPERTY_PARENT_OBJECT: return "MTP_PROPERTY_PARENT_OBJECT";
- case MTP_PROPERTY_PERSISTENT_UID: return "MTP_PROPERTY_PERSISTENT_UID";
- case MTP_PROPERTY_NAME: return "MTP_PROPERTY_NAME";
- case MTP_PROPERTY_DATE_ADDED: return "MTP_PROPERTY_DATE_ADDED";
- case MTP_PROPERTY_WIDTH: return "MTP_PROPERTY_WIDTH";
- case MTP_PROPERTY_HEIGHT: return "MTP_PROPERTY_HEIGHT";
- case MTP_PROPERTY_IMAGE_BIT_DEPTH: return "MTP_PROPERTY_IMAGE_BIT_DEPTH";
- case MTP_PROPERTY_DISPLAY_NAME: return "MTP_PROPERTY_DISPLAY_NAME";
- }
- return "MTP_PROPERTY_???";
-}
-
-static char*
-FormatDate(time_t aTime, char *aDateStr, size_t aDateStrSize)
-{
- struct tm tm;
- localtime_r(&aTime, &tm);
- MTP_LOG("(%ld) tm_zone = %s off = %ld", aTime, tm.tm_zone, tm.tm_gmtoff);
- strftime(aDateStr, aDateStrSize, "%Y%m%dT%H%M%S", &tm);
- return aDateStr;
-}
-
-MozMtpDatabase::MozMtpDatabase()
- : mMutex("MozMtpDatabase::mMutex"),
- mDb(mMutex),
- mStorage(mMutex),
- mBeginSendObjectCalled(false)
-{
- MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
-
- // We use the index into the array as the handle. Since zero isn't a valid
- // index, we stick a dummy entry there.
-
- RefPtr<DbEntry> dummy;
-
- MutexAutoLock lock(mMutex);
- mDb.AppendElement(dummy);
-}
-
-//virtual
-MozMtpDatabase::~MozMtpDatabase()
-{
- MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
-}
-
-void
-MozMtpDatabase::AddEntry(DbEntry *entry)
-{
- MutexAutoLock lock(mMutex);
-
- entry->mHandle = GetNextHandle();
- MOZ_ASSERT(mDb.Length() == entry->mHandle);
- mDb.AppendElement(entry);
-
- MTP_DBG("Handle: 0x%08x Parent: 0x%08x Path:'%s'",
- entry->mHandle, entry->mParent, entry->mPath.get());
-}
-
-void
-MozMtpDatabase::AddEntryAndNotify(DbEntry* entry, RefCountedMtpServer* aMtpServer)
-{
- AddEntry(entry);
- aMtpServer->sendObjectAdded(entry->mHandle);
-}
-
-void
-MozMtpDatabase::DumpEntries(const char* aLabel)
-{
- MutexAutoLock lock(mMutex);
-
- ProtectedDbArray::size_type numEntries = mDb.Length();
- MTP_LOG("%s: numEntries = %d", aLabel, numEntries);
- ProtectedDbArray::index_type entryIndex;
- for (entryIndex = 1; entryIndex < numEntries; entryIndex++) {
- RefPtr<DbEntry> entry = mDb[entryIndex];
- if (entry) {
- MTP_LOG("%s: mDb[%d]: mHandle: 0x%08x mParent: 0x%08x StorageID: 0x%08x path: '%s'",
- aLabel, entryIndex, entry->mHandle, entry->mParent, entry->mStorageID, entry->mPath.get());
- } else {
- MTP_LOG("%s: mDb[%2d]: entry is NULL", aLabel, entryIndex);
- }
- }
-}
-
-MtpObjectHandle
-MozMtpDatabase::FindEntryByPath(const nsACString& aPath)
-{
- MutexAutoLock lock(mMutex);
-
- ProtectedDbArray::size_type numEntries = mDb.Length();
- ProtectedDbArray::index_type entryIndex;
- for (entryIndex = 1; entryIndex < numEntries; entryIndex++) {
- RefPtr<DbEntry> entry = mDb[entryIndex];
- if (entry && entry->mPath.Equals(aPath)) {
- return entryIndex;
- }
- }
- return 0;
-}
-
-already_AddRefed<MozMtpDatabase::DbEntry>
-MozMtpDatabase::GetEntry(MtpObjectHandle aHandle)
-{
- MutexAutoLock lock(mMutex);
-
- RefPtr<DbEntry> entry;
-
- if (aHandle > 0 && aHandle < mDb.Length()) {
- entry = mDb[aHandle];
- }
- return entry.forget();
-}
-
-void
-MozMtpDatabase::RemoveEntry(MtpObjectHandle aHandle)
-{
- MutexAutoLock lock(mMutex);
- if (!IsValidHandle(aHandle)) {
- return;
- }
-
- RefPtr<DbEntry> removedEntry = mDb[aHandle];
- mDb[aHandle] = nullptr;
- MTP_DBG("0x%08x removed", aHandle);
- // if the entry is not a folder, just return.
- if (removedEntry->mObjectFormat != MTP_FORMAT_ASSOCIATION) {
- return;
- }
-
- // Find out and remove the children of aHandle.
- // Since the index for a directory will always be less than the index of any of its children,
- // we can remove the entire subtree in one pass.
- ProtectedDbArray::size_type numEntries = mDb.Length();
- ProtectedDbArray::index_type entryIndex;
- for (entryIndex = aHandle+1; entryIndex < numEntries; entryIndex++) {
- RefPtr<DbEntry> entry = mDb[entryIndex];
- if (entry && IsValidHandle(entry->mParent) && !mDb[entry->mParent]) {
- mDb[entryIndex] = nullptr;
- MTP_DBG("0x%08x removed", aHandle);
- }
- }
-}
-
-void
-MozMtpDatabase::RemoveEntryAndNotify(MtpObjectHandle aHandle, RefCountedMtpServer* aMtpServer)
-{
- RemoveEntry(aHandle);
- aMtpServer->sendObjectRemoved(aHandle);
-}
-
-void
-MozMtpDatabase::UpdateEntryAndNotify(MtpObjectHandle aHandle, DeviceStorageFile* aFile, RefCountedMtpServer* aMtpServer)
-{
- UpdateEntry(aHandle, aFile);
- aMtpServer->sendObjectAdded(aHandle);
-}
-
-
-void
-MozMtpDatabase::UpdateEntry(MtpObjectHandle aHandle, DeviceStorageFile* aFile)
-{
- MutexAutoLock lock(mMutex);
-
- RefPtr<DbEntry> entry = mDb[aHandle];
-
- int64_t fileSize = 0;
- aFile->mFile->GetFileSize(&fileSize);
- entry->mObjectSize = fileSize;
-
- PRTime dateModifiedMsecs;
- // GetLastModifiedTime returns msecs
- aFile->mFile->GetLastModifiedTime(&dateModifiedMsecs);
- entry->mDateModified = dateModifiedMsecs / PR_MSEC_PER_SEC;
- entry->mDateCreated = entry->mDateModified;
- entry->mDateAdded = entry->mDateModified;
-
- #if USE_DEBUG
- char dateStr[20];
- MTP_DBG("UpdateEntry (0x%08x file %s) modified (%ld) %s",
- entry->mHandle, entry->mPath.get(),
- entry->mDateModified,
- FormatDate(entry->mDateModified, dateStr, sizeof(dateStr)));
- #endif
-}
-
-
-class MtpWatcherNotifyRunnable final : public Runnable
-{
-public:
- MtpWatcherNotifyRunnable(nsACString& aStorageName,
- nsACString& aPath,
- const char* aEventType)
- : mStorageName(aStorageName),
- mPath(aPath),
- mEventType(aEventType)
- {}
-
- NS_IMETHOD Run() override
- {
- MOZ_ASSERT(NS_IsMainThread());
-
- NS_ConvertUTF8toUTF16 storageName(mStorageName);
- NS_ConvertUTF8toUTF16 path(mPath);
-
- RefPtr<DeviceStorageFile> dsf(
- new DeviceStorageFile(NS_LITERAL_STRING(DEVICESTORAGE_SDCARD),
- storageName, path));
- NS_ConvertUTF8toUTF16 eventType(mEventType);
- nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
-
- MTP_DBG("Sending mtp-watcher-notify %s %s %s",
- mEventType.get(), mStorageName.get(), mPath.get());
-
- obs->NotifyObservers(dsf, kMtpWatcherNotify, eventType.get());
- return NS_OK;
- }
-
-private:
- nsCString mStorageName;
- nsCString mPath;
- nsCString mEventType;
-};
-
-// MtpWatcherNotify is used to tell DeviceStorage when a file was changed
-// through the MTP server.
-void
-MozMtpDatabase::MtpWatcherNotify(DbEntry* aEntry, const char* aEventType)
-{
- // This function gets called from the MozMtpServer::mServerThread
- MOZ_ASSERT(!NS_IsMainThread());
-
- MTP_DBG("file: %s %s", aEntry->mPath.get(), aEventType);
-
- // Tell interested parties that a file was created, deleted, or modified.
-
- RefPtr<StorageEntry> storageEntry;
- {
- MutexAutoLock lock(mMutex);
-
- // FindStorage and the mStorage[] access both need to have the mutex held.
- StorageArray::index_type storageIndex = FindStorage(aEntry->mStorageID);
- if (storageIndex == StorageArray::NoIndex) {
- return;
- }
- storageEntry = mStorage[storageIndex];
- }
-
- // DeviceStorage wants the storageName and the path relative to the root
- // of the storage area, so we need to strip off the storagePath
-
- nsAutoCString relPath(Substring(aEntry->mPath,
- storageEntry->mStoragePath.Length() + 1));
-
- RefPtr<MtpWatcherNotifyRunnable> r =
- new MtpWatcherNotifyRunnable(storageEntry->mStorageName, relPath, aEventType);
- DebugOnly<nsresult> rv = NS_DispatchToMainThread(r);
- MOZ_ASSERT(NS_SUCCEEDED(rv));
-}
-
-// Called to tell the MTP server about new or deleted files,
-void
-MozMtpDatabase::MtpWatcherUpdate(RefCountedMtpServer* aMtpServer,
- DeviceStorageFile* aFile,
- const nsACString& aEventType)
-{
- // Runs on the MtpWatcherUpdate->mIOThread (see MozMtpServer.cpp)
- MOZ_ASSERT(!NS_IsMainThread());
-
- // Figure out which storage the belongs to (if any)
-
- if (!aFile->mFile) {
- // No path - don't bother looking.
- return;
- }
- nsString wideFilePath;
- aFile->mFile->GetPath(wideFilePath);
- NS_ConvertUTF16toUTF8 filePath(wideFilePath);
-
- nsCString evtType(aEventType);
- MTP_LOG("file %s %s", filePath.get(), evtType.get());
-
- MtpObjectHandle entryHandle = FindEntryByPath(filePath);
-
- if (aEventType.EqualsLiteral("modified")) {
- // To update the file information to the newest, we remove the entry for
- // the existing file, then re-add the entry for the file.
-
- if (entryHandle != 0) {
- // Update entry for the file and tell MTP.
- MTP_LOG("About to update handle 0x%08x file %s", entryHandle, filePath.get());
- UpdateEntryAndNotify(entryHandle, aFile, aMtpServer);
- }
- else {
- // Create entry for the file and tell MTP.
- CreateEntryForFileAndNotify(filePath, aFile, aMtpServer);
- }
- return;
- }
-
- if (aEventType.EqualsLiteral("deleted")) {
- if (entryHandle == 0) {
- // The entry has already been removed. We can't tell MTP.
- return;
- }
- MTP_LOG("About to call sendObjectRemoved Handle 0x%08x file %s", entryHandle, filePath.get());
- RemoveEntryAndNotify(entryHandle, aMtpServer);
- return;
- }
-}
-
-nsCString
-MozMtpDatabase::BaseName(const nsCString& path)
-{
- nsCOMPtr<nsIFile> file;
- NS_NewNativeLocalFile(path, false, getter_AddRefs(file));
- if (file) {
- nsCString leafName;
- file->GetNativeLeafName(leafName);
- return leafName;
- }
- return path;
-}
-
-static nsCString
-GetPathWithoutFileName(const nsCString& aFullPath)
-{
- nsCString path;
-
- int32_t offset = aFullPath.RFindChar('/');
- if (offset != kNotFound) {
- // The trailing slash will be as part of 'path'
- path = StringHead(aFullPath, offset + 1);
- }
-
- MTP_LOG("returning '%s'", path.get());
-
- return path;
-}
-
-void
-MozMtpDatabase::CreateEntryForFileAndNotify(const nsACString& aPath,
- DeviceStorageFile* aFile,
- RefCountedMtpServer* aMtpServer)
-{
- // Find the StorageID that this path corresponds to.
-
- nsCString remainder;
- MtpStorageID storageID = FindStorageIDFor(aPath, remainder);
- if (storageID == 0) {
- // The path in question isn't for a storage area we're monitoring.
- nsCString path(aPath);
- return;
- }
-
- bool exists = false;
- aFile->mFile->Exists(&exists);
- if (!exists) {
- // File doesn't exist, no sense telling MTP about it.
- // This could happen if Device Storage created and deleted a file right
- // away. Since the notifications wind up being async, the file might
- // not exist any more.
- return;
- }
-
- // Now walk the remaining directories, finding or creating as required.
-
- MtpObjectHandle parent = MTP_PARENT_ROOT;
- bool doFind = true;
- int32_t offset = aPath.Length() - remainder.Length();
- int32_t slash;
-
- do {
- nsDependentCSubstring component;
- slash = aPath.FindChar('/', offset);
- if (slash == kNotFound) {
- component.Rebind(aPath, 0, aPath.Length());
- } else {
- component.Rebind(aPath, 0 , slash);
- }
- if (doFind) {
- MtpObjectHandle entryHandle = FindEntryByPath(component);
- if (entryHandle != 0) {
- // We found an entry.
- parent = entryHandle;
- offset = slash + 1 ;
- continue;
- }
- }
-
- // We've got a directory component that doesn't exist. This means that all
- // further subdirectories won't exist either, so we can skip searching
- // for them.
- doFind = false;
-
- // This directory and the file don't exist, create them
-
- RefPtr<DbEntry> entry = new DbEntry;
-
- entry->mStorageID = storageID;
- entry->mObjectName = Substring(aPath, offset, slash - offset);
- entry->mParent = parent;
- entry->mDisplayName = entry->mObjectName;
- entry->mPath = component;
-
- if (slash == kNotFound) {
- // No slash - this is the file component
- entry->mObjectFormat = MTP_FORMAT_DEFINED;
-
- int64_t fileSize = 0;
- aFile->mFile->GetFileSize(&fileSize);
- entry->mObjectSize = fileSize;
-
- // Note: Even though PRTime records usec, GetLastModifiedTime returns
- // msecs.
- PRTime dateModifiedMsecs;
- aFile->mFile->GetLastModifiedTime(&dateModifiedMsecs);
- entry->mDateModified = dateModifiedMsecs / PR_MSEC_PER_SEC;
- } else {
- // Found a slash, this makes this a directory component
- entry->mObjectFormat = MTP_FORMAT_ASSOCIATION;
- entry->mObjectSize = 0;
- time(&entry->mDateModified);
- }
- entry->mDateCreated = entry->mDateModified;
- entry->mDateAdded = entry->mDateModified;
-
- AddEntryAndNotify(entry, aMtpServer);
- MTP_LOG("About to call sendObjectAdded Handle 0x%08x file %s", entry->mHandle, entry->mPath.get());
-
- parent = entry->mHandle;
- offset = slash + 1;
- } while (slash != kNotFound);
-
- return;
-}
-
-void
-MozMtpDatabase::AddDirectory(MtpStorageID aStorageID,
- const char* aPath,
- MtpObjectHandle aParent)
-{
- MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
-
- ScopedCloseDir dir;
-
- if (!(dir = PR_OpenDir(aPath))) {
- MTP_ERR("Unable to open directory '%s'", aPath);
- return;
- }
-
- PRDirEntry* dirEntry;
- while ((dirEntry = PR_ReadDir(dir, PR_SKIP_BOTH))) {
- nsPrintfCString filename("%s/%s", aPath, dirEntry->name);
- PRFileInfo64 fileInfo;
- if (PR_GetFileInfo64(filename.get(), &fileInfo) != PR_SUCCESS) {
- MTP_ERR("Unable to retrieve file information for '%s'", filename.get());
- continue;
- }
-
- RefPtr<DbEntry> entry = new DbEntry;
-
- entry->mStorageID = aStorageID;
- entry->mParent = aParent;
- entry->mObjectName = dirEntry->name;
- entry->mDisplayName = dirEntry->name;
- entry->mPath = filename;
-
- // PR_GetFileInfo64 returns timestamps in usecs
- entry->mDateModified = fileInfo.modifyTime / PR_USEC_PER_SEC;
- entry->mDateCreated = fileInfo.creationTime / PR_USEC_PER_SEC;
- time(&entry->mDateAdded);
-
- if (fileInfo.type == PR_FILE_FILE) {
- entry->mObjectFormat = MTP_FORMAT_DEFINED;
- //TODO: Check how 64-bit filesize are dealt with
- entry->mObjectSize = fileInfo.size;
- AddEntry(entry);
- } else if (fileInfo.type == PR_FILE_DIRECTORY) {
- entry->mObjectFormat = MTP_FORMAT_ASSOCIATION;
- entry->mObjectSize = 0;
- AddEntry(entry);
- AddDirectory(aStorageID, filename.get(), entry->mHandle);
- }
- }
-}
-
-MozMtpDatabase::StorageArray::index_type
-MozMtpDatabase::FindStorage(MtpStorageID aStorageID)
-{
- // Currently, this routine is called from MozMtpDatabase::RemoveStorage
- // and MozMtpDatabase::MtpWatcherNotify, which both hold mMutex.
-
- StorageArray::size_type numStorages = mStorage.Length();
- StorageArray::index_type storageIndex;
-
- for (storageIndex = 0; storageIndex < numStorages; storageIndex++) {
- RefPtr<StorageEntry> storage = mStorage[storageIndex];
- if (storage->mStorageID == aStorageID) {
- return storageIndex;
- }
- }
- return StorageArray::NoIndex;
-}
-
-// Find the storage ID for the storage area that contains aPath.
-MtpStorageID
-MozMtpDatabase::FindStorageIDFor(const nsACString& aPath, nsCSubstring& aRemainder)
-{
- MutexAutoLock lock(mMutex);
-
- aRemainder.Truncate();
-
- StorageArray::size_type numStorages = mStorage.Length();
- StorageArray::index_type storageIndex;
-
- for (storageIndex = 0; storageIndex < numStorages; storageIndex++) {
- RefPtr<StorageEntry> storage = mStorage[storageIndex];
- if (StringHead(aPath, storage->mStoragePath.Length()).Equals(storage->mStoragePath)) {
- if (aPath.Length() == storage->mStoragePath.Length()) {
- return storage->mStorageID;
- }
- if (aPath[storage->mStoragePath.Length()] == '/') {
- aRemainder = Substring(aPath, storage->mStoragePath.Length() + 1);
- return storage->mStorageID;
- }
- }
- }
- return 0;
-}
-
-void
-MozMtpDatabase::AddStorage(MtpStorageID aStorageID,
- const char* aPath,
- const char* aName)
-{
- // This is called on the IOThread from MozMtpStorage::StorageAvailable
- MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
-
- MTP_DBG("StorageID: 0x%08x aPath: '%s' aName: '%s'",
- aStorageID, aPath, aName);
-
- PRFileInfo fileInfo;
- if (PR_GetFileInfo(aPath, &fileInfo) != PR_SUCCESS) {
- MTP_ERR("'%s' doesn't exist", aPath);
- return;
- }
- if (fileInfo.type != PR_FILE_DIRECTORY) {
- MTP_ERR("'%s' isn't a directory", aPath);
- return;
- }
-
- RefPtr<StorageEntry> storageEntry = new StorageEntry;
-
- storageEntry->mStorageID = aStorageID;
- storageEntry->mStoragePath = aPath;
- storageEntry->mStorageName = aName;
- {
- MutexAutoLock lock(mMutex);
- mStorage.AppendElement(storageEntry);
- }
-
- AddDirectory(aStorageID, aPath, MTP_PARENT_ROOT);
- {
- MutexAutoLock lock(mMutex);
- MTP_LOG("added %d items from tree '%s'", mDb.Length(), aPath);
- }
-}
-
-void
-MozMtpDatabase::RemoveStorage(MtpStorageID aStorageID)
-{
- MutexAutoLock lock(mMutex);
-
- // This is called on the IOThread from MozMtpStorage::StorageAvailable
- MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
-
- ProtectedDbArray::size_type numEntries = mDb.Length();
- ProtectedDbArray::index_type entryIndex;
- for (entryIndex = 1; entryIndex < numEntries; entryIndex++) {
- RefPtr<DbEntry> entry = mDb[entryIndex];
- if (entry && entry->mStorageID == aStorageID) {
- mDb[entryIndex] = nullptr;
- }
- }
- StorageArray::index_type storageIndex = FindStorage(aStorageID);
- if (storageIndex != StorageArray::NoIndex) {
- mStorage.RemoveElementAt(storageIndex);
- }
-}
-
-// called from SendObjectInfo to reserve a database entry for the incoming file
-//virtual
-MtpObjectHandle
-MozMtpDatabase::beginSendObject(const char* aPath,
- MtpObjectFormat aFormat,
- MtpObjectHandle aParent,
- MtpStorageID aStorageID,
- uint64_t aSize,
- time_t aModified)
-{
- // If MtpServer::doSendObjectInfo receives a request with a parent of
- // MTP_PARENT_ROOT, then it fills in aPath with the fully qualified path
- // and then passes in a parent of zero.
-
- if (aParent == 0) {
- // Undo what doSendObjectInfo did
- aParent = MTP_PARENT_ROOT;
- }
-
- RefPtr<DbEntry> entry = new DbEntry;
-
- entry->mStorageID = aStorageID;
- entry->mParent = aParent;
- entry->mPath = aPath;
- entry->mObjectName = BaseName(entry->mPath);
- entry->mDisplayName = entry->mObjectName;
- entry->mObjectFormat = aFormat;
- entry->mObjectSize = aSize;
-
- if (aModified != 0) {
- // Currently, due to the way that parseDateTime is coded in
- // frameworks/av/media/mtp/MtpUtils.cpp, aModified winds up being the number
- // of seconds from the epoch in local time, rather than UTC time. So we
- // need to convert it back to being relative to UTC since that's what linux
- // expects time_t to contain.
- //
- // In more concrete testable terms, if the host parses 2015-08-02 02:22:00
- // as a local time in the Pacific timezone, aModified will come to us as
- // 1438482120.
- //
- // What we want is what mktime would pass us with the same date. Using python
- // (because its simple) with the current timezone set to be America/Vancouver:
- //
- // >>> import time
- // >>> time.mktime((2015, 8, 2, 2, 22, 0, 0, 0, -1))
- // 1438507320.0
- // >>> time.localtime(1438507320)
- // time.struct_time(tm_year=2015, tm_mon=8, tm_mday=2, tm_hour=2, tm_min=22, tm_sec=0, tm_wday=6, tm_yday=214, tm_isdst=1)
- //
- // Currently, when a file has a modification time of 2015-08-22 02:22:00 PDT
- // then aModified will come in as 1438482120 which corresponds to
- // 2015-08-22 02:22:00 UTC
-
- struct tm tm;
- if (gmtime_r(&aModified, &tm) != NULL) {
- // GMT always comes back with tm_isdst = 0, so we set it to -1 in order
- // to have mktime figure out dst based on the date.
- tm.tm_isdst = -1;
- aModified = mktime(&tm);
- if (aModified == (time_t)-1) {
- aModified = 0;
- }
- } else {
- aModified = 0;
- }
- }
- if (aModified == 0) {
- // The ubuntu host doesn't pass in the modified/created times in the
- // SENDOBJECT packet, so aModified winds up being zero. About the best
- // we can do with that is to use the current time.
- time(&aModified);
- }
-
- // And just an FYI for anybody else looking at timestamps. Under OSX you
- // need to use the Android File Transfer program to copy files into the
- // phone. That utility passes in both date modified and date created
- // timestamps, but they're both equal to the time that the file was copied
- // and not the times that are associated with the files.
-
- // Now we have aModified in a traditional time_t format, which is the number
- // of seconds from the UTC epoch.
-
- entry->mDateModified = aModified;
- entry->mDateCreated = entry->mDateModified;
- entry->mDateAdded = entry->mDateModified;
-
- AddEntry(entry);
-
- #if USE_DEBUG
- char dateStr[20];
- MTP_LOG("Handle: 0x%08x Parent: 0x%08x Path: '%s' aModified %ld %s",
- entry->mHandle, aParent, aPath, aModified,
- FormatDate(entry->mDateModified, dateStr, sizeof(dateStr)));
- #endif
-
- mBeginSendObjectCalled = true;
- return entry->mHandle;
-}
-
-// called to report success or failure of the SendObject file transfer
-// success should signal a notification of the new object's creation,
-// failure should remove the database entry created in beginSendObject
-
-//virtual
-void
-MozMtpDatabase::endSendObject(const char* aPath,
- MtpObjectHandle aHandle,
- MtpObjectFormat aFormat,
- bool aSucceeded)
-{
- MTP_LOG("Handle: 0x%08x Path: '%s'", aHandle, aPath);
-
- if (aSucceeded) {
- RefPtr<DbEntry> entry = GetEntry(aHandle);
- if (entry) {
- // The android MTP server only copies the data in, it doesn't set the
- // modified timestamp, so we do that here.
-
- struct utimbuf new_times;
- struct stat sb;
-
- char dateStr[20];
- MTP_LOG("Path: '%s' setting modified time to (%ld) %s",
- entry->mPath.get(), entry->mDateModified,
- FormatDate(entry->mDateModified, dateStr, sizeof(dateStr)));
-
- stat(entry->mPath.get(), &sb);
- new_times.actime = sb.st_atime; // Preserve atime
- new_times.modtime = entry->mDateModified;
- utime(entry->mPath.get(), &new_times);
-
- MtpWatcherNotify(entry, "modified");
- }
- } else {
- RemoveEntry(aHandle);
- }
- mBeginSendObjectCalled = false;
-}
-
-//virtual
-MtpObjectHandleList*
-MozMtpDatabase::getObjectList(MtpStorageID aStorageID,
- MtpObjectFormat aFormat,
- MtpObjectHandle aParent)
-{
- MTP_LOG("StorageID: 0x%08x Format: 0x%04x Parent: 0x%08x",
- aStorageID, aFormat, aParent);
-
- // aStorageID == 0xFFFFFFFF for all storage
- // aFormat == 0 for all formats
- // aParent == 0xFFFFFFFF for objects with no parents
- // aParent == 0 for all objects
-
- //TODO: Optimize
-
- UniquePtr<MtpObjectHandleList> list(new MtpObjectHandleList());
-
- MutexAutoLock lock(mMutex);
-
- ProtectedDbArray::size_type numEntries = mDb.Length();
- ProtectedDbArray::index_type entryIndex;
- for (entryIndex = 1; entryIndex < numEntries; entryIndex++) {
- RefPtr<DbEntry> entry = mDb[entryIndex];
- if (entry &&
- (aStorageID == 0xFFFFFFFF || entry->mStorageID == aStorageID) &&
- (aFormat == 0 || entry->mObjectFormat == aFormat) &&
- (aParent == 0 || entry->mParent == aParent)) {
- list->push(entry->mHandle);
- }
- }
- MTP_LOG(" returning %d items", list->size());
- return list.release();
-}
-
-//virtual
-int
-MozMtpDatabase::getNumObjects(MtpStorageID aStorageID,
- MtpObjectFormat aFormat,
- MtpObjectHandle aParent)
-{
- MTP_LOG("");
-
- // aStorageID == 0xFFFFFFFF for all storage
- // aFormat == 0 for all formats
- // aParent == 0xFFFFFFFF for objects with no parents
- // aParent == 0 for all objects
-
- int count = 0;
-
- MutexAutoLock lock(mMutex);
-
- ProtectedDbArray::size_type numEntries = mDb.Length();
- ProtectedDbArray::index_type entryIndex;
- for (entryIndex = 1; entryIndex < numEntries; entryIndex++) {
- RefPtr<DbEntry> entry = mDb[entryIndex];
- if (entry &&
- (aStorageID == 0xFFFFFFFF || entry->mStorageID == aStorageID) &&
- (aFormat == 0 || entry->mObjectFormat == aFormat) &&
- (aParent == 0 || entry->mParent == aParent)) {
- count++;
- }
- }
-
- MTP_LOG(" returning %d items", count);
- return count;
-}
-
-//virtual
-MtpObjectFormatList*
-MozMtpDatabase::getSupportedPlaybackFormats()
-{
- static const uint16_t init_data[] = {MTP_FORMAT_UNDEFINED, MTP_FORMAT_ASSOCIATION,
- MTP_FORMAT_TEXT, MTP_FORMAT_HTML, MTP_FORMAT_WAV,
- MTP_FORMAT_MP3, MTP_FORMAT_MPEG, MTP_FORMAT_EXIF_JPEG,
- MTP_FORMAT_TIFF_EP, MTP_FORMAT_BMP, MTP_FORMAT_GIF,
- MTP_FORMAT_PNG, MTP_FORMAT_TIFF, MTP_FORMAT_WMA,
- MTP_FORMAT_OGG, MTP_FORMAT_AAC, MTP_FORMAT_MP4_CONTAINER,
- MTP_FORMAT_MP2, MTP_FORMAT_3GP_CONTAINER, MTP_FORMAT_FLAC};
-
- MtpObjectFormatList *list = new MtpObjectFormatList();
- list->appendArray(init_data, MOZ_ARRAY_LENGTH(init_data));
-
- MTP_LOG("returning Supported Playback Formats");
- return list;
-}
-
-//virtual
-MtpObjectFormatList*
-MozMtpDatabase::getSupportedCaptureFormats()
-{
- static const uint16_t init_data[] = {MTP_FORMAT_ASSOCIATION, MTP_FORMAT_PNG};
-
- MtpObjectFormatList *list = new MtpObjectFormatList();
- list->appendArray(init_data, MOZ_ARRAY_LENGTH(init_data));
- MTP_LOG("returning MTP_FORMAT_ASSOCIATION, MTP_FORMAT_PNG");
- return list;
-}
-
-static const MtpObjectProperty sSupportedObjectProperties[] =
-{
- MTP_PROPERTY_STORAGE_ID,
- MTP_PROPERTY_OBJECT_FORMAT,
- MTP_PROPERTY_PROTECTION_STATUS, // UINT16 - always 0
- MTP_PROPERTY_OBJECT_SIZE,
- MTP_PROPERTY_OBJECT_FILE_NAME, // just the filename - no directory
- MTP_PROPERTY_NAME,
- MTP_PROPERTY_DATE_CREATED,
- MTP_PROPERTY_DATE_MODIFIED,
- MTP_PROPERTY_PARENT_OBJECT,
- MTP_PROPERTY_PERSISTENT_UID,
- MTP_PROPERTY_DATE_ADDED,
-};
-
-//virtual
-MtpObjectPropertyList*
-MozMtpDatabase::getSupportedObjectProperties(MtpObjectFormat aFormat)
-{
- MTP_LOG("");
- MtpObjectPropertyList *list = new MtpObjectPropertyList();
- list->appendArray(sSupportedObjectProperties,
- MOZ_ARRAY_LENGTH(sSupportedObjectProperties));
- return list;
-}
-
-//virtual
-MtpDevicePropertyList*
-MozMtpDatabase::getSupportedDeviceProperties()
-{
- MTP_LOG("");
- static const uint16_t init_data[] = { MTP_DEVICE_PROPERTY_UNDEFINED };
-
- MtpDevicePropertyList *list = new MtpDevicePropertyList();
- list->appendArray(init_data, MOZ_ARRAY_LENGTH(init_data));
- return list;
-}
-
-//virtual
-MtpResponseCode
-MozMtpDatabase::getObjectPropertyValue(MtpObjectHandle aHandle,
- MtpObjectProperty aProperty,
- MtpDataPacket& aPacket)
-{
- RefPtr<DbEntry> entry = GetEntry(aHandle);
- if (!entry) {
- MTP_ERR("Invalid Handle: 0x%08x", aHandle);
- return MTP_RESPONSE_INVALID_OBJECT_HANDLE;
- }
-
- MTP_LOG("Handle: 0x%08x '%s' Property: %s 0x%08x",
- aHandle, entry->mDisplayName.get(), ObjectPropertyAsStr(aProperty), aProperty);
-
- switch (aProperty)
- {
- case MTP_PROPERTY_STORAGE_ID: aPacket.putUInt32(entry->mStorageID); break;
- case MTP_PROPERTY_PARENT_OBJECT: aPacket.putUInt32(entry->mParent); break;
- case MTP_PROPERTY_OBJECT_FORMAT: aPacket.putUInt16(entry->mObjectFormat); break;
- case MTP_PROPERTY_OBJECT_SIZE: aPacket.putUInt64(entry->mObjectSize); break;
- case MTP_PROPERTY_DISPLAY_NAME: aPacket.putString(entry->mDisplayName.get()); break;
- case MTP_PROPERTY_PERSISTENT_UID:
- // the same as aPacket.putUInt128
- aPacket.putUInt64(entry->mHandle);
- aPacket.putUInt64(entry->mStorageID);
- break;
- case MTP_PROPERTY_NAME: aPacket.putString(entry->mDisplayName.get()); break;
-
- default:
- MTP_LOG("Invalid Property: 0x%08x", aProperty);
- return MTP_RESPONSE_INVALID_OBJECT_PROP_CODE;
- }
-
- return MTP_RESPONSE_OK;
-}
-
-static int
-GetTypeOfObjectProp(MtpObjectProperty aProperty)
-{
- struct PropertyTableEntry {
- MtpObjectProperty property;
- int type;
- };
-
- static const PropertyTableEntry kObjectPropertyTable[] = {
- {MTP_PROPERTY_STORAGE_ID, MTP_TYPE_UINT32 },
- {MTP_PROPERTY_OBJECT_FORMAT, MTP_TYPE_UINT16 },
- {MTP_PROPERTY_PROTECTION_STATUS, MTP_TYPE_UINT16 },
- {MTP_PROPERTY_OBJECT_SIZE, MTP_TYPE_UINT64 },
- {MTP_PROPERTY_OBJECT_FILE_NAME, MTP_TYPE_STR },
- {MTP_PROPERTY_DATE_CREATED, MTP_TYPE_STR },
- {MTP_PROPERTY_DATE_MODIFIED, MTP_TYPE_STR },
- {MTP_PROPERTY_PARENT_OBJECT, MTP_TYPE_UINT32 },
- {MTP_PROPERTY_DISPLAY_NAME, MTP_TYPE_STR },
- {MTP_PROPERTY_NAME, MTP_TYPE_STR },
- {MTP_PROPERTY_PERSISTENT_UID, MTP_TYPE_UINT128 },
- {MTP_PROPERTY_DATE_ADDED, MTP_TYPE_STR },
- };
-
- int count = sizeof(kObjectPropertyTable) / sizeof(kObjectPropertyTable[0]);
- const PropertyTableEntry* entryProp = kObjectPropertyTable;
- int type = 0;
-
- for (int i = 0; i < count; ++i, ++entryProp) {
- if (entryProp->property == aProperty) {
- type = entryProp->type;
- break;
- }
- }
-
- return type;
-}
-
-//virtual
-MtpResponseCode
-MozMtpDatabase::setObjectPropertyValue(MtpObjectHandle aHandle,
- MtpObjectProperty aProperty,
- MtpDataPacket& aPacket)
-{
- MTP_LOG("Handle: 0x%08x Property: 0x%08x", aHandle, aProperty);
-
- // Only support file name change
- if (aProperty != MTP_PROPERTY_OBJECT_FILE_NAME) {
- MTP_ERR("property 0x%x not supported", aProperty);
- return MTP_RESPONSE_OBJECT_PROP_NOT_SUPPORTED;
- }
-
- if (GetTypeOfObjectProp(aProperty) != MTP_TYPE_STR) {
- MTP_ERR("property type 0x%x not supported", GetTypeOfObjectProp(aProperty));
- return MTP_RESPONSE_GENERAL_ERROR;
- }
-
- RefPtr<DbEntry> entry = GetEntry(aHandle);
- if (!entry) {
- MTP_ERR("Invalid Handle: 0x%08x", aHandle);
- return MTP_RESPONSE_INVALID_OBJECT_HANDLE;
- }
-
- MtpStringBuffer buf;
- aPacket.getString(buf);
-
- nsDependentCString newFileName(buf);
- nsCString newFileFullPath(GetPathWithoutFileName(entry->mPath) + newFileName);
-
- if (PR_Rename(entry->mPath.get(), newFileFullPath.get()) != PR_SUCCESS) {
- MTP_ERR("Failed to rename '%s' to '%s'",
- entry->mPath.get(), newFileFullPath.get());
- return MTP_RESPONSE_GENERAL_ERROR;
- }
-
- MTP_LOG("renamed '%s' to '%s'", entry->mPath.get(), newFileFullPath.get());
-
- entry->mPath = newFileFullPath;
- entry->mObjectName = BaseName(entry->mPath);
- entry->mDisplayName = entry->mObjectName;
-
- return MTP_RESPONSE_OK;
-}
-
-//virtual
-MtpResponseCode
-MozMtpDatabase::getDevicePropertyValue(MtpDeviceProperty aProperty,
- MtpDataPacket& aPacket)
-{
- MTP_LOG("(GENERAL ERROR)");
- return MTP_RESPONSE_GENERAL_ERROR;
-}
-
-//virtual
-MtpResponseCode
-MozMtpDatabase::setDevicePropertyValue(MtpDeviceProperty aProperty,
- MtpDataPacket& aPacket)
-{
- MTP_LOG("(NOT SUPPORTED)");
- return MTP_RESPONSE_OPERATION_NOT_SUPPORTED;
-}
-
-//virtual
-MtpResponseCode
-MozMtpDatabase::resetDeviceProperty(MtpDeviceProperty aProperty)
-{
- MTP_LOG("(NOT SUPPORTED)");
- return MTP_RESPONSE_OPERATION_NOT_SUPPORTED;
-}
-
-void
-MozMtpDatabase::QueryEntries(MozMtpDatabase::MatchType aMatchType,
- uint32_t aMatchField1,
- uint32_t aMatchField2,
- UnprotectedDbArray &result)
-{
- MutexAutoLock lock(mMutex);
-
- ProtectedDbArray::size_type numEntries = mDb.Length();
- ProtectedDbArray::index_type entryIdx;
- RefPtr<DbEntry> entry;
-
- result.Clear();
-
- switch (aMatchType) {
-
- case MatchAll:
- for (entryIdx = 0; entryIdx < numEntries; entryIdx++) {
- if (mDb[entryIdx]) {
- result.AppendElement(mDb[entryIdx]);
- }
- }
- break;
-
- case MatchHandle:
- for (entryIdx = 0; entryIdx < numEntries; entryIdx++) {
- entry = mDb[entryIdx];
- if (entry && entry->mHandle == aMatchField1) {
- result.AppendElement(entry);
- // Handles are unique - return the one that we found.
- return;
- }
- }
- break;
-
- case MatchParent:
- for (entryIdx = 0; entryIdx < numEntries; entryIdx++) {
- entry = mDb[entryIdx];
- if (entry && entry->mParent == aMatchField1) {
- result.AppendElement(entry);
- }
- }
- break;
-
- case MatchFormat:
- for (entryIdx = 0; entryIdx < numEntries; entryIdx++) {
- entry = mDb[entryIdx];
- if (entry && entry->mObjectFormat == aMatchField1) {
- result.AppendElement(entry);
- }
- }
- break;
-
- case MatchHandleFormat:
- for (entryIdx = 0; entryIdx < numEntries; entryIdx++) {
- entry = mDb[entryIdx];
- if (entry && entry->mHandle == aMatchField1) {
- if (entry->mObjectFormat == aMatchField2) {
- result.AppendElement(entry);
- }
- // Only 1 entry can match my aHandle. So we can return early.
- return;
- }
- }
- break;
-
- case MatchParentFormat:
- for (entryIdx = 0; entryIdx < numEntries; entryIdx++) {
- entry = mDb[entryIdx];
- if (entry && entry->mParent == aMatchField1 && entry->mObjectFormat == aMatchField2) {
- result.AppendElement(entry);
- }
- }
- break;
-
- default:
- MOZ_ASSERT(!"Invalid MatchType");
- }
-}
-
-//virtual
-MtpResponseCode
-MozMtpDatabase::getObjectPropertyList(MtpObjectHandle aHandle,
- uint32_t aFormat,
- uint32_t aProperty,
- int aGroupCode,
- int aDepth,
- MtpDataPacket& aPacket)
-{
- MTP_LOG("Handle: 0x%08x Format: 0x%08x aProperty: 0x%08x aGroupCode: %d aDepth %d",
- aHandle, aFormat, aProperty, aGroupCode, aDepth);
-
- if (aDepth > 1) {
- return MTP_RESPONSE_SPECIFICATION_BY_DEPTH_UNSUPPORTED;
- }
- if (aGroupCode != 0) {
- return MTP_RESPONSE_SPECIFICATION_BY_GROUP_UNSUPPORTED;
- }
-
- MatchType matchType = MatchAll;
- uint32_t matchField1 = 0;
- uint32_t matchField2 = 0;
-
- // aHandle == 0 implies all objects at the root level
- // further specificed by aFormat and/or aDepth
-
- if (aFormat == 0) {
- if (aHandle == 0xffffffff) {
- // select all objects
- matchType = MatchAll;
- } else {
- if (aDepth == 1) {
- // select objects whose Parent matches aHandle
- matchType = MatchParent;
- matchField1 = aHandle;
- } else {
- // select object whose handle matches aHandle
- matchType = MatchHandle;
- matchField1 = aHandle;
- }
- }
- } else {
- if (aHandle == 0xffffffff) {
- // select all objects whose format matches aFormat
- matchType = MatchFormat;
- matchField1 = aFormat;
- } else {
- if (aDepth == 1) {
- // select objects whose Parent is aHandle and format matches aFormat
- matchType = MatchParentFormat;
- matchField1 = aHandle;
- matchField2 = aFormat;
- } else {
- // select objects whose handle is aHandle and format matches aFormat
- matchType = MatchHandleFormat;
- matchField1 = aHandle;
- matchField2 = aFormat;
- }
- }
- }
-
- UnprotectedDbArray result;
- QueryEntries(matchType, matchField1, matchField2, result);
-
- const MtpObjectProperty *objectPropertyList;
- size_t numObjectProperties = 0;
- MtpObjectProperty objectProperty;
-
- if (aProperty == 0xffffffff) {
- // return all supported properties
- numObjectProperties = MOZ_ARRAY_LENGTH(sSupportedObjectProperties);
- objectPropertyList = sSupportedObjectProperties;
- } else {
- // return property indicated by aProperty
- numObjectProperties = 1;
- objectProperty = aProperty;
- objectPropertyList = &objectProperty;
- }
-
- UnprotectedDbArray::size_type numEntries = result.Length();
- UnprotectedDbArray::index_type entryIdx;
-
- char dateStr[20];
-
- aPacket.putUInt32(numObjectProperties * numEntries);
- for (entryIdx = 0; entryIdx < numEntries; entryIdx++) {
- RefPtr<DbEntry> entry = result[entryIdx];
-
- for (size_t propertyIdx = 0; propertyIdx < numObjectProperties; propertyIdx++) {
- aPacket.putUInt32(entry->mHandle);
- MtpObjectProperty prop = objectPropertyList[propertyIdx];
- aPacket.putUInt16(prop);
- switch (prop) {
-
- case MTP_PROPERTY_STORAGE_ID:
- aPacket.putUInt16(MTP_TYPE_UINT32);
- aPacket.putUInt32(entry->mStorageID);
- break;
-
- case MTP_PROPERTY_PARENT_OBJECT:
- aPacket.putUInt16(MTP_TYPE_UINT32);
- aPacket.putUInt32(entry->mParent);
- break;
-
- case MTP_PROPERTY_PERSISTENT_UID:
- aPacket.putUInt16(MTP_TYPE_UINT128);
- // the same as aPacket.putUInt128
- aPacket.putUInt64(entry->mHandle);
- aPacket.putUInt64(entry->mStorageID);
- break;
-
- case MTP_PROPERTY_OBJECT_FORMAT:
- aPacket.putUInt16(MTP_TYPE_UINT16);
- aPacket.putUInt16(entry->mObjectFormat);
- break;
-
- case MTP_PROPERTY_OBJECT_SIZE:
- aPacket.putUInt16(MTP_TYPE_UINT64);
- aPacket.putUInt64(entry->mObjectSize);
- break;
-
- case MTP_PROPERTY_OBJECT_FILE_NAME:
- case MTP_PROPERTY_NAME:
- aPacket.putUInt16(MTP_TYPE_STR);
- aPacket.putString(entry->mObjectName.get());
- break;
-
- case MTP_PROPERTY_PROTECTION_STATUS:
- aPacket.putUInt16(MTP_TYPE_UINT16);
- aPacket.putUInt16(0); // 0 = No Protection
- break;
-
- case MTP_PROPERTY_DATE_CREATED: {
- aPacket.putUInt16(MTP_TYPE_STR);
- aPacket.putString(FormatDate(entry->mDateCreated, dateStr, sizeof(dateStr)));
- MTP_LOG("mDateCreated: (%ld) %s", entry->mDateCreated, dateStr);
- break;
- }
-
- case MTP_PROPERTY_DATE_MODIFIED: {
- aPacket.putUInt16(MTP_TYPE_STR);
- aPacket.putString(FormatDate(entry->mDateModified, dateStr, sizeof(dateStr)));
- MTP_LOG("mDateModified: (%ld) %s", entry->mDateModified, dateStr);
- break;
- }
-
- case MTP_PROPERTY_DATE_ADDED: {
- aPacket.putUInt16(MTP_TYPE_STR);
- aPacket.putString(FormatDate(entry->mDateAdded, dateStr, sizeof(dateStr)));
- MTP_LOG("mDateAdded: (%ld) %s", entry->mDateAdded, dateStr);
- break;
- }
-
- default:
- MTP_ERR("Unrecognized property code: %u", prop);
- return MTP_RESPONSE_GENERAL_ERROR;
- }
- }
- }
- return MTP_RESPONSE_OK;
-}
-
-//virtual
-MtpResponseCode
-MozMtpDatabase::getObjectInfo(MtpObjectHandle aHandle,
- MtpObjectInfo& aInfo)
-{
- RefPtr<DbEntry> entry = GetEntry(aHandle);
- if (!entry) {
- MTP_ERR("Handle 0x%08x is invalid", aHandle);
- return MTP_RESPONSE_INVALID_OBJECT_HANDLE;
- }
-
- MTP_LOG("Handle: 0x%08x Display:'%s' Object:'%s'", aHandle, entry->mDisplayName.get(), entry->mObjectName.get());
-
- aInfo.mHandle = aHandle;
- aInfo.mStorageID = entry->mStorageID;
- aInfo.mFormat = entry->mObjectFormat;
- aInfo.mProtectionStatus = 0x0;
-
- if (entry->mObjectSize > 0xFFFFFFFFuLL) {
- aInfo.mCompressedSize = 0xFFFFFFFFuLL;
- } else {
- aInfo.mCompressedSize = entry->mObjectSize;
- }
-
- aInfo.mThumbFormat = MTP_FORMAT_UNDEFINED;
- aInfo.mThumbCompressedSize = 0;
- aInfo.mThumbPixWidth = 0;
- aInfo.mThumbPixHeight = 0;
- aInfo.mImagePixWidth = 0;
- aInfo.mImagePixHeight = 0;
- aInfo.mImagePixDepth = 0;
- aInfo.mParent = entry->mParent;
- aInfo.mAssociationType = 0;
- aInfo.mAssociationDesc = 0;
- aInfo.mSequenceNumber = 0;
- aInfo.mName = ::strdup(entry->mObjectName.get());
- aInfo.mDateCreated = entry->mDateCreated;
- aInfo.mDateModified = entry->mDateModified;
-
- MTP_LOG("aInfo.mDateCreated = %ld entry->mDateCreated = %ld",
- aInfo.mDateCreated, entry->mDateCreated);
- MTP_LOG("aInfo.mDateModified = %ld entry->mDateModified = %ld",
- aInfo.mDateModified, entry->mDateModified);
-
- aInfo.mKeywords = ::strdup("fxos,touch");
-
- return MTP_RESPONSE_OK;
-}
-
-//virtual
-void*
-MozMtpDatabase::getThumbnail(MtpObjectHandle aHandle, size_t& aOutThumbSize)
-{
- MTP_LOG("Handle: 0x%08x (returning nullptr)", aHandle);
-
- aOutThumbSize = 0;
-
- return nullptr;
-}
-
-//virtual
-MtpResponseCode
-MozMtpDatabase::getObjectFilePath(MtpObjectHandle aHandle,
- MtpString& aOutFilePath,
- int64_t& aOutFileLength,
- MtpObjectFormat& aOutFormat)
-{
- RefPtr<DbEntry> entry = GetEntry(aHandle);
- if (!entry) {
- MTP_ERR("Handle 0x%08x is invalid", aHandle);
- return MTP_RESPONSE_INVALID_OBJECT_HANDLE;
- }
-
- MTP_LOG("Handle: 0x%08x FilePath: '%s'", aHandle, entry->mPath.get());
-
- aOutFilePath = entry->mPath.get();
- aOutFileLength = entry->mObjectSize;
- aOutFormat = entry->mObjectFormat;
-
- return MTP_RESPONSE_OK;
-}
-
-//virtual
-MtpResponseCode
-MozMtpDatabase::deleteFile(MtpObjectHandle aHandle)
-{
- RefPtr<DbEntry> entry = GetEntry(aHandle);
- if (!entry) {
- MTP_ERR("Invalid Handle: 0x%08x", aHandle);
- return MTP_RESPONSE_INVALID_OBJECT_HANDLE;
- }
-
- MTP_LOG("Handle: 0x%08x '%s'", aHandle, entry->mPath.get());
-
- // File deletion will happen in lower level implementation.
- // The only thing we need to do is removing the entry from the db.
- RemoveEntry(aHandle);
-
- // Tell Device Storage that the file is gone.
- MtpWatcherNotify(entry, "deleted");
-
- return MTP_RESPONSE_OK;
-}
-
-#if 0
-//virtual
-MtpResponseCode
-MozMtpDatabase::moveFile(MtpObjectHandle aHandle, MtpObjectHandle aNewParent)
-{
- MTP_LOG("Handle: 0x%08x NewParent: 0x%08x", aHandle, aNewParent);
-
- // change parent
-
- return MTP_RESPONSE_OK
-}
-
-//virtual
-MtpResponseCode
-MozMtpDatabase::copyFile(MtpObjectHandle aHandle, MtpObjectHandle aNewParent)
-{
- MTP_LOG("Handle: 0x%08x NewParent: 0x%08x", aHandle, aNewParent);
-
- // duplicate DbEntry
- // change parent
-
- return MTP_RESPONSE_OK
-}
-#endif
-
-//virtual
-MtpObjectHandleList*
-MozMtpDatabase::getObjectReferences(MtpObjectHandle aHandle)
-{
- MTP_LOG("Handle: 0x%08x (returning nullptr)", aHandle);
- return nullptr;
-}
-
-//virtual
-MtpResponseCode
-MozMtpDatabase::setObjectReferences(MtpObjectHandle aHandle,
- MtpObjectHandleList* aReferences)
-{
- MTP_LOG("Handle: 0x%08x (NOT SUPPORTED)", aHandle);
- return MTP_RESPONSE_OPERATION_NOT_SUPPORTED;
-}
-
-//virtual
-MtpProperty*
-MozMtpDatabase::getObjectPropertyDesc(MtpObjectProperty aProperty,
- MtpObjectFormat aFormat)
-{
- MTP_LOG("Property: %s 0x%08x", ObjectPropertyAsStr(aProperty), aProperty);
-
- MtpProperty* result = nullptr;
- switch (aProperty)
- {
- case MTP_PROPERTY_PROTECTION_STATUS:
- result = new MtpProperty(aProperty, MTP_TYPE_UINT16);
- break;
- case MTP_PROPERTY_OBJECT_FORMAT:
- result = new MtpProperty(aProperty, MTP_TYPE_UINT16, false, aFormat);
- break;
- case MTP_PROPERTY_STORAGE_ID:
- case MTP_PROPERTY_PARENT_OBJECT:
- case MTP_PROPERTY_WIDTH:
- case MTP_PROPERTY_HEIGHT:
- case MTP_PROPERTY_IMAGE_BIT_DEPTH:
- result = new MtpProperty(aProperty, MTP_TYPE_UINT32);
- break;
- case MTP_PROPERTY_OBJECT_SIZE:
- result = new MtpProperty(aProperty, MTP_TYPE_UINT64);
- break;
- case MTP_PROPERTY_DISPLAY_NAME:
- case MTP_PROPERTY_NAME:
- result = new MtpProperty(aProperty, MTP_TYPE_STR);
- break;
- case MTP_PROPERTY_OBJECT_FILE_NAME:
- result = new MtpProperty(aProperty, MTP_TYPE_STR, true);
- break;
- case MTP_PROPERTY_DATE_CREATED:
- case MTP_PROPERTY_DATE_MODIFIED:
- case MTP_PROPERTY_DATE_ADDED:
- result = new MtpProperty(aProperty, MTP_TYPE_STR);
- result->setFormDateTime();
- break;
- case MTP_PROPERTY_PERSISTENT_UID:
- result = new MtpProperty(aProperty, MTP_TYPE_UINT128);
- break;
- default:
- break;
- }
-
- return result;
-}
-
-//virtual
-MtpProperty*
-MozMtpDatabase::getDevicePropertyDesc(MtpDeviceProperty aProperty)
-{
- MTP_LOG("(returning MTP_DEVICE_PROPERTY_UNDEFINED)");
- return new MtpProperty(MTP_DEVICE_PROPERTY_UNDEFINED, MTP_TYPE_UNDEFINED);
-}
-
-//virtual
-void
-MozMtpDatabase::sessionStarted()
-{
- MTP_LOG("");
-}
-
-//virtual
-void
-MozMtpDatabase::sessionEnded()
-{
- MTP_LOG("");
-}
-
-END_MTP_NAMESPACE
diff --git a/dom/system/gonk/MozMtpDatabase.h b/dom/system/gonk/MozMtpDatabase.h
deleted file mode 100644
index 8b308762e8..0000000000
--- a/dom/system/gonk/MozMtpDatabase.h
+++ /dev/null
@@ -1,288 +0,0 @@
-/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
-/* 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/. */
-
-#ifndef mozilla_system_mozmtpdatabase_h__
-#define mozilla_system_mozmtpdatabase_h__
-
-#include "MozMtpCommon.h"
-
-#include "mozilla/Mutex.h"
-#include "mozilla/RefPtr.h"
-#include "nsCOMPtr.h"
-#include "nsString.h"
-#include "nsIThread.h"
-#include "nsTArray.h"
-
-class DeviceStorageFile;
-
-BEGIN_MTP_NAMESPACE // mozilla::system::mtp
-
-class RefCountedMtpServer;
-
-using namespace android;
-
-class MozMtpDatabase final : public MtpDatabase
-{
-public:
- NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MozMtpDatabase)
-
- MozMtpDatabase();
-
- // called from SendObjectInfo to reserve a database entry for the incoming file
- virtual MtpObjectHandle beginSendObject(const char* aPath,
- MtpObjectFormat aFormat,
- MtpObjectHandle aParent,
- MtpStorageID aStorageID,
- uint64_t aSize,
- time_t aModified);
-
- // called to report success or failure of the SendObject file transfer
- // success should signal a notification of the new object's creation,
- // failure should remove the database entry created in beginSendObject
- virtual void endSendObject(const char* aPath,
- MtpObjectHandle aHandle,
- MtpObjectFormat aFormat,
- bool aSucceeded);
-
- virtual MtpObjectHandleList* getObjectList(MtpStorageID aStorageID,
- MtpObjectFormat aFormat,
- MtpObjectHandle aParent);
-
- virtual int getNumObjects(MtpStorageID aStorageID,
- MtpObjectFormat aFormat,
- MtpObjectHandle aParent);
-
- virtual MtpObjectFormatList* getSupportedPlaybackFormats();
-
- virtual MtpObjectFormatList* getSupportedCaptureFormats();
-
- virtual MtpObjectPropertyList* getSupportedObjectProperties(MtpObjectFormat aFormat);
-
- virtual MtpDevicePropertyList* getSupportedDeviceProperties();
-
- virtual MtpResponseCode getObjectPropertyValue(MtpObjectHandle aHandle,
- MtpObjectProperty aProperty,
- MtpDataPacket& aPacket);
-
- virtual MtpResponseCode setObjectPropertyValue(MtpObjectHandle aHandle,
- MtpObjectProperty aProperty,
- MtpDataPacket& aPacket);
-
- virtual MtpResponseCode getDevicePropertyValue(MtpDeviceProperty aProperty,
- MtpDataPacket& aPacket);
-
- virtual MtpResponseCode setDevicePropertyValue(MtpDeviceProperty aProperty,
- MtpDataPacket& aPacket);
-
- virtual MtpResponseCode resetDeviceProperty(MtpDeviceProperty aProperty);
-
- virtual MtpResponseCode getObjectPropertyList(MtpObjectHandle aHandle,
- uint32_t aFormat,
- uint32_t aProperty,
- int aGroupCode,
- int aDepth,
- MtpDataPacket& aPacket);
-
- virtual MtpResponseCode getObjectInfo(MtpObjectHandle aHandle,
- MtpObjectInfo& aInfo);
-
- virtual void* getThumbnail(MtpObjectHandle aHandle, size_t& aOutThumbSize);
-
- virtual MtpResponseCode getObjectFilePath(MtpObjectHandle aHandle,
- MtpString& aOutFilePath,
- int64_t& aOutFileLength,
- MtpObjectFormat& aOutFormat);
-
- virtual MtpResponseCode deleteFile(MtpObjectHandle aHandle);
-
- virtual MtpObjectHandleList* getObjectReferences(MtpObjectHandle aHandle);
-
- virtual MtpResponseCode setObjectReferences(MtpObjectHandle aHandle,
- MtpObjectHandleList* aReferences);
-
- virtual MtpProperty* getObjectPropertyDesc(MtpObjectProperty aProperty,
- MtpObjectFormat aFormat);
-
- virtual MtpProperty* getDevicePropertyDesc(MtpDeviceProperty aProperty);
-
- virtual void sessionStarted();
-
- virtual void sessionEnded();
-
- void AddStorage(MtpStorageID aStorageID, const char* aPath, const char *aName);
- void RemoveStorage(MtpStorageID aStorageID);
-
- void MtpWatcherUpdate(RefCountedMtpServer* aMtpServer,
- DeviceStorageFile* aFile,
- const nsACString& aEventType);
-
-protected:
- virtual ~MozMtpDatabase();
-
-private:
-
- struct DbEntry final
- {
- DbEntry()
- : mHandle(0),
- mStorageID(0),
- mObjectFormat(MTP_FORMAT_DEFINED),
- mParent(0),
- mObjectSize(0),
- mDateCreated(0),
- mDateModified(0),
- mDateAdded(0) {}
-
- NS_INLINE_DECL_THREADSAFE_REFCOUNTING(DbEntry)
-
- MtpObjectHandle mHandle; // uint32_t
- MtpStorageID mStorageID; // uint32_t
- nsCString mObjectName;
- MtpObjectFormat mObjectFormat; // uint16_t
- MtpObjectHandle mParent; // uint32_t
- uint64_t mObjectSize;
- nsCString mDisplayName;
- nsCString mPath;
- time_t mDateCreated;
- time_t mDateModified;
- time_t mDateAdded;
-
- protected:
- ~DbEntry() {}
- };
-
- template<class T>
- class ProtectedTArray : private nsTArray<T>
- {
- public:
- typedef T elem_type;
- typedef typename nsTArray<T>::size_type size_type;
- typedef typename nsTArray<T>::index_type index_type;
- typedef nsTArray<T> base_type;
-
- static const index_type NoIndex = base_type::NoIndex;
-
- ProtectedTArray(mozilla::Mutex& aMutex)
- : mMutex(aMutex)
- {}
-
- size_type Length() const
- {
- // GRR - This assert prints to stderr and won't show up in logcat.
- mMutex.AssertCurrentThreadOwns();
- return base_type::Length();
- }
-
- template <class Item>
- elem_type* AppendElement(const Item& aItem)
- {
- mMutex.AssertCurrentThreadOwns();
- return base_type::AppendElement(aItem);
- }
-
- void Clear()
- {
- mMutex.AssertCurrentThreadOwns();
- base_type::Clear();
- }
-
- void RemoveElementAt(index_type aIndex)
- {
- mMutex.AssertCurrentThreadOwns();
- base_type::RemoveElementAt(aIndex);
- }
-
- elem_type& operator[](index_type aIndex)
- {
- mMutex.AssertCurrentThreadOwns();
- return base_type::ElementAt(aIndex);
- }
-
- const elem_type& operator[](index_type aIndex) const
- {
- mMutex.AssertCurrentThreadOwns();
- return base_type::ElementAt(aIndex);
- }
-
- private:
- mozilla::Mutex& mMutex;
- };
- typedef nsTArray<RefPtr<DbEntry> > UnprotectedDbArray;
- typedef ProtectedTArray<RefPtr<DbEntry> > ProtectedDbArray;
-
- struct StorageEntry final
- {
- NS_INLINE_DECL_THREADSAFE_REFCOUNTING(StorageEntry)
-
- MtpStorageID mStorageID;
- nsCString mStoragePath;
- nsCString mStorageName;
-
- protected:
- ~StorageEntry() {}
- };
- typedef ProtectedTArray<RefPtr<StorageEntry> > StorageArray;
-
- enum MatchType
- {
- MatchAll,
- MatchHandle,
- MatchParent,
- MatchFormat,
- MatchHandleFormat,
- MatchParentFormat,
- };
-
- bool IsValidHandle(MtpObjectHandle aHandle)
- {
- return aHandle > 0 && aHandle < mDb.Length();
- }
-
- void AddEntry(DbEntry* aEntry);
- void AddEntryAndNotify(DbEntry* aEntr, RefCountedMtpServer* aMtpServer);
- void DumpEntries(const char* aLabel);
- MtpObjectHandle FindEntryByPath(const nsACString& aPath);
- already_AddRefed<DbEntry> GetEntry(MtpObjectHandle aHandle);
- void RemoveEntry(MtpObjectHandle aHandle);
- void RemoveEntryAndNotify(MtpObjectHandle aHandle, RefCountedMtpServer* aMtpServer);
- void UpdateEntry(MtpObjectHandle aHandle, DeviceStorageFile* aFile);
- void UpdateEntryAndNotify(MtpObjectHandle aHandle, DeviceStorageFile* aFile,
- RefCountedMtpServer* aMtpServer);
- void QueryEntries(MatchType aMatchType, uint32_t aMatchField1,
- uint32_t aMatchField2, UnprotectedDbArray& aResult);
-
- nsCString BaseName(const nsCString& aPath);
-
-
- MtpObjectHandle GetNextHandle()
- {
- return mDb.Length();
- }
-
- void AddDirectory(MtpStorageID aStorageID, const char *aPath, MtpObjectHandle aParent);
-
- void CreateEntryForFileAndNotify(const nsACString& aPath,
- DeviceStorageFile* aFile,
- RefCountedMtpServer* aMtpServer);
-
- StorageArray::index_type FindStorage(MtpStorageID aStorageID);
- MtpStorageID FindStorageIDFor(const nsACString& aPath, nsCSubstring& aRemainder);
- void MtpWatcherNotify(DbEntry* aEntry, const char* aEventType);
-
- // We need a mutex to protext mDb and mStorage. The MTP server runs on a
- // dedicated thread, and it updates/accesses mDb. When files are updated
- // through DeviceStorage, we need to update/access mDb and mStorage as well
- // (from a non-MTP server thread).
- mozilla::Mutex mMutex;
- ProtectedDbArray mDb;
- StorageArray mStorage;
-
- bool mBeginSendObjectCalled;
-};
-
-END_MTP_NAMESPACE
-
-#endif // mozilla_system_mozmtpdatabase_h__
diff --git a/dom/system/gonk/MozMtpServer.cpp b/dom/system/gonk/MozMtpServer.cpp
deleted file mode 100644
index c26b6368be..0000000000
--- a/dom/system/gonk/MozMtpServer.cpp
+++ /dev/null
@@ -1,263 +0,0 @@
-/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
-/* 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/. */
-
-#include "MozMtpServer.h"
-#include "MozMtpDatabase.h"
-
-#include <fcntl.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-
-#include <errno.h>
-#include <stdio.h>
-#include <unistd.h>
-
-#include <cutils/properties.h>
-#include <private/android_filesystem_config.h>
-
-#include "base/message_loop.h"
-#include "DeviceStorage.h"
-#include "mozilla/LazyIdleThread.h"
-#include "mozilla/Scoped.h"
-#include "mozilla/Services.h"
-#include "mozilla/StaticPtr.h"
-#include "nsIObserver.h"
-#include "nsIObserverService.h"
-#include "nsISupportsImpl.h"
-#include "nsThreadUtils.h"
-#include "nsXULAppAPI.h"
-
-#include "Volume.h"
-
-#define DEFAULT_THREAD_TIMEOUT_MS 30000
-
-using namespace android;
-using namespace mozilla;
-BEGIN_MTP_NAMESPACE
-
-static const char* kMtpWatcherUpdate = "mtp-watcher-update";
-
-class MtpWatcherUpdateRunnable final : public Runnable
-{
-public:
- MtpWatcherUpdateRunnable(MozMtpDatabase* aMozMtpDatabase,
- RefCountedMtpServer* aMtpServer,
- DeviceStorageFile* aFile,
- const nsACString& aEventType)
- : mMozMtpDatabase(aMozMtpDatabase),
- mMtpServer(aMtpServer),
- mFile(aFile),
- mEventType(aEventType)
- {}
-
- NS_IMETHOD Run() override
- {
- // Runs on the MtpWatcherUpdate->mIOThread
- MOZ_ASSERT(!NS_IsMainThread());
-
- mMozMtpDatabase->MtpWatcherUpdate(mMtpServer, mFile, mEventType);
- return NS_OK;
- }
-
-private:
- RefPtr<MozMtpDatabase> mMozMtpDatabase;
- RefPtr<RefCountedMtpServer> mMtpServer;
- RefPtr<DeviceStorageFile> mFile;
- nsCString mEventType;
-};
-
-// The MtpWatcherUpdate class listens for mtp-watcher-update events
-// and tells the MtpServer about changes made in device storage.
-class MtpWatcherUpdate final : public nsIObserver
-{
-public:
- NS_DECL_THREADSAFE_ISUPPORTS
-
- MtpWatcherUpdate(MozMtpServer* aMozMtpServer)
- : mMozMtpServer(aMozMtpServer)
- {
- MOZ_ASSERT(NS_IsMainThread());
-
- mIOThread = new LazyIdleThread(
- DEFAULT_THREAD_TIMEOUT_MS,
- NS_LITERAL_CSTRING("MtpWatcherUpdate"));
-
- nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
- obs->AddObserver(this, kMtpWatcherUpdate, false);
- }
-
- NS_IMETHOD
- Observe(nsISupports* aSubject, const char* aTopic, const char16_t* aData)
- {
- MOZ_ASSERT(NS_IsMainThread());
-
- if (strcmp(aTopic, kMtpWatcherUpdate)) {
- // We're only interested in mtp-watcher-update events
- return NS_OK;
- }
-
- NS_ConvertUTF16toUTF8 eventType(aData);
- if (!eventType.EqualsLiteral("modified") && !eventType.EqualsLiteral("deleted")) {
- // Bug 1074604: Needn't handle "created" event, once file operation
- // finished, it would trigger "modified" event.
- return NS_OK;
- }
-
- DeviceStorageFile* file = static_cast<DeviceStorageFile*>(aSubject);
- file->Dump(kMtpWatcherUpdate);
- MTP_LOG("%s: file %s %s", kMtpWatcherUpdate,
- NS_LossyConvertUTF16toASCII(file->mPath).get(),
- eventType.get());
-
- RefPtr<MozMtpDatabase> mozMtpDatabase = mMozMtpServer->GetMozMtpDatabase();
- RefPtr<RefCountedMtpServer> mtpServer = mMozMtpServer->GetMtpServer();
-
- // We're not supposed to perform I/O on the main thread, so punt the
- // notification (which will write to /dev/mtp_usb) to an I/O Thread.
-
- RefPtr<MtpWatcherUpdateRunnable> r =
- new MtpWatcherUpdateRunnable(mozMtpDatabase, mtpServer, file, eventType);
- mIOThread->Dispatch(r, NS_DISPATCH_NORMAL);
-
- return NS_OK;
- }
-
-protected:
- ~MtpWatcherUpdate()
- {
- MOZ_ASSERT(NS_IsMainThread());
-
- nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
- obs->RemoveObserver(this, kMtpWatcherUpdate);
- }
-
-private:
- RefPtr<MozMtpServer> mMozMtpServer;
- nsCOMPtr<nsIThread> mIOThread;
-};
-NS_IMPL_ISUPPORTS(MtpWatcherUpdate, nsIObserver)
-static StaticRefPtr<MtpWatcherUpdate> sMtpWatcherUpdate;
-
-class AllocMtpWatcherUpdateRunnable final : public Runnable
-{
-public:
- AllocMtpWatcherUpdateRunnable(MozMtpServer* aMozMtpServer)
- : mMozMtpServer(aMozMtpServer)
- {}
-
- NS_IMETHOD Run() override
- {
- MOZ_ASSERT(NS_IsMainThread());
-
- sMtpWatcherUpdate = new MtpWatcherUpdate(mMozMtpServer);
- return NS_OK;
- }
-private:
- RefPtr<MozMtpServer> mMozMtpServer;
-};
-
-class FreeMtpWatcherUpdateRunnable final : public Runnable
-{
-public:
- FreeMtpWatcherUpdateRunnable(MozMtpServer* aMozMtpServer)
- : mMozMtpServer(aMozMtpServer)
- {}
-
- NS_IMETHOD Run() override
- {
- MOZ_ASSERT(NS_IsMainThread());
-
- sMtpWatcherUpdate = nullptr;
- return NS_OK;
- }
-private:
- RefPtr<MozMtpServer> mMozMtpServer;
-};
-
-class MtpServerRunnable : public Runnable
-{
-public:
- MtpServerRunnable(int aMtpUsbFd, MozMtpServer* aMozMtpServer)
- : mMozMtpServer(aMozMtpServer),
- mMtpUsbFd(aMtpUsbFd)
- {
- }
-
- nsresult Run()
- {
- RefPtr<RefCountedMtpServer> server = mMozMtpServer->GetMtpServer();
-
- DebugOnly<nsresult> rv =
- NS_DispatchToMainThread(new AllocMtpWatcherUpdateRunnable(mMozMtpServer));
- MOZ_ASSERT(NS_SUCCEEDED(rv));
-
- MTP_LOG("MozMtpServer started");
- server->run();
- MTP_LOG("MozMtpServer finished");
-
- // server->run will have closed the file descriptor.
- mMtpUsbFd.forget();
-
- rv = NS_DispatchToMainThread(new FreeMtpWatcherUpdateRunnable(mMozMtpServer));
- MOZ_ASSERT(NS_SUCCEEDED(rv));
-
- return NS_OK;
- }
-
-private:
- RefPtr<MozMtpServer> mMozMtpServer;
- ScopedClose mMtpUsbFd; // We want to hold this open while the server runs
-};
-
-already_AddRefed<RefCountedMtpServer>
-MozMtpServer::GetMtpServer()
-{
- RefPtr<RefCountedMtpServer> server = mMtpServer;
- return server.forget();
-}
-
-already_AddRefed<MozMtpDatabase>
-MozMtpServer::GetMozMtpDatabase()
-{
- RefPtr<MozMtpDatabase> db = mMozMtpDatabase;
- return db.forget();
-}
-
-bool
-MozMtpServer::Init()
-{
- MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
-
- const char *mtpUsbFilename = "/dev/mtp_usb";
- mMtpUsbFd = open(mtpUsbFilename, O_RDWR);
- if (mMtpUsbFd.get() < 0) {
- MTP_ERR("open of '%s' failed((%s))", mtpUsbFilename, strerror(errno));
- return false;
- }
- MTP_LOG("Opened '%s' fd %d", mtpUsbFilename, mMtpUsbFd.get());
-
- mMozMtpDatabase = new MozMtpDatabase();
- mMtpServer = new RefCountedMtpServer(mMtpUsbFd.get(), // fd
- mMozMtpDatabase.get(), // MtpDatabase
- false, // ptp?
- AID_MEDIA_RW, // file group
- 0664, // file permissions
- 0775); // dir permissions
- return true;
-}
-
-void
-MozMtpServer::Run()
-{
- nsresult rv = NS_NewNamedThread("MtpServer", getter_AddRefs(mServerThread));
- if (NS_WARN_IF(NS_FAILED(rv))) {
- return;
- }
- MOZ_ASSERT(mServerThread);
- mServerThread->Dispatch(new MtpServerRunnable(mMtpUsbFd.forget(), this), NS_DISPATCH_NORMAL);
-}
-
-END_MTP_NAMESPACE
diff --git a/dom/system/gonk/MozMtpServer.h b/dom/system/gonk/MozMtpServer.h
deleted file mode 100644
index 4989c25eff..0000000000
--- a/dom/system/gonk/MozMtpServer.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
-/* 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/. */
-
-#ifndef mozilla_system_mozmtpserver_h__
-#define mozilla_system_mozmtpserver_h__
-
-#include "MozMtpCommon.h"
-#include "MozMtpDatabase.h"
-
-#include "mozilla/FileUtils.h"
-
-#include "nsCOMPtr.h"
-#include "nsIThread.h"
-
-BEGIN_MTP_NAMESPACE
-using namespace android;
-
-class RefCountedMtpServer : public MtpServer
-{
-public:
- NS_INLINE_DECL_THREADSAFE_REFCOUNTING(RefCountedMtpServer)
-
- RefCountedMtpServer(int aFd, MtpDatabase* aDatabase, bool aPtp,
- int aFileGroup, int aFilePerm, int aDirectoryPerm)
- : MtpServer(aFd, aDatabase, aPtp, aFileGroup, aFilePerm, aDirectoryPerm)
- {
- }
-
-protected:
- virtual ~RefCountedMtpServer() {}
-};
-
-class MozMtpServer
-{
-public:
- NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MozMtpServer)
-
- bool Init();
- void Run();
-
- already_AddRefed<RefCountedMtpServer> GetMtpServer();
- already_AddRefed<MozMtpDatabase> GetMozMtpDatabase();
-
-protected:
- virtual ~MozMtpServer() {}
-
-private:
- RefPtr<RefCountedMtpServer> mMtpServer;
- RefPtr<MozMtpDatabase> mMozMtpDatabase;
- nsCOMPtr<nsIThread> mServerThread;
- ScopedClose mMtpUsbFd;
-};
-
-END_MTP_NAMESPACE
-
-#endif // mozilla_system_mozmtpserver_h__
-
-
diff --git a/dom/system/gonk/MozMtpStorage.cpp b/dom/system/gonk/MozMtpStorage.cpp
deleted file mode 100644
index 9c358a1324..0000000000
--- a/dom/system/gonk/MozMtpStorage.cpp
+++ /dev/null
@@ -1,135 +0,0 @@
-/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
-/* 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/. */
-
-#include "MozMtpStorage.h"
-#include "MozMtpDatabase.h"
-#include "MozMtpServer.h"
-
-#include "base/message_loop.h"
-#include "nsXULAppAPI.h"
-
-BEGIN_MTP_NAMESPACE
-using namespace android;
-
-MozMtpStorage::MozMtpStorage(Volume* aVolume, MozMtpServer* aMozMtpServer)
- : mMozMtpServer(aMozMtpServer),
- mVolume(aVolume)
-{
- MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
-
- // The MtpStorageID has the physical volume in the top 16 bits, and the
- // logical volumein the lower 16 bits. We treat each volume as a separate
- // phsyical storage;
- mStorageID = mVolume->Id() << 16 | 1;
-
- MTP_LOG("Storage constructed for Volume %s mStorageID 0x%08x",
- aVolume->NameStr(), mStorageID);
-
- Volume::RegisterVolumeObserver(this, "MozMtpStorage");
-
- // Get things in sync
- Notify(mVolume);
-}
-
-MozMtpStorage::~MozMtpStorage()
-{
- MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
-
- MTP_LOG("Storage destructed for Volume %s mStorageID 0x%08x",
- mVolume->NameStr(), mStorageID);
-
- Volume::UnregisterVolumeObserver(this, "MozMtpStorage");
- if (mMtpStorage) {
- StorageUnavailable();
- }
-}
-
-// virtual
-void
-MozMtpStorage::Notify(Volume* const& aVolume)
-{
- MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
-
- if (aVolume != mVolume) {
- // Not our volume
- return;
- }
- Volume::STATE volState = aVolume->State();
-
- MTP_LOG("Volume %s mStorageID 0x%08x state changed to %s SharingEnabled: %d",
- aVolume->NameStr(), mStorageID, aVolume->StateStr(),
- aVolume->IsSharingEnabled());
-
- // vol->IsSharingEnabled really only applies to UMS volumes. We assume that
- // that as long as MTP is enabled, then all volumes will be shared. The UI
- // currently doesn't give us anything more granular than on/off.
-
- if (mMtpStorage) {
- if (volState != nsIVolume::STATE_MOUNTED) {
- // The volume is no longer accessible. We need to remove this storage
- // from the MTP server
- StorageUnavailable();
- }
- } else {
- if (volState == nsIVolume::STATE_MOUNTED) {
- // The volume is accessible. Tell the MTP server.
- StorageAvailable();
- }
- }
-}
-
-void
-MozMtpStorage::StorageAvailable()
-{
- MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
-
- nsCString mountPoint = mVolume->MountPoint();
-
- MTP_LOG("Adding Volume %s mStorageID 0x%08x mountPoint %s to MozMtpDatabase",
- mVolume->NameStr(), mStorageID, mountPoint.get());
-
- RefPtr<MozMtpDatabase> db = mMozMtpServer->GetMozMtpDatabase();
- db->AddStorage(mStorageID, mountPoint.get(), mVolume->NameStr());
-
- MOZ_ASSERT(!mMtpStorage);
-
- //TODO: Figure out what to do about maxFileSize.
-
- mMtpStorage.reset(new MtpStorage(mStorageID, // id
- mountPoint.get(), // filePath
- mVolume->NameStr(), // description
- 1024uLL * 1024uLL, // reserveSpace
- mVolume->IsHotSwappable(), // removable
- 2uLL * 1024uLL * 1024uLL * 1024uLL)); // maxFileSize
- RefPtr<RefCountedMtpServer> server = mMozMtpServer->GetMtpServer();
-
- MTP_LOG("Adding Volume %s mStorageID 0x%08x mountPoint %s to MtpServer",
- mVolume->NameStr(), mStorageID, mountPoint.get());
- server->addStorage(mMtpStorage.get());
-}
-
-void
-MozMtpStorage::StorageUnavailable()
-{
- MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
- MOZ_ASSERT(mMtpStorage);
-
- MTP_LOG("Removing mStorageID 0x%08x from MtpServer", mStorageID);
-
- RefPtr<RefCountedMtpServer> server = mMozMtpServer->GetMtpServer();
- server->removeStorage(mMtpStorage.get());
-
- MTP_LOG("Removing mStorageID 0x%08x from MozMtpDatabse", mStorageID);
-
- RefPtr<MozMtpDatabase> db = mMozMtpServer->GetMozMtpDatabase();
- db->RemoveStorage(mStorageID);
-
- mMtpStorage = nullptr;
-}
-
-END_MTP_NAMESPACE
-
-
diff --git a/dom/system/gonk/MozMtpStorage.h b/dom/system/gonk/MozMtpStorage.h
deleted file mode 100644
index 18d1e04ac9..0000000000
--- a/dom/system/gonk/MozMtpStorage.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
-/* 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/. */
-
-#ifndef mozilla_system_mozmtpstorage_h__
-#define mozilla_system_mozmtpstorage_h__
-
-#include "MozMtpCommon.h"
-
-#include "mozilla/UniquePtr.h"
-
-#include "Volume.h"
-
-BEGIN_MTP_NAMESPACE
-using namespace android;
-
-class MozMtpServer;
-
-class MozMtpStorage : public Volume::EventObserver
-{
-public:
- NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MozMtpStorage)
-
- MozMtpStorage(Volume* aVolume, MozMtpServer* aMozMtpServer);
-
- typedef nsTArray<RefPtr<MozMtpStorage> > Array;
-
-private:
- virtual ~MozMtpStorage();
- virtual void Notify(Volume* const& aEvent);
-
- void StorageAvailable();
- void StorageUnavailable();
-
- RefPtr<MozMtpServer> mMozMtpServer;
- UniquePtr<MtpStorage> mMtpStorage;
- RefPtr<Volume> mVolume;
- MtpStorageID mStorageID;
-};
-
-END_MTP_NAMESPACE
-
-#endif // mozilla_system_mozmtpstorage_h__
-
-
diff --git a/dom/system/gonk/NetIdManager.cpp b/dom/system/gonk/NetIdManager.cpp
deleted file mode 100644
index 510ec8b224..0000000000
--- a/dom/system/gonk/NetIdManager.cpp
+++ /dev/null
@@ -1,68 +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 "NetIdManager.h"
-
-NetIdManager::NetIdManager()
- : mNextNetId(MIN_NET_ID)
-{
-}
-
-int NetIdManager::getNextNetId()
-{
- // Modified from
- // http://androidxref.com/5.0.0_r2/xref/frameworks/base/services/
- // core/java/com/android/server/ConnectivityService.java#764
-
- int netId = mNextNetId;
- if (++mNextNetId > MAX_NET_ID) {
- mNextNetId = MIN_NET_ID;
- }
-
- return netId;
-}
-
-void NetIdManager::acquire(const nsString& aInterfaceName,
- NetIdInfo* aNetIdInfo)
-{
- // Lookup or create one.
- if (!mInterfaceToNetIdHash.Get(aInterfaceName, aNetIdInfo)) {
- aNetIdInfo->mNetId = getNextNetId();
- aNetIdInfo->mRefCnt = 1;
- } else {
- aNetIdInfo->mRefCnt++;
- }
-
- // Update hash and return.
- mInterfaceToNetIdHash.Put(aInterfaceName, *aNetIdInfo);
-
- return;
-}
-
-bool NetIdManager::lookup(const nsString& aInterfaceName,
- NetIdInfo* aNetIdInfo)
-{
- return mInterfaceToNetIdHash.Get(aInterfaceName, aNetIdInfo);
-}
-
-bool NetIdManager::release(const nsString& aInterfaceName,
- NetIdInfo* aNetIdInfo)
-{
- if (!mInterfaceToNetIdHash.Get(aInterfaceName, aNetIdInfo)) {
- return false; // No such key.
- }
-
- aNetIdInfo->mRefCnt--;
-
- // Update the hash if still be referenced.
- if (aNetIdInfo->mRefCnt > 0) {
- mInterfaceToNetIdHash.Put(aInterfaceName, *aNetIdInfo);
- return true;
- }
-
- // No longer be referenced. Remove the entry.
- mInterfaceToNetIdHash.Remove(aInterfaceName);
-
- return true;
-} \ No newline at end of file
diff --git a/dom/system/gonk/NetIdManager.h b/dom/system/gonk/NetIdManager.h
deleted file mode 100644
index e35d0ecd2c..0000000000
--- a/dom/system/gonk/NetIdManager.h
+++ /dev/null
@@ -1,45 +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/. */
-
-#ifndef NetIdManager_h
-#define NetIdManager_h
-
-#include "nsString.h"
-#include "nsDataHashtable.h"
-
-// NetId is a logical network identifier defined by netd.
-// A network is typically a physical one (i.e. PhysicalNetwork.cpp)
-// for netd but it could be a virtual network as well.
-// We currently use physical network only and use one-to-one
-// network-interface mapping.
-
-class NetIdManager {
-public:
- // keep in sync with system/netd/NetworkController.cpp
- enum {
- MIN_NET_ID = 100,
- MAX_NET_ID = 65535,
- };
-
- // We need to count the number of references since different
- // application like data and mms may use the same interface.
- struct NetIdInfo {
- int mNetId;
- int mRefCnt;
- };
-
-public:
- NetIdManager();
-
- bool lookup(const nsString& aInterfaceName, NetIdInfo* aNetIdInfo);
- void acquire(const nsString& aInterfaceName, NetIdInfo* aNetIdInfo);
- bool release(const nsString& aInterfaceName, NetIdInfo* aNetIdInfo);
-
-private:
- int getNextNetId();
- int mNextNetId;
- nsDataHashtable<nsStringHashKey, NetIdInfo> mInterfaceToNetIdHash;
-};
-
-#endif \ No newline at end of file
diff --git a/dom/system/gonk/NetworkInterfaceListService.js b/dom/system/gonk/NetworkInterfaceListService.js
deleted file mode 100644
index 62fe046aad..0000000000
--- a/dom/system/gonk/NetworkInterfaceListService.js
+++ /dev/null
@@ -1,110 +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");
-
-const NETWORKLISTSERVICE_CONTRACTID =
- "@mozilla.org/network/interface-list-service;1";
-const NETWORKLISTSERVICE_CID =
- Components.ID("{3780be6e-7012-4e53-ade6-15212fb88a0d}");
-
-XPCOMUtils.defineLazyServiceGetter(this, "cpmm",
- "@mozilla.org/childprocessmessagemanager;1",
- "nsISyncMessageSender");
-
-function NetworkInterfaceListService () {
-}
-
-NetworkInterfaceListService.prototype = {
- classID: NETWORKLISTSERVICE_CID,
-
- QueryInterface: XPCOMUtils.generateQI([Ci.nsINetworkInterfaceListService]),
-
- getDataInterfaceList: function(aConditions) {
- return new NetworkInterfaceList(
- cpmm.sendSyncMessage(
- 'NetworkInterfaceList:ListInterface',
- {
- excludeSupl: (aConditions &
- Ci.nsINetworkInterfaceListService.
- LIST_NOT_INCLUDE_SUPL_INTERFACES) != 0,
- excludeMms: (aConditions &
- Ci.nsINetworkInterfaceListService.
- LIST_NOT_INCLUDE_MMS_INTERFACES) != 0,
- excludeIms: (aConditions &
- Ci.nsINetworkInterfaceListService.
- LIST_NOT_INCLUDE_IMS_INTERFACES) != 0,
- excludeDun: (aConditions &
- Ci.nsINetworkInterfaceListService.
- LIST_NOT_INCLUDE_DUN_INTERFACES) != 0,
- excludeFota: (aConditions &
- Ci.nsINetworkInterfaceListService.
- LIST_NOT_INCLUDE_FOTA_INTERFACES) != 0
- }
- )[0]);
- }
-};
-
-function FakeNetworkInfo(aAttributes) {
- this.state = aAttributes.state;
- this.type = aAttributes.type;
- this.name = aAttributes.name;
- this.ips = aAttributes.ips;
- this.prefixLengths = aAttributes.prefixLengths;
- this.gateways = aAttributes.gateways;
- this.dnses = aAttributes.dnses;
-}
-FakeNetworkInfo.prototype = {
- QueryInterface: XPCOMUtils.generateQI([Ci.nsINetworkInfo]),
-
- 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();
- }
-};
-
-function NetworkInterfaceList (aInterfaceLiterals) {
- this._interfaces = [];
- for (let entry of aInterfaceLiterals) {
- this._interfaces.push(new FakeNetworkInfo(entry));
- }
-}
-
-NetworkInterfaceList.prototype = {
- QueryInterface: XPCOMUtils.generateQI([Ci.nsINetworkInterfaceList]),
-
- getNumberOfInterface: function() {
- return this._interfaces.length;
- },
-
- getInterfaceInfo: function(index) {
- if (!this._interfaces) {
- return null;
- }
- return this._interfaces[index];
- }
-};
-
-this.NSGetFactory = XPCOMUtils.generateNSGetFactory([NetworkInterfaceListService]);
-
diff --git a/dom/system/gonk/NetworkInterfaceListService.manifest b/dom/system/gonk/NetworkInterfaceListService.manifest
deleted file mode 100644
index a827e778f5..0000000000
--- a/dom/system/gonk/NetworkInterfaceListService.manifest
+++ /dev/null
@@ -1,17 +0,0 @@
-# Copyright 2012 Mozilla Foundation and Mozilla contributors
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-# NetworkInterfaceListService.js
-component {3780be6e-7012-4e53-ade6-15212fb88a0d} NetworkInterfaceListService.js
-contract @mozilla.org/network/interface-list-service;1 {3780be6e-7012-4e53-ade6-15212fb88a0d}
diff --git a/dom/system/gonk/NetworkManager.js b/dom/system/gonk/NetworkManager.js
deleted file mode 100644
index 9d7a5683e8..0000000000
--- a/dom/system/gonk/NetworkManager.js
+++ /dev/null
@@ -1,1219 +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/FileUtils.jsm");
-Cu.import("resource://gre/modules/systemlibs.js");
-Cu.import("resource://gre/modules/Promise.jsm");
-
-const NETWORKMANAGER_CONTRACTID = "@mozilla.org/network/manager;1";
-const NETWORKMANAGER_CID =
- Components.ID("{1ba9346b-53b5-4660-9dc6-58f0b258d0a6}");
-
-const DEFAULT_PREFERRED_NETWORK_TYPE = Ci.nsINetworkInterface.NETWORK_TYPE_ETHERNET;
-
-XPCOMUtils.defineLazyGetter(this, "ppmm", function() {
- return Cc["@mozilla.org/parentprocessmessagemanager;1"]
- .getService(Ci.nsIMessageBroadcaster);
-});
-
-XPCOMUtils.defineLazyServiceGetter(this, "gDNSService",
- "@mozilla.org/network/dns-service;1",
- "nsIDNSService");
-
-XPCOMUtils.defineLazyServiceGetter(this, "gNetworkService",
- "@mozilla.org/network/service;1",
- "nsINetworkService");
-
-XPCOMUtils.defineLazyServiceGetter(this, "gTetheringService",
- "@mozilla.org/tethering/service;1",
- "nsITetheringService");
-
-const TOPIC_INTERFACE_REGISTERED = "network-interface-registered";
-const TOPIC_INTERFACE_UNREGISTERED = "network-interface-unregistered";
-const TOPIC_ACTIVE_CHANGED = "network-active-changed";
-const TOPIC_PREF_CHANGED = "nsPref:changed";
-const TOPIC_XPCOM_SHUTDOWN = "xpcom-shutdown";
-const TOPIC_CONNECTION_STATE_CHANGED = "network-connection-state-changed";
-const PREF_MANAGE_OFFLINE_STATUS = "network.gonk.manage-offline-status";
-const PREF_NETWORK_DEBUG_ENABLED = "network.debugging.enabled";
-
-const IPV4_ADDRESS_ANY = "0.0.0.0";
-const IPV6_ADDRESS_ANY = "::0";
-
-const IPV4_MAX_PREFIX_LENGTH = 32;
-const IPV6_MAX_PREFIX_LENGTH = 128;
-
-// Connection Type for Network Information API
-const CONNECTION_TYPE_CELLULAR = 0;
-const CONNECTION_TYPE_BLUETOOTH = 1;
-const CONNECTION_TYPE_ETHERNET = 2;
-const CONNECTION_TYPE_WIFI = 3;
-const CONNECTION_TYPE_OTHER = 4;
-const CONNECTION_TYPE_NONE = 5;
-
-const MANUAL_PROXY_CONFIGURATION = 1;
-
-var 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("-*- NetworkManager: " + s + "\n");
- };
- } else {
- debug = function(s) {};
- }
-}
-updateDebug();
-
-function defineLazyRegExp(obj, name, pattern) {
- obj.__defineGetter__(name, function() {
- delete obj[name];
- return obj[name] = new RegExp(pattern);
- });
-}
-
-function ExtraNetworkInfo(aNetwork) {
- let ips = {};
- let prefixLengths = {};
- aNetwork.info.getAddresses(ips, prefixLengths);
-
- this.state = aNetwork.info.state;
- this.type = aNetwork.info.type;
- this.name = aNetwork.info.name;
- this.ips = ips.value;
- this.prefixLengths = prefixLengths.value;
- this.gateways = aNetwork.info.getGateways();
- this.dnses = aNetwork.info.getDnses();
- this.httpProxyHost = aNetwork.httpProxyHost;
- this.httpProxyPort = aNetwork.httpProxyPort;
- this.mtu = aNetwork.mtu;
-}
-ExtraNetworkInfo.prototype = {
- getAddresses: function(aIps, aPrefixLengths) {
- aIps.value = this.ips.slice();
- aPrefixLengths.value = this.prefixLengths.slice();
-
- return this.ips.length;
- },
-
- getGateways: function(aCount) {
- if (aCount) {
- aCount.value = this.gateways.length;
- }
-
- return this.gateways.slice();
- },
-
- getDnses: function(aCount) {
- if (aCount) {
- aCount.value = this.dnses.length;
- }
-
- return this.dnses.slice();
- }
-};
-
-function NetworkInterfaceLinks()
-{
- this.resetLinks();
-}
-NetworkInterfaceLinks.prototype = {
- linkRoutes: null,
- gateways: null,
- interfaceName: null,
- extraRoutes: null,
-
- setLinks: function(linkRoutes, gateways, interfaceName) {
- this.linkRoutes = linkRoutes;
- this.gateways = gateways;
- this.interfaceName = interfaceName;
- },
-
- resetLinks: function() {
- this.linkRoutes = [];
- this.gateways = [];
- this.interfaceName = "";
- this.extraRoutes = [];
- },
-
- compareGateways: function(gateways) {
- if (this.gateways.length != gateways.length) {
- return false;
- }
-
- for (let i = 0; i < this.gateways.length; i++) {
- if (this.gateways[i] != gateways[i]) {
- return false;
- }
- }
-
- return true;
- }
-};
-
-/**
- * This component watches for network interfaces changing state and then
- * adjusts routes etc. accordingly.
- */
-function NetworkManager() {
- this.networkInterfaces = {};
- this.networkInterfaceLinks = {};
-
- try {
- this._manageOfflineStatus =
- Services.prefs.getBoolPref(PREF_MANAGE_OFFLINE_STATUS);
- } catch(ex) {
- // Ignore.
- }
- Services.prefs.addObserver(PREF_MANAGE_OFFLINE_STATUS, this, false);
- Services.prefs.addObserver(PREF_NETWORK_DEBUG_ENABLED, this, false);
- Services.obs.addObserver(this, TOPIC_XPCOM_SHUTDOWN, false);
-
- this.setAndConfigureActive();
-
- ppmm.addMessageListener('NetworkInterfaceList:ListInterface', this);
-
- // Used in resolveHostname().
- defineLazyRegExp(this, "REGEXP_IPV4", "^\\d{1,3}(?:\\.\\d{1,3}){3}$");
- defineLazyRegExp(this, "REGEXP_IPV6", "^[\\da-fA-F]{4}(?::[\\da-fA-F]{4}){7}$");
-}
-NetworkManager.prototype = {
- classID: NETWORKMANAGER_CID,
- classInfo: XPCOMUtils.generateCI({classID: NETWORKMANAGER_CID,
- contractID: NETWORKMANAGER_CONTRACTID,
- classDescription: "Network Manager",
- interfaces: [Ci.nsINetworkManager]}),
- QueryInterface: XPCOMUtils.generateQI([Ci.nsINetworkManager,
- Ci.nsISupportsWeakReference,
- Ci.nsIObserver,
- Ci.nsISettingsServiceCallback]),
-
- // nsIObserver
-
- observe: function(subject, topic, data) {
- switch (topic) {
- case TOPIC_PREF_CHANGED:
- if (data === PREF_NETWORK_DEBUG_ENABLED) {
- updateDebug();
- } else if (data === PREF_MANAGE_OFFLINE_STATUS) {
- this._manageOfflineStatus =
- Services.prefs.getBoolPref(PREF_MANAGE_OFFLINE_STATUS);
- debug(PREF_MANAGE_OFFLINE_STATUS + " has changed to " + this._manageOfflineStatus);
- }
- break;
- case TOPIC_XPCOM_SHUTDOWN:
- Services.obs.removeObserver(this, TOPIC_XPCOM_SHUTDOWN);
- Services.prefs.removeObserver(PREF_MANAGE_OFFLINE_STATUS, this);
- Services.prefs.removeObserver(PREF_NETWORK_DEBUG_ENABLED, this);
- break;
- }
- },
-
- receiveMessage: function(aMsg) {
- switch (aMsg.name) {
- case "NetworkInterfaceList:ListInterface": {
- let excludeMms = aMsg.json.excludeMms;
- let excludeSupl = aMsg.json.excludeSupl;
- let excludeIms = aMsg.json.excludeIms;
- let excludeDun = aMsg.json.excludeDun;
- let excludeFota = aMsg.json.excludeFota;
- let interfaces = [];
-
- for (let key in this.networkInterfaces) {
- let network = this.networkInterfaces[key];
- let i = network.info;
- if ((i.type == Ci.nsINetworkInfo.NETWORK_TYPE_MOBILE_MMS && excludeMms) ||
- (i.type == Ci.nsINetworkInfo.NETWORK_TYPE_MOBILE_SUPL && excludeSupl) ||
- (i.type == Ci.nsINetworkInfo.NETWORK_TYPE_MOBILE_IMS && excludeIms) ||
- (i.type == Ci.nsINetworkInfo.NETWORK_TYPE_MOBILE_DUN && excludeDun) ||
- (i.type == Ci.nsINetworkInfo.NETWORK_TYPE_MOBILE_FOTA && excludeFota)) {
- continue;
- }
-
- let ips = {};
- let prefixLengths = {};
- i.getAddresses(ips, prefixLengths);
-
- interfaces.push({
- state: i.state,
- type: i.type,
- name: i.name,
- ips: ips.value,
- prefixLengths: prefixLengths.value,
- gateways: i.getGateways(),
- dnses: i.getDnses()
- });
- }
- return interfaces;
- }
- }
- },
-
- getNetworkId: function(aNetworkInfo) {
- let id = "device";
- try {
- if (aNetworkInfo instanceof Ci.nsIRilNetworkInfo) {
- let rilInfo = aNetworkInfo.QueryInterface(Ci.nsIRilNetworkInfo);
- id = "ril" + rilInfo.serviceId;
- }
- } catch (e) {}
-
- return id + "-" + aNetworkInfo.type;
- },
-
- // nsINetworkManager
-
- registerNetworkInterface: function(network) {
- if (!(network instanceof Ci.nsINetworkInterface)) {
- throw Components.Exception("Argument must be nsINetworkInterface.",
- Cr.NS_ERROR_INVALID_ARG);
- }
- let networkId = this.getNetworkId(network.info);
- if (networkId in this.networkInterfaces) {
- throw Components.Exception("Network with that type already registered!",
- Cr.NS_ERROR_INVALID_ARG);
- }
- this.networkInterfaces[networkId] = network;
- this.networkInterfaceLinks[networkId] = new NetworkInterfaceLinks();
-
- Services.obs.notifyObservers(network.info, TOPIC_INTERFACE_REGISTERED, null);
- debug("Network '" + networkId + "' registered.");
- },
-
- _addSubnetRoutes: function(network) {
- let ips = {};
- let prefixLengths = {};
- let length = network.getAddresses(ips, prefixLengths);
- let promises = [];
-
- for (let i = 0; i < length; i++) {
- debug('Adding subnet routes: ' + ips.value[i] + '/' + prefixLengths.value[i]);
- promises.push(
- gNetworkService.modifyRoute(Ci.nsINetworkService.MODIFY_ROUTE_ADD,
- network.name, ips.value[i], prefixLengths.value[i])
- .catch(aError => {
- debug("_addSubnetRoutes error: " + aError);
- }));
- }
-
- return Promise.all(promises);
- },
-
- updateNetworkInterface: function(network) {
- if (!(network instanceof Ci.nsINetworkInterface)) {
- throw Components.Exception("Argument must be nsINetworkInterface.",
- Cr.NS_ERROR_INVALID_ARG);
- }
- let networkId = this.getNetworkId(network.info);
- if (!(networkId in this.networkInterfaces)) {
- throw Components.Exception("No network with that type registered.",
- Cr.NS_ERROR_INVALID_ARG);
- }
- debug("Network " + network.info.type + "/" + network.info.name +
- " changed state to " + network.info.state);
-
- // Keep a copy of network in case it is modified while we are updating.
- let extNetworkInfo = new ExtraNetworkInfo(network);
-
- // Note that since Lollipop we need to allocate and initialize
- // something through netd, so we add createNetwork/destroyNetwork
- // to deal with that explicitly.
-
- switch (extNetworkInfo.state) {
- case Ci.nsINetworkInfo.NETWORK_STATE_CONNECTED:
-
- this._createNetwork(extNetworkInfo.name)
- // Remove pre-created default route and let setAndConfigureActive()
- // to set default route only on preferred network
- .then(() => this._removeDefaultRoute(extNetworkInfo))
- // Set DNS server as early as possible to prevent from
- // premature domain name lookup.
- .then(() => this._setDNS(extNetworkInfo))
- .then(() => {
- // Add host route for data calls
- if (!this.isNetworkTypeMobile(extNetworkInfo.type)) {
- return;
- }
-
- let currentInterfaceLinks = this.networkInterfaceLinks[networkId];
- let newLinkRoutes = extNetworkInfo.getDnses().concat(
- extNetworkInfo.httpProxyHost);
- // If gateways have changed, remove all old routes first.
- return this._handleGateways(networkId, extNetworkInfo.getGateways())
- .then(() => this._updateRoutes(currentInterfaceLinks.linkRoutes,
- newLinkRoutes,
- extNetworkInfo.getGateways(),
- extNetworkInfo.name))
- .then(() => currentInterfaceLinks.setLinks(newLinkRoutes,
- extNetworkInfo.getGateways(),
- extNetworkInfo.name));
- })
- .then(() => {
- if (extNetworkInfo.type !=
- Ci.nsINetworkInfo.NETWORK_TYPE_MOBILE_DUN) {
- return;
- }
- // Dun type is a special case where we add the default route to a
- // secondary table.
- return this.setSecondaryDefaultRoute(extNetworkInfo);
- })
- .then(() => this._addSubnetRoutes(extNetworkInfo))
- .then(() => {
- if (extNetworkInfo.mtu <= 0) {
- return;
- }
-
- return this._setMtu(extNetworkInfo);
- })
- .then(() => this.setAndConfigureActive())
- .then(() => {
- // Update data connection when Wifi connected/disconnected
- if (extNetworkInfo.type ==
- Ci.nsINetworkInfo.NETWORK_TYPE_WIFI && this.mRil) {
- for (let i = 0; i < this.mRil.numRadioInterfaces; i++) {
- this.mRil.getRadioInterface(i).updateRILNetworkInterface();
- }
- }
-
- // Probing the public network accessibility after routing table is ready
- CaptivePortalDetectionHelper
- .notify(CaptivePortalDetectionHelper.EVENT_CONNECT,
- this.activeNetworkInfo);
- })
- .then(() => {
- // Notify outer modules like MmsService to start the transaction after
- // the configuration of the network interface is done.
- Services.obs.notifyObservers(network.info,
- TOPIC_CONNECTION_STATE_CHANGED,
- this.convertConnectionType(network.info));
- })
- .catch(aError => {
- debug("updateNetworkInterface error: " + aError);
- });
- break;
- case Ci.nsINetworkInfo.NETWORK_STATE_DISCONNECTED:
- Promise.resolve()
- .then(() => {
- if (!this.isNetworkTypeMobile(extNetworkInfo.type)) {
- return;
- }
- // Remove host route for data calls
- return this._cleanupAllHostRoutes(networkId);
- })
- .then(() => {
- if (extNetworkInfo.type !=
- Ci.nsINetworkInfo.NETWORK_TYPE_MOBILE_DUN) {
- return;
- }
- // Remove secondary default route for dun.
- return this.removeSecondaryDefaultRoute(extNetworkInfo);
- })
- .then(() => {
- if (extNetworkInfo.type == Ci.nsINetworkInfo.NETWORK_TYPE_WIFI ||
- extNetworkInfo.type == Ci.nsINetworkInfo.NETWORK_TYPE_ETHERNET) {
- // Remove routing table in /proc/net/route
- return this._resetRoutingTable(extNetworkInfo.name);
- }
- if (extNetworkInfo.type == Ci.nsINetworkInfo.NETWORK_TYPE_MOBILE) {
- return this._removeDefaultRoute(extNetworkInfo)
- }
- })
- .then(() => {
- // Clear http proxy on active network.
- if (this.activeNetworkInfo &&
- extNetworkInfo.type == this.activeNetworkInfo.type) {
- this.clearNetworkProxy();
- }
-
- // Abort ongoing captive portal detection on the wifi interface
- CaptivePortalDetectionHelper
- .notify(CaptivePortalDetectionHelper.EVENT_DISCONNECT, extNetworkInfo);
- })
- .then(() => this.setAndConfigureActive())
- .then(() => {
- // Update data connection when Wifi connected/disconnected
- if (extNetworkInfo.type ==
- Ci.nsINetworkInfo.NETWORK_TYPE_WIFI && this.mRil) {
- for (let i = 0; i < this.mRil.numRadioInterfaces; i++) {
- this.mRil.getRadioInterface(i).updateRILNetworkInterface();
- }
- }
- })
- .then(() => this._destroyNetwork(extNetworkInfo.name))
- .then(() => {
- // Notify outer modules like MmsService to start the transaction after
- // the configuration of the network interface is done.
- Services.obs.notifyObservers(network.info,
- TOPIC_CONNECTION_STATE_CHANGED,
- this.convertConnectionType(network.info));
- })
- .catch(aError => {
- debug("updateNetworkInterface error: " + aError);
- });
- break;
- }
- },
-
- unregisterNetworkInterface: function(network) {
- if (!(network instanceof Ci.nsINetworkInterface)) {
- throw Components.Exception("Argument must be nsINetworkInterface.",
- Cr.NS_ERROR_INVALID_ARG);
- }
- let networkId = this.getNetworkId(network.info);
- if (!(networkId in this.networkInterfaces)) {
- throw Components.Exception("No network with that type registered.",
- Cr.NS_ERROR_INVALID_ARG);
- }
-
- // This is for in case a network gets unregistered without being
- // DISCONNECTED.
- if (this.isNetworkTypeMobile(network.info.type)) {
- this._cleanupAllHostRoutes(networkId);
- }
-
- delete this.networkInterfaces[networkId];
-
- Services.obs.notifyObservers(network.info, TOPIC_INTERFACE_UNREGISTERED, null);
- debug("Network '" + networkId + "' unregistered.");
- },
-
- _manageOfflineStatus: true,
-
- networkInterfaces: null,
-
- networkInterfaceLinks: null,
-
- _networkTypePriorityList: [Ci.nsINetworkInterface.NETWORK_TYPE_ETHERNET,
- Ci.nsINetworkInterface.NETWORK_TYPE_WIFI,
- Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE],
- get networkTypePriorityList() {
- return this._networkTypePriorityList;
- },
- set networkTypePriorityList(val) {
- if (val.length != this._networkTypePriorityList.length) {
- throw "Priority list length should equal to " +
- this._networkTypePriorityList.length;
- }
-
- // Check if types in new priority list are valid and also make sure there
- // are no duplicate types.
- let list = [Ci.nsINetworkInterface.NETWORK_TYPE_ETHERNET,
- Ci.nsINetworkInterface.NETWORK_TYPE_WIFI,
- Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE];
- while (list.length) {
- let type = list.shift();
- if (val.indexOf(type) == -1) {
- throw "There is missing network type";
- }
- }
-
- this._networkTypePriorityList = val;
- },
-
- getPriority: function(type) {
- if (this._networkTypePriorityList.indexOf(type) == -1) {
- // 0 indicates the lowest priority.
- return 0;
- }
-
- return this._networkTypePriorityList.length -
- this._networkTypePriorityList.indexOf(type);
- },
-
- get allNetworkInfo() {
- let allNetworkInfo = {};
-
- for (let networkId in this.networkInterfaces) {
- if (this.networkInterfaces.hasOwnProperty(networkId)) {
- allNetworkInfo[networkId] = this.networkInterfaces[networkId].info;
- }
- }
-
- return allNetworkInfo;
- },
-
- _preferredNetworkType: DEFAULT_PREFERRED_NETWORK_TYPE,
- get preferredNetworkType() {
- return this._preferredNetworkType;
- },
- set preferredNetworkType(val) {
- if ([Ci.nsINetworkInterface.NETWORK_TYPE_WIFI,
- Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE,
- Ci.nsINetworkInterface.NETWORK_TYPE_ETHERNET].indexOf(val) == -1) {
- throw "Invalid network type";
- }
- this._preferredNetworkType = val;
- },
-
- _activeNetwork: null,
-
- get activeNetworkInfo() {
- return this._activeNetwork && this._activeNetwork.info;
- },
-
- _overriddenActive: null,
-
- overrideActive: function(network) {
- if ([Ci.nsINetworkInterface.NETWORK_TYPE_WIFI,
- Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE,
- Ci.nsINetworkInterface.NETWORK_TYPE_ETHERNET].indexOf(val) == -1) {
- throw "Invalid network type";
- }
-
- this._overriddenActive = network;
- this.setAndConfigureActive();
- },
-
- _updateRoutes: function(oldLinks, newLinks, gateways, interfaceName) {
- // Returns items that are in base but not in target.
- function getDifference(base, target) {
- return base.filter(function(i) { return target.indexOf(i) < 0; });
- }
-
- let addedLinks = getDifference(newLinks, oldLinks);
- let removedLinks = getDifference(oldLinks, newLinks);
-
- if (addedLinks.length === 0 && removedLinks.length === 0) {
- return Promise.resolve();
- }
-
- return this._setHostRoutes(false, removedLinks, interfaceName, gateways)
- .then(this._setHostRoutes(true, addedLinks, interfaceName, gateways));
- },
-
- _setHostRoutes: function(doAdd, ipAddresses, networkName, gateways) {
- let getMaxPrefixLength = (aIp) => {
- return aIp.match(this.REGEXP_IPV4) ? IPV4_MAX_PREFIX_LENGTH : IPV6_MAX_PREFIX_LENGTH;
- }
-
- let promises = [];
-
- ipAddresses.forEach((aIpAddress) => {
- let gateway = this.selectGateway(gateways, aIpAddress);
- if (gateway) {
- promises.push((doAdd)
- ? gNetworkService.modifyRoute(Ci.nsINetworkService.MODIFY_ROUTE_ADD,
- networkName, aIpAddress,
- getMaxPrefixLength(aIpAddress), gateway)
- : gNetworkService.modifyRoute(Ci.nsINetworkService.MODIFY_ROUTE_REMOVE,
- networkName, aIpAddress,
- getMaxPrefixLength(aIpAddress), gateway));
- }
- });
-
- return Promise.all(promises);
- },
-
- isValidatedNetwork: function(aNetworkInfo) {
- let isValid = false;
- try {
- isValid = (this.getNetworkId(aNetworkInfo) in this.networkInterfaces);
- } catch (e) {
- debug("Invalid network interface: " + e);
- }
-
- return isValid;
- },
-
- addHostRoute: function(aNetworkInfo, aHost) {
- if (!this.isValidatedNetwork(aNetworkInfo)) {
- return Promise.reject("Invalid network info.");
- }
-
- return this.resolveHostname(aNetworkInfo, aHost)
- .then((ipAddresses) => {
- let promises = [];
- let networkId = this.getNetworkId(aNetworkInfo);
-
- ipAddresses.forEach((aIpAddress) => {
- let promise =
- this._setHostRoutes(true, [aIpAddress], aNetworkInfo.name, aNetworkInfo.getGateways())
- .then(() => this.networkInterfaceLinks[networkId].extraRoutes.push(aIpAddress));
-
- promises.push(promise);
- });
-
- return Promise.all(promises);
- });
- },
-
- removeHostRoute: function(aNetworkInfo, aHost) {
- if (!this.isValidatedNetwork(aNetworkInfo)) {
- return Promise.reject("Invalid network info.");
- }
-
- return this.resolveHostname(aNetworkInfo, aHost)
- .then((ipAddresses) => {
- let promises = [];
- let networkId = this.getNetworkId(aNetworkInfo);
-
- ipAddresses.forEach((aIpAddress) => {
- let found = this.networkInterfaceLinks[networkId].extraRoutes.indexOf(aIpAddress);
- if (found < 0) {
- return; // continue
- }
-
- let promise =
- this._setHostRoutes(false, [aIpAddress], aNetworkInfo.name, aNetworkInfo.getGateways())
- .then(() => {
- this.networkInterfaceLinks[networkId].extraRoutes.splice(found, 1);
- }, () => {
- // We should remove it even if the operation failed.
- this.networkInterfaceLinks[networkId].extraRoutes.splice(found, 1);
- });
- promises.push(promise);
- });
-
- return Promise.all(promises);
- });
- },
-
- isNetworkTypeSecondaryMobile: function(type) {
- return (type == Ci.nsINetworkInfo.NETWORK_TYPE_MOBILE_MMS ||
- type == Ci.nsINetworkInfo.NETWORK_TYPE_MOBILE_SUPL ||
- type == Ci.nsINetworkInfo.NETWORK_TYPE_MOBILE_IMS ||
- type == Ci.nsINetworkInfo.NETWORK_TYPE_MOBILE_DUN ||
- type == Ci.nsINetworkInfo.NETWORK_TYPE_MOBILE_FOTA);
- },
-
- isNetworkTypeMobile: function(type) {
- return (type == Ci.nsINetworkInfo.NETWORK_TYPE_MOBILE ||
- this.isNetworkTypeSecondaryMobile(type));
- },
-
- _handleGateways: function(networkId, gateways) {
- let currentNetworkLinks = this.networkInterfaceLinks[networkId];
- if (currentNetworkLinks.gateways.length == 0 ||
- currentNetworkLinks.compareGateways(gateways)) {
- return Promise.resolve();
- }
-
- let currentExtraRoutes = currentNetworkLinks.extraRoutes;
- return this._cleanupAllHostRoutes(networkId)
- .then(() => {
- // If gateways have changed, re-add extra host routes with new gateways.
- if (currentExtraRoutes.length > 0) {
- this._setHostRoutes(true,
- currentExtraRoutes,
- currentNetworkLinks.interfaceName,
- gateways)
- .then(() => {
- currentNetworkLinks.extraRoutes = currentExtraRoutes;
- });
- }
- });
- },
-
- _cleanupAllHostRoutes: function(networkId) {
- let currentNetworkLinks = this.networkInterfaceLinks[networkId];
- let hostRoutes = currentNetworkLinks.linkRoutes.concat(
- currentNetworkLinks.extraRoutes);
-
- if (hostRoutes.length === 0) {
- return Promise.resolve();
- }
-
- return this._setHostRoutes(false,
- hostRoutes,
- currentNetworkLinks.interfaceName,
- currentNetworkLinks.gateways)
- .catch((aError) => {
- debug("Error (" + aError + ") on _cleanupAllHostRoutes, keep proceeding.");
- })
- .then(() => currentNetworkLinks.resetLinks());
- },
-
- selectGateway: function(gateways, host) {
- for (let i = 0; i < gateways.length; i++) {
- let gateway = gateways[i];
- if (gateway.match(this.REGEXP_IPV4) && host.match(this.REGEXP_IPV4) ||
- gateway.indexOf(":") != -1 && host.indexOf(":") != -1) {
- return gateway;
- }
- }
- return null;
- },
-
- _setSecondaryRoute: function(aDoAdd, aInterfaceName, aRoute) {
- return new Promise((aResolve, aReject) => {
- if (aDoAdd) {
- gNetworkService.addSecondaryRoute(aInterfaceName, aRoute,
- (aSuccess) => {
- if (!aSuccess) {
- aReject("addSecondaryRoute failed");
- return;
- }
- aResolve();
- });
- } else {
- gNetworkService.removeSecondaryRoute(aInterfaceName, aRoute,
- (aSuccess) => {
- if (!aSuccess) {
- debug("removeSecondaryRoute failed")
- }
- // Always resolve.
- aResolve();
- });
- }
- });
- },
-
- setSecondaryDefaultRoute: function(network) {
- let gateways = network.getGateways();
- let promises = [];
-
- for (let i = 0; i < gateways.length; i++) {
- let isIPv6 = (gateways[i].indexOf(":") != -1) ? true : false;
- // First, we need to add a host route to the gateway in the secondary
- // routing table to make the gateway reachable. Host route takes the max
- // prefix and gateway address 'any'.
- let hostRoute = {
- ip: gateways[i],
- prefix: isIPv6 ? IPV6_MAX_PREFIX_LENGTH : IPV4_MAX_PREFIX_LENGTH,
- gateway: isIPv6 ? IPV6_ADDRESS_ANY : IPV4_ADDRESS_ANY
- };
- // Now we can add the default route through gateway. Default route takes the
- // min prefix and destination ip 'any'.
- let defaultRoute = {
- ip: isIPv6 ? IPV6_ADDRESS_ANY : IPV4_ADDRESS_ANY,
- prefix: 0,
- gateway: gateways[i]
- };
-
- let promise = this._setSecondaryRoute(true, network.name, hostRoute)
- .then(() => this._setSecondaryRoute(true, network.name, defaultRoute));
-
- promises.push(promise);
- }
-
- return Promise.all(promises);
- },
-
- removeSecondaryDefaultRoute: function(network) {
- let gateways = network.getGateways();
- let promises = [];
-
- for (let i = 0; i < gateways.length; i++) {
- let isIPv6 = (gateways[i].indexOf(":") != -1) ? true : false;
- // Remove both default route and host route.
- let defaultRoute = {
- ip: isIPv6 ? IPV6_ADDRESS_ANY : IPV4_ADDRESS_ANY,
- prefix: 0,
- gateway: gateways[i]
- };
- let hostRoute = {
- ip: gateways[i],
- prefix: isIPv6 ? IPV6_MAX_PREFIX_LENGTH : IPV4_MAX_PREFIX_LENGTH,
- gateway: isIPv6 ? IPV6_ADDRESS_ANY : IPV4_ADDRESS_ANY
- };
-
- let promise = this._setSecondaryRoute(false, network.name, defaultRoute)
- .then(() => this._setSecondaryRoute(false, network.name, hostRoute));
-
- promises.push(promise);
- }
-
- return Promise.all(promises);
- },
-
- /**
- * Determine the active interface and configure it.
- */
- setAndConfigureActive: function() {
- debug("Evaluating whether active network needs to be changed.");
- let oldActive = this._activeNetwork;
-
- if (this._overriddenActive) {
- debug("We have an override for the active network: " +
- this._overriddenActive.info.name);
- // The override was just set, so reconfigure the network.
- if (this._activeNetwork != this._overriddenActive) {
- this._activeNetwork = this._overriddenActive;
- this._setDefaultRouteAndProxy(this._activeNetwork, oldActive);
- Services.obs.notifyObservers(this.activeNetworkInfo,
- TOPIC_ACTIVE_CHANGED, null);
- }
- return;
- }
-
- // The active network is already our preferred type.
- if (this.activeNetworkInfo &&
- this.activeNetworkInfo.state == Ci.nsINetworkInfo.NETWORK_STATE_CONNECTED &&
- this.activeNetworkInfo.type == this._preferredNetworkType) {
- debug("Active network is already our preferred type.");
- return this._setDefaultRouteAndProxy(this._activeNetwork, oldActive);
- }
-
- // Find a suitable network interface to activate.
- this._activeNetwork = null;
- let anyConnected = false;
-
- for (let key in this.networkInterfaces) {
- let network = this.networkInterfaces[key];
- if (network.info.state != Ci.nsINetworkInfo.NETWORK_STATE_CONNECTED) {
- continue;
- }
- anyConnected = true;
-
- // Set active only for default connections.
- if (network.info.type != Ci.nsINetworkInfo.NETWORK_TYPE_WIFI &&
- network.info.type != Ci.nsINetworkInfo.NETWORK_TYPE_MOBILE &&
- network.info.type != Ci.nsINetworkInfo.NETWORK_TYPE_ETHERNET) {
- continue;
- }
-
- if (network.info.type == this.preferredNetworkType) {
- this._activeNetwork = network;
- debug("Found our preferred type of network: " + network.info.name);
- break;
- }
-
- // Initialize the active network with the first connected network.
- if (!this._activeNetwork) {
- this._activeNetwork = network;
- continue;
- }
-
- // Compare the prioriy between two network types. If found incoming
- // network with higher priority, replace the active network.
- if (this.getPriority(this._activeNetwork.type) < this.getPriority(network.type)) {
- this._activeNetwork = network;
- }
- }
-
- return Promise.resolve()
- .then(() => {
- if (!this._activeNetwork) {
- return Promise.resolve();
- }
-
- return this._setDefaultRouteAndProxy(this._activeNetwork, oldActive);
- })
- .then(() => {
- if (this._activeNetwork != oldActive) {
- Services.obs.notifyObservers(this.activeNetworkInfo,
- TOPIC_ACTIVE_CHANGED, null);
- }
-
- if (this._manageOfflineStatus) {
- Services.io.offline = !anyConnected &&
- (gTetheringService.state ===
- Ci.nsITetheringService.TETHERING_STATE_INACTIVE);
- }
- });
- },
-
- resolveHostname: function(aNetworkInfo, aHostname) {
- // Sanity check for null, undefined and empty string... etc.
- if (!aHostname) {
- return Promise.reject(new Error("hostname is empty: " + aHostname));
- }
-
- if (aHostname.match(this.REGEXP_IPV4) ||
- aHostname.match(this.REGEXP_IPV6)) {
- return Promise.resolve([aHostname]);
- }
-
- // Wrap gDNSService.asyncResolveExtended to a promise, which
- // resolves with an array of ip addresses or rejects with
- // the reason otherwise.
- let hostResolveWrapper = aNetId => {
- return new Promise((aResolve, aReject) => {
- // Callback for gDNSService.asyncResolveExtended.
- let onLookupComplete = (aRequest, aRecord, aStatus) => {
- if (!Components.isSuccessCode(aStatus)) {
- aReject(new Error("Failed to resolve '" + aHostname +
- "', with status: " + aStatus));
- return;
- }
-
- let retval = [];
- while (aRecord.hasMore()) {
- retval.push(aRecord.getNextAddrAsString());
- }
-
- if (!retval.length) {
- aReject(new Error("No valid address after DNS lookup!"));
- return;
- }
-
- debug("hostname is resolved: " + aHostname);
- debug("Addresses: " + JSON.stringify(retval));
-
- aResolve(retval);
- };
-
- debug('Calling gDNSService.asyncResolveExtended: ' + aNetId + ', ' + aHostname);
- gDNSService.asyncResolveExtended(aHostname,
- 0,
- aNetId,
- onLookupComplete,
- Services.tm.mainThread);
- });
- };
-
- // TODO: |getNetId| will be implemented as a sync call in nsINetworkManager
- // once Bug 1141903 is landed.
- return gNetworkService.getNetId(aNetworkInfo.name)
- .then(aNetId => hostResolveWrapper(aNetId));
- },
-
- convertConnectionType: function(aNetworkInfo) {
- // If there is internal interface change (e.g., MOBILE_MMS, MOBILE_SUPL),
- // the function will return null so that it won't trigger type change event
- // in NetworkInformation API.
- if (aNetworkInfo.type != Ci.nsINetworkInterface.NETWORK_TYPE_WIFI &&
- aNetworkInfo.type != Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE &&
- aNetworkInfo.type != Ci.nsINetworkInterface.NETWORK_TYPE_ETHERNET) {
- return null;
- }
-
- if (aNetworkInfo.state == Ci.nsINetworkInfo.NETWORK_STATE_DISCONNECTED) {
- return CONNECTION_TYPE_NONE;
- }
-
- switch (aNetworkInfo.type) {
- case Ci.nsINetworkInfo.NETWORK_TYPE_WIFI:
- return CONNECTION_TYPE_WIFI;
- case Ci.nsINetworkInfo.NETWORK_TYPE_MOBILE:
- return CONNECTION_TYPE_CELLULAR;
- case Ci.nsINetworkInterface.NETWORK_TYPE_ETHERNET:
- return CONNECTION_TYPE_ETHERNET;
- }
- },
-
- _setDNS: function(aNetworkInfo) {
- return new Promise((aResolve, aReject) => {
- let dnses = aNetworkInfo.getDnses();
- let gateways = aNetworkInfo.getGateways();
- gNetworkService.setDNS(aNetworkInfo.name, dnses.length, dnses,
- gateways.length, gateways, (aError) => {
- if (aError) {
- aReject("setDNS failed");
- return;
- }
- aResolve();
- });
- });
- },
-
- _setMtu: function(aNetworkInfo) {
- return new Promise((aResolve, aReject) => {
- gNetworkService.setMtu(aNetworkInfo.name, aNetworkInfo.mtu, (aSuccess) => {
- if (!aSuccess) {
- debug("setMtu failed");
- }
- // Always resolve.
- aResolve();
- });
- });
- },
-
- _createNetwork: function(aInterfaceName) {
- return new Promise((aResolve, aReject) => {
- gNetworkService.createNetwork(aInterfaceName, (aSuccess) => {
- if (!aSuccess) {
- aReject("createNetwork failed");
- return;
- }
- aResolve();
- });
- });
- },
-
- _destroyNetwork: function(aInterfaceName) {
- return new Promise((aResolve, aReject) => {
- gNetworkService.destroyNetwork(aInterfaceName, (aSuccess) => {
- if (!aSuccess) {
- debug("destroyNetwork failed")
- }
- // Always resolve.
- aResolve();
- });
- });
- },
-
- _resetRoutingTable: function(aInterfaceName) {
- return new Promise((aResolve, aReject) => {
- gNetworkService.resetRoutingTable(aInterfaceName, (aSuccess) => {
- if (!aSuccess) {
- debug("resetRoutingTable failed");
- }
- // Always resolve.
- aResolve();
- });
- });
- },
-
- _removeDefaultRoute: function(aNetworkInfo) {
- return new Promise((aResolve, aReject) => {
- let gateways = aNetworkInfo.getGateways();
- gNetworkService.removeDefaultRoute(aNetworkInfo.name, gateways.length,
- gateways, (aSuccess) => {
- if (!aSuccess) {
- debug("removeDefaultRoute failed");
- }
- // Always resolve.
- aResolve();
- });
- });
- },
-
- _setDefaultRouteAndProxy: function(aNetwork, aOldNetwork) {
- if (aOldNetwork) {
- return this._removeDefaultRoute(aOldNetwork.info)
- .then(() => this._setDefaultRouteAndProxy(aNetwork, null));
- }
-
- return new Promise((aResolve, aReject) => {
- let networkInfo = aNetwork.info;
- let gateways = networkInfo.getGateways();
-
- gNetworkService.setDefaultRoute(networkInfo.name, gateways.length, gateways,
- (aSuccess) => {
- if (!aSuccess) {
- gNetworkService.destroyNetwork(networkInfo.name, function() {
- aReject("setDefaultRoute failed");
- });
- return;
- }
- this.setNetworkProxy(aNetwork);
- aResolve();
- });
- });
- },
-
- setNetworkProxy: function(aNetwork) {
- try {
- if (!aNetwork.httpProxyHost || aNetwork.httpProxyHost === "") {
- // Sets direct connection to internet.
- this.clearNetworkProxy();
-
- debug("No proxy support for " + aNetwork.info.name + " network interface.");
- return;
- }
-
- debug("Going to set proxy settings for " + aNetwork.info.name + " network interface.");
- // Sets manual proxy configuration.
- Services.prefs.setIntPref("network.proxy.type", MANUAL_PROXY_CONFIGURATION);
-
- // Do not use this proxy server for all protocols.
- Services.prefs.setBoolPref("network.proxy.share_proxy_settings", false);
- Services.prefs.setCharPref("network.proxy.http", aNetwork.httpProxyHost);
- Services.prefs.setCharPref("network.proxy.ssl", aNetwork.httpProxyHost);
- let port = aNetwork.httpProxyPort === 0 ? 8080 : aNetwork.httpProxyPort;
- Services.prefs.setIntPref("network.proxy.http_port", port);
- Services.prefs.setIntPref("network.proxy.ssl_port", port);
- } catch(ex) {
- debug("Exception " + ex + ". Unable to set proxy setting for " +
- aNetwork.info.name + " network interface.");
- }
- },
-
- clearNetworkProxy: function() {
- debug("Going to clear all network proxy.");
-
- Services.prefs.clearUserPref("network.proxy.type");
- Services.prefs.clearUserPref("network.proxy.share_proxy_settings");
- Services.prefs.clearUserPref("network.proxy.http");
- Services.prefs.clearUserPref("network.proxy.http_port");
- Services.prefs.clearUserPref("network.proxy.ssl");
- Services.prefs.clearUserPref("network.proxy.ssl_port");
- },
-};
-
-var CaptivePortalDetectionHelper = (function() {
-
- const EVENT_CONNECT = "Connect";
- const EVENT_DISCONNECT = "Disconnect";
- let _ongoingInterface = null;
- let _available = ("nsICaptivePortalDetector" in Ci);
- let getService = function() {
- return Cc['@mozilla.org/toolkit/captive-detector;1']
- .getService(Ci.nsICaptivePortalDetector);
- };
-
- let _performDetection = function(interfaceName, callback) {
- let capService = getService();
- let capCallback = {
- QueryInterface: XPCOMUtils.generateQI([Ci.nsICaptivePortalCallback]),
- prepare: function() {
- capService.finishPreparation(interfaceName);
- },
- complete: function(success) {
- _ongoingInterface = null;
- callback(success);
- }
- };
-
- // Abort any unfinished captive portal detection.
- if (_ongoingInterface != null) {
- capService.abort(_ongoingInterface);
- _ongoingInterface = null;
- }
- try {
- capService.checkCaptivePortal(interfaceName, capCallback);
- _ongoingInterface = interfaceName;
- } catch (e) {
- debug('Fail to detect captive portal due to: ' + e.message);
- }
- };
-
- let _abort = function(interfaceName) {
- if (_ongoingInterface !== interfaceName) {
- return;
- }
-
- let capService = getService();
- capService.abort(_ongoingInterface);
- _ongoingInterface = null;
- };
-
- return {
- EVENT_CONNECT: EVENT_CONNECT,
- EVENT_DISCONNECT: EVENT_DISCONNECT,
- notify: function(eventType, network) {
- switch (eventType) {
- case EVENT_CONNECT:
- // perform captive portal detection on wifi interface
- if (_available && network &&
- network.type == Ci.nsINetworkInfo.NETWORK_TYPE_WIFI) {
- _performDetection(network.name, function() {
- // TODO: bug 837600
- // We can disconnect wifi in here if user abort the login procedure.
- });
- }
-
- break;
- case EVENT_DISCONNECT:
- if (_available &&
- network.type == Ci.nsINetworkInfo.NETWORK_TYPE_WIFI) {
- _abort(network.name);
- }
- break;
- }
- }
- };
-}());
-
-XPCOMUtils.defineLazyGetter(NetworkManager.prototype, "mRil", function() {
- try {
- return Cc["@mozilla.org/ril;1"].getService(Ci.nsIRadioInterfaceLayer);
- } catch (e) {}
-
- return null;
-});
-
-this.NSGetFactory = XPCOMUtils.generateNSGetFactory([NetworkManager]);
diff --git a/dom/system/gonk/NetworkManager.manifest b/dom/system/gonk/NetworkManager.manifest
deleted file mode 100644
index 995fa65598..0000000000
--- a/dom/system/gonk/NetworkManager.manifest
+++ /dev/null
@@ -1,3 +0,0 @@
-# NetworkManager.js
-component {1ba9346b-53b5-4660-9dc6-58f0b258d0a6} NetworkManager.js
-contract @mozilla.org/network/manager;1 {1ba9346b-53b5-4660-9dc6-58f0b258d0a6}
diff --git a/dom/system/gonk/NetworkService.js b/dom/system/gonk/NetworkService.js
deleted file mode 100644
index 7147f40c72..0000000000
--- a/dom/system/gonk/NetworkService.js
+++ /dev/null
@@ -1,862 +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/NetUtil.jsm");
-Cu.import("resource://gre/modules/FileUtils.jsm");
-Cu.import("resource://gre/modules/Promise.jsm");
-
-const NETWORKSERVICE_CONTRACTID = "@mozilla.org/network/service;1";
-const NETWORKSERVICE_CID = Components.ID("{48c13741-aec9-4a86-8962-432011708261}");
-
-const TOPIC_PREF_CHANGED = "nsPref:changed";
-const TOPIC_XPCOM_SHUTDOWN = "xpcom-shutdown";
-const PREF_NETWORK_DEBUG_ENABLED = "network.debugging.enabled";
-
-XPCOMUtils.defineLazyServiceGetter(this, "gNetworkWorker",
- "@mozilla.org/network/worker;1",
- "nsINetworkWorker");
-
-// 1xx - Requested action is proceeding
-const NETD_COMMAND_PROCEEDING = 100;
-// 2xx - Requested action has been successfully completed
-const NETD_COMMAND_OKAY = 200;
-// 4xx - The command is accepted but the requested action didn't
-// take place.
-const NETD_COMMAND_FAIL = 400;
-// 5xx - The command syntax or parameters error
-const NETD_COMMAND_ERROR = 500;
-// 6xx - Unsolicited broadcasts
-const NETD_COMMAND_UNSOLICITED = 600;
-
-const WIFI_CTRL_INTERFACE = "wl0.1";
-
-var 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("-*- NetworkService: " + s + "\n");
- };
- } else {
- debug = function(s) {};
- }
-}
-updateDebug();
-
-function netdResponseType(aCode) {
- return Math.floor(aCode / 100) * 100;
-}
-
-function isError(aCode) {
- let type = netdResponseType(aCode);
- return (type !== NETD_COMMAND_PROCEEDING && type !== NETD_COMMAND_OKAY);
-}
-
-function Task(aId, aParams, aSetupFunction) {
- this.id = aId;
- this.params = aParams;
- this.setupFunction = aSetupFunction;
-}
-
-function NetworkWorkerRequestQueue(aNetworkService) {
- this.networkService = aNetworkService;
- this.tasks = [];
-}
-NetworkWorkerRequestQueue.prototype = {
- runQueue: function() {
- if (this.tasks.length === 0) {
- return;
- }
-
- let task = this.tasks[0];
- debug("run task id: " + task.id);
-
- if (typeof task.setupFunction === 'function') {
- // If setupFunction returns false, skip sending to Network Worker but call
- // handleWorkerMessage() directly with task id, as if the response was
- // returned from Network Worker.
- if (!task.setupFunction()) {
- this.networkService.handleWorkerMessage({id: task.id});
- return;
- }
- }
-
- gNetworkWorker.postMessage(task.params);
- },
-
- enqueue: function(aId, aParams, aSetupFunction) {
- debug("enqueue id: " + aId);
- this.tasks.push(new Task(aId, aParams, aSetupFunction));
-
- if (this.tasks.length === 1) {
- this.runQueue();
- }
- },
-
- dequeue: function(aId) {
- debug("dequeue id: " + aId);
-
- if (!this.tasks.length || this.tasks[0].id != aId) {
- debug("Id " + aId + " is not on top of the queue");
- return;
- }
-
- this.tasks.shift();
- if (this.tasks.length > 0) {
- // Run queue on the next tick.
- Services.tm.currentThread.dispatch(() => {
- this.runQueue();
- }, Ci.nsIThread.DISPATCH_NORMAL);
- }
- }
-};
-
-
-/**
- * This component watches for network interfaces changing state and then
- * adjusts routes etc. accordingly.
- */
-function NetworkService() {
- debug("Starting NetworkService.");
-
- let self = this;
-
- if (gNetworkWorker) {
- let networkListener = {
- onEvent: function(aEvent) {
- self.handleWorkerMessage(aEvent);
- }
- };
- gNetworkWorker.start(networkListener);
- }
- // Callbacks to invoke when a reply arrives from the net_worker.
- this.controlCallbacks = Object.create(null);
-
- this.addedRoutes = new Map();
- this.netWorkerRequestQueue = new NetworkWorkerRequestQueue(this);
- this.shutdown = false;
-
- Services.prefs.addObserver(PREF_NETWORK_DEBUG_ENABLED, this, false);
- Services.obs.addObserver(this, TOPIC_XPCOM_SHUTDOWN, false);
-}
-
-NetworkService.prototype = {
- classID: NETWORKSERVICE_CID,
- classInfo: XPCOMUtils.generateCI({classID: NETWORKSERVICE_CID,
- contractID: NETWORKSERVICE_CONTRACTID,
- classDescription: "Network Service",
- interfaces: [Ci.nsINetworkService]}),
- QueryInterface: XPCOMUtils.generateQI([Ci.nsINetworkService,
- Ci.nsIObserver]),
-
- addedRoutes: null,
-
- shutdown: false,
-
- // nsIObserver
-
- observe: function(aSubject, aTopic, aData) {
- switch (aTopic) {
- case TOPIC_PREF_CHANGED:
- if (aData === PREF_NETWORK_DEBUG_ENABLED) {
- updateDebug();
- }
- break;
- case TOPIC_XPCOM_SHUTDOWN:
- debug("NetworkService shutdown");
- this.shutdown = true;
- if (gNetworkWorker) {
- gNetworkWorker.shutdown();
- gNetworkWorker = null;
- }
-
- Services.obs.removeObserver(this, TOPIC_XPCOM_SHUTDOWN);
- Services.prefs.removeObserver(PREF_NETWORK_DEBUG_ENABLED, this);
- break;
- }
- },
-
- // Helpers
-
- idgen: 0,
- controlMessage: function(aParams, aCallback, aSetupFunction) {
- if (this.shutdown) {
- return;
- }
-
- let id = this.idgen++;
- aParams.id = id;
- if (aCallback) {
- this.controlCallbacks[id] = aCallback;
- }
-
- // For now, we use aSetupFunction to determine if this command needs to be
- // queued or not.
- if (aSetupFunction) {
- this.netWorkerRequestQueue.enqueue(id, aParams, aSetupFunction);
- return;
- }
-
- if (gNetworkWorker) {
- gNetworkWorker.postMessage(aParams);
- }
- },
-
- handleWorkerMessage: function(aResponse) {
- debug("NetworkManager received message from worker: " + JSON.stringify(aResponse));
- let id = aResponse.id;
- if (aResponse.broadcast === true) {
- Services.obs.notifyObservers(null, aResponse.topic, aResponse.reason);
- return;
- }
- let callback = this.controlCallbacks[id];
- if (callback) {
- callback.call(this, aResponse);
- delete this.controlCallbacks[id];
- }
-
- this.netWorkerRequestQueue.dequeue(id);
- },
-
- // nsINetworkService
-
- getNetworkInterfaceStats: function(aInterfaceName, aCallback) {
- debug("getNetworkInterfaceStats for " + aInterfaceName);
-
- let file = new FileUtils.File("/proc/net/dev");
- if (!file) {
- aCallback.networkStatsAvailable(false, 0, 0, Date.now());
- return;
- }
-
- NetUtil.asyncFetch({
- uri: NetUtil.newURI(file),
- loadUsingSystemPrincipal: true
- }, function(inputStream, status) {
- let rxBytes = 0,
- txBytes = 0,
- now = Date.now();
-
- if (Components.isSuccessCode(status)) {
- // Find record for corresponding interface.
- let statExpr = /(\S+): +(\d+) +\d+ +\d+ +\d+ +\d+ +\d+ +\d+ +\d+ +(\d+) +\d+ +\d+ +\d+ +\d+ +\d+ +\d+ +\d+/;
- let data =
- NetUtil.readInputStreamToString(inputStream, inputStream.available())
- .split("\n");
- for (let i = 2; i < data.length; i++) {
- let parseResult = statExpr.exec(data[i]);
- if (parseResult && parseResult[1] === aInterfaceName) {
- rxBytes = parseInt(parseResult[2], 10);
- txBytes = parseInt(parseResult[3], 10);
- break;
- }
- }
- }
-
- // netd always return success even interface doesn't exist.
- aCallback.networkStatsAvailable(true, rxBytes, txBytes, now);
- });
- },
-
- setNetworkTetheringAlarm(aEnable, aInterface) {
- // Method called when enabling disabling tethering, it checks if there is
- // some alarm active and move from interfaceAlarm to globalAlarm because
- // interfaceAlarm doens't work in tethering scenario due to forwarding.
- debug("setNetworkTetheringAlarm for tethering" + aEnable);
-
- let filename = aEnable ? "/proc/net/xt_quota/" + aInterface + "Alert" :
- "/proc/net/xt_quota/globalAlert";
-
- let file = new FileUtils.File(filename);
- if (!file) {
- return;
- }
-
- NetUtil.asyncFetch({
- uri: NetUtil.newURI(file),
- loadUsingSystemPrincipal: true
- }, (inputStream, status) => {
- if (Components.isSuccessCode(status)) {
- let data = NetUtil.readInputStreamToString(inputStream, inputStream.available())
- .split("\n");
- if (data) {
- let threshold = parseInt(data[0], 10);
-
- this._setNetworkTetheringAlarm(aEnable, aInterface, threshold);
- }
- }
- });
- },
-
- _setNetworkTetheringAlarm(aEnable, aInterface, aThreshold, aCallback) {
- debug("_setNetworkTetheringAlarm for tethering" + aEnable);
-
- let cmd = aEnable ? "setTetheringAlarm" : "removeTetheringAlarm";
-
- let params = {
- cmd: cmd,
- ifname: aInterface,
- threshold: aThreshold,
- };
-
- this.controlMessage(params, function(aData) {
- let code = aData.resultCode;
- let reason = aData.resultReason;
- let enableString = aEnable ? "Enable" : "Disable";
- debug(enableString + " tethering Alarm result: Code " + code + " reason " + reason);
- if (aCallback) {
- aCallback.networkUsageAlarmResult(null);
- }
- });
- },
-
- setNetworkInterfaceAlarm: function(aInterfaceName, aThreshold, aCallback) {
- if (!aInterfaceName) {
- aCallback.networkUsageAlarmResult(-1);
- return;
- }
-
- let self = this;
- this._disableNetworkInterfaceAlarm(aInterfaceName, function(aResult) {
- if (aThreshold < 0) {
- if (!isError(aResult.resultCode)) {
- aCallback.networkUsageAlarmResult(null);
- return;
- }
- aCallback.networkUsageAlarmResult(aResult.reason);
- return
- }
-
- // Check if tethering is enabled
- let params = {
- cmd: "getTetheringStatus"
- };
-
- self.controlMessage(params, function(aResult) {
- if (isError(aResult.resultCode)) {
- aCallback.networkUsageAlarmResult(aResult.reason);
- return;
- }
-
- if (aResult.resultReason.indexOf('started') == -1) {
- // Tethering disabled, set interfaceAlarm
- self._setNetworkInterfaceAlarm(aInterfaceName, aThreshold, aCallback);
- return;
- }
-
- // Tethering enabled, set globalAlarm
- self._setNetworkTetheringAlarm(true, aInterfaceName, aThreshold, aCallback);
- });
- });
- },
-
- _setNetworkInterfaceAlarm: function(aInterfaceName, aThreshold, aCallback) {
- debug("setNetworkInterfaceAlarm for " + aInterfaceName + " at " + aThreshold + "bytes");
-
- let params = {
- cmd: "setNetworkInterfaceAlarm",
- ifname: aInterfaceName,
- threshold: aThreshold
- };
-
- params.report = true;
-
- this.controlMessage(params, function(aResult) {
- if (!isError(aResult.resultCode)) {
- aCallback.networkUsageAlarmResult(null);
- return;
- }
-
- this._enableNetworkInterfaceAlarm(aInterfaceName, aThreshold, aCallback);
- });
- },
-
- _enableNetworkInterfaceAlarm: function(aInterfaceName, aThreshold, aCallback) {
- debug("enableNetworkInterfaceAlarm for " + aInterfaceName + " at " + aThreshold + "bytes");
-
- let params = {
- cmd: "enableNetworkInterfaceAlarm",
- ifname: aInterfaceName,
- threshold: aThreshold
- };
-
- params.report = true;
-
- this.controlMessage(params, function(aResult) {
- if (!isError(aResult.resultCode)) {
- aCallback.networkUsageAlarmResult(null);
- return;
- }
- aCallback.networkUsageAlarmResult(aResult.reason);
- });
- },
-
- _disableNetworkInterfaceAlarm: function(aInterfaceName, aCallback) {
- debug("disableNetworkInterfaceAlarm for " + aInterfaceName);
-
- let params = {
- cmd: "disableNetworkInterfaceAlarm",
- ifname: aInterfaceName,
- };
-
- params.report = true;
-
- this.controlMessage(params, function(aResult) {
- aCallback(aResult);
- });
- },
-
- setWifiOperationMode: function(aInterfaceName, aMode, aCallback) {
- debug("setWifiOperationMode on " + aInterfaceName + " to " + aMode);
-
- let params = {
- cmd: "setWifiOperationMode",
- ifname: aInterfaceName,
- mode: aMode
- };
-
- params.report = true;
-
- this.controlMessage(params, function(aResult) {
- if (isError(aResult.resultCode)) {
- aCallback.wifiOperationModeResult("netd command error");
- } else {
- aCallback.wifiOperationModeResult(null);
- }
- });
- },
-
- resetRoutingTable: function(aInterfaceName, aCallback) {
- let options = {
- cmd: "removeNetworkRoute",
- ifname: aInterfaceName
- };
-
- this.controlMessage(options, function(aResult) {
- aCallback.nativeCommandResult(!aResult.error);
- });
- },
-
- setDNS: function(aInterfaceName, aDnsesCount, aDnses, aGatewaysCount,
- aGateways, aCallback) {
- debug("Going to set DNS to " + aInterfaceName);
- let options = {
- cmd: "setDNS",
- ifname: aInterfaceName,
- domain: "mozilla." + aInterfaceName + ".domain",
- dnses: aDnses,
- gateways: aGateways
- };
- this.controlMessage(options, function(aResult) {
- aCallback.setDnsResult(aResult.success ? null : aResult.reason);
- });
- },
-
- setDefaultRoute: function(aInterfaceName, aCount, aGateways, aCallback) {
- debug("Going to change default route to " + aInterfaceName);
- let options = {
- cmd: "setDefaultRoute",
- ifname: aInterfaceName,
- gateways: aGateways
- };
- this.controlMessage(options, function(aResult) {
- aCallback.nativeCommandResult(!aResult.error);
- });
- },
-
- removeDefaultRoute: function(aInterfaceName, aCount, aGateways, aCallback) {
- debug("Remove default route for " + aInterfaceName);
- let options = {
- cmd: "removeDefaultRoute",
- ifname: aInterfaceName,
- gateways: aGateways
- };
- this.controlMessage(options, function(aResult) {
- aCallback.nativeCommandResult(!aResult.error);
- });
- },
-
- _routeToString: function(aInterfaceName, aHost, aPrefixLength, aGateway) {
- return aHost + "-" + aPrefixLength + "-" + aGateway + "-" + aInterfaceName;
- },
-
- modifyRoute: function(aAction, aInterfaceName, aHost, aPrefixLength, aGateway) {
- let command;
-
- switch (aAction) {
- case Ci.nsINetworkService.MODIFY_ROUTE_ADD:
- command = 'addHostRoute';
- break;
- case Ci.nsINetworkService.MODIFY_ROUTE_REMOVE:
- command = 'removeHostRoute';
- break;
- default:
- debug('Unknown action: ' + aAction);
- return Promise.reject();
- }
-
- let route = this._routeToString(aInterfaceName, aHost, aPrefixLength, aGateway);
- let setupFunc = () => {
- let count = this.addedRoutes.get(route);
- debug(command + ": " + route + " -> " + count);
-
- // Return false if there is no need to send the command to network worker.
- if ((aAction == Ci.nsINetworkService.MODIFY_ROUTE_ADD && count) ||
- (aAction == Ci.nsINetworkService.MODIFY_ROUTE_REMOVE &&
- (!count || count > 1))) {
- return false;
- }
-
- return true;
- };
-
- debug(command + " " + aHost + " on " + aInterfaceName);
- let options = {
- cmd: command,
- ifname: aInterfaceName,
- gateway: aGateway,
- prefixLength: aPrefixLength,
- ip: aHost
- };
-
- return new Promise((aResolve, aReject) => {
- this.controlMessage(options, (aData) => {
- let count = this.addedRoutes.get(route);
-
- // Remove route from addedRoutes on success or failure.
- if (aAction == Ci.nsINetworkService.MODIFY_ROUTE_REMOVE) {
- if (count > 1) {
- this.addedRoutes.set(route, count - 1);
- } else {
- this.addedRoutes.delete(route);
- }
- }
-
- if (aData.error) {
- aReject(aData.reason);
- return;
- }
-
- if (aAction == Ci.nsINetworkService.MODIFY_ROUTE_ADD) {
- this.addedRoutes.set(route, count ? count + 1 : 1);
- }
-
- aResolve();
- }, setupFunc);
- });
- },
-
- addSecondaryRoute: function(aInterfaceName, aRoute, aCallback) {
- debug("Going to add route to secondary table on " + aInterfaceName);
- let options = {
- cmd: "addSecondaryRoute",
- ifname: aInterfaceName,
- ip: aRoute.ip,
- prefix: aRoute.prefix,
- gateway: aRoute.gateway
- };
- this.controlMessage(options, function(aResult) {
- aCallback.nativeCommandResult(!aResult.error);
- });
- },
-
- removeSecondaryRoute: function(aInterfaceName, aRoute, aCallback) {
- debug("Going to remove route from secondary table on " + aInterfaceName);
- let options = {
- cmd: "removeSecondaryRoute",
- ifname: aInterfaceName,
- ip: aRoute.ip,
- prefix: aRoute.prefix,
- gateway: aRoute.gateway
- };
- this.controlMessage(options, function(aResult) {
- aCallback.nativeCommandResult(!aResult.error);
- });
- },
-
- // Enable/Disable DHCP server.
- setDhcpServer: function(aEnabled, aConfig, aCallback) {
- if (null === aConfig) {
- aConfig = {};
- }
-
- aConfig.cmd = "setDhcpServer";
- aConfig.enabled = aEnabled;
-
- this.controlMessage(aConfig, function(aResponse) {
- if (!aResponse.success) {
- aCallback.dhcpServerResult('Set DHCP server error');
- return;
- }
- aCallback.dhcpServerResult(null);
- });
- },
-
- // Enable/disable WiFi tethering by sending commands to netd.
- setWifiTethering: function(aEnable, aConfig, aCallback) {
- // config should've already contained:
- // .ifname
- // .internalIfname
- // .externalIfname
- aConfig.wifictrlinterfacename = WIFI_CTRL_INTERFACE;
- aConfig.cmd = "setWifiTethering";
-
- // The callback function in controlMessage may not be fired immediately.
- this.controlMessage(aConfig, (aData) => {
- let code = aData.resultCode;
- let reason = aData.resultReason;
- let enable = aData.enable;
- let enableString = aEnable ? "Enable" : "Disable";
-
- debug(enableString + " Wifi tethering result: Code " + code + " reason " + reason);
-
- this.setNetworkTetheringAlarm(aEnable, aConfig.externalIfname);
-
- if (isError(code)) {
- aCallback.wifiTetheringEnabledChange("netd command error");
- } else {
- aCallback.wifiTetheringEnabledChange(null);
- }
- });
- },
-
- // Enable/disable USB tethering by sending commands to netd.
- setUSBTethering: function(aEnable, aConfig, aCallback) {
- aConfig.cmd = "setUSBTethering";
- // The callback function in controlMessage may not be fired immediately.
- this.controlMessage(aConfig, (aData) => {
- let code = aData.resultCode;
- let reason = aData.resultReason;
- let enable = aData.enable;
- let enableString = aEnable ? "Enable" : "Disable";
-
- debug(enableString + " USB tethering result: Code " + code + " reason " + reason);
-
- this.setNetworkTetheringAlarm(aEnable, aConfig.externalIfname);
-
- if (isError(code)) {
- aCallback.usbTetheringEnabledChange("netd command error");
- } else {
- aCallback.usbTetheringEnabledChange(null);
- }
- });
- },
-
- // Switch usb function by modifying property of persist.sys.usb.config.
- enableUsbRndis: function(aEnable, aCallback) {
- debug("enableUsbRndis: " + aEnable);
-
- let params = {
- cmd: "enableUsbRndis",
- enable: aEnable
- };
- // Ask net work to report the result when this value is set to true.
- if (aCallback) {
- params.report = true;
- } else {
- params.report = false;
- }
-
- // The callback function in controlMessage may not be fired immediately.
- //this._usbTetheringAction = TETHERING_STATE_ONGOING;
- this.controlMessage(params, function(aData) {
- aCallback.enableUsbRndisResult(aData.result, aData.enable);
- });
- },
-
- updateUpStream: function(aPrevious, aCurrent, aCallback) {
- let params = {
- cmd: "updateUpStream",
- preInternalIfname: aPrevious.internalIfname,
- preExternalIfname: aPrevious.externalIfname,
- curInternalIfname: aCurrent.internalIfname,
- curExternalIfname: aCurrent.externalIfname
- };
-
- this.controlMessage(params, function(aData) {
- let code = aData.resultCode;
- let reason = aData.resultReason;
- debug("updateUpStream result: Code " + code + " reason " + reason);
- aCallback.updateUpStreamResult(!isError(code), aData.curExternalIfname);
- });
- },
-
- getInterfaces: function(callback) {
- let params = {
- cmd: "getInterfaces",
- isAsync: true
- };
-
- this.controlMessage(params, function(data) {
- debug("getInterfaces result: " + JSON.stringify(data));
- let success = !isError(data.resultCode);
- callback.getInterfacesResult(success, data.interfaceList);
- });
- },
-
- getInterfaceConfig: function(ifname, callback) {
- let params = {
- cmd: "getInterfaceConfig",
- ifname: ifname,
- isAsync: true
- };
-
- this.controlMessage(params, function(data) {
- debug("getInterfaceConfig result: " + JSON.stringify(data));
- let success = !isError(data.resultCode);
- let result = { ip: data.ipAddr,
- prefix: data.prefixLength,
- link: data.flag,
- mac: data.macAddr };
- callback.getInterfaceConfigResult(success, result);
- });
- },
-
- setInterfaceConfig: function(config, callback) {
- config.cmd = "setInterfaceConfig";
- config.isAsync = true;
-
- this.controlMessage(config, function(data) {
- debug("setInterfaceConfig result: " + JSON.stringify(data));
- let success = !isError(data.resultCode);
- callback.setInterfaceConfigResult(success);
- });
- },
-
- configureInterface: function(aConfig, aCallback) {
- let params = {
- cmd: "configureInterface",
- ifname: aConfig.ifname,
- ipaddr: aConfig.ipaddr,
- mask: aConfig.mask,
- gateway_long: aConfig.gateway,
- dns1_long: aConfig.dns1,
- dns2_long: aConfig.dns2,
- };
-
- this.controlMessage(params, function(aResult) {
- aCallback.nativeCommandResult(!aResult.error);
- });
- },
-
- dhcpRequest: function(aInterfaceName, aCallback) {
- let params = {
- cmd: "dhcpRequest",
- ifname: aInterfaceName
- };
-
- this.controlMessage(params, function(aResult) {
- aCallback.dhcpRequestResult(!aResult.error, aResult.error ? null : aResult);
- });
- },
-
- stopDhcp: function(aInterfaceName, aCallback) {
- let params = {
- cmd: "stopDhcp",
- ifname: aInterfaceName
- };
-
- this.controlMessage(params, function(aResult) {
- aCallback.nativeCommandResult(!aResult.error);
- });
- },
-
- enableInterface: function(aInterfaceName, aCallback) {
- let params = {
- cmd: "enableInterface",
- ifname: aInterfaceName
- };
-
- this.controlMessage(params, function(aResult) {
- aCallback.nativeCommandResult(!aResult.error);
- });
- },
-
- disableInterface: function(aInterfaceName, aCallback) {
- let params = {
- cmd: "disableInterface",
- ifname: aInterfaceName
- };
-
- this.controlMessage(params, function(aResult) {
- aCallback.nativeCommandResult(!aResult.error);
- });
- },
-
- resetConnections: function(aInterfaceName, aCallback) {
- let params = {
- cmd: "resetConnections",
- ifname: aInterfaceName
- };
-
- this.controlMessage(params, function(aResult) {
- aCallback.nativeCommandResult(!aResult.error);
- });
- },
-
- createNetwork: function(aInterfaceName, aCallback) {
- let params = {
- cmd: "createNetwork",
- ifname: aInterfaceName
- };
-
- this.controlMessage(params, function(aResult) {
- aCallback.nativeCommandResult(!aResult.error);
- });
- },
-
- destroyNetwork: function(aInterfaceName, aCallback) {
- let params = {
- cmd: "destroyNetwork",
- ifname: aInterfaceName
- };
-
- this.controlMessage(params, function(aResult) {
- aCallback.nativeCommandResult(!aResult.error);
- });
- },
-
- getNetId: function(aInterfaceName) {
- let params = {
- cmd: "getNetId",
- ifname: aInterfaceName
- };
-
- return new Promise((aResolve, aReject) => {
- this.controlMessage(params, result => {
- if (result.error) {
- aReject(result.reason);
- return;
- }
- aResolve(result.netId);
- });
- });
- },
-
- setMtu: function (aInterfaceName, aMtu, aCallback) {
- debug("Set MTU on " + aInterfaceName + ": " + aMtu);
-
- let params = {
- cmd: "setMtu",
- ifname: aInterfaceName,
- mtu: aMtu
- };
-
- this.controlMessage(params, function(aResult) {
- aCallback.nativeCommandResult(!aResult.error);
- });
- }
-};
-
-this.NSGetFactory = XPCOMUtils.generateNSGetFactory([NetworkService]);
diff --git a/dom/system/gonk/NetworkService.manifest b/dom/system/gonk/NetworkService.manifest
deleted file mode 100644
index caf8f2554f..0000000000
--- a/dom/system/gonk/NetworkService.manifest
+++ /dev/null
@@ -1,3 +0,0 @@
-# NetworkService.js
-component {48c13741-aec9-4a86-8962-432011708261} NetworkService.js
-contract @mozilla.org/network/service;1 {48c13741-aec9-4a86-8962-432011708261}
diff --git a/dom/system/gonk/NetworkUtils.cpp b/dom/system/gonk/NetworkUtils.cpp
deleted file mode 100644
index d661368b88..0000000000
--- a/dom/system/gonk/NetworkUtils.cpp
+++ /dev/null
@@ -1,2973 +0,0 @@
-/* Copyright 2012 Mozilla Foundation and Mozilla contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "NetworkUtils.h"
-
-#include "mozilla/Sprintf.h"
-#include "SystemProperty.h"
-
-#include <android/log.h>
-#include <limits>
-#include "mozilla/dom/network/NetUtils.h"
-#include "mozilla/fallible.h"
-#include "base/task.h"
-
-#include <errno.h>
-#include <string.h>
-#include <sys/types.h> // struct addrinfo
-#include <sys/socket.h> // getaddrinfo(), freeaddrinfo()
-#include <netdb.h>
-#include <arpa/inet.h> // inet_ntop()
-
-#define _DEBUG 0
-
-#define WARN(args...) __android_log_print(ANDROID_LOG_WARN, "NetworkUtils", ## args)
-#define ERROR(args...) __android_log_print(ANDROID_LOG_ERROR, "NetworkUtils", ## args)
-
-#if _DEBUG
-#define NU_DBG(args...) __android_log_print(ANDROID_LOG_DEBUG, "NetworkUtils" , ## args)
-#else
-#define NU_DBG(args...)
-#endif
-
-using namespace mozilla::dom;
-using namespace mozilla::ipc;
-using mozilla::system::Property;
-
-static const char* PERSIST_SYS_USB_CONFIG_PROPERTY = "persist.sys.usb.config";
-static const char* SYS_USB_CONFIG_PROPERTY = "sys.usb.config";
-static const char* SYS_USB_STATE_PROPERTY = "sys.usb.state";
-
-static const char* USB_FUNCTION_RNDIS = "rndis";
-static const char* USB_FUNCTION_ADB = "adb";
-
-// Use this command to continue the function chain.
-static const char* DUMMY_COMMAND = "tether status";
-
-// IPV6 Tethering is not supported in AOSP, use the property to
-// identify vendor specific support in IPV6. We can remove this flag
-// once upstream Android support IPV6 in tethering.
-static const char* IPV6_TETHERING = "ro.tethering.ipv6";
-
-// Retry 20 times (2 seconds) for usb state transition.
-static const uint32_t USB_FUNCTION_RETRY_TIMES = 20;
-// Check "sys.usb.state" every 100ms.
-static const uint32_t USB_FUNCTION_RETRY_INTERVAL = 100;
-
-// 1xx - Requested action is proceeding
-static const uint32_t NETD_COMMAND_PROCEEDING = 100;
-// 2xx - Requested action has been successfully completed
-static const uint32_t NETD_COMMAND_OKAY = 200;
-// 4xx - The command is accepted but the requested action didn't
-// take place.
-static const uint32_t NETD_COMMAND_FAIL = 400;
-// 5xx - The command syntax or parameters error
-static const uint32_t NETD_COMMAND_ERROR = 500;
-// 6xx - Unsolicited broadcasts
-static const uint32_t NETD_COMMAND_UNSOLICITED = 600;
-
-// Broadcast messages
-static const uint32_t NETD_COMMAND_INTERFACE_CHANGE = 600;
-static const uint32_t NETD_COMMAND_BANDWIDTH_CONTROLLER = 601;
-
-static const char* INTERFACE_DELIMIT = ",";
-static const char* USB_CONFIG_DELIMIT = ",";
-static const char* NETD_MESSAGE_DELIMIT = " ";
-
-static const uint32_t BUF_SIZE = 1024;
-
-static const int32_t SUCCESS = 0;
-
-static uint32_t SDK_VERSION;
-static uint32_t SUPPORT_IPV6_TETHERING;
-
-struct IFProperties {
- char gateway[Property::VALUE_MAX_LENGTH];
- char dns1[Property::VALUE_MAX_LENGTH];
- char dns2[Property::VALUE_MAX_LENGTH];
-};
-
-struct CurrentCommand {
- CommandChain* chain;
- CommandCallback callback;
- char command[MAX_COMMAND_SIZE];
-};
-
-typedef Tuple3<NetdCommand*, CommandChain*, CommandCallback> QueueData;
-
-#define GET_CURRENT_NETD_COMMAND (gCommandQueue.IsEmpty() ? nullptr : gCommandQueue[0].a)
-#define GET_CURRENT_CHAIN (gCommandQueue.IsEmpty() ? nullptr : gCommandQueue[0].b)
-#define GET_CURRENT_CALLBACK (gCommandQueue.IsEmpty() ? nullptr : gCommandQueue[0].c)
-#define GET_CURRENT_COMMAND (gCommandQueue.IsEmpty() ? nullptr : gCommandQueue[0].a->mData)
-
-// A macro for native function call return value check.
-// For native function call, non-zero return value means failure.
-#define RETURN_IF_FAILED(rv) do { \
- if (SUCCESS != rv) { \
- return rv; \
- } \
-} while (0);
-
-#define WARN_IF_FAILED(rv) do { \
- if (SUCCESS != rv) { \
- WARN("Error (%d) occurred in %s (%s:%d)", rv, __PRETTY_FUNCTION__, __FILE__, __LINE__); \
- } \
-} while (0);
-
-static NetworkUtils* gNetworkUtils;
-static nsTArray<QueueData> gCommandQueue;
-static CurrentCommand gCurrentCommand;
-static bool gPending = false;
-static nsTArray<nsCString> gReason;
-static NetworkParams *gWifiTetheringParms = 0;
-
-static nsTArray<CommandChain*> gCommandChainQueue;
-
-const CommandFunc NetworkUtils::sWifiEnableChain[] = {
- NetworkUtils::clearWifiTetherParms,
- NetworkUtils::wifiFirmwareReload,
- NetworkUtils::startAccessPointDriver,
- NetworkUtils::setAccessPoint,
- NetworkUtils::startSoftAP,
- NetworkUtils::setConfig,
- NetworkUtils::tetherInterface,
- NetworkUtils::addInterfaceToLocalNetwork,
- NetworkUtils::addRouteToLocalNetwork,
- NetworkUtils::setIpForwardingEnabled,
- NetworkUtils::tetheringStatus,
- NetworkUtils::startTethering,
- NetworkUtils::setDnsForwarders,
- NetworkUtils::enableNat,
- NetworkUtils::wifiTetheringSuccess
-};
-
-const CommandFunc NetworkUtils::sWifiDisableChain[] = {
- NetworkUtils::clearWifiTetherParms,
- NetworkUtils::stopSoftAP,
- NetworkUtils::stopAccessPointDriver,
- NetworkUtils::wifiFirmwareReload,
- NetworkUtils::untetherInterface,
- NetworkUtils::removeInterfaceFromLocalNetwork,
- NetworkUtils::preTetherInterfaceList,
- NetworkUtils::postTetherInterfaceList,
- NetworkUtils::disableNat,
- NetworkUtils::setIpForwardingEnabled,
- NetworkUtils::stopTethering,
- NetworkUtils::wifiTetheringSuccess
-};
-
-const CommandFunc NetworkUtils::sWifiFailChain[] = {
- NetworkUtils::clearWifiTetherParms,
- NetworkUtils::stopSoftAP,
- NetworkUtils::setIpForwardingEnabled,
- NetworkUtils::stopTethering
-};
-
-const CommandFunc NetworkUtils::sWifiRetryChain[] = {
- NetworkUtils::clearWifiTetherParms,
- NetworkUtils::stopSoftAP,
- NetworkUtils::stopTethering,
-
- // sWifiEnableChain:
- NetworkUtils::wifiFirmwareReload,
- NetworkUtils::startAccessPointDriver,
- NetworkUtils::setAccessPoint,
- NetworkUtils::startSoftAP,
- NetworkUtils::setConfig,
- NetworkUtils::tetherInterface,
- NetworkUtils::addInterfaceToLocalNetwork,
- NetworkUtils::addRouteToLocalNetwork,
- NetworkUtils::setIpForwardingEnabled,
- NetworkUtils::tetheringStatus,
- NetworkUtils::startTethering,
- NetworkUtils::setDnsForwarders,
- NetworkUtils::enableNat,
- NetworkUtils::wifiTetheringSuccess
-};
-
-const CommandFunc NetworkUtils::sWifiOperationModeChain[] = {
- NetworkUtils::wifiFirmwareReload,
- NetworkUtils::wifiOperationModeSuccess
-};
-
-const CommandFunc NetworkUtils::sUSBEnableChain[] = {
- NetworkUtils::setConfig,
- NetworkUtils::enableNat,
- NetworkUtils::setIpForwardingEnabled,
- NetworkUtils::tetherInterface,
- NetworkUtils::addInterfaceToLocalNetwork,
- NetworkUtils::addRouteToLocalNetwork,
- NetworkUtils::tetheringStatus,
- NetworkUtils::startTethering,
- NetworkUtils::setDnsForwarders,
- NetworkUtils::addUpstreamInterface,
- NetworkUtils::usbTetheringSuccess
-};
-
-const CommandFunc NetworkUtils::sUSBDisableChain[] = {
- NetworkUtils::untetherInterface,
- NetworkUtils::removeInterfaceFromLocalNetwork,
- NetworkUtils::preTetherInterfaceList,
- NetworkUtils::postTetherInterfaceList,
- NetworkUtils::removeUpstreamInterface,
- NetworkUtils::disableNat,
- NetworkUtils::setIpForwardingEnabled,
- NetworkUtils::stopTethering,
- NetworkUtils::usbTetheringSuccess
-};
-
-const CommandFunc NetworkUtils::sUSBFailChain[] = {
- NetworkUtils::stopSoftAP,
- NetworkUtils::setIpForwardingEnabled,
- NetworkUtils::stopTethering
-};
-
-const CommandFunc NetworkUtils::sUpdateUpStreamChain[] = {
- NetworkUtils::cleanUpStream,
- NetworkUtils::removeUpstreamInterface,
- NetworkUtils::createUpStream,
- NetworkUtils::addUpstreamInterface,
- NetworkUtils::updateUpStreamSuccess
-};
-
-const CommandFunc NetworkUtils::sStartDhcpServerChain[] = {
- NetworkUtils::setConfig,
- NetworkUtils::startTethering,
- NetworkUtils::setDhcpServerSuccess
-};
-
-const CommandFunc NetworkUtils::sStopDhcpServerChain[] = {
- NetworkUtils::stopTethering,
- NetworkUtils::setDhcpServerSuccess
-};
-
-const CommandFunc NetworkUtils::sNetworkInterfaceEnableAlarmChain[] = {
- NetworkUtils::enableAlarm,
- NetworkUtils::setQuota,
- NetworkUtils::setAlarm,
- NetworkUtils::networkInterfaceAlarmSuccess
-};
-
-const CommandFunc NetworkUtils::sNetworkInterfaceDisableAlarmChain[] = {
- NetworkUtils::removeQuota,
- NetworkUtils::disableAlarm,
- NetworkUtils::networkInterfaceAlarmSuccess
-};
-
-const CommandFunc NetworkUtils::sNetworkInterfaceSetAlarmChain[] = {
- NetworkUtils::setAlarm,
- NetworkUtils::networkInterfaceAlarmSuccess
-};
-
-const CommandFunc NetworkUtils::sGetInterfacesChain[] = {
- NetworkUtils::getInterfaceList,
- NetworkUtils::getInterfacesSuccess
-};
-
-const CommandFunc NetworkUtils::sGetInterfaceConfigChain[] = {
- NetworkUtils::getConfig,
- NetworkUtils::getInterfaceConfigSuccess
-};
-
-const CommandFunc NetworkUtils::sSetInterfaceConfigChain[] = {
- NetworkUtils::setConfig,
- NetworkUtils::setInterfaceConfigSuccess
-};
-
-const CommandFunc NetworkUtils::sTetheringInterfaceSetAlarmChain[] = {
- NetworkUtils::setGlobalAlarm,
- NetworkUtils::removeAlarm,
- NetworkUtils::networkInterfaceAlarmSuccess
-};
-
-const CommandFunc NetworkUtils::sTetheringInterfaceRemoveAlarmChain[] = {
- NetworkUtils::removeGlobalAlarm,
- NetworkUtils::setAlarm,
- NetworkUtils::networkInterfaceAlarmSuccess
-};
-
-const CommandFunc NetworkUtils::sTetheringGetStatusChain[] = {
- NetworkUtils::tetheringStatus,
- NetworkUtils::defaultAsyncSuccessHandler
-};
-
-/**
- * Helper function to get the mask from given prefix length.
- */
-static uint32_t makeMask(const uint32_t prefixLength)
-{
- uint32_t mask = 0;
- for (uint32_t i = 0; i < prefixLength; ++i) {
- mask |= (0x80000000 >> i);
- }
- return ntohl(mask);
-}
-
-/**
- * Helper function to get the network part of an ip from prefix.
- * param ip must be in network byte order.
- */
-static char* getNetworkAddr(const uint32_t ip, const uint32_t prefix)
-{
- uint32_t mask = 0, subnet = 0;
-
- mask = ~mask << (32 - prefix);
- mask = htonl(mask);
- subnet = ip & mask;
-
- struct in_addr addr;
- addr.s_addr = subnet;
-
- return inet_ntoa(addr);
-}
-
-/**
- * Helper function to split string by seperator, store split result as an nsTArray.
- */
-static void split(char* str, const char* sep, nsTArray<nsCString>& result)
-{
- char *s = strtok(str, sep);
- while (s != nullptr) {
- result.AppendElement(s);
- s = strtok(nullptr, sep);
- }
-}
-
-static void split(char* str, const char* sep, nsTArray<nsString>& result)
-{
- char *s = strtok(str, sep);
- while (s != nullptr) {
- result.AppendElement(NS_ConvertUTF8toUTF16(s));
- s = strtok(nullptr, sep);
- }
-}
-
-/**
- * Helper function that implement join function.
- */
-static void join(nsTArray<nsCString>& array,
- const char* sep,
- const uint32_t maxlen,
- char* result)
-{
-#define CHECK_LENGTH(len, add, max) len += add; \
- if (len > max - 1) \
- return; \
-
- uint32_t len = 0;
- uint32_t seplen = strlen(sep);
-
- if (array.Length() > 0) {
- CHECK_LENGTH(len, strlen(array[0].get()), maxlen)
- strcpy(result, array[0].get());
-
- for (uint32_t i = 1; i < array.Length(); i++) {
- CHECK_LENGTH(len, seplen, maxlen)
- strcat(result, sep);
-
- CHECK_LENGTH(len, strlen(array[i].get()), maxlen)
- strcat(result, array[i].get());
- }
- }
-
-#undef CHECK_LEN
-}
-
-static void convertUTF8toUTF16(nsTArray<nsCString>& narrow,
- nsTArray<nsString>& wide,
- uint32_t length)
-{
- for (uint32_t i = 0; i < length; i++) {
- wide.AppendElement(NS_ConvertUTF8toUTF16(narrow[i].get()));
- }
-}
-
-/**
- * Helper function to get network interface properties from the system property table.
- */
-static void getIFProperties(const char* ifname, IFProperties& prop)
-{
- char key[Property::KEY_MAX_LENGTH];
- snprintf(key, Property::KEY_MAX_LENGTH - 1, "net.%s.gw", ifname);
- Property::Get(key, prop.gateway, "");
- snprintf(key, Property::KEY_MAX_LENGTH - 1, "net.%s.dns1", ifname);
- Property::Get(key, prop.dns1, "");
- snprintf(key, Property::KEY_MAX_LENGTH - 1, "net.%s.dns2", ifname);
- Property::Get(key, prop.dns2, "");
-}
-
-static int getIpType(const char *aIp) {
- struct addrinfo hint, *ip_info = NULL;
-
- memset(&hint, 0, sizeof(hint));
- hint.ai_family = AF_UNSPEC;
- hint.ai_flags = AI_NUMERICHOST;
-
- if (getaddrinfo(aIp, NULL, &hint, &ip_info)) {
- return AF_UNSPEC;
- }
-
- int type = ip_info->ai_family;
- freeaddrinfo(ip_info);
-
- return type;
-}
-
-static void postMessage(NetworkResultOptions& aResult)
-{
- MOZ_ASSERT(gNetworkUtils);
- MOZ_ASSERT(gNetworkUtils->getMessageCallback());
-
- if (*(gNetworkUtils->getMessageCallback()))
- (*(gNetworkUtils->getMessageCallback()))(aResult);
-}
-
-static void postMessage(NetworkParams& aOptions, NetworkResultOptions& aResult)
-{
- MOZ_ASSERT(gNetworkUtils);
- MOZ_ASSERT(gNetworkUtils->getMessageCallback());
-
- aResult.mId = aOptions.mId;
-
- if (*(gNetworkUtils->getMessageCallback()))
- (*(gNetworkUtils->getMessageCallback()))(aResult);
-}
-
-void NetworkUtils::runNextQueuedCommandChain()
-{
- if (gCommandChainQueue.IsEmpty()) {
- NU_DBG("No command chain left in the queue. Done!");
- return;
- }
- NU_DBG("Process the queued command chain.");
- CommandChain* nextChain = gCommandChainQueue[0];
- NetworkResultOptions newResult;
- next(nextChain, false, newResult);
-}
-
-void NetworkUtils::next(CommandChain* aChain, bool aError, NetworkResultOptions& aResult)
-{
- if (aError) {
- ErrorCallback onError = aChain->getErrorCallback();
- if(onError) {
- aResult.mError = true;
- (*onError)(aChain->getParams(), aResult);
- }
- delete aChain;
- gCommandChainQueue.RemoveElementAt(0);
- runNextQueuedCommandChain();
- return;
- }
- CommandFunc f = aChain->getNextCommand();
- if (!f) {
- delete aChain;
- gCommandChainQueue.RemoveElementAt(0);
- runNextQueuedCommandChain();
- return;
- }
-
- (*f)(aChain, next, aResult);
-}
-
-CommandResult::CommandResult(int32_t aResultCode)
- : mIsPending(false)
-{
- // This is usually not a netd command. We treat the return code
- // typical linux convention, which uses 0 to indicate success.
- mResult.mError = (aResultCode == SUCCESS ? false : true);
- mResult.mResultCode = aResultCode;
- if (aResultCode != SUCCESS) {
- // The returned value is sometimes negative, make sure we pass a positive
- // error number to strerror.
- enum { STRERROR_R_BUF_SIZE = 1024, };
- char strerrorBuf[STRERROR_R_BUF_SIZE];
- strerror_r(abs(aResultCode), strerrorBuf, STRERROR_R_BUF_SIZE);
- mResult.mReason = NS_ConvertUTF8toUTF16(strerrorBuf);
- }
-}
-
-CommandResult::CommandResult(const mozilla::dom::NetworkResultOptions& aResult)
- : mResult(aResult)
- , mIsPending(false)
-{
-}
-
-CommandResult::CommandResult(const Pending&)
- : mIsPending(true)
-{
-}
-
-bool CommandResult::isPending() const
-{
- return mIsPending;
-}
-
-/**
- * Send command to netd.
- */
-void NetworkUtils::nextNetdCommand()
-{
- if (gCommandQueue.IsEmpty() || gPending) {
- return;
- }
-
- gCurrentCommand.chain = GET_CURRENT_CHAIN;
- gCurrentCommand.callback = GET_CURRENT_CALLBACK;
- snprintf(gCurrentCommand.command, MAX_COMMAND_SIZE - 1, "%s", GET_CURRENT_COMMAND);
-
- NU_DBG("Sending \'%s\' command to netd.", gCurrentCommand.command);
- SendNetdCommand(GET_CURRENT_NETD_COMMAND);
-
- gCommandQueue.RemoveElementAt(0);
- gPending = true;
-}
-
-/**
- * Composite NetdCommand sent to netd
- *
- * @param aCommand Command sent to netd to execute.
- * @param aChain Store command chain data, ex. command parameter.
- * @param aCallback Callback function to be executed when the result of
- * this command is returned from netd.
- */
-void NetworkUtils::doCommand(const char* aCommand, CommandChain* aChain, CommandCallback aCallback)
-{
- NU_DBG("Preparing to send \'%s\' command...", aCommand);
-
- NetdCommand* netdCommand = new NetdCommand();
-
- // Android JB version adds sequence number to netd command.
- if (SDK_VERSION >= 16) {
- snprintf((char*)netdCommand->mData, MAX_COMMAND_SIZE - 1, "0 %s", aCommand);
- } else {
- snprintf((char*)netdCommand->mData, MAX_COMMAND_SIZE - 1, "%s", aCommand);
- }
- netdCommand->mSize = strlen((char*)netdCommand->mData) + 1;
-
- gCommandQueue.AppendElement(QueueData(netdCommand, aChain, aCallback));
-
- nextNetdCommand();
-}
-
-/*
- * Netd command function
- */
-#define GET_CHAR(prop) NS_ConvertUTF16toUTF8(aChain->getParams().prop).get()
-#define GET_FIELD(prop) aChain->getParams().prop
-
-void NetworkUtils::wifiFirmwareReload(CommandChain* aChain,
- CommandCallback aCallback,
- NetworkResultOptions& aResult)
-{
- char command[MAX_COMMAND_SIZE];
- snprintf(command, MAX_COMMAND_SIZE - 1, "softap fwreload %s %s", GET_CHAR(mIfname), GET_CHAR(mMode));
-
- doCommand(command, aChain, aCallback);
-}
-
-void NetworkUtils::startAccessPointDriver(CommandChain* aChain,
- CommandCallback aCallback,
- NetworkResultOptions& aResult)
-{
- // Skip the command for sdk version >= 16.
- if (SDK_VERSION >= 16) {
- aResult.mResultCode = 0;
- aResult.mResultReason = NS_ConvertUTF8toUTF16("");
- aCallback(aChain, false, aResult);
- return;
- }
-
- char command[MAX_COMMAND_SIZE];
- snprintf(command, MAX_COMMAND_SIZE - 1, "softap start %s", GET_CHAR(mIfname));
-
- doCommand(command, aChain, aCallback);
-}
-
-void NetworkUtils::stopAccessPointDriver(CommandChain* aChain,
- CommandCallback aCallback,
- NetworkResultOptions& aResult)
-{
- // Skip the command for sdk version >= 16.
- if (SDK_VERSION >= 16) {
- aResult.mResultCode = 0;
- aResult.mResultReason = NS_ConvertUTF8toUTF16("");
- aCallback(aChain, false, aResult);
- return;
- }
-
- char command[MAX_COMMAND_SIZE];
- snprintf(command, MAX_COMMAND_SIZE - 1, "softap stop %s", GET_CHAR(mIfname));
-
- doCommand(command, aChain, aCallback);
-}
-
-/**
- * Command format for sdk version < 16
- * Arguments:
- * argv[2] - wlan interface
- * argv[3] - SSID
- * argv[4] - Security
- * argv[5] - Key
- * argv[6] - Channel
- * argv[7] - Preamble
- * argv[8] - Max SCB
- *
- * Command format for sdk version >= 16
- * Arguments:
- * argv[2] - wlan interface
- * argv[3] - SSID
- * argv[4] - Security
- * argv[5] - Key
- *
- * Command format for sdk version >= 18
- * Arguments:
- * argv[2] - wlan interface
- * argv[3] - SSID
- * argv[4] - Broadcast/Hidden
- * argv[5] - Channel
- * argv[6] - Security
- * argv[7] - Key
- */
-void NetworkUtils::setAccessPoint(CommandChain* aChain,
- CommandCallback aCallback,
- NetworkResultOptions& aResult)
-{
- char command[MAX_COMMAND_SIZE];
- nsCString ssid(GET_CHAR(mSsid));
- nsCString key(GET_CHAR(mKey));
-
- escapeQuote(ssid);
- escapeQuote(key);
-
- if (SDK_VERSION >= 19) {
- snprintf(command, MAX_COMMAND_SIZE - 1, "softap set %s \"%s\" broadcast 6 %s \"%s\"",
- GET_CHAR(mIfname),
- ssid.get(),
- GET_CHAR(mSecurity),
- key.get());
- } else if (SDK_VERSION >= 16) {
- snprintf(command, MAX_COMMAND_SIZE - 1, "softap set %s \"%s\" %s \"%s\"",
- GET_CHAR(mIfname),
- ssid.get(),
- GET_CHAR(mSecurity),
- key.get());
- } else {
- snprintf(command, MAX_COMMAND_SIZE - 1, "softap set %s %s \"%s\" %s \"%s\" 6 0 8",
- GET_CHAR(mIfname),
- GET_CHAR(mWifictrlinterfacename),
- ssid.get(),
- GET_CHAR(mSecurity),
- key.get());
- }
-
- doCommand(command, aChain, aCallback);
-}
-
-void NetworkUtils::cleanUpStream(CommandChain* aChain,
- CommandCallback aCallback,
- NetworkResultOptions& aResult)
-{
- char command[MAX_COMMAND_SIZE];
- snprintf(command, MAX_COMMAND_SIZE - 1, "nat disable %s %s 0", GET_CHAR(mPreInternalIfname), GET_CHAR(mPreExternalIfname));
-
- doCommand(command, aChain, aCallback);
-}
-
-void NetworkUtils::createUpStream(CommandChain* aChain,
- CommandCallback aCallback,
- NetworkResultOptions& aResult)
-{
- char command[MAX_COMMAND_SIZE];
- snprintf(command, MAX_COMMAND_SIZE - 1, "nat enable %s %s 0", GET_CHAR(mCurInternalIfname), GET_CHAR(mCurExternalIfname));
-
- doCommand(command, aChain, aCallback);
-}
-
-void NetworkUtils::startSoftAP(CommandChain* aChain,
- CommandCallback aCallback,
- NetworkResultOptions& aResult)
-{
- const char* command= "softap startap";
- doCommand(command, aChain, aCallback);
-}
-
-void NetworkUtils::stopSoftAP(CommandChain* aChain,
- CommandCallback aCallback,
- NetworkResultOptions& aResult)
-{
- const char* command= "softap stopap";
- doCommand(command, aChain, aCallback);
-}
-
-void NetworkUtils::clearWifiTetherParms(CommandChain* aChain,
- CommandCallback aCallback,
- NetworkResultOptions& aResult)
-{
- delete gWifiTetheringParms;
- gWifiTetheringParms = 0;
- next(aChain, false, aResult);
-}
-
-void NetworkUtils::enableAlarm(CommandChain* aChain,
- CommandCallback aCallback,
- NetworkResultOptions& aResult)
-{
- const char* command= "bandwidth enable";
- doCommand(command, aChain, aCallback);
-}
-
-void NetworkUtils::disableAlarm(CommandChain* aChain,
- CommandCallback aCallback,
- NetworkResultOptions& aResult)
-{
- const char* command= "bandwidth disable";
- doCommand(command, aChain, aCallback);
-}
-
-void NetworkUtils::setQuota(CommandChain* aChain,
- CommandCallback aCallback,
- NetworkResultOptions& aResult)
-{
- char command[MAX_COMMAND_SIZE];
- snprintf(command, MAX_COMMAND_SIZE - 1, "bandwidth setiquota %s % " PRId64, GET_CHAR(mIfname), INT64_MAX);
-
- doCommand(command, aChain, aCallback);
-}
-
-void NetworkUtils::removeQuota(CommandChain* aChain,
- CommandCallback aCallback,
- NetworkResultOptions& aResult)
-{
- char command[MAX_COMMAND_SIZE];
- snprintf(command, MAX_COMMAND_SIZE - 1, "bandwidth removeiquota %s", GET_CHAR(mIfname));
-
- doCommand(command, aChain, aCallback);
-}
-
-void NetworkUtils::setAlarm(CommandChain* aChain,
- CommandCallback aCallback,
- NetworkResultOptions& aResult)
-{
- char command[MAX_COMMAND_SIZE];
- snprintf(command, MAX_COMMAND_SIZE - 1, "bandwidth setinterfacealert %s %lld",
- GET_CHAR(mIfname), GET_FIELD(mThreshold));
-
- doCommand(command, aChain, aCallback);
-}
-
-void NetworkUtils::removeAlarm(CommandChain* aChain,
- CommandCallback aCallback,
- NetworkResultOptions& aResult)
-{
- char command[MAX_COMMAND_SIZE];
- snprintf(command, MAX_COMMAND_SIZE - 1, "bandwidth removeinterfacealert %s", GET_CHAR(mIfname));
-
- doCommand(command, aChain, aCallback);
-}
-
-void NetworkUtils::setGlobalAlarm(CommandChain* aChain,
- CommandCallback aCallback,
- NetworkResultOptions& aResult)
-{
- char command[MAX_COMMAND_SIZE];
-
- snprintf(command, MAX_COMMAND_SIZE - 1, "bandwidth setglobalalert %lld", GET_FIELD(mThreshold));
- doCommand(command, aChain, aCallback);
-}
-
-void NetworkUtils::removeGlobalAlarm(CommandChain* aChain,
- CommandCallback aCallback,
- NetworkResultOptions& aResult)
-{
- char command[MAX_COMMAND_SIZE];
-
- snprintf(command, MAX_COMMAND_SIZE - 1, "bandwidth removeglobalalert");
- doCommand(command, aChain, aCallback);
-}
-
-void NetworkUtils::tetherInterface(CommandChain* aChain,
- CommandCallback aCallback,
- NetworkResultOptions& aResult)
-{
- char command[MAX_COMMAND_SIZE];
- snprintf(command, MAX_COMMAND_SIZE - 1, "tether interface add %s", GET_CHAR(mIfname));
-
- doCommand(command, aChain, aCallback);
-}
-
-void NetworkUtils::addInterfaceToLocalNetwork(CommandChain* aChain,
- CommandCallback aCallback,
- NetworkResultOptions& aResult)
-{
- // Skip the command for sdk version < 20.
- if (SDK_VERSION < 20) {
- aResult.mResultCode = 0;
- aResult.mResultReason = NS_ConvertUTF8toUTF16("");
- aCallback(aChain, false, aResult);
- return;
- }
-
- char command[MAX_COMMAND_SIZE];
- snprintf(command, MAX_COMMAND_SIZE - 1, "network interface add local %s",
- GET_CHAR(mInternalIfname));
-
- doCommand(command, aChain, aCallback);
-}
-
-void NetworkUtils::addRouteToLocalNetwork(CommandChain* aChain,
- CommandCallback aCallback,
- NetworkResultOptions& aResult)
-{
- // Skip the command for sdk version < 20.
- if (SDK_VERSION < 20) {
- aResult.mResultCode = 0;
- aResult.mResultReason = NS_ConvertUTF8toUTF16("");
- aCallback(aChain, false, aResult);
- return;
- }
-
- char command[MAX_COMMAND_SIZE];
- uint32_t prefix = atoi(GET_CHAR(mPrefix));
- uint32_t ip = inet_addr(GET_CHAR(mIp));
- char* networkAddr = getNetworkAddr(ip, prefix);
-
- snprintf(command, MAX_COMMAND_SIZE - 1, "network route add local %s %s/%s",
- GET_CHAR(mInternalIfname), networkAddr, GET_CHAR(mPrefix));
-
- doCommand(command, aChain, aCallback);
-}
-
-void NetworkUtils::preTetherInterfaceList(CommandChain* aChain,
- CommandCallback aCallback,
- NetworkResultOptions& aResult)
-{
- char command[MAX_COMMAND_SIZE];
- if (SDK_VERSION >= 16) {
- snprintf(command, MAX_COMMAND_SIZE - 1, "tether interface list");
- } else {
- snprintf(command, MAX_COMMAND_SIZE - 1, "tether interface list 0");
- }
-
- doCommand(command, aChain, aCallback);
-}
-
-void NetworkUtils::postTetherInterfaceList(CommandChain* aChain,
- CommandCallback aCallback,
- NetworkResultOptions& aResult)
-{
- // Send the dummy command to continue the function chain.
- char command[MAX_COMMAND_SIZE];
- snprintf(command, MAX_COMMAND_SIZE - 1, "%s", DUMMY_COMMAND);
-
- char buf[BUF_SIZE];
- NS_ConvertUTF16toUTF8 reason(aResult.mResultReason);
-
- size_t length = reason.Length() + 1 < BUF_SIZE ? reason.Length() + 1 : BUF_SIZE;
- memcpy(buf, reason.get(), length);
- split(buf, INTERFACE_DELIMIT, GET_FIELD(mInterfaceList));
-
- doCommand(command, aChain, aCallback);
-}
-
-bool isCommandChainIPv6(CommandChain* aChain, const char *externalInterface) {
- // Check by gateway address
- if (getIpType(GET_CHAR(mGateway)) == AF_INET6) {
- return true;
- }
-
- uint32_t length = GET_FIELD(mGateways).Length();
- for (uint32_t i = 0; i < length; i++) {
- NS_ConvertUTF16toUTF8 autoGateway(GET_FIELD(mGateways)[i]);
- if(getIpType(autoGateway.get()) == AF_INET6) {
- return true;
- }
- }
-
- // Check by external inteface address
- FILE *file = fopen("/proc/net/if_inet6", "r");
- if (!file) {
- return false;
- }
-
- bool isIPv6 = false;
- char interface[32];
- while(fscanf(file, "%*s %*s %*s %*s %*s %32s", interface)) {
- if (strcmp(interface, externalInterface) == 0) {
- isIPv6 = true;
- break;
- }
- }
-
- fclose(file);
- return isIPv6;
-}
-
-void NetworkUtils::addUpstreamInterface(CommandChain* aChain,
- CommandCallback aCallback,
- NetworkResultOptions& aResult)
-{
- nsCString interface(GET_CHAR(mExternalIfname));
- if (!interface.get()[0]) {
- interface = GET_CHAR(mCurExternalIfname);
- }
-
- if (SUPPORT_IPV6_TETHERING == 0 || !isCommandChainIPv6(aChain, interface.get())) {
- aCallback(aChain, false, aResult);
- return;
- }
-
- char command[MAX_COMMAND_SIZE];
- snprintf(command, MAX_COMMAND_SIZE - 1, "tether interface add_upstream %s",
- interface.get());
- doCommand(command, aChain, aCallback);
-}
-
-void NetworkUtils::removeUpstreamInterface(CommandChain* aChain,
- CommandCallback aCallback,
- NetworkResultOptions& aResult)
-{
- nsCString interface(GET_CHAR(mExternalIfname));
- if (!interface.get()[0]) {
- interface = GET_CHAR(mPreExternalIfname);
- }
-
- if (SUPPORT_IPV6_TETHERING == 0 || !isCommandChainIPv6(aChain, interface.get())) {
- aCallback(aChain, false, aResult);
- return;
- }
-
- char command[MAX_COMMAND_SIZE];
- snprintf(command, MAX_COMMAND_SIZE - 1, "tether interface remove_upstream %s",
- interface.get());
- doCommand(command, aChain, aCallback);
-}
-
-void NetworkUtils::setIpForwardingEnabled(CommandChain* aChain,
- CommandCallback aCallback,
- NetworkResultOptions& aResult)
-{
- char command[MAX_COMMAND_SIZE];
-
- if (GET_FIELD(mEnable)) {
- snprintf(command, MAX_COMMAND_SIZE - 1, "ipfwd enable");
- } else {
- // Don't disable ip forwarding because others interface still need it.
- // Send the dummy command to continue the function chain.
- if (GET_FIELD(mInterfaceList).Length() > 1) {
- snprintf(command, MAX_COMMAND_SIZE - 1, "%s", DUMMY_COMMAND);
- } else {
- snprintf(command, MAX_COMMAND_SIZE - 1, "ipfwd disable");
- }
- }
-
- doCommand(command, aChain, aCallback);
-}
-
-void NetworkUtils::tetheringStatus(CommandChain* aChain,
- CommandCallback aCallback,
- NetworkResultOptions& aResult)
-{
- const char* command= "tether status";
- doCommand(command, aChain, aCallback);
-}
-
-void NetworkUtils::stopTethering(CommandChain* aChain,
- CommandCallback aCallback,
- NetworkResultOptions& aResult)
-{
- char command[MAX_COMMAND_SIZE];
-
- // Don't stop tethering because others interface still need it.
- // Send the dummy to continue the function chain.
- if (GET_FIELD(mInterfaceList).Length() > 1) {
- snprintf(command, MAX_COMMAND_SIZE - 1, "%s", DUMMY_COMMAND);
- } else {
- snprintf(command, MAX_COMMAND_SIZE - 1, "tether stop");
- }
-
- doCommand(command, aChain, aCallback);
-}
-
-void NetworkUtils::startTethering(CommandChain* aChain,
- CommandCallback aCallback,
- NetworkResultOptions& aResult)
-{
- char command[MAX_COMMAND_SIZE];
-
- // We don't need to start tethering again.
- // Send the dummy command to continue the function chain.
- if (aResult.mResultReason.Find("started") != kNotFound) {
- snprintf(command, MAX_COMMAND_SIZE - 1, "%s", DUMMY_COMMAND);
- } else {
- // If usbStartIp/usbEndIp is not valid, don't append them since
- // the trailing white spaces will be parsed to extra empty args
- // See: http://androidxref.com/4.3_r2.1/xref/system/core/libsysutils/src/FrameworkListener.cpp#78
- if (!GET_FIELD(mUsbStartIp).IsEmpty() && !GET_FIELD(mUsbEndIp).IsEmpty()) {
- snprintf(command, MAX_COMMAND_SIZE - 1, "tether start %s %s %s %s",
- GET_CHAR(mWifiStartIp), GET_CHAR(mWifiEndIp),
- GET_CHAR(mUsbStartIp), GET_CHAR(mUsbEndIp));
- } else {
- snprintf(command, MAX_COMMAND_SIZE - 1, "tether start %s %s",
- GET_CHAR(mWifiStartIp), GET_CHAR(mWifiEndIp));
- }
- }
-
- doCommand(command, aChain, aCallback);
-}
-
-void NetworkUtils::untetherInterface(CommandChain* aChain,
- CommandCallback aCallback,
- NetworkResultOptions& aResult)
-{
- char command[MAX_COMMAND_SIZE];
- snprintf(command, MAX_COMMAND_SIZE - 1, "tether interface remove %s", GET_CHAR(mIfname));
-
- doCommand(command, aChain, aCallback);
-}
-
-void NetworkUtils::removeInterfaceFromLocalNetwork(CommandChain* aChain,
- CommandCallback aCallback,
- NetworkResultOptions& aResult)
-{
- // Skip the command for sdk version < 20.
- if (SDK_VERSION < 20) {
- aResult.mResultCode = 0;
- aResult.mResultReason = NS_ConvertUTF8toUTF16("");
- aCallback(aChain, false, aResult);
- return;
- }
-
- char command[MAX_COMMAND_SIZE];
- snprintf(command, MAX_COMMAND_SIZE - 1, "network interface remove local %s",
- GET_CHAR(mIfname));
-
- doCommand(command, aChain, aCallback);
-}
-
-void NetworkUtils::setDnsForwarders(CommandChain* aChain,
- CommandCallback aCallback,
- NetworkResultOptions& aResult)
-{
- char command[MAX_COMMAND_SIZE];
-
- if (SDK_VERSION >= 20) {
- snprintf(command, MAX_COMMAND_SIZE - 1, "tether dns set %d %s %s",
- GET_FIELD(mNetId), GET_CHAR(mDns1), GET_CHAR(mDns2));
- } else {
- snprintf(command, MAX_COMMAND_SIZE - 1, "tether dns set %s %s",
- GET_CHAR(mDns1), GET_CHAR(mDns2));
- }
-
- doCommand(command, aChain, aCallback);
-}
-
-void NetworkUtils::enableNat(CommandChain* aChain,
- CommandCallback aCallback,
- NetworkResultOptions& aResult)
-{
- char command[MAX_COMMAND_SIZE];
-
- if (!GET_FIELD(mIp).IsEmpty() && !GET_FIELD(mPrefix).IsEmpty()) {
- uint32_t prefix = atoi(GET_CHAR(mPrefix));
- uint32_t ip = inet_addr(GET_CHAR(mIp));
- char* networkAddr = getNetworkAddr(ip, prefix);
-
- // address/prefix will only take effect when secondary routing table exists.
- snprintf(command, MAX_COMMAND_SIZE - 1, "nat enable %s %s 1 %s/%s",
- GET_CHAR(mInternalIfname), GET_CHAR(mExternalIfname), networkAddr,
- GET_CHAR(mPrefix));
- } else {
- snprintf(command, MAX_COMMAND_SIZE - 1, "nat enable %s %s 0",
- GET_CHAR(mInternalIfname), GET_CHAR(mExternalIfname));
- }
-
- doCommand(command, aChain, aCallback);
-}
-
-void NetworkUtils::disableNat(CommandChain* aChain,
- CommandCallback aCallback,
- NetworkResultOptions& aResult)
-{
- char command[MAX_COMMAND_SIZE];
-
- if (!GET_FIELD(mIp).IsEmpty() && !GET_FIELD(mPrefix).IsEmpty()) {
- uint32_t prefix = atoi(GET_CHAR(mPrefix));
- uint32_t ip = inet_addr(GET_CHAR(mIp));
- char* networkAddr = getNetworkAddr(ip, prefix);
-
- snprintf(command, MAX_COMMAND_SIZE - 1, "nat disable %s %s 1 %s/%s",
- GET_CHAR(mInternalIfname), GET_CHAR(mExternalIfname), networkAddr,
- GET_CHAR(mPrefix));
- } else {
- snprintf(command, MAX_COMMAND_SIZE - 1, "nat disable %s %s 0",
- GET_CHAR(mInternalIfname), GET_CHAR(mExternalIfname));
- }
-
- doCommand(command, aChain, aCallback);
-}
-
-void NetworkUtils::setDefaultInterface(CommandChain* aChain,
- CommandCallback aCallback,
- NetworkResultOptions& aResult)
-{
- char command[MAX_COMMAND_SIZE];
- snprintf(command, MAX_COMMAND_SIZE - 1, "resolver setdefaultif %s", GET_CHAR(mIfname));
-
- doCommand(command, aChain, aCallback);
-}
-
-void NetworkUtils::removeDefaultRoute(CommandChain* aChain,
- CommandCallback aCallback,
- NetworkResultOptions& aResult)
-{
- if (GET_FIELD(mLoopIndex) >= GET_FIELD(mGateways).Length()) {
- aCallback(aChain, false, aResult);
- return;
- }
-
- char command[MAX_COMMAND_SIZE];
- nsTArray<nsString>& gateways = GET_FIELD(mGateways);
- NS_ConvertUTF16toUTF8 autoGateway(gateways[GET_FIELD(mLoopIndex)]);
-
- int type = getIpType(autoGateway.get());
- snprintf(command, MAX_COMMAND_SIZE - 1, "network route remove %d %s %s/0 %s",
- GET_FIELD(mNetId), GET_CHAR(mIfname),
- type == AF_INET6 ? "::" : "0.0.0.0", autoGateway.get());
-
- struct MyCallback {
- static void callback(CommandCallback::CallbackType aOriginalCallback,
- CommandChain* aChain,
- bool aError,
- mozilla::dom::NetworkResultOptions& aResult)
- {
- NS_ConvertUTF16toUTF8 reason(aResult.mResultReason);
- NU_DBG("removeDefaultRoute's reason: %s", reason.get());
- if (aError && !reason.EqualsASCII("removeRoute() failed (No such process)")) {
- return aOriginalCallback(aChain, aError, aResult);
- }
-
- GET_FIELD(mLoopIndex)++;
- return removeDefaultRoute(aChain, aOriginalCallback, aResult);
- }
- };
-
- CommandCallback wrappedCallback(MyCallback::callback, aCallback);
- doCommand(command, aChain, wrappedCallback);
-}
-
-void NetworkUtils::setInterfaceDns(CommandChain* aChain,
- CommandCallback aCallback,
- NetworkResultOptions& aResult)
-{
- char command[MAX_COMMAND_SIZE];
- int written;
-
- if (SDK_VERSION >= 20) {
- written = SprintfLiteral(command, "resolver setnetdns %d %s",
- GET_FIELD(mNetId), GET_CHAR(mDomain));
- } else {
- written = SprintfLiteral(command, "resolver setifdns %s %s",
- GET_CHAR(mIfname), GET_CHAR(mDomain));
- }
-
- nsTArray<nsString>& dnses = GET_FIELD(mDnses);
- uint32_t length = dnses.Length();
-
- for (uint32_t i = 0; i < length; i++) {
- NS_ConvertUTF16toUTF8 autoDns(dnses[i]);
-
- int ret = snprintf(command + written, sizeof(command) - written, " %s", autoDns.get());
- if (ret <= 1) {
- command[written] = '\0';
- continue;
- }
-
- if (((size_t)ret + written) >= sizeof(command)) {
- command[written] = '\0';
- break;
- }
-
- written += ret;
- }
-
- doCommand(command, aChain, aCallback);
-}
-
-void NetworkUtils::getInterfaceList(CommandChain* aChain,
- CommandCallback aCallback,
- NetworkResultOptions& aResult)
-{
- char command[MAX_COMMAND_SIZE];
- snprintf(command, MAX_COMMAND_SIZE - 1, "interface list");
-
- doCommand(command, aChain, aCallback);
-}
-
-void NetworkUtils::getConfig(CommandChain* aChain,
- CommandCallback aCallback,
- NetworkResultOptions& aResult)
-{
- char command[MAX_COMMAND_SIZE];
- snprintf(command, MAX_COMMAND_SIZE - 1, "interface getcfg %s", GET_CHAR(mIfname));
-
- doCommand(command, aChain, aCallback);
-}
-
-void NetworkUtils::setConfig(CommandChain* aChain,
- CommandCallback aCallback,
- NetworkResultOptions& aResult)
-{
- char command[MAX_COMMAND_SIZE];
- if (SDK_VERSION >= 16) {
- snprintf(command, MAX_COMMAND_SIZE - 1, "interface setcfg %s %s %s %s",
- GET_CHAR(mIfname),
- GET_CHAR(mIp),
- GET_CHAR(mPrefix),
- GET_CHAR(mLink));
- } else {
- snprintf(command, MAX_COMMAND_SIZE - 1, "interface setcfg %s %s %s [%s]",
- GET_CHAR(mIfname),
- GET_CHAR(mIp),
- GET_CHAR(mPrefix),
- GET_CHAR(mLink));
- }
- doCommand(command, aChain, aCallback);
-}
-
-void NetworkUtils::clearAddrForInterface(CommandChain* aChain,
- CommandCallback aCallback,
- NetworkResultOptions& aResult)
-{
- char command[MAX_COMMAND_SIZE];
- snprintf(command, MAX_COMMAND_SIZE - 1, "interface clearaddrs %s", GET_CHAR(mIfname));
-
- doCommand(command, aChain, aCallback);
-}
-
-void NetworkUtils::createNetwork(CommandChain* aChain,
- CommandCallback aCallback,
- NetworkResultOptions& aResult)
-{
- char command[MAX_COMMAND_SIZE];
- snprintf(command, MAX_COMMAND_SIZE - 1, "network create %d", GET_FIELD(mNetId));
-
- doCommand(command, aChain, aCallback);
-}
-
-void NetworkUtils::destroyNetwork(CommandChain* aChain,
- CommandCallback aCallback,
- NetworkResultOptions& aResult)
-{
- char command[MAX_COMMAND_SIZE];
- snprintf(command, MAX_COMMAND_SIZE - 1, "network destroy %d", GET_FIELD(mNetId));
-
- doCommand(command, aChain, aCallback);
-}
-
-void NetworkUtils::addInterfaceToNetwork(CommandChain* aChain,
- CommandCallback aCallback,
- NetworkResultOptions& aResult)
-{
- char command[MAX_COMMAND_SIZE];
- snprintf(command, MAX_COMMAND_SIZE - 1, "network interface add %d %s",
- GET_FIELD(mNetId), GET_CHAR(mIfname));
-
- doCommand(command, aChain, aCallback);
-}
-
-void NetworkUtils::addRouteToInterface(CommandChain* aChain,
- CommandCallback aCallback,
- NetworkResultOptions& aResult)
-{
- struct MyCallback {
- static void callback(CommandCallback::CallbackType aOriginalCallback,
- CommandChain* aChain,
- bool aError,
- mozilla::dom::NetworkResultOptions& aResult)
- {
- NS_ConvertUTF16toUTF8 reason(aResult.mResultReason);
- NU_DBG("addRouteToInterface's reason: %s", reason.get());
- if (aError && reason.EqualsASCII("addRoute() failed (File exists)")) {
- NU_DBG("Ignore \"File exists\" error when adding host route.");
- return aOriginalCallback(aChain, false, aResult);
- }
- aOriginalCallback(aChain, aError, aResult);
- }
- };
-
- CommandCallback wrappedCallback(MyCallback::callback, aCallback);
- modifyRouteOnInterface(aChain, wrappedCallback, aResult, true);
-}
-
-void NetworkUtils::removeRouteFromInterface(CommandChain* aChain,
- CommandCallback aCallback,
- NetworkResultOptions& aResult)
-{
- modifyRouteOnInterface(aChain, aCallback, aResult, false);
-}
-
-void NetworkUtils::modifyRouteOnInterface(CommandChain* aChain,
- CommandCallback aCallback,
- NetworkResultOptions& aResult,
- bool aDoAdd)
-{
- char command[MAX_COMMAND_SIZE];
-
- // AOSP adds host route to its interface table but it doesn't work for
- // B2G because we cannot set fwmark per application. So, we add
- // all host routes to legacy_system table except scope link route.
-
- nsCString ipOrSubnetIp = NS_ConvertUTF16toUTF8(GET_FIELD(mIp));
- nsCString gatewayOrEmpty;
- const char* legacyOrEmpty = "legacy 0 "; // Add to legacy by default.
- if (GET_FIELD(mGateway).IsEmpty()) {
- ipOrSubnetIp = getSubnetIp(ipOrSubnetIp, GET_FIELD(mPrefixLength));
- legacyOrEmpty = ""; // Add to interface table for scope link route.
- } else {
- gatewayOrEmpty = nsCString(" ") + NS_ConvertUTF16toUTF8(GET_FIELD(mGateway));
- }
-
- const char* action = aDoAdd ? "add" : "remove";
-
- snprintf(command, MAX_COMMAND_SIZE - 1, "network route %s%s %d %s %s/%d%s",
- legacyOrEmpty, action,
- GET_FIELD(mNetId), GET_CHAR(mIfname), ipOrSubnetIp.get(),
- GET_FIELD(mPrefixLength), gatewayOrEmpty.get());
-
- doCommand(command, aChain, aCallback);
-}
-
-void NetworkUtils::addDefaultRouteToNetwork(CommandChain* aChain,
- CommandCallback aCallback,
- NetworkResultOptions& aResult)
-{
- if (GET_FIELD(mLoopIndex) >= GET_FIELD(mGateways).Length()) {
- aCallback(aChain, false, aResult);
- return;
- }
-
- char command[MAX_COMMAND_SIZE];
- nsTArray<nsString>& gateways = GET_FIELD(mGateways);
- NS_ConvertUTF16toUTF8 autoGateway(gateways[GET_FIELD(mLoopIndex)]);
-
- int type = getIpType(autoGateway.get());
- snprintf(command, MAX_COMMAND_SIZE - 1, "network route add %d %s %s/0 %s",
- GET_FIELD(mNetId), GET_CHAR(mIfname),
- type == AF_INET6 ? "::" : "0.0.0.0", autoGateway.get());
-
- struct MyCallback {
- static void callback(CommandCallback::CallbackType aOriginalCallback,
- CommandChain* aChain,
- bool aError,
- mozilla::dom::NetworkResultOptions& aResult)
- {
- NS_ConvertUTF16toUTF8 reason(aResult.mResultReason);
- NU_DBG("addDefaultRouteToNetwork's reason: %s", reason.get());
- if (aError && !reason.EqualsASCII("addRoute() failed (File exists)")) {
- return aOriginalCallback(aChain, aError, aResult);
- }
-
- GET_FIELD(mLoopIndex)++;
- return addDefaultRouteToNetwork(aChain, aOriginalCallback, aResult);
- }
- };
-
- CommandCallback wrappedCallback(MyCallback::callback, aCallback);
- doCommand(command, aChain, wrappedCallback);
-}
-
-void NetworkUtils::setDefaultNetwork(CommandChain* aChain,
- CommandCallback aCallback,
- NetworkResultOptions& aResult)
-{
- char command[MAX_COMMAND_SIZE];
- snprintf(command, MAX_COMMAND_SIZE - 1, "network default set %d", GET_FIELD(mNetId));
-
- doCommand(command, aChain, aCallback);
-}
-
-void NetworkUtils::addRouteToSecondaryTable(CommandChain* aChain,
- CommandCallback aCallback,
- NetworkResultOptions& aResult) {
-
- char command[MAX_COMMAND_SIZE];
-
- if (SDK_VERSION >= 20) {
- snprintf(command, MAX_COMMAND_SIZE - 1,
- "network route add %d %s %s/%s %s",
- GET_FIELD(mNetId),
- GET_CHAR(mIfname),
- GET_CHAR(mIp),
- GET_CHAR(mPrefix),
- GET_CHAR(mGateway));
- } else {
- snprintf(command, MAX_COMMAND_SIZE - 1,
- "interface route add %s secondary %s %s %s",
- GET_CHAR(mIfname),
- GET_CHAR(mIp),
- GET_CHAR(mPrefix),
- GET_CHAR(mGateway));
- }
-
- doCommand(command, aChain, aCallback);
-}
-
-void NetworkUtils::removeRouteFromSecondaryTable(CommandChain* aChain,
- CommandCallback aCallback,
- NetworkResultOptions& aResult) {
- char command[MAX_COMMAND_SIZE];
-
- if (SDK_VERSION >= 20) {
- snprintf(command, MAX_COMMAND_SIZE - 1,
- "network route remove %d %s %s/%s %s",
- GET_FIELD(mNetId),
- GET_CHAR(mIfname),
- GET_CHAR(mIp),
- GET_CHAR(mPrefix),
- GET_CHAR(mGateway));
- } else {
- snprintf(command, MAX_COMMAND_SIZE - 1,
- "interface route remove %s secondary %s %s %s",
- GET_CHAR(mIfname),
- GET_CHAR(mIp),
- GET_CHAR(mPrefix),
- GET_CHAR(mGateway));
- }
-
- doCommand(command, aChain, aCallback);
-}
-
-void NetworkUtils::setIpv6Enabled(CommandChain* aChain,
- CommandCallback aCallback,
- NetworkResultOptions& aResult,
- bool aEnabled)
-{
- char command[MAX_COMMAND_SIZE];
- snprintf(command, MAX_COMMAND_SIZE - 1, "interface ipv6 %s %s",
- GET_CHAR(mIfname), aEnabled ? "enable" : "disable");
-
- struct MyCallback {
- static void callback(CommandCallback::CallbackType aOriginalCallback,
- CommandChain* aChain,
- bool aError,
- mozilla::dom::NetworkResultOptions& aResult)
- {
- aOriginalCallback(aChain, false, aResult);
- }
- };
-
- CommandCallback wrappedCallback(MyCallback::callback, aCallback);
- doCommand(command, aChain, wrappedCallback);
-}
-
-void NetworkUtils::enableIpv6(CommandChain* aChain,
- CommandCallback aCallback,
- NetworkResultOptions& aResult)
-{
- setIpv6Enabled(aChain, aCallback, aResult, true);
-}
-
-void NetworkUtils::disableIpv6(CommandChain* aChain,
- CommandCallback aCallback,
- NetworkResultOptions& aResult)
-{
- setIpv6Enabled(aChain, aCallback, aResult, false);
-}
-
-void NetworkUtils::setMtu(CommandChain* aChain,
- CommandCallback aCallback,
- NetworkResultOptions& aResult)
-{
- char command[MAX_COMMAND_SIZE];
- snprintf(command, MAX_COMMAND_SIZE - 1, "interface setmtu %s %ld",
- GET_CHAR(mIfname), GET_FIELD(mMtu));
-
- doCommand(command, aChain, aCallback);
-}
-
-#undef GET_CHAR
-#undef GET_FIELD
-
-/*
- * Netd command success/fail function
- */
-#define ASSIGN_FIELD(prop) aResult.prop = aChain->getParams().prop;
-#define ASSIGN_FIELD_VALUE(prop, value) aResult.prop = value;
-
-template<size_t N>
-void NetworkUtils::runChain(const NetworkParams& aParams,
- const CommandFunc (&aCmds)[N],
- ErrorCallback aError)
-{
- CommandChain* chain = new CommandChain(aParams, aCmds, N, aError);
- gCommandChainQueue.AppendElement(chain);
-
- if (gCommandChainQueue.Length() > 1) {
- NU_DBG("%d command chains are queued. Wait!", gCommandChainQueue.Length());
- return;
- }
-
- NetworkResultOptions result;
- NetworkUtils::next(gCommandChainQueue[0], false, result);
-}
-
-// Called to clean up the command chain and process the queued command chain if any.
-void NetworkUtils::finalizeSuccess(CommandChain* aChain,
- NetworkResultOptions& aResult)
-{
- next(aChain, false, aResult);
-}
-
-void NetworkUtils::wifiTetheringFail(NetworkParams& aOptions, NetworkResultOptions& aResult)
-{
- // Notify the main thread.
- postMessage(aOptions, aResult);
-
- // If one of the stages fails, we try roll back to ensure
- // we don't leave the network systems in limbo.
- ASSIGN_FIELD_VALUE(mEnable, false)
- runChain(aOptions, sWifiFailChain, nullptr);
-}
-
-void NetworkUtils::wifiTetheringSuccess(CommandChain* aChain,
- CommandCallback aCallback,
- NetworkResultOptions& aResult)
-{
- ASSIGN_FIELD(mEnable)
-
- if (aChain->getParams().mEnable) {
- MOZ_ASSERT(!gWifiTetheringParms);
- gWifiTetheringParms = new NetworkParams(aChain->getParams());
- }
- postMessage(aChain->getParams(), aResult);
- finalizeSuccess(aChain, aResult);
-}
-
-void NetworkUtils::usbTetheringFail(NetworkParams& aOptions,
- NetworkResultOptions& aResult)
-{
- // Notify the main thread.
- postMessage(aOptions, aResult);
- // Try to roll back to ensure
- // we don't leave the network systems in limbo.
- // This parameter is used to disable ipforwarding.
- {
- aOptions.mEnable = false;
- runChain(aOptions, sUSBFailChain, nullptr);
- }
-
- // Disable usb rndis function.
- {
- NetworkParams options;
- options.mEnable = false;
- options.mReport = false;
- gNetworkUtils->enableUsbRndis(options);
- }
-}
-
-void NetworkUtils::usbTetheringSuccess(CommandChain* aChain,
- CommandCallback aCallback,
- NetworkResultOptions& aResult)
-{
- ASSIGN_FIELD(mEnable)
- postMessage(aChain->getParams(), aResult);
- finalizeSuccess(aChain, aResult);
-}
-
-void NetworkUtils::networkInterfaceAlarmFail(NetworkParams& aOptions, NetworkResultOptions& aResult)
-{
- postMessage(aOptions, aResult);
-}
-
-void NetworkUtils::networkInterfaceAlarmSuccess(CommandChain* aChain,
- CommandCallback aCallback,
- NetworkResultOptions& aResult)
-{
- // TODO : error is not used , and it is conflict with boolean type error.
- // params.error = parseFloat(params.resultReason);
- postMessage(aChain->getParams(), aResult);
- finalizeSuccess(aChain, aResult);
-}
-
-void NetworkUtils::updateUpStreamFail(NetworkParams& aOptions, NetworkResultOptions& aResult)
-{
- postMessage(aOptions, aResult);
-}
-
-void NetworkUtils::updateUpStreamSuccess(CommandChain* aChain,
- CommandCallback aCallback,
- NetworkResultOptions& aResult)
-{
- ASSIGN_FIELD(mCurExternalIfname)
- ASSIGN_FIELD(mCurInternalIfname)
- postMessage(aChain->getParams(), aResult);
- finalizeSuccess(aChain, aResult);
-}
-
-void NetworkUtils::setDhcpServerFail(NetworkParams& aOptions, NetworkResultOptions& aResult)
-{
- aResult.mSuccess = false;
- postMessage(aOptions, aResult);
-}
-
-void NetworkUtils::setDhcpServerSuccess(CommandChain* aChain, CommandCallback aCallback, NetworkResultOptions& aResult)
-{
- aResult.mSuccess = true;
- postMessage(aChain->getParams(), aResult);
- finalizeSuccess(aChain, aResult);
-}
-
-void NetworkUtils::wifiOperationModeFail(NetworkParams& aOptions, NetworkResultOptions& aResult)
-{
- postMessage(aOptions, aResult);
-}
-
-void NetworkUtils::wifiOperationModeSuccess(CommandChain* aChain,
- CommandCallback aCallback,
- NetworkResultOptions& aResult)
-{
- postMessage(aChain->getParams(), aResult);
- finalizeSuccess(aChain, aResult);
-}
-
-void NetworkUtils::setDnsFail(NetworkParams& aOptions, NetworkResultOptions& aResult)
-{
- postMessage(aOptions, aResult);
-}
-
-void NetworkUtils::defaultAsyncSuccessHandler(CommandChain* aChain,
- CommandCallback aCallback,
- NetworkResultOptions& aResult)
-{
- NU_DBG("defaultAsyncSuccessHandler");
- aResult.mRet = true;
- postMessage(aChain->getParams(), aResult);
- finalizeSuccess(aChain, aResult);
-}
-
-void NetworkUtils::defaultAsyncFailureHandler(NetworkParams& aOptions, NetworkResultOptions& aResult)
-{
- aResult.mRet = false;
- postMessage(aOptions, aResult);
-}
-
-void NetworkUtils::getInterfacesFail(NetworkParams& aOptions, NetworkResultOptions& aResult)
-{
- postMessage(aOptions, aResult);
-}
-
-void NetworkUtils::getInterfacesSuccess(CommandChain* aChain,
- CommandCallback aCallback,
- NetworkResultOptions& aResult)
-{
- char buf[BUF_SIZE];
- NS_ConvertUTF16toUTF8 reason(aResult.mResultReason);
- memcpy(buf, reason.get(), strlen(reason.get()));
-
- nsTArray<nsCString> result;
- split(buf, INTERFACE_DELIMIT, result);
-
- nsTArray<nsString> interfaceList;
- uint32_t length = result.Length();
- convertUTF8toUTF16(result, interfaceList, length);
-
- aResult.mInterfaceList.Construct();
- for (uint32_t i = 0; i < length; i++) {
- aResult.mInterfaceList.Value().AppendElement(interfaceList[i], fallible_t());
- }
-
- postMessage(aChain->getParams(), aResult);
- finalizeSuccess(aChain, aResult);
-}
-
-void NetworkUtils::getInterfaceConfigFail(NetworkParams& aOptions,
- NetworkResultOptions& aResult)
-{
- postMessage(aOptions, aResult);
-}
-
-void NetworkUtils::getInterfaceConfigSuccess(CommandChain* aChain,
- CommandCallback aCallback,
- NetworkResultOptions& aResult)
-{
- char buf[BUF_SIZE];
- NS_ConvertUTF16toUTF8 reason(aResult.mResultReason);
- memcpy(buf, reason.get(), strlen(reason.get()));
-
- nsTArray<nsCString> result;
- split(buf, NETD_MESSAGE_DELIMIT, result);
-
- ASSIGN_FIELD_VALUE(mMacAddr, NS_ConvertUTF8toUTF16(result[0]))
- ASSIGN_FIELD_VALUE(mIpAddr, NS_ConvertUTF8toUTF16(result[1]))
- ASSIGN_FIELD_VALUE(mPrefixLength, atol(result[2].get()))
-
- if (result[3].Find("up")) {
- ASSIGN_FIELD_VALUE(mFlag, NS_ConvertUTF8toUTF16("up"))
- } else {
- ASSIGN_FIELD_VALUE(mFlag, NS_ConvertUTF8toUTF16("down"))
- }
-
- postMessage(aChain->getParams(), aResult);
- finalizeSuccess(aChain, aResult);
-}
-
-void NetworkUtils::setInterfaceConfigFail(NetworkParams& aOptions,
- NetworkResultOptions& aResult)
-{
- postMessage(aOptions, aResult);
-}
-
-void NetworkUtils::setInterfaceConfigSuccess(CommandChain* aChain,
- CommandCallback aCallback,
- NetworkResultOptions& aResult)
-{
- postMessage(aChain->getParams(), aResult);
- finalizeSuccess(aChain, aResult);
-}
-
-#undef ASSIGN_FIELD
-#undef ASSIGN_FIELD_VALUE
-
-NetworkUtils::NetworkUtils(MessageCallback aCallback)
- : mMessageCallback(aCallback)
-{
- mNetUtils = new NetUtils();
-
- char value[Property::VALUE_MAX_LENGTH];
- Property::Get("ro.build.version.sdk", value, nullptr);
- SDK_VERSION = atoi(value);
-
- Property::Get(IPV6_TETHERING, value, "0");
- SUPPORT_IPV6_TETHERING = atoi(value);
-
- gNetworkUtils = this;
-}
-
-NetworkUtils::~NetworkUtils()
-{
-}
-
-#define GET_CHAR(prop) NS_ConvertUTF16toUTF8(aOptions.prop).get()
-#define GET_FIELD(prop) aOptions.prop
-
-// Hoist this type definition to global to avoid template
-// instantiation error on gcc 4.4 used by ICS emulator.
-typedef CommandResult (NetworkUtils::*CommandHandler)(NetworkParams&);
-struct CommandHandlerEntry
-{
- const char* mCommandName;
- CommandHandler mCommandHandler;
-};
-
-void NetworkUtils::ExecuteCommand(NetworkParams aOptions)
-{
- const static CommandHandlerEntry
- COMMAND_HANDLER_TABLE[] = {
-
- // For command 'testCommand', BUILD_ENTRY(testCommand) will generate
- // {"testCommand", NetworkUtils::testCommand}
- #define BUILD_ENTRY(c) {#c, &NetworkUtils::c}
-
- BUILD_ENTRY(removeNetworkRoute),
- BUILD_ENTRY(setDNS),
- BUILD_ENTRY(setDefaultRoute),
- BUILD_ENTRY(removeDefaultRoute),
- BUILD_ENTRY(addHostRoute),
- BUILD_ENTRY(removeHostRoute),
- BUILD_ENTRY(addSecondaryRoute),
- BUILD_ENTRY(removeSecondaryRoute),
- BUILD_ENTRY(setNetworkInterfaceAlarm),
- BUILD_ENTRY(enableNetworkInterfaceAlarm),
- BUILD_ENTRY(disableNetworkInterfaceAlarm),
- BUILD_ENTRY(setTetheringAlarm),
- BUILD_ENTRY(removeTetheringAlarm),
- BUILD_ENTRY(getTetheringStatus),
- BUILD_ENTRY(setWifiOperationMode),
- BUILD_ENTRY(setDhcpServer),
- BUILD_ENTRY(setWifiTethering),
- BUILD_ENTRY(setUSBTethering),
- BUILD_ENTRY(enableUsbRndis),
- BUILD_ENTRY(updateUpStream),
- BUILD_ENTRY(configureInterface),
- BUILD_ENTRY(dhcpRequest),
- BUILD_ENTRY(stopDhcp),
- BUILD_ENTRY(enableInterface),
- BUILD_ENTRY(disableInterface),
- BUILD_ENTRY(resetConnections),
- BUILD_ENTRY(createNetwork),
- BUILD_ENTRY(destroyNetwork),
- BUILD_ENTRY(getNetId),
- BUILD_ENTRY(getInterfaces),
- BUILD_ENTRY(getInterfaceConfig),
- BUILD_ENTRY(setInterfaceConfig),
- BUILD_ENTRY(setMtu),
-
- #undef BUILD_ENTRY
- };
-
- // Loop until we find the command name which matches aOptions.mCmd.
- CommandHandler handler = nullptr;
- for (size_t i = 0; i < mozilla::ArrayLength(COMMAND_HANDLER_TABLE); i++) {
- if (aOptions.mCmd.EqualsASCII(COMMAND_HANDLER_TABLE[i].mCommandName)) {
- handler = COMMAND_HANDLER_TABLE[i].mCommandHandler;
- break;
- }
- }
-
- if (!handler) {
- // Command not found in COMMAND_HANDLER_TABLE.
- WARN("unknown message: %s", NS_ConvertUTF16toUTF8(aOptions.mCmd).get());
- return;
- }
-
- // The handler would return one of the following 3 values
- // to be wrapped to CommandResult:
- //
- // 1) |int32_t| for mostly synchronous native function calls.
- // 2) |NetworkResultOptions| to populate additional results. (e.g. dhcpRequest)
- // 3) |CommandResult::Pending| to indicate the result is not
- // obtained yet.
- //
- // If the handler returns "Pending", the handler should take the
- // responsibility for posting result to main thread.
- CommandResult commandResult = (this->*handler)(aOptions);
- if (!commandResult.isPending()) {
- postMessage(aOptions, commandResult.mResult);
- }
-}
-
-/**
- * Handle received data from netd.
- */
-void NetworkUtils::onNetdMessage(NetdCommand* aCommand)
-{
- char* data = (char*)aCommand->mData;
-
- // get code & reason.
- char* result = strtok(data, NETD_MESSAGE_DELIMIT);
-
- if (!result) {
- nextNetdCommand();
- return;
- }
- uint32_t code = atoi(result);
-
- if (!isBroadcastMessage(code) && SDK_VERSION >= 16) {
- strtok(nullptr, NETD_MESSAGE_DELIMIT);
- }
-
- char* reason = strtok(nullptr, "\0");
-
- if (isBroadcastMessage(code)) {
- NU_DBG("Receiving broadcast message from netd.");
- NU_DBG(" ==> Code: %d Reason: %s", code, reason);
- sendBroadcastMessage(code, reason);
-
- if (code == NETD_COMMAND_INTERFACE_CHANGE) {
- if (gWifiTetheringParms) {
- char linkdownReason[MAX_COMMAND_SIZE];
- snprintf(linkdownReason, MAX_COMMAND_SIZE - 1,
- "Iface linkstate %s down",
- NS_ConvertUTF16toUTF8(gWifiTetheringParms->mIfname).get());
-
- if (!strcmp(reason, linkdownReason)) {
- NU_DBG("Wifi link down, restarting tethering.");
- runChain(*gWifiTetheringParms, sWifiRetryChain, wifiTetheringFail);
- }
- }
- }
-
- nextNetdCommand();
- return;
- }
-
- // Set pending to false before we handle next command.
- NU_DBG("Receiving \"%s\" command response from netd.", gCurrentCommand.command);
- NU_DBG(" ==> Code: %d Reason: %s", code, reason);
-
- gReason.AppendElement(nsCString(reason));
-
- // 1xx response code regards as command is proceeding, we need to wait for
- // final response code such as 2xx, 4xx and 5xx before sending next command.
- if (isProceeding(code)) {
- return;
- }
-
- if (isComplete(code)) {
- gPending = false;
- }
-
- {
- char buf[BUF_SIZE];
- join(gReason, INTERFACE_DELIMIT, BUF_SIZE, buf);
-
- NetworkResultOptions result;
- result.mResultCode = code;
- result.mResultReason = NS_ConvertUTF8toUTF16(buf);
- (gCurrentCommand.callback)(gCurrentCommand.chain, isError(code), result);
- gReason.Clear();
- }
-
- // Handling pending commands if any.
- if (isComplete(code)) {
- nextNetdCommand();
- }
-}
-
-/**
- * Start/Stop DHCP server.
- */
-CommandResult NetworkUtils::setDhcpServer(NetworkParams& aOptions)
-{
- if (aOptions.mEnabled) {
- aOptions.mWifiStartIp = aOptions.mStartIp;
- aOptions.mWifiEndIp = aOptions.mEndIp;
- aOptions.mIp = aOptions.mServerIp;
- aOptions.mPrefix = aOptions.mMaskLength;
- aOptions.mLink = NS_ConvertUTF8toUTF16("up");
-
- runChain(aOptions, sStartDhcpServerChain, setDhcpServerFail);
- } else {
- runChain(aOptions, sStopDhcpServerChain, setDhcpServerFail);
- }
- return CommandResult::Pending();
-}
-
-/**
- * Set DNS servers for given network interface.
- */
-CommandResult NetworkUtils::setDNS(NetworkParams& aOptions)
-{
- uint32_t length = aOptions.mDnses.Length();
-
- if (length > 0) {
- for (uint32_t i = 0; i < length; i++) {
- NS_ConvertUTF16toUTF8 autoDns(aOptions.mDnses[i]);
-
- char dns_prop_key[Property::VALUE_MAX_LENGTH];
- SprintfLiteral(dns_prop_key, "net.dns%d", i+1);
- Property::Set(dns_prop_key, autoDns.get());
- }
- } else {
- // Set dnses from system properties.
- IFProperties interfaceProperties;
- getIFProperties(GET_CHAR(mIfname), interfaceProperties);
-
- Property::Set("net.dns1", interfaceProperties.dns1);
- Property::Set("net.dns2", interfaceProperties.dns2);
- }
-
- // Bump the DNS change property.
- char dnschange[Property::VALUE_MAX_LENGTH];
- Property::Get("net.dnschange", dnschange, "0");
-
- char num[Property::VALUE_MAX_LENGTH];
- snprintf(num, Property::VALUE_MAX_LENGTH - 1, "%d", atoi(dnschange) + 1);
- Property::Set("net.dnschange", num);
-
- // DNS needs to be set through netd since JellyBean (4.3).
- if (SDK_VERSION >= 20) {
- // Lollipop.
- static CommandFunc COMMAND_CHAIN[] = {
- setInterfaceDns,
- addDefaultRouteToNetwork,
- defaultAsyncSuccessHandler
- };
- NetIdManager::NetIdInfo netIdInfo;
- if (!mNetIdManager.lookup(aOptions.mIfname, &netIdInfo)) {
- return -1;
- }
- aOptions.mNetId = netIdInfo.mNetId;
- runChain(aOptions, COMMAND_CHAIN, setDnsFail);
- return CommandResult::Pending();
- }
- if (SDK_VERSION >= 18) {
- // JB, KK.
- static CommandFunc COMMAND_CHAIN[] = {
- #if ANDROID_VERSION == 18
- // Since we don't use per-interface DNS lookup feature on JB,
- // we need to set the default DNS interface whenever setting the
- // DNS name server.
- setDefaultInterface,
- #endif
- setInterfaceDns,
- defaultAsyncSuccessHandler
- };
- runChain(aOptions, COMMAND_CHAIN, setDnsFail);
- return CommandResult::Pending();
- }
-
- return SUCCESS;
-}
-
-CommandResult NetworkUtils::configureInterface(NetworkParams& aOptions)
-{
- NS_ConvertUTF16toUTF8 autoIfname(aOptions.mIfname);
- return mNetUtils->do_ifc_configure(
- autoIfname.get(),
- aOptions.mIpaddr,
- aOptions.mMask,
- aOptions.mGateway_long,
- aOptions.mDns1_long,
- aOptions.mDns2_long
- );
-}
-
-CommandResult NetworkUtils::stopDhcp(NetworkParams& aOptions)
-{
- return mNetUtils->do_dhcp_stop(GET_CHAR(mIfname));
-}
-
-CommandResult NetworkUtils::dhcpRequest(NetworkParams& aOptions) {
- mozilla::dom::NetworkResultOptions result;
-
- NS_ConvertUTF16toUTF8 autoIfname(aOptions.mIfname);
- char ipaddr[Property::VALUE_MAX_LENGTH];
- char gateway[Property::VALUE_MAX_LENGTH];
- uint32_t prefixLength;
- char dns1[Property::VALUE_MAX_LENGTH];
- char dns2[Property::VALUE_MAX_LENGTH];
- char server[Property::VALUE_MAX_LENGTH];
- uint32_t lease;
- char vendorinfo[Property::VALUE_MAX_LENGTH];
- int32_t ret = mNetUtils->do_dhcp_do_request(autoIfname.get(),
- ipaddr,
- gateway,
- &prefixLength,
- dns1,
- dns2,
- server,
- &lease,
- vendorinfo);
-
- RETURN_IF_FAILED(ret);
-
- result.mIpaddr_str = NS_ConvertUTF8toUTF16(ipaddr);
- result.mGateway_str = NS_ConvertUTF8toUTF16(gateway);
- result.mDns1_str = NS_ConvertUTF8toUTF16(dns1);
- result.mDns2_str = NS_ConvertUTF8toUTF16(dns2);
- result.mServer_str = NS_ConvertUTF8toUTF16(server);
- result.mVendor_str = NS_ConvertUTF8toUTF16(vendorinfo);
- result.mLease = lease;
- result.mPrefixLength = prefixLength;
- result.mMask = makeMask(prefixLength);
-
- uint32_t inet4; // only support IPv4 for now.
-
-#define INET_PTON(var, field) \
- PR_BEGIN_MACRO \
- inet_pton(AF_INET, var, &inet4); \
- result.field = inet4; \
- PR_END_MACRO
-
- INET_PTON(ipaddr, mIpaddr);
- INET_PTON(gateway, mGateway);
-
- if (dns1[0] != '\0') {
- INET_PTON(dns1, mDns1);
- }
-
- if (dns2[0] != '\0') {
- INET_PTON(dns2, mDns2);
- }
-
- INET_PTON(server, mServer);
-
- char inet_str[64];
- if (inet_ntop(AF_INET, &result.mMask, inet_str, sizeof(inet_str))) {
- result.mMask_str = NS_ConvertUTF8toUTF16(inet_str);
- }
-
- return result;
-}
-
-CommandResult NetworkUtils::enableInterface(NetworkParams& aOptions) {
- return mNetUtils->do_ifc_enable(
- NS_ConvertUTF16toUTF8(aOptions.mIfname).get());
-}
-
-CommandResult NetworkUtils::disableInterface(NetworkParams& aOptions) {
- return mNetUtils->do_ifc_disable(
- NS_ConvertUTF16toUTF8(aOptions.mIfname).get());
-}
-
-CommandResult NetworkUtils::resetConnections(NetworkParams& aOptions) {
- NS_ConvertUTF16toUTF8 autoIfname(aOptions.mIfname);
- return mNetUtils->do_ifc_reset_connections(
- NS_ConvertUTF16toUTF8(aOptions.mIfname).get(),
- RESET_ALL_ADDRESSES);
-}
-
-/**
- * Set default route and DNS servers for given network interface.
- */
-CommandResult NetworkUtils::setDefaultRoute(NetworkParams& aOptions)
-{
- if (SDK_VERSION < 20) {
- return setDefaultRouteLegacy(aOptions);
- }
-
- static CommandFunc COMMAND_CHAIN[] = {
- addDefaultRouteToNetwork,
- setDefaultNetwork,
- defaultAsyncSuccessHandler,
- };
-
- NetIdManager::NetIdInfo netIdInfo;
- if (!mNetIdManager.lookup(GET_FIELD(mIfname), &netIdInfo)) {
- ERROR("No such interface");
- return -1;
- }
-
- aOptions.mNetId = netIdInfo.mNetId;
- aOptions.mLoopIndex = 0;
- runChain(aOptions, COMMAND_CHAIN, defaultAsyncFailureHandler);
-
- return CommandResult::Pending();
-}
-
-/**
- * Set default route and DNS servers for given network interface by obsoleted libnetutils.
- */
-CommandResult NetworkUtils::setDefaultRouteLegacy(NetworkParams& aOptions)
-{
- NS_ConvertUTF16toUTF8 autoIfname(aOptions.mIfname);
-
- uint32_t length = aOptions.mGateways.Length();
- if (length > 0) {
- for (uint32_t i = 0; i < length; i++) {
- NS_ConvertUTF16toUTF8 autoGateway(aOptions.mGateways[i]);
-
- int type = getIpType(autoGateway.get());
- if (type != AF_INET && type != AF_INET6) {
- continue;
- }
-
- if (type == AF_INET6) {
- RETURN_IF_FAILED(mNetUtils->do_ifc_add_route(autoIfname.get(), "::", 0, autoGateway.get()));
- } else { /* type == AF_INET */
- RETURN_IF_FAILED(mNetUtils->do_ifc_set_default_route(autoIfname.get(), inet_addr(autoGateway.get())));
- }
- }
- } else {
- // Set default froute from system properties.
- char key[Property::KEY_MAX_LENGTH];
- char gateway[Property::KEY_MAX_LENGTH];
-
- snprintf(key, sizeof key - 1, "net.%s.gw", autoIfname.get());
- Property::Get(key, gateway, "");
-
- int type = getIpType(gateway);
- if (type != AF_INET && type != AF_INET6) {
- return EAFNOSUPPORT;
- }
-
- if (type == AF_INET6) {
- RETURN_IF_FAILED(mNetUtils->do_ifc_add_route(autoIfname.get(), "::", 0, gateway));
- } else { /* type == AF_INET */
- RETURN_IF_FAILED(mNetUtils->do_ifc_set_default_route(autoIfname.get(), inet_addr(gateway)));
- }
- }
-
- // Set the default DNS interface.
- if (SDK_VERSION >= 18) {
- // For JB, KK only.
- static CommandFunc COMMAND_CHAIN[] = {
- setDefaultInterface,
- defaultAsyncSuccessHandler
- };
- runChain(aOptions, COMMAND_CHAIN, setDnsFail);
- return CommandResult::Pending();
- }
-
- return SUCCESS;
-}
-
-/**
- * Remove default route for given network interface.
- */
-CommandResult NetworkUtils::removeDefaultRoute(NetworkParams& aOptions)
-{
- NU_DBG("Calling NetworkUtils::removeDefaultRoute");
-
- if (SDK_VERSION < 20) {
- return removeDefaultRouteLegacy(aOptions);
- }
-
- static CommandFunc COMMAND_CHAIN[] = {
- removeDefaultRoute,
- defaultAsyncSuccessHandler,
- };
-
- NetIdManager::NetIdInfo netIdInfo;
- if (!mNetIdManager.lookup(GET_FIELD(mIfname), &netIdInfo)) {
- ERROR("No such interface: %s", GET_CHAR(mIfname));
- return -1;
- }
-
- NU_DBG("Obtained netid %d for interface %s", netIdInfo.mNetId, GET_CHAR(mIfname));
-
- aOptions.mNetId = netIdInfo.mNetId;
- aOptions.mLoopIndex = 0;
- runChain(aOptions, COMMAND_CHAIN, defaultAsyncFailureHandler);
-
- return CommandResult::Pending();
-}
-
-/**
- * Remove default route for given network interface by obsoleted libnetutils.
- */
-CommandResult NetworkUtils::removeDefaultRouteLegacy(NetworkParams& aOptions)
-{
- // Legacy libnetutils calls before Lollipop.
- uint32_t length = aOptions.mGateways.Length();
- for (uint32_t i = 0; i < length; i++) {
- NS_ConvertUTF16toUTF8 autoGateway(aOptions.mGateways[i]);
-
- int type = getIpType(autoGateway.get());
- if (type != AF_INET && type != AF_INET6) {
- return EAFNOSUPPORT;
- }
-
- WARN_IF_FAILED(mNetUtils->do_ifc_remove_route(GET_CHAR(mIfname),
- type == AF_INET ? "0.0.0.0" : "::",
- 0, autoGateway.get()));
- }
-
- return SUCCESS;
-}
-
-/**
- * Add host route for given network interface.
- */
-CommandResult NetworkUtils::addHostRoute(NetworkParams& aOptions)
-{
- if (SDK_VERSION < 20) {
- return addHostRouteLegacy(aOptions);
- }
-
- static CommandFunc COMMAND_CHAIN[] = {
- addRouteToInterface,
- defaultAsyncSuccessHandler,
- };
-
- NetIdManager::NetIdInfo netIdInfo;
- if (!mNetIdManager.lookup(GET_FIELD(mIfname), &netIdInfo)) {
- ERROR("No such interface: %s", GET_CHAR(mIfname));
- return -1;
- }
-
- NU_DBG("Obtained netid %d for interface %s", netIdInfo.mNetId, GET_CHAR(mIfname));
-
- aOptions.mNetId = netIdInfo.mNetId;
- runChain(aOptions, COMMAND_CHAIN, defaultAsyncFailureHandler);
-
- return CommandResult::Pending();
-}
-
-/**
- * Add host route for given network interface.
- */
-CommandResult NetworkUtils::addHostRouteLegacy(NetworkParams& aOptions)
-{
- if (aOptions.mGateway.IsEmpty()) {
- ERROR("addHostRouteLegacy does not support empty gateway.");
- return EINVAL;
- }
-
- NS_ConvertUTF16toUTF8 autoIfname(aOptions.mIfname);
- NS_ConvertUTF16toUTF8 autoHostname(aOptions.mIp);
- NS_ConvertUTF16toUTF8 autoGateway(aOptions.mGateway);
- int type, prefix;
-
- type = getIpType(autoHostname.get());
- if (type != AF_INET && type != AF_INET6) {
- return EAFNOSUPPORT;
- }
-
- if (type != getIpType(autoGateway.get())) {
- return EINVAL;
- }
-
- prefix = type == AF_INET ? 32 : 128;
- return mNetUtils->do_ifc_add_route(autoIfname.get(), autoHostname.get(),
- prefix, autoGateway.get());
-}
-
-/**
- * Remove host route for given network interface.
- */
-CommandResult NetworkUtils::removeHostRoute(NetworkParams& aOptions)
-{
- if (SDK_VERSION < 20) {
- return removeHostRouteLegacy(aOptions);
- }
-
- static CommandFunc COMMAND_CHAIN[] = {
- removeRouteFromInterface,
- defaultAsyncSuccessHandler,
- };
-
- NetIdManager::NetIdInfo netIdInfo;
- if (!mNetIdManager.lookup(GET_FIELD(mIfname), &netIdInfo)) {
- ERROR("No such interface: %s", GET_CHAR(mIfname));
- return -1;
- }
-
- NU_DBG("Obtained netid %d for interface %s", netIdInfo.mNetId, GET_CHAR(mIfname));
-
- aOptions.mNetId = netIdInfo.mNetId;
- runChain(aOptions, COMMAND_CHAIN, defaultAsyncFailureHandler);
-
- return CommandResult::Pending();
-}
-
-/**
- * Remove host route for given network interface.
- */
-CommandResult NetworkUtils::removeHostRouteLegacy(NetworkParams& aOptions)
-{
- NS_ConvertUTF16toUTF8 autoIfname(aOptions.mIfname);
- NS_ConvertUTF16toUTF8 autoHostname(aOptions.mIp);
- NS_ConvertUTF16toUTF8 autoGateway(aOptions.mGateway);
- int type, prefix;
-
- type = getIpType(autoHostname.get());
- if (type != AF_INET && type != AF_INET6) {
- return EAFNOSUPPORT;
- }
-
- if (type != getIpType(autoGateway.get())) {
- return EINVAL;
- }
-
- prefix = type == AF_INET ? 32 : 128;
- return mNetUtils->do_ifc_remove_route(autoIfname.get(), autoHostname.get(),
- prefix, autoGateway.get());
-}
-
-CommandResult NetworkUtils::removeNetworkRoute(NetworkParams& aOptions)
-{
- if (SDK_VERSION < 20) {
- return removeNetworkRouteLegacy(aOptions);
- }
-
- static CommandFunc COMMAND_CHAIN[] = {
- clearAddrForInterface,
- defaultAsyncSuccessHandler,
- };
-
- NetIdManager::NetIdInfo netIdInfo;
- if (!mNetIdManager.lookup(GET_FIELD(mIfname), &netIdInfo)) {
- ERROR("interface %s is not present in any network", GET_CHAR(mIfname));
- return -1;
- }
-
- NU_DBG("Obtained netid %d for interface %s", netIdInfo.mNetId, GET_CHAR(mIfname));
-
- aOptions.mNetId = netIdInfo.mNetId;
- runChain(aOptions, COMMAND_CHAIN, defaultAsyncFailureHandler);
-
- return CommandResult::Pending();
-}
-
-nsCString NetworkUtils::getSubnetIp(const nsCString& aIp, int aPrefixLength)
-{
- int type = getIpType(aIp.get());
-
- if (AF_INET6 == type) {
- struct in6_addr in6;
- if (inet_pton(AF_INET6, aIp.get(), &in6) != 1) {
- return nsCString();
- }
-
- uint32_t p, i, p1, mask;
- p = aPrefixLength;
- i = 0;
- while (i < 4) {
- p1 = p > 32 ? 32 : p;
- p -= p1;
- mask = p1 ? ~0x0 << (32 - p1) : 0;
- in6.s6_addr32[i++] &= htonl(mask);
- }
-
- char subnetStr[INET6_ADDRSTRLEN];
- if (!inet_ntop(AF_INET6, &in6, subnetStr, sizeof subnetStr)) {
- return nsCString();
- }
-
- return nsCString(subnetStr);
- }
-
- if (AF_INET == type) {
- uint32_t ip = inet_addr(aIp.get());
- uint32_t netmask = makeMask(aPrefixLength);
- uint32_t subnet = ip & netmask;
- struct in_addr addr;
- addr.s_addr = subnet;
- return nsCString(inet_ntoa(addr));
- }
-
- return nsCString();
-}
-
-CommandResult NetworkUtils::removeNetworkRouteLegacy(NetworkParams& aOptions)
-{
- NS_ConvertUTF16toUTF8 autoIfname(aOptions.mIfname);
- NS_ConvertUTF16toUTF8 autoIp(aOptions.mIp);
-
- int type = getIpType(autoIp.get());
- if (type != AF_INET && type != AF_INET6) {
- return EAFNOSUPPORT;
- }
-
- uint32_t prefixLength = GET_FIELD(mPrefixLength);
-
- if (type == AF_INET6) {
- // Calculate subnet.
- struct in6_addr in6;
- if (inet_pton(AF_INET6, autoIp.get(), &in6) != 1) {
- return EINVAL;
- }
-
- uint32_t p, i, p1, mask;
- p = prefixLength;
- i = 0;
- while (i < 4) {
- p1 = p > 32 ? 32 : p;
- p -= p1;
- mask = p1 ? ~0x0 << (32 - p1) : 0;
- in6.s6_addr32[i++] &= htonl(mask);
- }
-
- char subnetStr[INET6_ADDRSTRLEN];
- if (!inet_ntop(AF_INET6, &in6, subnetStr, sizeof subnetStr)) {
- return EINVAL;
- }
-
- // Remove default route.
- WARN_IF_FAILED(mNetUtils->do_ifc_remove_route(autoIfname.get(), "::", 0, NULL));
-
- // Remove subnet route.
- RETURN_IF_FAILED(mNetUtils->do_ifc_remove_route(autoIfname.get(), subnetStr, prefixLength, NULL));
- return SUCCESS;
- }
-
- /* type == AF_INET */
- uint32_t ip = inet_addr(autoIp.get());
- uint32_t netmask = makeMask(prefixLength);
- uint32_t subnet = ip & netmask;
- const char* gateway = "0.0.0.0";
- struct in_addr addr;
- addr.s_addr = subnet;
- const char* dst = inet_ntoa(addr);
-
- RETURN_IF_FAILED(mNetUtils->do_ifc_remove_default_route(autoIfname.get()));
- RETURN_IF_FAILED(mNetUtils->do_ifc_remove_route(autoIfname.get(), dst, prefixLength, gateway));
- return SUCCESS;
-}
-
-CommandResult NetworkUtils::addSecondaryRoute(NetworkParams& aOptions)
-{
- static CommandFunc COMMAND_CHAIN[] = {
- addRouteToSecondaryTable,
- defaultAsyncSuccessHandler
- };
-
- if (SDK_VERSION >= 20) {
- NetIdManager::NetIdInfo netIdInfo;
- if (!mNetIdManager.lookup(aOptions.mIfname, &netIdInfo)) {
- return -1;
- }
- aOptions.mNetId = netIdInfo.mNetId;
- }
-
- runChain(aOptions, COMMAND_CHAIN, defaultAsyncFailureHandler);
- return CommandResult::Pending();
-}
-
-CommandResult NetworkUtils::removeSecondaryRoute(NetworkParams& aOptions)
-{
- static CommandFunc COMMAND_CHAIN[] = {
- removeRouteFromSecondaryTable,
- defaultAsyncSuccessHandler
- };
-
- if (SDK_VERSION >= 20) {
- NetIdManager::NetIdInfo netIdInfo;
- if (!mNetIdManager.lookup(aOptions.mIfname, &netIdInfo)) {
- return -1;
- }
- aOptions.mNetId = netIdInfo.mNetId;
- }
-
- runChain(aOptions, COMMAND_CHAIN, defaultAsyncFailureHandler);
- return CommandResult::Pending();
-}
-
-CommandResult NetworkUtils::setNetworkInterfaceAlarm(NetworkParams& aOptions)
-{
- NU_DBG("setNetworkInterfaceAlarms: %s", GET_CHAR(mIfname));
- runChain(aOptions, sNetworkInterfaceSetAlarmChain, networkInterfaceAlarmFail);
- return CommandResult::Pending();
-}
-
-CommandResult NetworkUtils::enableNetworkInterfaceAlarm(NetworkParams& aOptions)
-{
- NU_DBG("enableNetworkInterfaceAlarm: %s", GET_CHAR(mIfname));
- runChain(aOptions, sNetworkInterfaceEnableAlarmChain, networkInterfaceAlarmFail);
- return CommandResult::Pending();
-}
-
-CommandResult NetworkUtils::disableNetworkInterfaceAlarm(NetworkParams& aOptions)
-{
- NU_DBG("disableNetworkInterfaceAlarms: %s", GET_CHAR(mIfname));
- runChain(aOptions, sNetworkInterfaceDisableAlarmChain, networkInterfaceAlarmFail);
- return CommandResult::Pending();
-}
-
-CommandResult NetworkUtils::setTetheringAlarm(NetworkParams& aOptions)
-{
- NU_DBG("setTetheringAlarm");
- runChain(aOptions, sTetheringInterfaceSetAlarmChain, networkInterfaceAlarmFail);
- return CommandResult::Pending();
-}
-
-CommandResult NetworkUtils::removeTetheringAlarm(NetworkParams& aOptions)
-{
- NU_DBG("removeTetheringAlarm");
- runChain(aOptions, sTetheringInterfaceRemoveAlarmChain, networkInterfaceAlarmFail);
- return CommandResult::Pending();
-}
-
-CommandResult NetworkUtils::getTetheringStatus(NetworkParams& aOptions)
-{
- NU_DBG("getTetheringStatus");
- runChain(aOptions, sTetheringGetStatusChain, networkInterfaceAlarmFail);
- return CommandResult::Pending();
-}
-
-/**
- * handling main thread's reload Wifi firmware request
- */
-CommandResult NetworkUtils::setWifiOperationMode(NetworkParams& aOptions)
-{
- NU_DBG("setWifiOperationMode: %s %s", GET_CHAR(mIfname), GET_CHAR(mMode));
- runChain(aOptions, sWifiOperationModeChain, wifiOperationModeFail);
- return CommandResult::Pending();
-}
-
-/**
- * handling main thread's enable/disable WiFi Tethering request
- */
-CommandResult NetworkUtils::setWifiTethering(NetworkParams& aOptions)
-{
- bool enable = aOptions.mEnable;
- IFProperties interfaceProperties;
- getIFProperties(GET_CHAR(mExternalIfname), interfaceProperties);
-
- if (strcmp(interfaceProperties.dns1, "")) {
- int type = getIpType(interfaceProperties.dns1);
- if (type != AF_INET6) {
- aOptions.mDns1 = NS_ConvertUTF8toUTF16(interfaceProperties.dns1);
- }
- }
- if (strcmp(interfaceProperties.dns2, "")) {
- int type = getIpType(interfaceProperties.dns2);
- if (type != AF_INET6) {
- aOptions.mDns2 = NS_ConvertUTF8toUTF16(interfaceProperties.dns2);
- }
- }
- dumpParams(aOptions, "WIFI");
-
- if (SDK_VERSION >= 20) {
- NetIdManager::NetIdInfo netIdInfo;
- if (!mNetIdManager.lookup(aOptions.mExternalIfname, &netIdInfo)) {
- ERROR("No such interface: %s", GET_CHAR(mExternalIfname));
- return -1;
- }
- aOptions.mNetId = netIdInfo.mNetId;
- }
-
- if (enable) {
- NU_DBG("Starting Wifi Tethering on %s <-> %s",
- GET_CHAR(mInternalIfname), GET_CHAR(mExternalIfname));
- runChain(aOptions, sWifiEnableChain, wifiTetheringFail);
- } else {
- NU_DBG("Stopping Wifi Tethering on %s <-> %s",
- GET_CHAR(mInternalIfname), GET_CHAR(mExternalIfname));
- runChain(aOptions, sWifiDisableChain, wifiTetheringFail);
- }
- return CommandResult::Pending();
-}
-
-CommandResult NetworkUtils::setUSBTethering(NetworkParams& aOptions)
-{
- bool enable = aOptions.mEnable;
- IFProperties interfaceProperties;
- getIFProperties(GET_CHAR(mExternalIfname), interfaceProperties);
-
- if (strcmp(interfaceProperties.dns1, "")) {
- int type = getIpType(interfaceProperties.dns1);
- if (type != AF_INET6) {
- aOptions.mDns1 = NS_ConvertUTF8toUTF16(interfaceProperties.dns1);
- }
- }
- if (strcmp(interfaceProperties.dns2, "")) {
- int type = getIpType(interfaceProperties.dns2);
- if (type != AF_INET6) {
- aOptions.mDns2 = NS_ConvertUTF8toUTF16(interfaceProperties.dns2);
- }
- }
- dumpParams(aOptions, "USB");
-
- if (SDK_VERSION >= 20) {
- NetIdManager::NetIdInfo netIdInfo;
- if (!mNetIdManager.lookup(aOptions.mExternalIfname, &netIdInfo)) {
- ERROR("No such interface: %s", GET_CHAR(mExternalIfname));
- return -1;
- }
- aOptions.mNetId = netIdInfo.mNetId;
- }
-
- if (enable) {
- NU_DBG("Starting USB Tethering on %s <-> %s",
- GET_CHAR(mInternalIfname), GET_CHAR(mExternalIfname));
- runChain(aOptions, sUSBEnableChain, usbTetheringFail);
- } else {
- NU_DBG("Stopping USB Tethering on %s <-> %s",
- GET_CHAR(mInternalIfname), GET_CHAR(mExternalIfname));
- runChain(aOptions, sUSBDisableChain, usbTetheringFail);
- }
- return CommandResult::Pending();
-}
-
-void NetworkUtils::escapeQuote(nsCString& aString)
-{
- aString.ReplaceSubstring("\\", "\\\\");
- aString.ReplaceSubstring("\"", "\\\"");
-}
-
-CommandResult NetworkUtils::checkUsbRndisState(NetworkParams& aOptions)
-{
- static uint32_t retry = 0;
-
- char currentState[Property::VALUE_MAX_LENGTH];
- Property::Get(SYS_USB_STATE_PROPERTY, currentState, nullptr);
-
- nsTArray<nsCString> stateFuncs;
- split(currentState, USB_CONFIG_DELIMIT, stateFuncs);
- bool rndisPresent = stateFuncs.Contains(nsCString(USB_FUNCTION_RNDIS));
-
- if (aOptions.mEnable == rndisPresent) {
- NetworkResultOptions result;
- result.mEnable = aOptions.mEnable;
- result.mResult = true;
- retry = 0;
- return result;
- }
- if (retry < USB_FUNCTION_RETRY_TIMES) {
- retry++;
- usleep(USB_FUNCTION_RETRY_INTERVAL * 1000);
- return checkUsbRndisState(aOptions);
- }
-
- NetworkResultOptions result;
- result.mResult = false;
- retry = 0;
- return result;
-}
-
-/**
- * Modify usb function's property to turn on USB RNDIS function
- */
-CommandResult NetworkUtils::enableUsbRndis(NetworkParams& aOptions)
-{
- bool report = aOptions.mReport;
-
- // For some reason, rndis doesn't play well with diag,modem,nmea.
- // So when turning rndis on, we set sys.usb.config to either "rndis"
- // or "rndis,adb". When turning rndis off, we go back to
- // persist.sys.usb.config.
- //
- // On the otoro/unagi, persist.sys.usb.config should be one of:
- //
- // diag,modem,nmea,mass_storage
- // diag,modem,nmea,mass_storage,adb
- //
- // When rndis is enabled, sys.usb.config should be one of:
- //
- // rdnis
- // rndis,adb
- //
- // and when rndis is disabled, it should revert to persist.sys.usb.config
-
- char currentConfig[Property::VALUE_MAX_LENGTH];
- Property::Get(SYS_USB_CONFIG_PROPERTY, currentConfig, nullptr);
-
- nsTArray<nsCString> configFuncs;
- split(currentConfig, USB_CONFIG_DELIMIT, configFuncs);
-
- char persistConfig[Property::VALUE_MAX_LENGTH];
- Property::Get(PERSIST_SYS_USB_CONFIG_PROPERTY, persistConfig, nullptr);
-
- nsTArray<nsCString> persistFuncs;
- split(persistConfig, USB_CONFIG_DELIMIT, persistFuncs);
-
- if (aOptions.mEnable) {
- configFuncs.Clear();
- configFuncs.AppendElement(nsCString(USB_FUNCTION_RNDIS));
- if (persistFuncs.Contains(nsCString(USB_FUNCTION_ADB))) {
- configFuncs.AppendElement(nsCString(USB_FUNCTION_ADB));
- }
- } else {
- // We're turning rndis off, revert back to the persist setting.
- // adb will already be correct there, so we don't need to do any
- // further adjustments.
- configFuncs = persistFuncs;
- }
-
- char newConfig[Property::VALUE_MAX_LENGTH] = "";
- Property::Get(SYS_USB_CONFIG_PROPERTY, currentConfig, nullptr);
- join(configFuncs, USB_CONFIG_DELIMIT, Property::VALUE_MAX_LENGTH, newConfig);
- if (strcmp(currentConfig, newConfig)) {
- Property::Set(SYS_USB_CONFIG_PROPERTY, newConfig);
- }
-
- // Trigger the timer to check usb state and report the result to NetworkManager.
- if (report) {
- usleep(USB_FUNCTION_RETRY_INTERVAL * 1000);
- return checkUsbRndisState(aOptions);
- }
- return SUCCESS;
-}
-
-/**
- * handling upstream interface change event.
- */
-CommandResult NetworkUtils::updateUpStream(NetworkParams& aOptions)
-{
- runChain(aOptions, sUpdateUpStreamChain, updateUpStreamFail);
- return CommandResult::Pending();
-}
-
-/**
- * handling upstream interface change event.
- */
-CommandResult NetworkUtils::createNetwork(NetworkParams& aOptions)
-{
- if (SDK_VERSION < 20) {
- return SUCCESS;
- }
-
- static CommandFunc COMMAND_CHAIN[] = {
- createNetwork,
- enableIpv6,
- addInterfaceToNetwork,
- defaultAsyncSuccessHandler,
- };
-
- NetIdManager::NetIdInfo netIdInfo;
- mNetIdManager.acquire(GET_FIELD(mIfname), &netIdInfo);
- if (netIdInfo.mRefCnt > 1) {
- // Already created. Just return.
- NU_DBG("Interface %s (%d) has been created.", GET_CHAR(mIfname),
- netIdInfo.mNetId);
- return SUCCESS;
- }
-
- NU_DBG("Request netd to create a network with netid %d", netIdInfo.mNetId);
- // Newly created netid. Ask netd to create network.
- aOptions.mNetId = netIdInfo.mNetId;
- runChain(aOptions, COMMAND_CHAIN, defaultAsyncFailureHandler);
-
- return CommandResult::Pending();
-}
-
-/**
- * handling upstream interface change event.
- */
-CommandResult NetworkUtils::destroyNetwork(NetworkParams& aOptions)
-{
- if (SDK_VERSION < 20) {
- return SUCCESS;
- }
-
- static CommandFunc COMMAND_CHAIN[] = {
- disableIpv6,
- destroyNetwork,
- defaultAsyncSuccessHandler,
- };
-
- NetIdManager::NetIdInfo netIdInfo;
- if (!mNetIdManager.release(GET_FIELD(mIfname), &netIdInfo)) {
- ERROR("No existing netid for %s", GET_CHAR(mIfname));
- return -1;
- }
-
- if (netIdInfo.mRefCnt > 0) {
- // Still be referenced. Just return.
- NU_DBG("Someone is still using this interface.");
- return SUCCESS;
- }
-
- NU_DBG("Interface %s (%d) is no longer used. Tell netd to destroy.",
- GET_CHAR(mIfname), netIdInfo.mNetId);
-
- aOptions.mNetId = netIdInfo.mNetId;
- runChain(aOptions, COMMAND_CHAIN, defaultAsyncFailureHandler);
- return CommandResult::Pending();
-}
-
-/**
- * Query the netId associated with the given network interface name.
- */
-CommandResult NetworkUtils::getNetId(NetworkParams& aOptions)
-{
- NetworkResultOptions result;
-
- if (SDK_VERSION < 20) {
- // For pre-Lollipop, use the interface name as the fallback.
- result.mNetId = GET_FIELD(mIfname);
- return result;
- }
-
- NetIdManager::NetIdInfo netIdInfo;
- if (-1 == mNetIdManager.lookup(GET_FIELD(mIfname), &netIdInfo)) {
- return ESRCH;
- }
- result.mNetId.AppendInt(netIdInfo.mNetId, 10);
- return result;
-}
-
-/**
- * Get existing network interfaces.
- */
-CommandResult NetworkUtils::getInterfaces(NetworkParams& aOptions)
-{
- runChain(aOptions, sGetInterfacesChain, getInterfacesFail);
- return CommandResult::Pending();
-}
-
-/**
- * Get network config of a specified interface.
- */
-CommandResult NetworkUtils::getInterfaceConfig(NetworkParams& aOptions)
-{
- runChain(aOptions, sGetInterfaceConfigChain, getInterfaceConfigFail);
- return CommandResult::Pending();
-}
-
-/**
- * Set network config for a specified interface.
- */
-CommandResult NetworkUtils::setInterfaceConfig(NetworkParams& aOptions)
-{
- runChain(aOptions, sSetInterfaceConfigChain, setInterfaceConfigFail);
- return CommandResult::Pending();
-}
-
-CommandResult NetworkUtils::setMtu(NetworkParams& aOptions)
-{
- // Setting/getting mtu is supported since Kitkat.
- if (SDK_VERSION < 19) {
- ERROR("setMtu is not supported in current SDK_VERSION.");
- return -1;
- }
-
- static CommandFunc COMMAND_CHAIN[] = {
- setMtu,
- defaultAsyncSuccessHandler,
- };
-
- runChain(aOptions, COMMAND_CHAIN, defaultAsyncFailureHandler);
- return CommandResult::Pending();
-}
-
-void NetworkUtils::sendBroadcastMessage(uint32_t code, char* reason)
-{
- NetworkResultOptions result;
- switch(code) {
- case NETD_COMMAND_INTERFACE_CHANGE:
- result.mTopic = NS_ConvertUTF8toUTF16("netd-interface-change");
- break;
- case NETD_COMMAND_BANDWIDTH_CONTROLLER:
- result.mTopic = NS_ConvertUTF8toUTF16("netd-bandwidth-control");
- break;
- default:
- return;
- }
-
- result.mBroadcast = true;
- result.mReason = NS_ConvertUTF8toUTF16(reason);
- postMessage(result);
-}
-
-inline uint32_t NetworkUtils::netdResponseType(uint32_t code)
-{
- return (code / 100) * 100;
-}
-
-inline bool NetworkUtils::isBroadcastMessage(uint32_t code)
-{
- uint32_t type = netdResponseType(code);
- return type == NETD_COMMAND_UNSOLICITED;
-}
-
-inline bool NetworkUtils::isError(uint32_t code)
-{
- uint32_t type = netdResponseType(code);
- return type != NETD_COMMAND_PROCEEDING && type != NETD_COMMAND_OKAY;
-}
-
-inline bool NetworkUtils::isComplete(uint32_t code)
-{
- uint32_t type = netdResponseType(code);
- return type != NETD_COMMAND_PROCEEDING;
-}
-
-inline bool NetworkUtils::isProceeding(uint32_t code)
-{
- uint32_t type = netdResponseType(code);
- return type == NETD_COMMAND_PROCEEDING;
-}
-
-void NetworkUtils::dumpParams(NetworkParams& aOptions, const char* aType)
-{
-#ifdef _DEBUG
- NU_DBG("Dump params:");
- NU_DBG(" ifname: %s", GET_CHAR(mIfname));
- NU_DBG(" ip: %s", GET_CHAR(mIp));
- NU_DBG(" link: %s", GET_CHAR(mLink));
- NU_DBG(" prefix: %s", GET_CHAR(mPrefix));
- NU_DBG(" wifiStartIp: %s", GET_CHAR(mWifiStartIp));
- NU_DBG(" wifiEndIp: %s", GET_CHAR(mWifiEndIp));
- NU_DBG(" usbStartIp: %s", GET_CHAR(mUsbStartIp));
- NU_DBG(" usbEndIp: %s", GET_CHAR(mUsbEndIp));
- NU_DBG(" dnsserver1: %s", GET_CHAR(mDns1));
- NU_DBG(" dnsserver2: %s", GET_CHAR(mDns2));
- NU_DBG(" internalIfname: %s", GET_CHAR(mInternalIfname));
- NU_DBG(" externalIfname: %s", GET_CHAR(mExternalIfname));
- if (!strcmp(aType, "WIFI")) {
- NU_DBG(" wifictrlinterfacename: %s", GET_CHAR(mWifictrlinterfacename));
- NU_DBG(" ssid: %s", GET_CHAR(mSsid));
- NU_DBG(" security: %s", GET_CHAR(mSecurity));
- NU_DBG(" key: %s", GET_CHAR(mKey));
- }
-#endif
-}
-
-#undef GET_CHAR
-#undef GET_FIELD
diff --git a/dom/system/gonk/NetworkUtils.h b/dom/system/gonk/NetworkUtils.h
deleted file mode 100644
index d1af35f09d..0000000000
--- a/dom/system/gonk/NetworkUtils.h
+++ /dev/null
@@ -1,498 +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/. */
-
-#ifndef NetworkUtils_h
-#define NetworkUtils_h
-
-#include "nsAutoPtr.h"
-#include "nsString.h"
-#include "mozilla/dom/NetworkOptionsBinding.h"
-#include "mozilla/dom/network/NetUtils.h"
-#include "mozilla/ipc/Netd.h"
-#include "nsTArray.h"
-#include "NetIdManager.h"
-
-class NetworkParams;
-class CommandChain;
-
-class CommandCallback {
-public:
- typedef void (*CallbackType)(CommandChain*, bool,
- mozilla::dom::NetworkResultOptions& aResult);
-
- typedef void (*CallbackWrapperType)(CallbackType aOriginalCallback,
- CommandChain*, bool,
- mozilla::dom::NetworkResultOptions& aResult);
-
- CommandCallback()
- : mCallback(nullptr)
- , mCallbackWrapper(nullptr)
- {
- }
-
- CommandCallback(CallbackType aCallback)
- : mCallback(aCallback)
- , mCallbackWrapper(nullptr)
- {
- }
-
- CommandCallback(CallbackWrapperType aCallbackWrapper,
- CommandCallback aOriginalCallback)
- : mCallback(aOriginalCallback.mCallback)
- , mCallbackWrapper(aCallbackWrapper)
- {
- }
-
- void operator()(CommandChain* aChain, bool aError,
- mozilla::dom::NetworkResultOptions& aResult)
- {
- if (mCallbackWrapper) {
- return mCallbackWrapper(mCallback, aChain, aError, aResult);
- }
- if (mCallback) {
- return mCallback(aChain, aError, aResult);
- }
- }
-
-private:
- CallbackType mCallback;
- CallbackWrapperType mCallbackWrapper;
-};
-
-typedef void (*CommandFunc)(CommandChain*, CommandCallback,
- mozilla::dom::NetworkResultOptions& aResult);
-typedef void (*MessageCallback)(mozilla::dom::NetworkResultOptions& aResult);
-typedef void (*ErrorCallback)(NetworkParams& aOptions,
- mozilla::dom::NetworkResultOptions& aResult);
-
-class NetworkParams
-{
-public:
- NetworkParams() {
- }
-
- NetworkParams(const mozilla::dom::NetworkCommandOptions& aOther) {
-
-#define COPY_SEQUENCE_FIELD(prop, type) \
- if (aOther.prop.WasPassed()) { \
- mozilla::dom::Sequence<type > const & currentValue = aOther.prop.InternalValue(); \
- uint32_t length = currentValue.Length(); \
- for (uint32_t idx = 0; idx < length; idx++) { \
- prop.AppendElement(currentValue[idx]); \
- } \
- }
-
-#define COPY_OPT_STRING_FIELD(prop, defaultValue) \
- if (aOther.prop.WasPassed()) { \
- if (aOther.prop.Value().EqualsLiteral("null")) { \
- prop = defaultValue; \
- } else { \
- prop = aOther.prop.Value(); \
- } \
- } else { \
- prop = defaultValue; \
- }
-
-#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_STRING_FIELD(mDomain, EmptyString())
- COPY_OPT_STRING_FIELD(mGateway, EmptyString())
- COPY_SEQUENCE_FIELD(mGateways, nsString)
- COPY_OPT_STRING_FIELD(mIfname, EmptyString())
- COPY_OPT_STRING_FIELD(mIp, EmptyString())
- COPY_OPT_FIELD(mPrefixLength, 0)
- COPY_OPT_STRING_FIELD(mMode, EmptyString())
- COPY_OPT_FIELD(mReport, false)
- COPY_OPT_FIELD(mEnabled, false)
- COPY_OPT_STRING_FIELD(mWifictrlinterfacename, EmptyString())
- COPY_OPT_STRING_FIELD(mInternalIfname, EmptyString())
- COPY_OPT_STRING_FIELD(mExternalIfname, EmptyString())
- COPY_OPT_FIELD(mEnable, false)
- COPY_OPT_STRING_FIELD(mSsid, EmptyString())
- COPY_OPT_STRING_FIELD(mSecurity, EmptyString())
- COPY_OPT_STRING_FIELD(mKey, EmptyString())
- COPY_OPT_STRING_FIELD(mPrefix, EmptyString())
- COPY_OPT_STRING_FIELD(mLink, EmptyString())
- COPY_SEQUENCE_FIELD(mInterfaceList, nsString)
- COPY_OPT_STRING_FIELD(mWifiStartIp, EmptyString())
- COPY_OPT_STRING_FIELD(mWifiEndIp, EmptyString())
- COPY_OPT_STRING_FIELD(mUsbStartIp, EmptyString())
- COPY_OPT_STRING_FIELD(mUsbEndIp, EmptyString())
- COPY_OPT_STRING_FIELD(mDns1, EmptyString())
- COPY_OPT_STRING_FIELD(mDns2, EmptyString())
- COPY_SEQUENCE_FIELD(mDnses, nsString)
- COPY_OPT_STRING_FIELD(mStartIp, EmptyString())
- COPY_OPT_STRING_FIELD(mEndIp, EmptyString())
- COPY_OPT_STRING_FIELD(mServerIp, EmptyString())
- COPY_OPT_STRING_FIELD(mMaskLength, EmptyString())
- COPY_OPT_STRING_FIELD(mPreInternalIfname, EmptyString())
- COPY_OPT_STRING_FIELD(mPreExternalIfname, EmptyString())
- COPY_OPT_STRING_FIELD(mCurInternalIfname, EmptyString())
- COPY_OPT_STRING_FIELD(mCurExternalIfname, EmptyString())
- COPY_OPT_FIELD(mThreshold, -1)
- COPY_OPT_FIELD(mIpaddr, 0)
- COPY_OPT_FIELD(mMask, 0)
- COPY_OPT_FIELD(mGateway_long, 0)
- COPY_OPT_FIELD(mDns1_long, 0)
- COPY_OPT_FIELD(mDns2_long, 0)
- COPY_OPT_FIELD(mMtu, 0)
-
- mLoopIndex = 0;
-
-#undef COPY_SEQUENCE_FIELD
-#undef COPY_OPT_STRING_FIELD
-#undef COPY_OPT_FIELD
-#undef COPY_FIELD
- }
-
- // Followings attributes are 1-to-1 mapping to NetworkCommandOptions.
- int32_t mId;
- nsString mCmd;
- nsString mDomain;
- nsString mGateway;
- nsTArray<nsString> mGateways;
- nsString mIfname;
- nsString mIp;
- uint32_t mPrefixLength;
- nsString mMode;
- bool mReport;
- bool mEnabled;
- nsString mWifictrlinterfacename;
- nsString mInternalIfname;
- nsString mExternalIfname;
- bool mEnable;
- nsString mSsid;
- nsString mSecurity;
- nsString mKey;
- nsString mPrefix;
- nsString mLink;
- nsTArray<nsString> mInterfaceList;
- nsString mWifiStartIp;
- nsString mWifiEndIp;
- nsString mUsbStartIp;
- nsString mUsbEndIp;
- nsString mDns1;
- nsString mDns2;
- nsTArray<nsString> mDnses;
- nsString mStartIp;
- nsString mEndIp;
- nsString mServerIp;
- nsString mMaskLength;
- nsString mPreInternalIfname;
- nsString mPreExternalIfname;
- nsString mCurInternalIfname;
- nsString mCurExternalIfname;
- long long mThreshold;
- long mIpaddr;
- long mMask;
- long mGateway_long;
- long mDns1_long;
- long mDns2_long;
- long mMtu;
-
- // Auxiliary information required to carry accros command chain.
- int mNetId; // A locally defined id per interface.
- uint32_t mLoopIndex; // Loop index for adding/removing multiple gateways.
-};
-
-// CommandChain store the necessary information to execute command one by one.
-// Including :
-// 1. Command parameters.
-// 2. Command list.
-// 3. Error callback function.
-// 4. Index of current execution command.
-class CommandChain final
-{
-public:
- CommandChain(const NetworkParams& aParams,
- const CommandFunc aCmds[],
- uint32_t aLength,
- ErrorCallback aError)
- : mIndex(-1)
- , mParams(aParams)
- , mCommands(aCmds)
- , mLength(aLength)
- , mError(aError) {
- }
-
- NetworkParams&
- getParams()
- {
- return mParams;
- };
-
- CommandFunc
- getNextCommand()
- {
- mIndex++;
- return mIndex < mLength ? mCommands[mIndex] : nullptr;
- };
-
- ErrorCallback
- getErrorCallback() const
- {
- return mError;
- };
-
-private:
- uint32_t mIndex;
- NetworkParams mParams;
- const CommandFunc* mCommands;
- uint32_t mLength;
- ErrorCallback mError;
-};
-
-// A helper class to easily construct a resolved
-// or a pending result for command execution.
-class CommandResult
-{
-public:
- struct Pending {};
-
-public:
- CommandResult(int32_t aResultCode);
- CommandResult(const mozilla::dom::NetworkResultOptions& aResult);
- CommandResult(const Pending&);
- bool isPending() const;
-
- mozilla::dom::NetworkResultOptions mResult;
-
-private:
- bool mIsPending;
-};
-
-class NetworkUtils final
-{
-public:
- NetworkUtils(MessageCallback aCallback);
- ~NetworkUtils();
-
- void ExecuteCommand(NetworkParams aOptions);
- void onNetdMessage(mozilla::ipc::NetdCommand* aCommand);
-
- MessageCallback getMessageCallback() { return mMessageCallback; }
-
-private:
- /**
- * Commands supported by NetworkUtils.
- */
- CommandResult configureInterface(NetworkParams& aOptions);
- CommandResult dhcpRequest(NetworkParams& aOptions);
- CommandResult stopDhcp(NetworkParams& aOptions);
- CommandResult enableInterface(NetworkParams& aOptions);
- CommandResult disableInterface(NetworkParams& aOptions);
- CommandResult resetConnections(NetworkParams& aOptions);
- CommandResult setDefaultRoute(NetworkParams& aOptions);
- CommandResult addHostRoute(NetworkParams& aOptions);
- CommandResult removeDefaultRoute(NetworkParams& aOptions);
- CommandResult removeHostRoute(NetworkParams& aOptions);
- CommandResult removeNetworkRoute(NetworkParams& aOptions);
- CommandResult setDNS(NetworkParams& aOptions);
- CommandResult addSecondaryRoute(NetworkParams& aOptions);
- CommandResult removeSecondaryRoute(NetworkParams& aOptions);
- CommandResult setNetworkInterfaceAlarm(NetworkParams& aOptions);
- CommandResult enableNetworkInterfaceAlarm(NetworkParams& aOptions);
- CommandResult disableNetworkInterfaceAlarm(NetworkParams& aOptions);
- CommandResult setTetheringAlarm(NetworkParams& aOptions);
- CommandResult removeTetheringAlarm(NetworkParams& aOptions);
- CommandResult getTetheringStatus(NetworkParams& aOptions);
- CommandResult setWifiOperationMode(NetworkParams& aOptions);
- CommandResult setDhcpServer(NetworkParams& aOptions);
- CommandResult setWifiTethering(NetworkParams& aOptions);
- CommandResult setUSBTethering(NetworkParams& aOptions);
- CommandResult enableUsbRndis(NetworkParams& aOptions);
- CommandResult updateUpStream(NetworkParams& aOptions);
- CommandResult createNetwork(NetworkParams& aOptions);
- CommandResult destroyNetwork(NetworkParams& aOptions);
- CommandResult getNetId(NetworkParams& aOptions);
- CommandResult setMtu(NetworkParams& aOptions);
- CommandResult getInterfaces(NetworkParams& aOptions);
- CommandResult getInterfaceConfig(NetworkParams& aOptions);
- CommandResult setInterfaceConfig(NetworkParams& aOptions);
-
- CommandResult addHostRouteLegacy(NetworkParams& aOptions);
- CommandResult removeHostRouteLegacy(NetworkParams& aOptions);
- CommandResult setDefaultRouteLegacy(NetworkParams& aOptions);
- CommandResult removeDefaultRouteLegacy(NetworkParams& aOptions);
- CommandResult removeNetworkRouteLegacy(NetworkParams& aOptions);
-
-
- /**
- * function pointer array holds all netd commands should be executed
- * in sequence to accomplish a given command by other module.
- */
- static const CommandFunc sWifiEnableChain[];
- static const CommandFunc sWifiDisableChain[];
- static const CommandFunc sWifiFailChain[];
- static const CommandFunc sWifiRetryChain[];
- static const CommandFunc sWifiOperationModeChain[];
- static const CommandFunc sUSBEnableChain[];
- static const CommandFunc sUSBDisableChain[];
- static const CommandFunc sUSBFailChain[];
- static const CommandFunc sUpdateUpStreamChain[];
- static const CommandFunc sStartDhcpServerChain[];
- static const CommandFunc sStopDhcpServerChain[];
- static const CommandFunc sNetworkInterfaceEnableAlarmChain[];
- static const CommandFunc sNetworkInterfaceDisableAlarmChain[];
- static const CommandFunc sNetworkInterfaceSetAlarmChain[];
- static const CommandFunc sTetheringInterfaceSetAlarmChain[];
- static const CommandFunc sTetheringInterfaceRemoveAlarmChain[];
- static const CommandFunc sTetheringGetStatusChain[];
- static const CommandFunc sGetInterfacesChain[];
- static const CommandFunc sGetInterfaceConfigChain[];
- static const CommandFunc sSetInterfaceConfigChain[];
-
- /**
- * Individual netd command stored in command chain.
- */
-#define PARAMS CommandChain* aChain, CommandCallback aCallback, \
- mozilla::dom::NetworkResultOptions& aResult
- static void wifiFirmwareReload(PARAMS);
- static void startAccessPointDriver(PARAMS);
- static void stopAccessPointDriver(PARAMS);
- static void setAccessPoint(PARAMS);
- static void cleanUpStream(PARAMS);
- static void createUpStream(PARAMS);
- static void startSoftAP(PARAMS);
- static void stopSoftAP(PARAMS);
- static void clearWifiTetherParms(PARAMS);
- static void enableAlarm(PARAMS);
- static void disableAlarm(PARAMS);
- static void setQuota(PARAMS);
- static void removeQuota(PARAMS);
- static void setAlarm(PARAMS);
- static void removeAlarm(PARAMS);
- static void setGlobalAlarm(PARAMS);
- static void removeGlobalAlarm(PARAMS);
- static void tetherInterface(PARAMS);
- static void addInterfaceToLocalNetwork(PARAMS);
- static void addRouteToLocalNetwork(PARAMS);
- static void preTetherInterfaceList(PARAMS);
- static void postTetherInterfaceList(PARAMS);
- static void addUpstreamInterface(PARAMS);
- static void removeUpstreamInterface(PARAMS);
- static void setIpForwardingEnabled(PARAMS);
- static void tetheringStatus(PARAMS);
- static void stopTethering(PARAMS);
- static void startTethering(PARAMS);
- static void untetherInterface(PARAMS);
- static void removeInterfaceFromLocalNetwork(PARAMS);
- static void setDnsForwarders(PARAMS);
- static void enableNat(PARAMS);
- static void disableNat(PARAMS);
- static void setDefaultInterface(PARAMS);
- static void setInterfaceDns(PARAMS);
- static void getInterfaceList(PARAMS);
- static void getConfig(PARAMS);
- static void setConfig(PARAMS);
- static void wifiTetheringSuccess(PARAMS);
- static void usbTetheringSuccess(PARAMS);
- static void networkInterfaceAlarmSuccess(PARAMS);
- static void updateUpStreamSuccess(PARAMS);
- static void setDhcpServerSuccess(PARAMS);
- static void wifiOperationModeSuccess(PARAMS);
- static void clearAddrForInterface(PARAMS);
- static void createNetwork(PARAMS);
- static void destroyNetwork(PARAMS);
- static void addInterfaceToNetwork(PARAMS);
- static void addDefaultRouteToNetwork(PARAMS);
- static void setDefaultNetwork(PARAMS);
- static void removeDefaultRoute(PARAMS);
- static void removeNetworkRouteSuccess(PARAMS);
- static void removeNetworkRoute(PARAMS);
- static void addRouteToInterface(PARAMS);
- static void removeRouteFromInterface(PARAMS);
- static void modifyRouteOnInterface(PARAMS, bool aDoAdd);
- static void enableIpv6(PARAMS);
- static void disableIpv6(PARAMS);
- static void setMtu(PARAMS);
- static void setIpv6Enabled(PARAMS, bool aEnabled);
- static void addRouteToSecondaryTable(PARAMS);
- static void removeRouteFromSecondaryTable(PARAMS);
- static void defaultAsyncSuccessHandler(PARAMS);
- static void getInterfacesSuccess(PARAMS);
- static void getInterfaceConfigSuccess(PARAMS);
- static void setInterfaceConfigSuccess(PARAMS);
-
-#undef PARAMS
-
- /**
- * Error callback function executed when a command is fail.
- */
-#define PARAMS NetworkParams& aOptions, \
- mozilla::dom::NetworkResultOptions& aResult
- static void wifiTetheringFail(PARAMS);
- static void wifiOperationModeFail(PARAMS);
- static void usbTetheringFail(PARAMS);
- static void updateUpStreamFail(PARAMS);
- static void setDhcpServerFail(PARAMS);
- static void networkInterfaceAlarmFail(PARAMS);
- static void setDnsFail(PARAMS);
- static void defaultAsyncFailureHandler(PARAMS);
- static void getInterfacesFail(PARAMS);
- static void getInterfaceConfigFail(PARAMS);
- static void setInterfaceConfigFail(PARAMS);
-
-#undef PARAMS
-
- /**
- * Command chain processing functions.
- */
- static void next(CommandChain* aChain, bool aError,
- mozilla::dom::NetworkResultOptions& aResult);
- static void nextNetdCommand();
- static void doCommand(const char* aCommand, CommandChain* aChain, CommandCallback aCallback);
-
- /**
- * Notify broadcast message to main thread.
- */
- void sendBroadcastMessage(uint32_t code, char* reason);
-
- /**
- * Utility functions.
- */
- CommandResult checkUsbRndisState(NetworkParams& aOptions);
- void dumpParams(NetworkParams& aOptions, const char* aType);
-
- static void escapeQuote(nsCString& aString);
- inline uint32_t netdResponseType(uint32_t code);
- inline bool isBroadcastMessage(uint32_t code);
- inline bool isError(uint32_t code);
- inline bool isComplete(uint32_t code);
- inline bool isProceeding(uint32_t code);
- void Shutdown();
- static void runNextQueuedCommandChain();
- static void finalizeSuccess(CommandChain* aChain,
- mozilla::dom::NetworkResultOptions& aResult);
-
- template<size_t N>
- static void runChain(const NetworkParams& aParams,
- const CommandFunc (&aCmds)[N],
- ErrorCallback aError);
-
- static nsCString getSubnetIp(const nsCString& aIp, int aPrefixLength);
-
- /**
- * Callback function to send netd result to main thread.
- */
- MessageCallback mMessageCallback;
-
- /*
- * Utility class to access libnetutils.
- */
- nsAutoPtr<NetUtils> mNetUtils;
-
- NetIdManager mNetIdManager;
-};
-
-#endif
diff --git a/dom/system/gonk/NetworkWorker.cpp b/dom/system/gonk/NetworkWorker.cpp
deleted file mode 100644
index caf07f375c..0000000000
--- a/dom/system/gonk/NetworkWorker.cpp
+++ /dev/null
@@ -1,271 +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 "NetworkWorker.h"
-#include "NetworkUtils.h"
-#include <nsThreadUtils.h>
-#include "mozilla/ModuleUtils.h"
-#include "mozilla/ClearOnShutdown.h"
-#include "mozilla/dom/ScriptSettings.h"
-#include "mozilla/dom/ToJSValue.h"
-#include "nsAutoPtr.h"
-#include "nsXULAppAPI.h"
-
-#define NS_NETWORKWORKER_CID \
- { 0x6df093e1, 0x8127, 0x4fa7, {0x90, 0x13, 0xa3, 0xaa, 0xa7, 0x79, 0xbb, 0xdd} }
-
-using namespace mozilla;
-using namespace mozilla::dom;
-using namespace mozilla::ipc;
-
-namespace mozilla {
-
-nsCOMPtr<nsIThread> gWorkerThread;
-
-// The singleton network worker, to be used on the main thread.
-StaticRefPtr<NetworkWorker> gNetworkWorker;
-
-// The singleton networkutils class, that can be used on any thread.
-static nsAutoPtr<NetworkUtils> gNetworkUtils;
-
-// Runnable used dispatch command result on the main thread.
-class NetworkResultDispatcher : public Runnable
-{
-public:
- NetworkResultDispatcher(const NetworkResultOptions& aResult)
- : mResult(aResult)
- {
- MOZ_ASSERT(!NS_IsMainThread());
- }
-
- NS_IMETHOD Run() override
- {
- MOZ_ASSERT(NS_IsMainThread());
-
- if (gNetworkWorker) {
- gNetworkWorker->DispatchNetworkResult(mResult);
- }
- return NS_OK;
- }
-private:
- NetworkResultOptions mResult;
-};
-
-// Runnable used dispatch netd command on the worker thread.
-class NetworkCommandDispatcher : public Runnable
-{
-public:
- NetworkCommandDispatcher(const NetworkParams& aParams)
- : mParams(aParams)
- {
- MOZ_ASSERT(NS_IsMainThread());
- }
-
- NS_IMETHOD Run() override
- {
- MOZ_ASSERT(!NS_IsMainThread());
-
- if (gNetworkUtils) {
- gNetworkUtils->ExecuteCommand(mParams);
- }
- return NS_OK;
- }
-private:
- NetworkParams mParams;
-};
-
-// Runnable used dispatch netd result on the worker thread.
-class NetdEventRunnable : public Runnable
-{
-public:
- NetdEventRunnable(NetdCommand* aCommand)
- : mCommand(aCommand)
- {
- MOZ_ASSERT(!NS_IsMainThread());
- }
-
- NS_IMETHOD Run() override
- {
- MOZ_ASSERT(!NS_IsMainThread());
-
- if (gNetworkUtils) {
- gNetworkUtils->onNetdMessage(mCommand);
- }
- return NS_OK;
- }
-
-private:
- nsAutoPtr<NetdCommand> mCommand;
-};
-
-class NetdMessageConsumer : public NetdConsumer
-{
-public:
- NetdMessageConsumer()
- {
- MOZ_ASSERT(NS_IsMainThread());
- }
-
- void MessageReceived(NetdCommand* aCommand)
- {
- MOZ_ASSERT(!NS_IsMainThread());
-
- nsCOMPtr<nsIRunnable> runnable = new NetdEventRunnable(aCommand);
- if (gWorkerThread) {
- gWorkerThread->Dispatch(runnable, nsIEventTarget::DISPATCH_NORMAL);
- }
- }
-};
-
-NS_IMPL_ISUPPORTS(NetworkWorker, nsINetworkWorker)
-
-NetworkWorker::NetworkWorker()
-{
- MOZ_ASSERT(NS_IsMainThread());
- MOZ_ASSERT(!gNetworkWorker);
-}
-
-NetworkWorker::~NetworkWorker()
-{
- MOZ_ASSERT(!gNetworkWorker);
- MOZ_ASSERT(!mListener);
-}
-
-already_AddRefed<NetworkWorker>
-NetworkWorker::FactoryCreate()
-{
- if (!XRE_IsParentProcess()) {
- return nullptr;
- }
-
- MOZ_ASSERT(NS_IsMainThread());
-
- if (!gNetworkWorker) {
- gNetworkWorker = new NetworkWorker();
- ClearOnShutdown(&gNetworkWorker);
-
- gNetworkUtils = new NetworkUtils(NetworkWorker::NotifyResult);
- ClearOnShutdown(&gNetworkUtils);
- }
-
- RefPtr<NetworkWorker> worker = gNetworkWorker.get();
- return worker.forget();
-}
-
-NS_IMETHODIMP
-NetworkWorker::Start(nsINetworkEventListener* aListener)
-{
- MOZ_ASSERT(NS_IsMainThread());
- MOZ_ASSERT(aListener);
-
- if (mListener) {
- return NS_OK;
- }
-
- nsresult rv;
-
- rv = NS_NewNamedThread("NetworkWorker", getter_AddRefs(gWorkerThread));
- if (NS_FAILED(rv)) {
- NS_WARNING("Can't create network control thread");
- return NS_ERROR_FAILURE;
- }
-
- StartNetd(new NetdMessageConsumer());
- mListener = aListener;
-
- return NS_OK;
-}
-
-NS_IMETHODIMP
-NetworkWorker::Shutdown()
-{
- MOZ_ASSERT(NS_IsMainThread());
-
- if (!mListener) {
- return NS_OK;
- }
-
- StopNetd();
-
- gWorkerThread->Shutdown();
- gWorkerThread = nullptr;
-
- mListener = nullptr;
- return NS_OK;
-}
-
-// Receive command from main thread (NetworkService.js).
-NS_IMETHODIMP
-NetworkWorker::PostMessage(JS::Handle<JS::Value> aOptions, JSContext* aCx)
-{
- MOZ_ASSERT(NS_IsMainThread());
-
- NetworkCommandOptions options;
- if (!options.Init(aCx, aOptions)) {
- NS_WARNING("Bad dictionary passed to NetworkWorker::SendCommand");
- return NS_ERROR_FAILURE;
- }
-
- // Dispatch the command to the control thread.
- NetworkParams NetworkParams(options);
- nsCOMPtr<nsIRunnable> runnable = new NetworkCommandDispatcher(NetworkParams);
- if (gWorkerThread) {
- gWorkerThread->Dispatch(runnable, nsIEventTarget::DISPATCH_NORMAL);
- }
- return NS_OK;
-}
-
-void
-NetworkWorker::DispatchNetworkResult(const NetworkResultOptions& aOptions)
-{
- MOZ_ASSERT(NS_IsMainThread());
-
- mozilla::AutoSafeJSContext cx;
- JS::RootedValue val(cx);
-
- if (!ToJSValue(cx, aOptions, &val)) {
- return;
- }
-
- // Call the listener with a JS value.
- if (mListener) {
- mListener->OnEvent(val);
- }
-}
-
-// Callback function from network worker thread to update result on main thread.
-void
-NetworkWorker::NotifyResult(NetworkResultOptions& aResult)
-{
- MOZ_ASSERT(!NS_IsMainThread());
-
- nsCOMPtr<nsIRunnable> runnable = new NetworkResultDispatcher(aResult);
- NS_DispatchToMainThread(runnable);
-}
-
-NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(NetworkWorker,
- NetworkWorker::FactoryCreate)
-
-NS_DEFINE_NAMED_CID(NS_NETWORKWORKER_CID);
-
-static const mozilla::Module::CIDEntry kNetworkWorkerCIDs[] = {
- { &kNS_NETWORKWORKER_CID, false, nullptr, NetworkWorkerConstructor },
- { nullptr }
-};
-
-static const mozilla::Module::ContractIDEntry kNetworkWorkerContracts[] = {
- { "@mozilla.org/network/worker;1", &kNS_NETWORKWORKER_CID },
- { nullptr }
-};
-
-static const mozilla::Module kNetworkWorkerModule = {
- mozilla::Module::kVersion,
- kNetworkWorkerCIDs,
- kNetworkWorkerContracts,
- nullptr
-};
-
-} // namespace mozilla
-
-NSMODULE_DEFN(NetworkWorkerModule) = &kNetworkWorkerModule;
diff --git a/dom/system/gonk/NetworkWorker.h b/dom/system/gonk/NetworkWorker.h
deleted file mode 100644
index f5c0a8fdde..0000000000
--- a/dom/system/gonk/NetworkWorker.h
+++ /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/. */
-
-#ifndef NetworkWorker_h
-#define NetworkWorker_h
-
-#include "mozilla/dom/NetworkOptionsBinding.h"
-#include "mozilla/ipc/Netd.h"
-#include "nsINetworkWorker.h"
-#include "nsCOMPtr.h"
-#include "nsThread.h"
-
-namespace mozilla {
-
-class NetworkWorker final : public nsINetworkWorker
-{
-public:
- NS_DECL_ISUPPORTS
- NS_DECL_NSINETWORKWORKER
-
- static already_AddRefed<NetworkWorker> FactoryCreate();
-
- void DispatchNetworkResult(const mozilla::dom::NetworkResultOptions& aOptions);
-
-private:
- NetworkWorker();
- ~NetworkWorker();
-
- static void NotifyResult(mozilla::dom::NetworkResultOptions& aResult);
-
- nsCOMPtr<nsINetworkEventListener> mListener;
-};
-
-} // namespace mozilla
-
-#endif // NetworkWorker_h
diff --git a/dom/system/gonk/OpenFileFinder.cpp b/dom/system/gonk/OpenFileFinder.cpp
deleted file mode 100644
index 388e813e17..0000000000
--- a/dom/system/gonk/OpenFileFinder.cpp
+++ /dev/null
@@ -1,251 +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 "OpenFileFinder.h"
-
-#include "mozilla/FileUtils.h"
-#include "nsPrintfCString.h"
-
-#include <sys/stat.h>
-#include <errno.h>
-
-#undef USE_DEBUG
-#define USE_DEBUG 0
-
-#undef LOG
-#undef LOGW
-#undef ERR
-#define LOG(args...) __android_log_print(ANDROID_LOG_INFO, "OpenFileFinder", ## args)
-#define LOGW(args...) __android_log_print(ANDROID_LOG_WARN, "OpenFileFinder", ## args)
-#define ERR(args...) __android_log_print(ANDROID_LOG_ERROR, "OpenFileFinder", ## args)
-
-#undef DBG
-#if USE_DEBUG
-#define DBG(args...) __android_log_print(ANDROID_LOG_DEBUG, "OpenFileFinder" , ## args)
-#else
-#define DBG(args...)
-#endif
-
-namespace mozilla {
-namespace system {
-
-OpenFileFinder::OpenFileFinder(const nsACString& aPath,
- bool aCheckIsB2gOrDescendant /* = true */)
- : mPath(aPath),
- mProcDir(nullptr),
- mFdDir(nullptr),
- mPid(0),
- mCheckIsB2gOrDescendant(aCheckIsB2gOrDescendant)
-{
- // We assume that we're running in the parent process
- mMyPid = getpid();
-}
-
-OpenFileFinder::~OpenFileFinder()
-{
- Close();
-}
-
-bool
-OpenFileFinder::First(OpenFileFinder::Info* aInfo)
-{
- Close();
-
- mProcDir = opendir("/proc");
- if (!mProcDir) {
- return false;
- }
- mState = NEXT_PID;
- return Next(aInfo);
-}
-
-bool
-OpenFileFinder::Next(OpenFileFinder::Info* aInfo)
-{
- // NOTE: This function calls readdir and readlink, neither of which should
- // block since we're using the proc filesystem, which is a purely
- // kernel in-memory filesystem and doesn't depend on external driver
- // behaviour.
- while (mState != DONE) {
- switch (mState) {
- case NEXT_PID: {
- struct dirent *pidEntry;
- pidEntry = readdir(mProcDir);
- if (!pidEntry) {
- mState = DONE;
- break;
- }
- char *endPtr;
- mPid = strtol(pidEntry->d_name, &endPtr, 10);
- if (mPid == 0 || *endPtr != '\0') {
- // Not a +ve number - ignore
- continue;
- }
- // We've found a /proc/PID directory. Scan open file descriptors.
- if (mFdDir) {
- closedir(mFdDir);
- }
- nsPrintfCString fdDirPath("/proc/%d/fd", mPid);
- mFdDir = opendir(fdDirPath.get());
- if (!mFdDir) {
- continue;
- }
- mState = CHECK_FDS;
- }
- // Fall through
- case CHECK_FDS: {
- struct dirent *fdEntry;
- while((fdEntry = readdir(mFdDir))) {
- if (!strcmp(fdEntry->d_name, ".") ||
- !strcmp(fdEntry->d_name, "..")) {
- continue;
- }
- nsPrintfCString fdSymLink("/proc/%d/fd/%s", mPid, fdEntry->d_name);
- nsCString resolvedPath;
- if (ReadSymLink(fdSymLink, resolvedPath) && PathMatches(resolvedPath)) {
- // We found an open file contained within the directory tree passed
- // into the constructor.
- FillInfo(aInfo, resolvedPath);
- // If sCheckIsB2gOrDescendant is set false, the caller cares about
- // all processes which have open files. If sCheckIsB2gOrDescendant
- // is set false, we only care about the b2g proccess or its descendants.
- if (!mCheckIsB2gOrDescendant || aInfo->mIsB2gOrDescendant) {
- return true;
- }
- LOG("Ignore process(%d), not a b2g process or its descendant.",
- aInfo->mPid);
- }
- }
- // We've checked all of the files for this pid, move onto the next one.
- mState = NEXT_PID;
- continue;
- }
- case DONE:
- default:
- mState = DONE; // covers the default case
- break;
- }
- }
- return false;
-}
-
-void
-OpenFileFinder::Close()
-{
- if (mFdDir) {
- closedir(mFdDir);
- }
- if (mProcDir) {
- closedir(mProcDir);
- }
-}
-
-void
-OpenFileFinder::FillInfo(OpenFileFinder::Info* aInfo, const nsACString& aPath)
-{
- aInfo->mFileName = aPath;
- aInfo->mPid = mPid;
- nsPrintfCString exePath("/proc/%d/exe", mPid);
- ReadSymLink(exePath, aInfo->mExe);
- aInfo->mComm.Truncate();
- aInfo->mAppName.Truncate();
- nsPrintfCString statPath("/proc/%d/stat", mPid);
- nsCString statString;
- statString.SetLength(200);
- char *stat = statString.BeginWriting();
- if (!stat) {
- return;
- }
- ReadSysFile(statPath.get(), stat, statString.Length());
- // The stat line includes the comm field, surrounded by parenthesis.
- // However, the contents of the comm field itself is arbitrary and
- // and can include ')', so we search for the rightmost ) as being
- // the end of the comm field.
- char *closeParen = strrchr(stat, ')');
- if (!closeParen) {
- return;
- }
- char *openParen = strchr(stat, '(');
- if (!openParen) {
- return;
- }
- if (openParen >= closeParen) {
- return;
- }
- nsDependentCSubstring comm(&openParen[1], closeParen - openParen - 1);
- aInfo->mComm = comm;
- // There is a single character field after the comm and then
- // the parent pid (the field we're interested in).
- // ) X ppid
- // 01234
- int ppid = atoi(&closeParen[4]);
-
- if (mPid == mMyPid) {
- // This is chrome process
- aInfo->mIsB2gOrDescendant = true;
- DBG("Chrome process has open file(s)");
- return;
- }
- // For the rest (non-chrome process), we recursively check the ppid to know
- // it is a descendant of b2g or not. See bug 931456.
- while (ppid != mMyPid && ppid != 1) {
- DBG("Process(%d) is not forked from b2g(%d) or Init(1), keep looking",
- ppid, mMyPid);
- nsPrintfCString ppStatPath("/proc/%d/stat", ppid);
- ReadSysFile(ppStatPath.get(), stat, statString.Length());
- closeParen = strrchr(stat, ')');
- if (!closeParen) {
- return;
- }
- ppid = atoi(&closeParen[4]);
- }
- if (ppid == 1) {
- // This is a not a b2g process.
- DBG("Non-b2g process has open file(s)");
- aInfo->mIsB2gOrDescendant = false;
- return;
- }
- if (ppid == mMyPid) {
- // This is a descendant of b2g.
- DBG("Child process of chrome process has open file(s)");
- aInfo->mIsB2gOrDescendant = true;
- }
-
- // This looks like a content process. The comm field will be the
- // app name.
- aInfo->mAppName = aInfo->mComm;
-}
-
-bool
-OpenFileFinder::ReadSymLink(const nsACString& aSymLink, nsACString& aOutPath)
-{
- aOutPath.Truncate();
- const char *symLink = aSymLink.BeginReading();
-
- // Verify that we actually have a symlink.
- struct stat st;
- if (lstat(symLink, &st)) {
- return false;
- }
- if ((st.st_mode & S_IFMT) != S_IFLNK) {
- return false;
- }
-
- // Contrary to the documentation st.st_size doesn't seem to be a reliable
- // indication of the length when reading from /proc, so we use a fixed
- // size buffer instead.
-
- char resolvedSymLink[PATH_MAX];
- ssize_t pathLength = readlink(symLink, resolvedSymLink,
- sizeof(resolvedSymLink) - 1);
- if (pathLength <= 0) {
- return false;
- }
- resolvedSymLink[pathLength] = '\0';
- aOutPath.Assign(resolvedSymLink);
- return true;
-}
-
-} // system
-} // mozilla
diff --git a/dom/system/gonk/OpenFileFinder.h b/dom/system/gonk/OpenFileFinder.h
deleted file mode 100644
index 24517965a5..0000000000
--- a/dom/system/gonk/OpenFileFinder.h
+++ /dev/null
@@ -1,63 +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/. */
-
-#ifndef mozilla_system_openfilefinder_h__
-#define mozilla_system_openfilefinder_h__
-
-#include "nsString.h"
-
-#include <dirent.h>
-
-namespace mozilla {
-namespace system {
-
-class OpenFileFinder
-{
-public:
- enum State
- {
- NEXT_PID,
- CHECK_FDS,
- DONE
- };
- class Info
- {
- public:
- nsCString mFileName; // name of the the open file
- nsCString mAppName; // App which has the file open (if it's a b2g app)
- pid_t mPid; // pid of the process which has the file open
- nsCString mComm; // comm associated with pid
- nsCString mExe; // executable name associated with pid
- bool mIsB2gOrDescendant; // this is b2g/its descendant or not
- };
-
- OpenFileFinder(const nsACString& aPath, bool aCheckIsB2gOrDescendant = true);
- ~OpenFileFinder();
-
- bool First(Info* aInfo); // Return the first open file
- bool Next(Info* aInfo); // Return the next open file
- void Close();
-
-private:
-
- void FillInfo(Info *aInfo, const nsACString& aPath);
- bool ReadSymLink(const nsACString& aSymLink, nsACString& aOutPath);
- bool PathMatches(const nsACString& aPath)
- {
- return Substring(aPath, 0, mPath.Length()).Equals(mPath);
- }
-
- State mState; // Keeps track of what we're doing.
- nsCString mPath; // Only report files contained within this directory tree
- DIR* mProcDir; // Used for scanning /proc
- DIR* mFdDir; // Used for scanning /proc/PID/fd
- int mPid; // PID currently being processed
- pid_t mMyPid; // PID of parent process, we assume we're running on it.
- bool mCheckIsB2gOrDescendant; // Do we care about non-b2g process?
-};
-
-} // system
-} // mozilla
-
-#endif // mozilla_system_nsvolume_h__
diff --git a/dom/system/gonk/RILSystemMessenger.jsm b/dom/system/gonk/RILSystemMessenger.jsm
deleted file mode 100644
index 81373458ce..0000000000
--- a/dom/system/gonk/RILSystemMessenger.jsm
+++ /dev/null
@@ -1,338 +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");
-
-XPCOMUtils.defineLazyGetter(this, "RIL", function () {
- let obj = {};
- Cu.import("resource://gre/modules/ril_consts.js", obj);
- return obj;
-});
-
-/**
- * RILSystemMessenger
- */
-this.RILSystemMessenger = function() {};
-RILSystemMessenger.prototype = {
-
- /**
- * Hook of Broadcast function
- *
- * @param aType
- * The type of the message to be sent.
- * @param aMessage
- * The message object to be broadcasted.
- */
- broadcastMessage: function(aType, aMessage) {
- // Function stub to be replaced by the owner of this messenger.
- },
-
- /**
- * Hook of the function to create MozStkCommand message.
- * @param aStkProactiveCmd
- * nsIStkProactiveCmd instance.
- *
- * @return a JS object which complies the dictionary of MozStkCommand defined
- * in MozStkCommandEvent.webidl
- */
- createCommandMessage: function(aStkProactiveCmd) {
- // Function stub to be replaced by the owner of this messenger.
- },
-
- /**
- * Wrapper to send "telephony-new-call" system message.
- */
- notifyNewCall: function() {
- this.broadcastMessage("telephony-new-call", {});
- },
-
- /**
- * Wrapper to send "telephony-call-ended" system message.
- */
- notifyCallEnded: function(aServiceId, aNumber, aCdmaWaitingNumber, aEmergency,
- aDuration, aOutgoing, aHangUpLocal) {
- let data = {
- serviceId: aServiceId,
- number: aNumber,
- emergency: aEmergency,
- duration: aDuration,
- direction: aOutgoing ? "outgoing" : "incoming",
- hangUpLocal: aHangUpLocal
- };
-
- if (aCdmaWaitingNumber != null) {
- data.secondNumber = aCdmaWaitingNumber;
- }
-
- this.broadcastMessage("telephony-call-ended", data);
- },
-
- _convertSmsMessageClass: function(aMessageClass) {
- return RIL.GECKO_SMS_MESSAGE_CLASSES[aMessageClass] || null;
- },
-
- _convertSmsDelivery: function(aDelivery) {
- return ["received", "sending", "sent", "error"][aDelivery] || null;
- },
-
- _convertSmsDeliveryStatus: function(aDeliveryStatus) {
- return [
- RIL.GECKO_SMS_DELIVERY_STATUS_NOT_APPLICABLE,
- RIL.GECKO_SMS_DELIVERY_STATUS_SUCCESS,
- RIL.GECKO_SMS_DELIVERY_STATUS_PENDING,
- RIL.GECKO_SMS_DELIVERY_STATUS_ERROR
- ][aDeliveryStatus] || null;
- },
-
- /**
- * Wrapper to send 'sms-received', 'sms-delivery-success', 'sms-sent',
- * 'sms-failed', 'sms-delivery-error' system message.
- */
- notifySms: function(aNotificationType, aId, aThreadId, aIccId, aDelivery,
- aDeliveryStatus, aSender, aReceiver, aBody, aMessageClass,
- aTimestamp, aSentTimestamp, aDeliveryTimestamp, aRead) {
- let msgType = [
- "sms-received",
- "sms-sent",
- "sms-delivery-success",
- "sms-failed",
- "sms-delivery-error"
- ][aNotificationType];
-
- if (!msgType) {
- throw new Error("Invalid Notification Type: " + aNotificationType);
- }
-
- this.broadcastMessage(msgType, {
- iccId: aIccId,
- type: "sms",
- id: aId,
- threadId: aThreadId,
- delivery: this._convertSmsDelivery(aDelivery),
- deliveryStatus: this._convertSmsDeliveryStatus(aDeliveryStatus),
- sender: aSender,
- receiver: aReceiver,
- body: aBody,
- messageClass: this._convertSmsMessageClass(aMessageClass),
- timestamp: aTimestamp,
- sentTimestamp: aSentTimestamp,
- deliveryTimestamp: aDeliveryTimestamp,
- read: aRead
- });
- },
-
- _convertCbGsmGeographicalScope: function(aGeographicalScope) {
- return RIL.CB_GSM_GEOGRAPHICAL_SCOPE_NAMES[aGeographicalScope] || null;
- },
-
- _convertCbMessageClass: function(aMessageClass) {
- return RIL.GECKO_SMS_MESSAGE_CLASSES[aMessageClass] || null;
- },
-
- _convertCbEtwsWarningType: function(aWarningType) {
- return RIL.CB_ETWS_WARNING_TYPE_NAMES[aWarningType] || null;
- },
-
- /**
- * Wrapper to send 'cellbroadcast-received' system message.
- */
- notifyCbMessageReceived: function(aServiceId, aGsmGeographicalScope, aMessageCode,
- aMessageId, aLanguage, aBody, aMessageClass,
- aTimestamp, aCdmaServiceCategory, aHasEtwsInfo,
- aEtwsWarningType, aEtwsEmergencyUserAlert, aEtwsPopup) {
- // Align the same layout to MozCellBroadcastMessage
- let data = {
- serviceId: aServiceId,
- gsmGeographicalScope: this._convertCbGsmGeographicalScope(aGsmGeographicalScope),
- messageCode: aMessageCode,
- messageId: aMessageId,
- language: aLanguage,
- body: aBody,
- messageClass: this._convertCbMessageClass(aMessageClass),
- timestamp: aTimestamp,
- cdmaServiceCategory: null,
- etws: null
- };
-
- if (aHasEtwsInfo) {
- data.etws = {
- warningType: this._convertCbEtwsWarningType(aEtwsWarningType),
- emergencyUserAlert: aEtwsEmergencyUserAlert,
- popup: aEtwsPopup
- };
- }
-
- if (aCdmaServiceCategory !=
- Ci.nsICellBroadcastService.CDMA_SERVICE_CATEGORY_INVALID) {
- data.cdmaServiceCategory = aCdmaServiceCategory;
- }
-
- this.broadcastMessage("cellbroadcast-received", data);
- },
-
- /**
- * Wrapper to send 'ussd-received' system message.
- */
- notifyUssdReceived: function(aServiceId, aMessage, aSessionEnded) {
- this.broadcastMessage("ussd-received", {
- serviceId: aServiceId,
- message: aMessage,
- sessionEnded: aSessionEnded
- });
- },
-
- /**
- * Wrapper to send 'cdma-info-rec-received' system message with Display Info.
- */
- notifyCdmaInfoRecDisplay: function(aServiceId, aDisplay) {
- this.broadcastMessage("cdma-info-rec-received", {
- clientId: aServiceId,
- display: aDisplay
- });
- },
-
- /**
- * Wrapper to send 'cdma-info-rec-received' system message with Called Party
- * Number Info.
- */
- notifyCdmaInfoRecCalledPartyNumber: function(aServiceId, aType, aPlan,
- aNumber, aPi, aSi) {
- this.broadcastMessage("cdma-info-rec-received", {
- clientId: aServiceId,
- calledNumber: {
- type: aType,
- plan: aPlan,
- number: aNumber,
- pi: aPi,
- si: aSi
- }
- });
- },
-
- /**
- * Wrapper to send 'cdma-info-rec-received' system message with Calling Party
- * Number Info.
- */
- notifyCdmaInfoRecCallingPartyNumber: function(aServiceId, aType, aPlan,
- aNumber, aPi, aSi) {
- this.broadcastMessage("cdma-info-rec-received", {
- clientId: aServiceId,
- callingNumber: {
- type: aType,
- plan: aPlan,
- number: aNumber,
- pi: aPi,
- si: aSi
- }
- });
- },
-
- /**
- * Wrapper to send 'cdma-info-rec-received' system message with Connected Party
- * Number Info.
- */
- notifyCdmaInfoRecConnectedPartyNumber: function(aServiceId, aType, aPlan,
- aNumber, aPi, aSi) {
- this.broadcastMessage("cdma-info-rec-received", {
- clientId: aServiceId,
- connectedNumber: {
- type: aType,
- plan: aPlan,
- number: aNumber,
- pi: aPi,
- si: aSi
- }
- });
- },
-
- /**
- * Wrapper to send 'cdma-info-rec-received' system message with Signal Info.
- */
- notifyCdmaInfoRecSignal: function(aServiceId, aType, aAlertPitch, aSignal) {
- this.broadcastMessage("cdma-info-rec-received", {
- clientId: aServiceId,
- signal: {
- type: aType,
- alertPitch: aAlertPitch,
- signal: aSignal
- }
- });
- },
-
- /**
- * Wrapper to send 'cdma-info-rec-received' system message with Redirecting
- * Number Info.
- */
- notifyCdmaInfoRecRedirectingNumber: function(aServiceId, aType, aPlan,
- aNumber, aPi, aSi, aReason) {
- this.broadcastMessage("cdma-info-rec-received", {
- clientId: aServiceId,
- redirect: {
- type: aType,
- plan: aPlan,
- number: aNumber,
- pi: aPi,
- si: aSi,
- reason: aReason
- }
- });
- },
-
- /**
- * Wrapper to send 'cdma-info-rec-received' system message with Line Control Info.
- */
- notifyCdmaInfoRecLineControl: function(aServiceId, aPolarityIncluded,
- aToggle, aReverse, aPowerDenial) {
- this.broadcastMessage("cdma-info-rec-received", {
- clientId: aServiceId,
- lineControl: {
- polarityIncluded: aPolarityIncluded,
- toggle: aToggle,
- reverse: aReverse,
- powerDenial: aPowerDenial
- }
- });
- },
-
- /**
- * Wrapper to send 'cdma-info-rec-received' system message with CLIR Info.
- */
- notifyCdmaInfoRecClir: function(aServiceId, aCause) {
- this.broadcastMessage("cdma-info-rec-received", {
- clientId: aServiceId,
- clirCause: aCause
- });
- },
-
- /**
- * Wrapper to send 'cdma-info-rec-received' system message with Audio Control Info.
- */
- notifyCdmaInfoRecAudioControl: function(aServiceId, aUpLink, aDownLink) {
- this.broadcastMessage("cdma-info-rec-received", {
- clientId: aServiceId,
- audioControl: {
- upLink: aUpLink,
- downLink: aDownLink
- }
- });
- },
-
- /**
- * Wrapper to send 'icc-stkcommand' system message with Audio Control Info.
- */
- notifyStkProactiveCommand: function(aIccId, aCommand) {
- this.broadcastMessage("icc-stkcommand", {
- iccId: aIccId,
- command: this.createCommandMessage(aCommand)
- });
- }
-};
-
-this.EXPORTED_SYMBOLS = [
- 'RILSystemMessenger'
-];
diff --git a/dom/system/gonk/RILSystemMessengerHelper.js b/dom/system/gonk/RILSystemMessengerHelper.js
deleted file mode 100644
index 6ef263b660..0000000000
--- a/dom/system/gonk/RILSystemMessengerHelper.js
+++ /dev/null
@@ -1,169 +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/Services.jsm");
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-
-var RSM = {};
-Cu.import("resource://gre/modules/RILSystemMessenger.jsm", RSM);
-
-const RILSYSTEMMESSENGERHELPER_CONTRACTID =
- "@mozilla.org/ril/system-messenger-helper;1";
-const RILSYSTEMMESSENGERHELPER_CID =
- Components.ID("{19d9a4ea-580d-11e4-8f6c-37ababfaaea9}");
-
-XPCOMUtils.defineLazyServiceGetter(this, "gSystemMessenger",
- "@mozilla.org/system-message-internal;1",
- "nsISystemMessagesInternal");
-
-XPCOMUtils.defineLazyServiceGetter(this, "gStkCmdFactory",
- "@mozilla.org/icc/stkcmdfactory;1",
- "nsIStkCmdFactory");
-
-var DEBUG = false;
-function debug(s) {
- dump("-@- RILSystemMessenger: " + s + "\n");
-};
-
-// Read debug setting from pref.
-try {
- let debugPref = Services.prefs.getBoolPref("ril.debugging.enabled");
- DEBUG = DEBUG || debugPref;
-} catch (e) {}
-
-/**
- * RILSystemMessengerHelper
- */
-function RILSystemMessengerHelper() {
- this.messenger = new RSM.RILSystemMessenger();
- this.messenger.broadcastMessage = (aType, aMessage) => {
- if (DEBUG) {
- debug("broadcastMessage: aType: " + aType +
- ", aMessage: "+ JSON.stringify(aMessage));
- }
-
- gSystemMessenger.broadcastMessage(aType, aMessage);
- };
-
- this.messenger.createCommandMessage = (aStkProactiveCmd) => {
- return gStkCmdFactory.createCommandMessage(aStkProactiveCmd);
- };
-}
-RILSystemMessengerHelper.prototype = {
-
- classID: RILSYSTEMMESSENGERHELPER_CID,
- QueryInterface: XPCOMUtils.generateQI([Ci.nsITelephonyMessenger,
- Ci.nsISmsMessenger,
- Ci.nsICellbroadcastMessenger,
- Ci.nsIMobileConnectionMessenger,
- Ci.nsIIccMessenger]),
-
- /**
- * RILSystemMessenger instance.
- */
- messenger: null,
-
- /**
- * nsITelephonyMessenger API
- */
- notifyNewCall: function() {
- this.messenger.notifyNewCall();
- },
-
- notifyCallEnded: function(aServiceId, aNumber, aCdmaWaitingNumber, aEmergency,
- aDuration, aOutgoing, aHangUpLocal) {
- this.messenger.notifyCallEnded(aServiceId, aNumber, aCdmaWaitingNumber, aEmergency,
- aDuration, aOutgoing, aHangUpLocal);
- },
-
- notifyUssdReceived: function(aServiceId, aMessage, aSessionEnded) {
- this.messenger.notifyUssdReceived(aServiceId, aMessage, aSessionEnded);
- },
-
- /**
- * nsISmsMessenger API
- */
- notifySms: function(aNotificationType, aId, aThreadId, aIccId, aDelivery,
- aDeliveryStatus, aSender, aReceiver, aBody, aMessageClass,
- aTimestamp, aSentTimestamp, aDeliveryTimestamp, aRead) {
- this.messenger.notifySms(aNotificationType, aId, aThreadId, aIccId, aDelivery,
- aDeliveryStatus, aSender, aReceiver, aBody, aMessageClass,
- aTimestamp, aSentTimestamp, aDeliveryTimestamp, aRead);
- },
-
- /**
- * nsICellbroadcastMessenger API
- */
- notifyCbMessageReceived: function(aServiceId, aGsmGeographicalScope, aMessageCode,
- aMessageId, aLanguage, aBody, aMessageClass,
- aTimestamp, aCdmaServiceCategory, aHasEtwsInfo,
- aEtwsWarningType, aEtwsEmergencyUserAlert, aEtwsPopup) {
- this.messenger.notifyCbMessageReceived(aServiceId, aGsmGeographicalScope, aMessageCode,
- aMessageId, aLanguage, aBody, aMessageClass,
- aTimestamp, aCdmaServiceCategory, aHasEtwsInfo,
- aEtwsWarningType, aEtwsEmergencyUserAlert, aEtwsPopup);
- },
-
- /**
- * nsIMobileConnectionMessenger API
- */
- notifyCdmaInfoRecDisplay: function(aServiceId, aDisplay) {
- this.messenger.notifyCdmaInfoRecDisplay(aServiceId, aDisplay);
- },
-
- notifyCdmaInfoRecCalledPartyNumber: function(aServiceId, aType, aPlan,
- aNumber, aPi, aSi) {
- this.messenger.notifyCdmaInfoRecCalledPartyNumber(aServiceId, aType, aPlan,
- aNumber, aPi, aSi);
- },
-
- notifyCdmaInfoRecCallingPartyNumber: function(aServiceId, aType, aPlan,
- aNumber, aPi, aSi) {
- this.messenger.notifyCdmaInfoRecCallingPartyNumber(aServiceId, aType, aPlan,
- aNumber, aPi, aSi);
- },
-
- notifyCdmaInfoRecConnectedPartyNumber: function(aServiceId, aType, aPlan,
- aNumber, aPi, aSi) {
- this.messenger.notifyCdmaInfoRecConnectedPartyNumber(aServiceId, aType, aPlan,
- aNumber, aPi, aSi);
- },
-
- notifyCdmaInfoRecSignal: function(aServiceId, aType, aAlertPitch, aSignal) {
- this.messenger.notifyCdmaInfoRecSignal(aServiceId, aType, aAlertPitch, aSignal);
- },
-
- notifyCdmaInfoRecRedirectingNumber: function(aServiceId, aType, aPlan,
- aNumber, aPi, aSi, aReason) {
- this.messenger.notifyCdmaInfoRecRedirectingNumber(aServiceId, aType, aPlan,
- aNumber, aPi, aSi, aReason);
- },
-
- notifyCdmaInfoRecLineControl: function(aServiceId, aPolarityIncluded,
- aToggle, aReverse, aPowerDenial) {
- this.messenger.notifyCdmaInfoRecLineControl(aServiceId, aPolarityIncluded,
- aToggle, aReverse, aPowerDenial);
- },
-
- notifyCdmaInfoRecClir: function(aServiceId, aCause) {
- this.messenger.notifyCdmaInfoRecClir(aServiceId, aCause);
- },
-
- notifyCdmaInfoRecAudioControl: function(aServiceId, aUpLink, aDownLink) {
- this.messenger.notifyCdmaInfoRecAudioControl(aServiceId, aUpLink, aDownLink);
- },
-
- /**
- * nsIIccMessenger API
- */
- notifyStkProactiveCommand: function(aIccId, aCommand) {
- this.messenger.notifyStkProactiveCommand(aIccId, aCommand);
- }
-};
-
-this.NSGetFactory = XPCOMUtils.generateNSGetFactory([RILSystemMessengerHelper]);
diff --git a/dom/system/gonk/RILSystemMessengerHelper.manifest b/dom/system/gonk/RILSystemMessengerHelper.manifest
deleted file mode 100644
index 7d19437024..0000000000
--- a/dom/system/gonk/RILSystemMessengerHelper.manifest
+++ /dev/null
@@ -1,6 +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/.
-
-component {19d9a4ea-580d-11e4-8f6c-37ababfaaea9} RILSystemMessengerHelper.js
-contract @mozilla.org/ril/system-messenger-helper;1 {19d9a4ea-580d-11e4-8f6c-37ababfaaea9} \ No newline at end of file
diff --git a/dom/system/gonk/RadioInterfaceLayer.js b/dom/system/gonk/RadioInterfaceLayer.js
deleted file mode 100644
index f5885db5d4..0000000000
--- a/dom/system/gonk/RadioInterfaceLayer.js
+++ /dev/null
@@ -1,1324 +0,0 @@
-/* Copyright 2012 Mozilla Foundation and Mozilla contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-"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/Sntp.jsm");
-Cu.import("resource://gre/modules/systemlibs.js");
-Cu.import("resource://gre/modules/Promise.jsm");
-Cu.import("resource://gre/modules/FileUtils.jsm");
-
-XPCOMUtils.defineLazyGetter(this, "RIL", function () {
- let obj = {};
- Cu.import("resource://gre/modules/ril_consts.js", obj);
- return obj;
-});
-
-// Ril quirk to always turn the radio off for the client without SIM card
-// except hw default client.
-var RILQUIRKS_RADIO_OFF_WO_CARD =
- libcutils.property_get("ro.moz.ril.radio_off_wo_card", "false") == "true";
-
-const RADIOINTERFACELAYER_CID =
- Components.ID("{2d831c8d-6017-435b-a80c-e5d422810cea}");
-const RADIOINTERFACE_CID =
- Components.ID("{6a7c91f0-a2b3-4193-8562-8969296c0b54}");
-
-const NS_XPCOM_SHUTDOWN_OBSERVER_ID = "xpcom-shutdown";
-const kNetworkConnStateChangedTopic = "network-connection-state-changed";
-const kMozSettingsChangedObserverTopic = "mozsettings-changed";
-const kSysMsgListenerReadyObserverTopic = "system-message-listener-ready";
-const kSysClockChangeObserverTopic = "system-clock-change";
-const kScreenStateChangedTopic = "screen-state-changed";
-
-const kSettingsClockAutoUpdateEnabled = "time.clock.automatic-update.enabled";
-const kSettingsClockAutoUpdateAvailable = "time.clock.automatic-update.available";
-const kSettingsTimezoneAutoUpdateEnabled = "time.timezone.automatic-update.enabled";
-const kSettingsTimezoneAutoUpdateAvailable = "time.timezone.automatic-update.available";
-
-const NS_PREFBRANCH_PREFCHANGE_TOPIC_ID = "nsPref:changed";
-
-const kPrefRilNumRadioInterfaces = "ril.numRadioInterfaces";
-const kPrefRilDebuggingEnabled = "ril.debugging.enabled";
-
-const RADIO_POWER_OFF_TIMEOUT = 30000;
-const HW_DEFAULT_CLIENT_ID = 0;
-
-const NETWORK_TYPE_WIFI = Ci.nsINetworkInfo.NETWORK_TYPE_WIFI;
-const NETWORK_TYPE_MOBILE = Ci.nsINetworkInfo.NETWORK_TYPE_MOBILE;
-
-// set to true in ril_consts.js to see debug messages
-var DEBUG = RIL.DEBUG_RIL;
-
-function updateDebugFlag() {
- // Read debug setting from pref
- let debugPref;
- try {
- debugPref = Services.prefs.getBoolPref(kPrefRilDebuggingEnabled);
- } catch (e) {
- debugPref = false;
- }
- DEBUG = RIL.DEBUG_RIL || debugPref;
-}
-updateDebugFlag();
-
-function debug(s) {
- dump("-*- RadioInterfaceLayer: " + s + "\n");
-}
-
-XPCOMUtils.defineLazyServiceGetter(this, "gIccService",
- "@mozilla.org/icc/gonkiccservice;1",
- "nsIGonkIccService");
-
-XPCOMUtils.defineLazyServiceGetter(this, "gMobileMessageService",
- "@mozilla.org/mobilemessage/mobilemessageservice;1",
- "nsIMobileMessageService");
-
-XPCOMUtils.defineLazyServiceGetter(this, "gSmsService",
- "@mozilla.org/sms/gonksmsservice;1",
- "nsIGonkSmsService");
-
-XPCOMUtils.defineLazyServiceGetter(this, "ppmm",
- "@mozilla.org/parentprocessmessagemanager;1",
- "nsIMessageBroadcaster");
-
-XPCOMUtils.defineLazyServiceGetter(this, "gSettingsService",
- "@mozilla.org/settingsService;1",
- "nsISettingsService");
-
-XPCOMUtils.defineLazyServiceGetter(this, "gNetworkManager",
- "@mozilla.org/network/manager;1",
- "nsINetworkManager");
-
-XPCOMUtils.defineLazyServiceGetter(this, "gTimeService",
- "@mozilla.org/time/timeservice;1",
- "nsITimeService");
-
-XPCOMUtils.defineLazyServiceGetter(this, "gSystemWorkerManager",
- "@mozilla.org/telephony/system-worker-manager;1",
- "nsISystemWorkerManager");
-
-XPCOMUtils.defineLazyServiceGetter(this, "gTelephonyService",
- "@mozilla.org/telephony/telephonyservice;1",
- "nsIGonkTelephonyService");
-
-XPCOMUtils.defineLazyServiceGetter(this, "gMobileConnectionService",
- "@mozilla.org/mobileconnection/mobileconnectionservice;1",
- "nsIGonkMobileConnectionService");
-
-XPCOMUtils.defineLazyServiceGetter(this, "gCellBroadcastService",
- "@mozilla.org/cellbroadcast/cellbroadcastservice;1",
- "nsIGonkCellBroadcastService");
-
-XPCOMUtils.defineLazyServiceGetter(this, "gDataCallManager",
- "@mozilla.org/datacall/manager;1",
- "nsIDataCallManager");
-
-XPCOMUtils.defineLazyServiceGetter(this, "gDataCallInterfaceService",
- "@mozilla.org/datacall/interfaceservice;1",
- "nsIGonkDataCallInterfaceService");
-
-XPCOMUtils.defineLazyServiceGetter(this, "gStkCmdFactory",
- "@mozilla.org/icc/stkcmdfactory;1",
- "nsIStkCmdFactory");
-
-XPCOMUtils.defineLazyGetter(this, "gRadioEnabledController", function() {
- let _ril = null;
- let _pendingMessages = []; // For queueing "setRadioEnabled" message.
- let _isProcessingPending = false;
- let _timer = null;
- let _request = null;
- let _deactivatingDeferred = {};
- let _initializedCardState = {};
- let _allCardStateInitialized = !RILQUIRKS_RADIO_OFF_WO_CARD;
-
- return {
- init: function(ril) {
- _ril = ril;
- },
-
- receiveCardState: function(clientId) {
- if (_allCardStateInitialized) {
- return;
- }
-
- if (DEBUG) debug("RadioControl: receive cardState from " + clientId);
- _initializedCardState[clientId] = true;
- if (Object.keys(_initializedCardState).length == _ril.numRadioInterfaces) {
- _allCardStateInitialized = true;
- this._startProcessingPending();
- }
- },
-
- setRadioEnabled: function(clientId, data, callback) {
- if (DEBUG) debug("setRadioEnabled: " + clientId + ": " + JSON.stringify(data));
- let message = {
- clientId: clientId,
- data: data,
- callback: callback
- };
- _pendingMessages.push(message);
- this._startProcessingPending();
- },
-
- notifyRadioStateChanged: function(clientId, radioState) {
- gMobileConnectionService.notifyRadioStateChanged(clientId, radioState);
- },
-
- _startProcessingPending: function() {
- if (!_isProcessingPending) {
- if (DEBUG) debug("RadioControl: start dequeue");
- _isProcessingPending = true;
- this._processNextMessage();
- }
- },
-
- _processNextMessage: function() {
- if (_pendingMessages.length === 0 || !_allCardStateInitialized) {
- if (DEBUG) debug("RadioControl: stop dequeue");
- _isProcessingPending = false;
- return;
- }
-
- let msg = _pendingMessages.shift();
- this._handleMessage(msg);
- },
-
- _getNumCards: function() {
- let numCards = 0;
- for (let i = 0, N = _ril.numRadioInterfaces; i < N; ++i) {
- if (_ril.getRadioInterface(i).isCardPresent()) {
- numCards++;
- }
- }
- return numCards;
- },
-
- _isRadioAbleToEnableAtClient: function(clientId, numCards) {
- if (!RILQUIRKS_RADIO_OFF_WO_CARD) {
- return true;
- }
-
- // We could only turn on the radio for clientId if
- // 1. a SIM card is presented or
- // 2. it is the default clientId and there is no any SIM card at any client.
-
- if (_ril.getRadioInterface(clientId).isCardPresent()) {
- return true;
- }
-
- numCards = numCards == null ? this._getNumCards() : numCards;
- if (clientId === HW_DEFAULT_CLIENT_ID && numCards === 0) {
- return true;
- }
-
- return false;
- },
-
- _handleMessage: function(message) {
- if (DEBUG) debug("RadioControl: handleMessage: " + JSON.stringify(message));
- let clientId = message.clientId || 0;
- let connection =
- gMobileConnectionService.getItemByServiceId(clientId);
- let radioState = connection && connection.radioState;
-
- if (message.data.enabled) {
- if (this._isRadioAbleToEnableAtClient(clientId)) {
- this._setRadioEnabledInternal(message);
- } else {
- // Not really do it but respond success.
- message.callback(message.data);
- }
-
- this._processNextMessage();
- } else {
- _request = this._setRadioEnabledInternal.bind(this, message);
-
- // In 2G network, modem takes 35+ seconds to process deactivate data
- // call request if device has active voice call (please see bug 964974
- // for more details). Therefore we should hangup all active voice calls
- // first. And considering some DSDS architecture, toggling one radio may
- // toggle both, so we send hangUpAll to all clients.
- let hangUpCallback = {
- QueryInterface: XPCOMUtils.generateQI([Ci.nsITelephonyCallback]),
- notifySuccess: function() {},
- notifyError: function() {}
- };
-
- gTelephonyService.enumerateCalls({
- QueryInterface: XPCOMUtils.generateQI([Ci.nsITelephonyListener]),
- enumerateCallState: function(aInfo) {
- gTelephonyService.hangUpCall(aInfo.clientId, aInfo.callIndex,
- hangUpCallback);
- },
- enumerateCallStateComplete: function() {}
- });
-
- // In some DSDS architecture with only one modem, toggling one radio may
- // toggle both. Therefore, for safely turning off, we should first
- // explicitly deactivate all data calls from all clients.
- this._deactivateDataCalls().then(() => {
- if (DEBUG) debug("RadioControl: deactivation done");
- this._executeRequest();
- });
-
- this._createTimer();
- }
- },
-
- _setRadioEnabledInternal: function(message) {
- let clientId = message.clientId || 0;
- let enabled = message.data.enabled || false;
- let radioInterface = _ril.getRadioInterface(clientId);
-
- radioInterface.workerMessenger.send("setRadioEnabled", message.data,
- (function(response) {
- if (response.errorMsg) {
- // If request fails, set current radio state to unknown, since we will
- // handle it in |mobileConnectionService|.
- this.notifyRadioStateChanged(clientId,
- Ci.nsIMobileConnection.MOBILE_RADIO_STATE_UNKNOWN);
- }
- return message.callback(response);
- }).bind(this));
- },
-
- _deactivateDataCalls: function() {
- if (DEBUG) debug("RadioControl: deactivating data calls...");
- _deactivatingDeferred = {};
-
- let promise = Promise.resolve();
- for (let i = 0, N = _ril.numRadioInterfaces; i < N; ++i) {
- promise = promise.then(this._deactivateDataCallsForClient(i));
- }
-
- return promise;
- },
-
- _deactivateDataCallsForClient: function(clientId) {
- return function() {
- let deferred = _deactivatingDeferred[clientId] = Promise.defer();
- let dataCallHandler = gDataCallManager.getDataCallHandler(clientId);
-
- dataCallHandler.deactivateDataCalls(function() {
- deferred.resolve();
- });
-
- return deferred.promise;
- };
- },
-
- _createTimer: function() {
- if (!_timer) {
- _timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
- }
- _timer.initWithCallback(this._executeRequest.bind(this),
- RADIO_POWER_OFF_TIMEOUT,
- Ci.nsITimer.TYPE_ONE_SHOT);
- },
-
- _cancelTimer: function() {
- if (_timer) {
- _timer.cancel();
- }
- },
-
- _executeRequest: function() {
- if (typeof _request === "function") {
- if (DEBUG) debug("RadioControl: executeRequest");
- this._cancelTimer();
- _request();
- _request = null;
- }
- this._processNextMessage();
- },
- };
-});
-
-// Initialize shared preference "ril.numRadioInterfaces" according to system
-// property.
-try {
- Services.prefs.setIntPref(kPrefRilNumRadioInterfaces, (function() {
- // When Gonk property "ro.moz.ril.numclients" is not set, return 1; if
- // explicitly set to any number larger-equal than 0, return num; else, return
- // 1 for compatibility.
- try {
- let numString = libcutils.property_get("ro.moz.ril.numclients", "1");
- let num = parseInt(numString, 10);
- if (num >= 0) {
- return num;
- }
- } catch (e) {}
-
- return 1;
- })());
-} catch (e) {}
-
-function DataCall(aAttributes) {
- for (let key in aAttributes) {
- if (key === "pdpType") {
- // Convert pdp type into constant int value.
- this[key] = RIL.RIL_DATACALL_PDP_TYPES.indexOf(aAttributes[key]);
- continue;
- }
-
- this[key] = aAttributes[key];
- }
-}
-DataCall.prototype = {
- QueryInterface: XPCOMUtils.generateQI([Ci.nsIDataCall]),
-
- failCause: Ci.nsIDataCallInterface.DATACALL_FAIL_NONE,
- suggestedRetryTime: -1,
- cid: -1,
- active: -1,
- pdpType: -1,
- ifname: null,
- addreses: null,
- dnses: null,
- gateways: null,
- pcscf: null,
- mtu: -1
-};
-
-function RadioInterfaceLayer() {
- let workerMessenger = new WorkerMessenger();
- workerMessenger.init();
- this.setWorkerDebugFlag = workerMessenger.setDebugFlag.bind(workerMessenger);
-
- let numIfaces = this.numRadioInterfaces;
- if (DEBUG) debug(numIfaces + " interfaces");
- this.radioInterfaces = [];
- for (let clientId = 0; clientId < numIfaces; clientId++) {
- this.radioInterfaces.push(new RadioInterface(clientId, workerMessenger));
- }
-
- Services.obs.addObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, false);
- Services.prefs.addObserver(kPrefRilDebuggingEnabled, this, false);
-
- gRadioEnabledController.init(this);
-}
-RadioInterfaceLayer.prototype = {
-
- classID: RADIOINTERFACELAYER_CID,
- classInfo: XPCOMUtils.generateCI({classID: RADIOINTERFACELAYER_CID,
- classDescription: "RadioInterfaceLayer",
- interfaces: [Ci.nsIRadioInterfaceLayer]}),
-
- QueryInterface: XPCOMUtils.generateQI([Ci.nsIRadioInterfaceLayer,
- Ci.nsIObserver]),
-
- /**
- * nsIObserver interface methods.
- */
-
- observe: function(subject, topic, data) {
- switch (topic) {
- case NS_XPCOM_SHUTDOWN_OBSERVER_ID:
- for (let radioInterface of this.radioInterfaces) {
- radioInterface.shutdown();
- }
- this.radioInterfaces = null;
- Services.obs.removeObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID);
- break;
-
- case NS_PREFBRANCH_PREFCHANGE_TOPIC_ID:
- if (data === kPrefRilDebuggingEnabled) {
- updateDebugFlag();
- this.setWorkerDebugFlag(DEBUG);
- }
- break;
- }
- },
-
- /**
- * nsIRadioInterfaceLayer interface methods.
- */
-
- getRadioInterface: function(clientId) {
- return this.radioInterfaces[clientId];
- },
-
- setMicrophoneMuted: function(muted) {
- for (let clientId = 0; clientId < this.numRadioInterfaces; clientId++) {
- let radioInterface = this.radioInterfaces[clientId];
- radioInterface.workerMessenger.send("setMute", { muted: muted });
- }
- }
-};
-
-XPCOMUtils.defineLazyGetter(RadioInterfaceLayer.prototype,
- "numRadioInterfaces", function() {
- try {
- return Services.prefs.getIntPref(kPrefRilNumRadioInterfaces);
- } catch(e) {}
-
- return 1;
-});
-
-function WorkerMessenger() {
- // Initial owning attributes.
- this.radioInterfaces = [];
- this.tokenCallbackMap = {};
-
- this.worker = new ChromeWorker("resource://gre/modules/ril_worker.js");
- this.worker.onerror = this.onerror.bind(this);
- this.worker.onmessage = this.onmessage.bind(this);
-}
-WorkerMessenger.prototype = {
- radioInterfaces: null,
- worker: null,
-
- // This gets incremented each time we send out a message.
- token: 1,
-
- // Maps tokens we send out with messages to the message callback.
- tokenCallbackMap: null,
-
- init: function() {
- let options = {
- debug: DEBUG,
- quirks: {
- callstateExtraUint32:
- libcutils.property_get("ro.moz.ril.callstate_extra_int", "false") === "true",
- requestUseDialEmergencyCall:
- libcutils.property_get("ro.moz.ril.dial_emergency_call", "false") === "true",
- simAppStateExtraFields:
- libcutils.property_get("ro.moz.ril.simstate_extra_field", "false") === "true",
- extraUint2ndCall:
- libcutils.property_get("ro.moz.ril.extra_int_2nd_call", "false") === "true",
- haveQueryIccLockRetryCount:
- libcutils.property_get("ro.moz.ril.query_icc_count", "false") === "true",
- sendStkProfileDownload:
- libcutils.property_get("ro.moz.ril.send_stk_profile_dl", "false") === "true",
- smscAddressFormat:
- libcutils.property_get("ro.moz.ril.smsc_address_format", "text"),
- dataRegistrationOnDemand:
- libcutils.property_get("ro.moz.ril.data_reg_on_demand", "false") === "true",
- subscriptionControl:
- libcutils.property_get("ro.moz.ril.subscription_control", "false") === "true",
- signalExtraInt:
- libcutils.property_get("ro.moz.ril.signal_extra_int", "false") === "true",
- availableNetworkExtraStr:
- libcutils.property_get("ro.moz.ril.avlbl_nw_extra_str", "false") === "true",
- }
- };
-
- this.send(null, "setInitialOptions", options);
- },
-
- setDebugFlag: function(aDebug) {
- let options = { debug: aDebug };
- this.send(null, "setDebugFlag", options);
- },
-
- debug: function(aClientId, aMessage) {
- // We use the same debug subject with RadioInterface's here.
- dump("-*- RadioInterface[" + aClientId + "]: " + aMessage + "\n");
- },
-
- onerror: function(event) {
- if (DEBUG) {
- this.debug("X", "Got an error: " + event.filename + ":" +
- event.lineno + ": " + event.message + "\n");
- }
- event.preventDefault();
- },
-
- /**
- * Process the incoming message from the RIL worker.
- */
- onmessage: function(event) {
- let message = event.data;
- let clientId = message.rilMessageClientId;
- if (clientId === null) {
- return;
- }
-
- if (DEBUG) {
- this.debug(clientId, "Received message from worker: " + JSON.stringify(message));
- }
-
- let token = message.rilMessageToken;
- if (token == null) {
- // That's an unsolicited message. Pass to RadioInterface directly.
- let radioInterface = this.radioInterfaces[clientId];
- radioInterface.handleUnsolicitedWorkerMessage(message);
- return;
- }
-
- let callback = this.tokenCallbackMap[message.rilMessageToken];
- if (!callback) {
- if (DEBUG) this.debug(clientId, "Ignore orphan token: " + message.rilMessageToken);
- return;
- }
-
- let keep = false;
- try {
- keep = callback(message);
- } catch(e) {
- if (DEBUG) this.debug(clientId, "callback throws an exception: " + e);
- }
-
- if (!keep) {
- delete this.tokenCallbackMap[message.rilMessageToken];
- }
- },
-
- registerClient: function(aClientId, aRadioInterface) {
- if (DEBUG) this.debug(aClientId, "Starting RIL Worker");
-
- // Keep a reference so that we can dispatch unsolicited messages to it.
- this.radioInterfaces[aClientId] = aRadioInterface;
-
- this.send(null, "registerClient", { clientId: aClientId });
- gSystemWorkerManager.registerRilWorker(aClientId, this.worker);
- },
-
- /**
- * Send arbitrary message to worker.
- *
- * @param rilMessageType
- * A text message type.
- * @param message [optional]
- * An optional message object to send.
- * @param callback [optional]
- * An optional callback function which is called when worker replies
- * with an message containing a "rilMessageToken" attribute of the
- * same value we passed. This callback function accepts only one
- * parameter -- the reply from worker. It also returns a boolean
- * value true to keep current token-callback mapping and wait for
- * another worker reply, or false to remove the mapping.
- */
- send: function(clientId, rilMessageType, message, callback) {
- message = message || {};
-
- message.rilMessageClientId = clientId;
- message.rilMessageToken = this.token;
- this.token++;
-
- if (callback) {
- // Only create the map if callback is provided. For sending a request
- // and intentionally leaving the callback undefined, that reply will
- // be dropped in |this.onmessage| because of that orphan token.
- //
- // For sending a request that never replied at all, we're fine with this
- // because no callback shall be passed and we leave nothing to be cleaned
- // up later.
- this.tokenCallbackMap[message.rilMessageToken] = callback;
- }
-
- message.rilMessageType = rilMessageType;
- this.worker.postMessage(message);
- }
-};
-
-function RadioInterface(aClientId, aWorkerMessenger) {
- this.clientId = aClientId;
- this.workerMessenger = {
- send: aWorkerMessenger.send.bind(aWorkerMessenger, aClientId)
- };
- aWorkerMessenger.registerClient(aClientId, this);
-
- this.operatorInfo = {};
-
- let lock = gSettingsService.createLock();
-
- // Read the "time.clock.automatic-update.enabled" setting to see if
- // we need to adjust the system clock time by NITZ or SNTP.
- lock.get(kSettingsClockAutoUpdateEnabled, this);
-
- // Read the "time.timezone.automatic-update.enabled" setting to see if
- // we need to adjust the system timezone by NITZ.
- lock.get(kSettingsTimezoneAutoUpdateEnabled, this);
-
- // Set "time.clock.automatic-update.available" to false when starting up.
- this.setClockAutoUpdateAvailable(false);
-
- // Set "time.timezone.automatic-update.available" to false when starting up.
- this.setTimezoneAutoUpdateAvailable(false);
-
- Services.obs.addObserver(this, kMozSettingsChangedObserverTopic, false);
- Services.obs.addObserver(this, kSysClockChangeObserverTopic, false);
- Services.obs.addObserver(this, kScreenStateChangedTopic, false);
-
- Services.obs.addObserver(this, kNetworkConnStateChangedTopic, false);
-
- this._sntp = new Sntp(this.setClockBySntp.bind(this),
- Services.prefs.getIntPref("network.sntp.maxRetryCount"),
- Services.prefs.getIntPref("network.sntp.refreshPeriod"),
- Services.prefs.getIntPref("network.sntp.timeout"),
- Services.prefs.getCharPref("network.sntp.pools").split(";"),
- Services.prefs.getIntPref("network.sntp.port"));
-}
-
-RadioInterface.prototype = {
-
- classID: RADIOINTERFACE_CID,
- classInfo: XPCOMUtils.generateCI({classID: RADIOINTERFACE_CID,
- classDescription: "RadioInterface",
- interfaces: [Ci.nsIRadioInterface]}),
-
- QueryInterface: XPCOMUtils.generateQI([Ci.nsIRadioInterface,
- Ci.nsIObserver,
- Ci.nsISettingsServiceCallback]),
-
- // A private wrapped WorkerMessenger instance.
- workerMessenger: null,
-
- debug: function(s) {
- dump("-*- RadioInterface[" + this.clientId + "]: " + s + "\n");
- },
-
- shutdown: function() {
- Services.obs.removeObserver(this, kMozSettingsChangedObserverTopic);
- Services.obs.removeObserver(this, kSysClockChangeObserverTopic);
- Services.obs.removeObserver(this, kScreenStateChangedTopic);
- Services.obs.removeObserver(this, kNetworkConnStateChangedTopic);
- },
-
- isCardPresent: function() {
- let icc = gIccService.getIccByServiceId(this.clientId);
- let cardState = icc ? icc.cardState : Ci.nsIIcc.CARD_STATE_UNKNOWN;
- return cardState !== Ci.nsIIcc.CARD_STATE_UNDETECTED &&
- cardState !== Ci.nsIIcc.CARD_STATE_UNKNOWN;
- },
-
- handleUnsolicitedWorkerMessage: function(message) {
- switch (message.rilMessageType) {
- case "callRing":
- gTelephonyService.notifyCallRing();
- break;
- case "currentCalls":
- gTelephonyService.notifyCurrentCalls(this.clientId, message.calls);
- break;
- case "cdmaCallWaiting":
- gTelephonyService.notifyCdmaCallWaiting(this.clientId,
- message.waitingCall);
- break;
- case "suppSvcNotification":
- gTelephonyService.notifySupplementaryService(this.clientId,
- message.number,
- message.notification);
- break;
- case "ussdreceived":
- gTelephonyService.notifyUssdReceived(this.clientId, message.message,
- message.sessionEnded);
- break;
- case "datacalllistchanged":
- let dataCalls = message.datacalls.map(dataCall => new DataCall(dataCall));
- gDataCallInterfaceService.notifyDataCallListChanged(this.clientId,
- dataCalls.length,
- dataCalls);
- break;
- case "emergencyCbModeChange":
- gMobileConnectionService.notifyEmergencyCallbackModeChanged(this.clientId,
- message.active,
- message.timeoutMs);
- break;
- case "networkinfochanged":
- gMobileConnectionService.notifyNetworkInfoChanged(this.clientId,
- message);
- break;
- case "networkselectionmodechange":
- gMobileConnectionService.notifyNetworkSelectModeChanged(this.clientId,
- message.mode);
- break;
- case "voiceregistrationstatechange":
- gMobileConnectionService.notifyVoiceInfoChanged(this.clientId, message);
- break;
- case "dataregistrationstatechange":
- gMobileConnectionService.notifyDataInfoChanged(this.clientId, message);
- break;
- case "signalstrengthchange":
- gMobileConnectionService.notifySignalStrengthChanged(this.clientId,
- message);
- break;
- case "operatorchange":
- gMobileConnectionService.notifyOperatorChanged(this.clientId, message);
- break;
- case "otastatuschange":
- gMobileConnectionService.notifyOtaStatusChanged(this.clientId, message.status);
- break;
- case "deviceidentitieschange":
- gMobileConnectionService.notifyDeviceIdentitiesChanged(this.clientId,
- message.deviceIdentities.imei,
- message.deviceIdentities.imeisv,
- message.deviceIdentities.esn,
- message.deviceIdentities.meid);
- break;
- case "radiostatechange":
- // gRadioEnabledController should know the radio state for each client,
- // so notify gRadioEnabledController here.
- gRadioEnabledController.notifyRadioStateChanged(this.clientId,
- message.radioState);
- break;
- case "cardstatechange":
- gIccService.notifyCardStateChanged(this.clientId,
- message.cardState);
- gRadioEnabledController.receiveCardState(this.clientId);
- break;
- case "sms-received":
- this.handleSmsReceived(message);
- break;
- case "cellbroadcast-received":
- this.handleCellbroadcastMessageReceived(message);
- break;
- case "nitzTime":
- this.handleNitzTime(message);
- break;
- case "iccinfochange":
- gIccService.notifyIccInfoChanged(this.clientId,
- message.iccid ? message : null);
- break;
- case "iccimsi":
- gIccService.notifyImsiChanged(this.clientId, message.imsi);
- break;
- case "iccmbdn":
- this.handleIccMbdn(message);
- break;
- case "iccmwis":
- this.handleIccMwis(message.mwi);
- break;
- case "stkcommand":
- gIccService.notifyStkCommand(this.clientId,
- gStkCmdFactory.createCommand(message));
- break;
- case "stksessionend":
- gIccService.notifyStkSessionEnd(this.clientId);
- break;
- case "cdma-info-rec-received":
- this.handleCdmaInformationRecords(message.records);
- break;
- default:
- throw new Error("Don't know about this message type: " +
- message.rilMessageType);
- }
- },
-
- setDataRegistration: function(attach) {
- let deferred = Promise.defer();
- this.workerMessenger.send("setDataRegistration",
- {attach: attach},
- (function(response) {
- // Always resolve to proceed with the following steps.
- deferred.resolve(response.errorMsg ? response.errorMsg : null);
- }).bind(this));
-
- return deferred.promise;
- },
-
- /**
- * TODO: Bug 911713 - B2G NetworkManager: Move policy control logic to
- * NetworkManager
- */
- updateRILNetworkInterface: function() {
- let connHandler = gDataCallManager.getDataCallHandler(this.clientId);
- connHandler.updateRILNetworkInterface();
- },
-
- /**
- * handle received SMS.
- */
- handleSmsReceived: function(aMessage) {
- let header = aMessage.header;
- // Concatenation Info:
- // - segmentRef: a modulo 256 counter indicating the reference number for a
- // particular concatenated short message. '0' is a valid number.
- // - The concatenation info will not be available in |header| if
- // segmentSeq or segmentMaxSeq is 0.
- // See 3GPP TS 23.040, 9.2.3.24.1 Concatenated Short Messages.
- let segmentRef = (header && header.segmentRef !== undefined)
- ? header.segmentRef : 1;
- let segmentSeq = header && header.segmentSeq || 1;
- let segmentMaxSeq = header && header.segmentMaxSeq || 1;
- // Application Ports:
- // The port number ranges from 0 to 49151.
- // see 3GPP TS 23.040, 9.2.3.24.3/4 Application Port Addressing.
- let originatorPort = (header && header.originatorPort !== undefined)
- ? header.originatorPort
- : Ci.nsIGonkSmsService.SMS_APPLICATION_PORT_INVALID;
- let destinationPort = (header && header.destinationPort !== undefined)
- ? header.destinationPort
- : Ci.nsIGonkSmsService.SMS_APPLICATION_PORT_INVALID;
- // MWI info:
- let mwiPresent = (aMessage.mwi)? true : false;
- let mwiDiscard = (mwiPresent)? aMessage.mwi.discard: false;
- let mwiMsgCount = (mwiPresent)? aMessage.mwi.msgCount: 0;
- let mwiActive = (mwiPresent)? aMessage.mwi.active: false;
- // CDMA related attributes:
- let cdmaMessageType = aMessage.messageType || 0;
- let cdmaTeleservice = aMessage.teleservice || 0;
- let cdmaServiceCategory = aMessage.serviceCategory || 0;
-
- gSmsService
- .notifyMessageReceived(this.clientId,
- aMessage.SMSC || null,
- aMessage.sentTimestamp,
- aMessage.sender,
- aMessage.pid,
- aMessage.encoding,
- RIL.GECKO_SMS_MESSAGE_CLASSES
- .indexOf(aMessage.messageClass),
- aMessage.language || null,
- segmentRef,
- segmentSeq,
- segmentMaxSeq,
- originatorPort,
- destinationPort,
- mwiPresent,
- mwiDiscard,
- mwiMsgCount,
- mwiActive,
- cdmaMessageType,
- cdmaTeleservice,
- cdmaServiceCategory,
- aMessage.body || null,
- aMessage.data || [],
- (aMessage.data) ? aMessage.data.length : 0);
- },
-
- /**
- * Set the setting value of "time.clock.automatic-update.available".
- */
- setClockAutoUpdateAvailable: function(value) {
- gSettingsService.createLock().set(kSettingsClockAutoUpdateAvailable, value, null);
- },
-
- /**
- * Set the setting value of "time.timezone.automatic-update.available".
- */
- setTimezoneAutoUpdateAvailable: function(value) {
- gSettingsService.createLock().set(kSettingsTimezoneAutoUpdateAvailable, value, null);
- },
-
- /**
- * Set the system clock by NITZ.
- */
- setClockByNitz: function(message) {
- // To set the system clock time. Note that there could be a time diff
- // between when the NITZ was received and when the time is actually set.
- gTimeService.set(
- message.networkTimeInMS + (Date.now() - message.receiveTimeInMS));
- },
-
- /**
- * Set the system time zone by NITZ.
- */
- setTimezoneByNitz: function(message) {
- // To set the sytem timezone. Note that we need to convert the time zone
- // value to a UTC repesentation string in the format of "UTC(+/-)hh:mm".
- // Ex, time zone -480 is "UTC+08:00"; time zone 630 is "UTC-10:30".
- //
- // We can unapply the DST correction if we want the raw time zone offset:
- // message.networkTimeZoneInMinutes -= message.networkDSTInMinutes;
- if (message.networkTimeZoneInMinutes != (new Date()).getTimezoneOffset()) {
- let absTimeZoneInMinutes = Math.abs(message.networkTimeZoneInMinutes);
- let timeZoneStr = "UTC";
- timeZoneStr += (message.networkTimeZoneInMinutes > 0 ? "-" : "+");
- timeZoneStr += ("0" + Math.floor(absTimeZoneInMinutes / 60)).slice(-2);
- timeZoneStr += ":";
- timeZoneStr += ("0" + absTimeZoneInMinutes % 60).slice(-2);
- gSettingsService.createLock().set("time.timezone", timeZoneStr, null);
- }
- },
-
- /**
- * Handle the NITZ message.
- */
- handleNitzTime: function(message) {
- // Got the NITZ info received from the ril_worker.
- this.setClockAutoUpdateAvailable(true);
- this.setTimezoneAutoUpdateAvailable(true);
-
- // Cache the latest NITZ message whenever receiving it.
- this._lastNitzMessage = message;
-
- // Set the received NITZ clock if the setting is enabled.
- if (this._clockAutoUpdateEnabled) {
- this.setClockByNitz(message);
- }
- // Set the received NITZ timezone if the setting is enabled.
- if (this._timezoneAutoUpdateEnabled) {
- this.setTimezoneByNitz(message);
- }
- },
-
- /**
- * Set the system clock by SNTP.
- */
- setClockBySntp: function(offset) {
- // Got the SNTP info.
- this.setClockAutoUpdateAvailable(true);
- if (!this._clockAutoUpdateEnabled) {
- return;
- }
- if (this._lastNitzMessage) {
- if (DEBUG) debug("SNTP: NITZ available, discard SNTP");
- return;
- }
- gTimeService.set(Date.now() + offset);
- },
-
- handleIccMbdn: function(message) {
- let service = Cc["@mozilla.org/voicemail/voicemailservice;1"]
- .getService(Ci.nsIGonkVoicemailService);
- service.notifyInfoChanged(this.clientId, message.number, message.alphaId);
- },
-
- handleIccMwis: function(mwi) {
- let service = Cc["@mozilla.org/voicemail/voicemailservice;1"]
- .getService(Ci.nsIGonkVoicemailService);
- // Note: returnNumber and returnMessage is not available from UICC.
- service.notifyStatusChanged(this.clientId, mwi.active, mwi.msgCount,
- null, null);
- },
-
- _convertCbGsmGeographicalScope: function(aGeographicalScope) {
- return (aGeographicalScope != null)
- ? aGeographicalScope
- : Ci.nsICellBroadcastService.GSM_GEOGRAPHICAL_SCOPE_INVALID;
- },
-
- _convertCbMessageClass: function(aMessageClass) {
- let index = RIL.GECKO_SMS_MESSAGE_CLASSES.indexOf(aMessageClass);
- return (index != -1)
- ? index
- : Ci.nsICellBroadcastService.GSM_MESSAGE_CLASS_NORMAL;
- },
-
- _convertCbEtwsWarningType: function(aWarningType) {
- return (aWarningType != null)
- ? aWarningType
- : Ci.nsICellBroadcastService.GSM_ETWS_WARNING_INVALID;
- },
-
- handleCellbroadcastMessageReceived: function(aMessage) {
- let etwsInfo = aMessage.etws;
- let hasEtwsInfo = etwsInfo != null;
- let serviceCategory = (aMessage.serviceCategory)
- ? aMessage.serviceCategory
- : Ci.nsICellBroadcastService.CDMA_SERVICE_CATEGORY_INVALID;
-
- gCellBroadcastService
- .notifyMessageReceived(this.clientId,
- this._convertCbGsmGeographicalScope(aMessage.geographicalScope),
- aMessage.messageCode,
- aMessage.messageId,
- aMessage.language,
- aMessage.fullBody,
- this._convertCbMessageClass(aMessage.messageClass),
- Date.now(),
- serviceCategory,
- hasEtwsInfo,
- (hasEtwsInfo)
- ? this._convertCbEtwsWarningType(etwsInfo.warningType)
- : Ci.nsICellBroadcastService.GSM_ETWS_WARNING_INVALID,
- hasEtwsInfo ? etwsInfo.emergencyUserAlert : false,
- hasEtwsInfo ? etwsInfo.popup : false);
- },
-
- handleCdmaInformationRecords: function(aRecords) {
- if (DEBUG) this.debug("cdma-info-rec-received: " + JSON.stringify(aRecords));
-
- let clientId = this.clientId;
-
- aRecords.forEach(function(aRecord) {
- if (aRecord.display) {
- gMobileConnectionService
- .notifyCdmaInfoRecDisplay(clientId, aRecord.display);
- return;
- }
-
- if (aRecord.calledNumber) {
- gMobileConnectionService
- .notifyCdmaInfoRecCalledPartyNumber(clientId,
- aRecord.calledNumber.type,
- aRecord.calledNumber.plan,
- aRecord.calledNumber.number,
- aRecord.calledNumber.pi,
- aRecord.calledNumber.si);
- return;
- }
-
- if (aRecord.callingNumber) {
- gMobileConnectionService
- .notifyCdmaInfoRecCallingPartyNumber(clientId,
- aRecord.callingNumber.type,
- aRecord.callingNumber.plan,
- aRecord.callingNumber.number,
- aRecord.callingNumber.pi,
- aRecord.callingNumber.si);
- return;
- }
-
- if (aRecord.connectedNumber) {
- gMobileConnectionService
- .notifyCdmaInfoRecConnectedPartyNumber(clientId,
- aRecord.connectedNumber.type,
- aRecord.connectedNumber.plan,
- aRecord.connectedNumber.number,
- aRecord.connectedNumber.pi,
- aRecord.connectedNumber.si);
- return;
- }
-
- if (aRecord.signal) {
- gMobileConnectionService
- .notifyCdmaInfoRecSignal(clientId,
- aRecord.signal.type,
- aRecord.signal.alertPitch,
- aRecord.signal.signal);
- return;
- }
-
- if (aRecord.redirect) {
- gMobileConnectionService
- .notifyCdmaInfoRecRedirectingNumber(clientId,
- aRecord.redirect.type,
- aRecord.redirect.plan,
- aRecord.redirect.number,
- aRecord.redirect.pi,
- aRecord.redirect.si,
- aRecord.redirect.reason);
- return;
- }
-
- if (aRecord.lineControl) {
- gMobileConnectionService
- .notifyCdmaInfoRecLineControl(clientId,
- aRecord.lineControl.polarityIncluded,
- aRecord.lineControl.toggle,
- aRecord.lineControl.reverse,
- aRecord.lineControl.powerDenial);
- return;
- }
-
- if (aRecord.clirCause) {
- gMobileConnectionService
- .notifyCdmaInfoRecClir(clientId,
- aRecord.clirCause);
- return;
- }
-
- if (aRecord.audioControl) {
- gMobileConnectionService
- .notifyCdmaInfoRecAudioControl(clientId,
- aRecord.audioControl.upLink,
- aRecord.audioControl.downLink);
- return;
- }
- });
- },
-
- // nsIObserver
-
- observe: function(subject, topic, data) {
- switch (topic) {
- case kMozSettingsChangedObserverTopic:
- if ("wrappedJSObject" in subject) {
- subject = subject.wrappedJSObject;
- }
- this.handleSettingsChange(subject.key, subject.value, subject.isInternalChange);
- break;
- case kSysClockChangeObserverTopic:
- let offset = parseInt(data, 10);
- if (this._lastNitzMessage) {
- this._lastNitzMessage.receiveTimeInMS += offset;
- }
- this._sntp.updateOffset(offset);
- break;
- case kNetworkConnStateChangedTopic:
- let networkInfo = subject.QueryInterface(Ci.nsINetworkInfo);
- if (networkInfo.state != Ci.nsINetworkInfo.NETWORK_STATE_CONNECTED) {
- return;
- }
-
- // SNTP can only update when we have mobile or Wifi connections.
- if (networkInfo.type != NETWORK_TYPE_WIFI &&
- networkInfo.type != NETWORK_TYPE_MOBILE) {
- return;
- }
-
- // If the network comes from RIL, make sure the RIL service is matched.
- if (subject instanceof Ci.nsIRilNetworkInfo) {
- networkInfo = subject.QueryInterface(Ci.nsIRilNetworkInfo);
- if (networkInfo.serviceId != this.clientId) {
- return;
- }
- }
-
- // SNTP won't update unless the SNTP is already expired.
- if (this._sntp.isExpired()) {
- this._sntp.request();
- }
- break;
- case kScreenStateChangedTopic:
- this.workerMessenger.send("setScreenState", { on: (data === "on") });
- break;
- }
- },
-
- // Flag to determine whether to update system clock automatically. It
- // corresponds to the "time.clock.automatic-update.enabled" setting.
- _clockAutoUpdateEnabled: null,
-
- // Flag to determine whether to update system timezone automatically. It
- // corresponds to the "time.clock.automatic-update.enabled" setting.
- _timezoneAutoUpdateEnabled: null,
-
- // Remember the last NITZ message so that we can set the time based on
- // the network immediately when users enable network-based time.
- _lastNitzMessage: null,
-
- // Object that handles SNTP.
- _sntp: null,
-
- // Cell Broadcast settings values.
- _cellBroadcastSearchList: null,
-
- handleSettingsChange: function(aName, aResult, aIsInternalSetting) {
- // Don't allow any content processes to modify the setting
- // "time.clock.automatic-update.available" except for the chrome process.
- if (aName === kSettingsClockAutoUpdateAvailable &&
- !aIsInternalSetting) {
- let isClockAutoUpdateAvailable = this._lastNitzMessage !== null ||
- this._sntp.isAvailable();
- if (aResult !== isClockAutoUpdateAvailable) {
- if (DEBUG) {
- debug("Content processes cannot modify 'time.clock.automatic-update.available'. Restore!");
- }
- // Restore the setting to the current value.
- this.setClockAutoUpdateAvailable(isClockAutoUpdateAvailable);
- }
- }
-
- // Don't allow any content processes to modify the setting
- // "time.timezone.automatic-update.available" except for the chrome
- // process.
- if (aName === kSettingsTimezoneAutoUpdateAvailable &&
- !aIsInternalSetting) {
- let isTimezoneAutoUpdateAvailable = this._lastNitzMessage !== null;
- if (aResult !== isTimezoneAutoUpdateAvailable) {
- if (DEBUG) {
- this.debug("Content processes cannot modify 'time.timezone.automatic-update.available'. Restore!");
- }
- // Restore the setting to the current value.
- this.setTimezoneAutoUpdateAvailable(isTimezoneAutoUpdateAvailable);
- }
- }
-
- this.handle(aName, aResult);
- },
-
- // nsISettingsServiceCallback
- handle: function(aName, aResult) {
- switch(aName) {
- case kSettingsClockAutoUpdateEnabled:
- this._clockAutoUpdateEnabled = aResult;
- if (!this._clockAutoUpdateEnabled) {
- break;
- }
-
- // Set the latest cached NITZ time if it's available.
- if (this._lastNitzMessage) {
- this.setClockByNitz(this._lastNitzMessage);
- } else if (gNetworkManager.activeNetworkInfo &&
- gNetworkManager.activeNetworkInfo.state ==
- Ci.nsINetworkInfo.NETWORK_STATE_CONNECTED) {
- // Set the latest cached SNTP time if it's available.
- if (!this._sntp.isExpired()) {
- this.setClockBySntp(this._sntp.getOffset());
- } else {
- // Or refresh the SNTP.
- this._sntp.request();
- }
- } else {
- // Set a sane minimum time.
- let buildTime = libcutils.property_get("ro.build.date.utc", "0") * 1000;
- let file = FileUtils.File("/system/b2g/b2g");
- if (file.lastModifiedTime > buildTime) {
- buildTime = file.lastModifiedTime;
- }
- if (buildTime > Date.now()) {
- gTimeService.set(buildTime);
- }
- }
- break;
- case kSettingsTimezoneAutoUpdateEnabled:
- this._timezoneAutoUpdateEnabled = aResult;
-
- if (this._timezoneAutoUpdateEnabled) {
- // Apply the latest cached NITZ for timezone if it's available.
- if (this._timezoneAutoUpdateEnabled && this._lastNitzMessage) {
- this.setTimezoneByNitz(this._lastNitzMessage);
- }
- }
- break;
- }
- },
-
- handleError: function(aErrorMessage) {
- if (DEBUG) {
- this.debug("There was an error while reading RIL settings.");
- }
- },
-
- // nsIRadioInterface
-
- // TODO: Bug 928861 - B2G NetworkManager: Provide a more generic function
- // for connecting
- setupDataCallByType: function(networkType) {
- let connHandler = gDataCallManager.getDataCallHandler(this.clientId);
- connHandler.setupDataCallByType(networkType);
- },
-
- // TODO: Bug 928861 - B2G NetworkManager: Provide a more generic function
- // for connecting
- deactivateDataCallByType: function(networkType) {
- let connHandler = gDataCallManager.getDataCallHandler(this.clientId);
- connHandler.deactivateDataCallByType(networkType);
- },
-
- // TODO: Bug 904514 - [meta] NetworkManager enhancement
- getDataCallStateByType: function(networkType) {
- let connHandler = gDataCallManager.getDataCallHandler(this.clientId);
- return connHandler.getDataCallStateByType(networkType);
- },
-
- sendWorkerMessage: function(rilMessageType, message, callback) {
- // Special handler for setRadioEnabled.
- if (rilMessageType === "setRadioEnabled") {
- // Forward it to gRadioEnabledController.
- gRadioEnabledController.setRadioEnabled(this.clientId, message,
- callback.handleResponse);
- return;
- }
-
- if (callback) {
- this.workerMessenger.send(rilMessageType, message, function(response) {
- return callback.handleResponse(response);
- });
- } else {
- this.workerMessenger.send(rilMessageType, message);
- }
- },
-};
-
-this.NSGetFactory = XPCOMUtils.generateNSGetFactory([RadioInterfaceLayer]);
diff --git a/dom/system/gonk/RadioInterfaceLayer.manifest b/dom/system/gonk/RadioInterfaceLayer.manifest
deleted file mode 100644
index 3c7c3b8082..0000000000
--- a/dom/system/gonk/RadioInterfaceLayer.manifest
+++ /dev/null
@@ -1,18 +0,0 @@
-# Copyright 2012 Mozilla Foundation and Mozilla contributors
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-# RadioInterfaceLayer.js
-component {2d831c8d-6017-435b-a80c-e5d422810cea} RadioInterfaceLayer.js
-contract @mozilla.org/ril;1 {2d831c8d-6017-435b-a80c-e5d422810cea}
-category profile-after-change RadioInterfaceLayer @mozilla.org/ril;1
diff --git a/dom/system/gonk/SystemProperty.cpp b/dom/system/gonk/SystemProperty.cpp
deleted file mode 100644
index 1f874ce908..0000000000
--- a/dom/system/gonk/SystemProperty.cpp
+++ /dev/null
@@ -1,98 +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 "SystemProperty.h"
-
-#include <dlfcn.h>
-#include <string.h>
-
-#include "nsDebug.h"
-#include "prinit.h"
-
-namespace mozilla {
-namespace system {
-
-namespace {
-
-typedef int (*PropertyGet)(const char*, char*, const char*);
-typedef int (*PropertySet)(const char*, const char*);
-
-static void *sLibcUtils;
-static PRCallOnceType sInitLibcUtils;
-
-static int
-FakePropertyGet(const char* key, char* value, const char* default_value)
-{
- if(!default_value) {
- value[0] = '\0';
- return 0;
- }
-
- int len = strlen(default_value);
- if (len >= Property::VALUE_MAX_LENGTH) {
- len = Property::VALUE_MAX_LENGTH - 1;
- }
- memcpy(value, default_value, len);
- value[len] = '\0';
-
- return len;
-}
-
-static int
-FakePropertySet(const char* key, const char* value)
-{
- return 0;
-}
-
-static PRStatus
-InitLibcUtils()
-{
- sLibcUtils = dlopen("/system/lib/libcutils.so", RTLD_LAZY);
- // We will fallback to the fake getter/setter when sLibcUtils is not valid.
- return PR_SUCCESS;
-}
-
-static void*
-GetLibcUtils()
-{
- PR_CallOnce(&sInitLibcUtils, InitLibcUtils);
- return sLibcUtils;
-}
-
-} // anonymous namespace
-
-/*static*/ int
-Property::Get(const char* key, char* value, const char* default_value)
-{
- void *libcutils = GetLibcUtils();
- if (libcutils) {
- PropertyGet getter = (PropertyGet) dlsym(libcutils, "property_get");
- if (getter) {
- return getter(key, value, default_value);
- }
- NS_WARNING("Failed to get property_get() from libcutils!");
- }
- NS_WARNING("Fallback to the FakePropertyGet()");
- return FakePropertyGet(key, value, default_value);
-}
-
-/*static*/ int
-Property::Set(const char* key, const char* value)
-{
- void *libcutils = GetLibcUtils();
- if (libcutils) {
- PropertySet setter = (PropertySet) dlsym(libcutils, "property_set");
- if (setter) {
- return setter(key, value);
- }
- NS_WARNING("Failed to get property_set() from libcutils!");
- }
- NS_WARNING("Fallback to the FakePropertySet()");
- return FakePropertySet(key, value);
-}
-
-} // namespace system
-} // namespace mozilla
diff --git a/dom/system/gonk/SystemProperty.h b/dom/system/gonk/SystemProperty.h
deleted file mode 100644
index 2b5ceae8b6..0000000000
--- a/dom/system/gonk/SystemProperty.h
+++ /dev/null
@@ -1,39 +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_system_Property_h
-#define mozilla_system_Property_h
-
-namespace mozilla {
-namespace system {
-
-/**
-* Abstraction of property_get/property_get in libcutils from AOSP.
-*/
-class Property
-{
-public:
- // Constants defined in system_properties.h from AOSP.
- enum {
- KEY_MAX_LENGTH = 32,
- VALUE_MAX_LENGTH = 92
- };
-
- static int
- Get(const char* key, char* value, const char* default_value);
-
- static int
- Set(const char* key, const char* value);
-
-private:
- Property() {}
- virtual ~Property() {}
-};
-
-} // namespace system
-} // namespace mozilla
-
- #endif // mozilla_system_Property_h
diff --git a/dom/system/gonk/SystemWorkerManager.cpp b/dom/system/gonk/SystemWorkerManager.cpp
deleted file mode 100644
index ee3fc8de39..0000000000
--- a/dom/system/gonk/SystemWorkerManager.cpp
+++ /dev/null
@@ -1,214 +0,0 @@
-/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
-/* vim: set ts=2 et sw=2 tw=80: */
-/* Copyright 2012 Mozilla Foundation and Mozilla contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "SystemWorkerManager.h"
-
-#include "nsINetworkService.h"
-#include "nsIWifi.h"
-#include "nsIWorkerHolder.h"
-#include "nsIXPConnect.h"
-
-#include "jsfriendapi.h"
-#include "mozilla/dom/workers/Workers.h"
-#include "AutoMounter.h"
-#include "TimeZoneSettingObserver.h"
-#include "AudioManager.h"
-#include "mozilla/dom/ScriptSettings.h"
-#include "mozilla/ipc/KeyStore.h"
-#include "nsIObserverService.h"
-#include "nsServiceManagerUtils.h"
-#include "nsThreadUtils.h"
-#include "WifiWorker.h"
-#include "mozilla/Services.h"
-
-USING_WORKERS_NAMESPACE
-
-using namespace mozilla::dom::gonk;
-using namespace mozilla::ipc;
-using namespace mozilla::system;
-
-namespace {
-
-NS_DEFINE_CID(kWifiWorkerCID, NS_WIFIWORKER_CID);
-
-// Doesn't carry a reference, we're owned by services.
-SystemWorkerManager *gInstance = nullptr;
-
-} // namespace
-
-SystemWorkerManager::SystemWorkerManager()
- : mShutdown(false)
-{
- NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
- NS_ASSERTION(!gInstance, "There should only be one instance!");
-}
-
-SystemWorkerManager::~SystemWorkerManager()
-{
- NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
- NS_ASSERTION(!gInstance || gInstance == this,
- "There should only be one instance!");
- gInstance = nullptr;
-}
-
-nsresult
-SystemWorkerManager::Init()
-{
- if (!XRE_IsParentProcess()) {
- return NS_ERROR_NOT_AVAILABLE;
- }
-
- NS_ASSERTION(NS_IsMainThread(), "We can only initialize on the main thread");
- NS_ASSERTION(!mShutdown, "Already shutdown!");
-
- nsresult rv = InitWifi();
- if (NS_FAILED(rv)) {
- NS_WARNING("Failed to initialize WiFi Networking!");
- return rv;
- }
-
- InitKeyStore();
-
- InitAutoMounter();
- InitializeTimeZoneSettingObserver();
- nsCOMPtr<nsIAudioManager> audioManager =
- do_GetService(NS_AUDIOMANAGER_CONTRACTID);
-
- nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
- if (!obs) {
- NS_WARNING("Failed to get observer service!");
- return NS_ERROR_FAILURE;
- }
-
- rv = obs->AddObserver(this, WORKERS_SHUTDOWN_TOPIC, false);
- if (NS_FAILED(rv)) {
- NS_WARNING("Failed to initialize worker shutdown event!");
- return rv;
- }
-
- return NS_OK;
-}
-
-void
-SystemWorkerManager::Shutdown()
-{
- NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
-
- mShutdown = true;
-
- ShutdownAutoMounter();
-
- nsCOMPtr<nsIWifi> wifi(do_QueryInterface(mWifiWorker));
- if (wifi) {
- wifi->Shutdown();
- wifi = nullptr;
- }
- mWifiWorker = nullptr;
-
- if (mKeyStore) {
- mKeyStore->Shutdown();
- mKeyStore = nullptr;
- }
-
- nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
- if (obs) {
- obs->RemoveObserver(this, WORKERS_SHUTDOWN_TOPIC);
- }
-}
-
-// static
-already_AddRefed<SystemWorkerManager>
-SystemWorkerManager::FactoryCreate()
-{
- NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
-
- RefPtr<SystemWorkerManager> instance(gInstance);
-
- if (!instance) {
- instance = new SystemWorkerManager();
- if (NS_FAILED(instance->Init())) {
- instance->Shutdown();
- return nullptr;
- }
-
- gInstance = instance;
- }
-
- return instance.forget();
-}
-
-// static
-nsIInterfaceRequestor*
-SystemWorkerManager::GetInterfaceRequestor()
-{
- return gInstance;
-}
-
-NS_IMETHODIMP
-SystemWorkerManager::GetInterface(const nsIID &aIID, void **aResult)
-{
- NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
-
- if (aIID.Equals(NS_GET_IID(nsIWifi))) {
- return CallQueryInterface(mWifiWorker,
- reinterpret_cast<nsIWifi**>(aResult));
- }
-
- NS_WARNING("Got nothing for the requested IID!");
- return NS_ERROR_NO_INTERFACE;
-}
-
-nsresult
-SystemWorkerManager::RegisterRilWorker(unsigned int aClientId,
- JS::Handle<JS::Value> aWorker,
- JSContext *aCx)
-{
- return NS_ERROR_NOT_IMPLEMENTED;
-}
-
-nsresult
-SystemWorkerManager::InitWifi()
-{
- nsCOMPtr<nsIWorkerHolder> worker = do_CreateInstance(kWifiWorkerCID);
- NS_ENSURE_TRUE(worker, NS_ERROR_FAILURE);
-
- mWifiWorker = worker;
- return NS_OK;
-}
-
-nsresult
-SystemWorkerManager::InitKeyStore()
-{
- mKeyStore = new KeyStore();
- return NS_OK;
-}
-
-NS_IMPL_ISUPPORTS(SystemWorkerManager,
- nsIObserver,
- nsIInterfaceRequestor,
- nsISystemWorkerManager)
-
-NS_IMETHODIMP
-SystemWorkerManager::Observe(nsISupports *aSubject, const char *aTopic,
- const char16_t *aData)
-{
- if (!strcmp(aTopic, WORKERS_SHUTDOWN_TOPIC)) {
- Shutdown();
- }
-
- return NS_OK;
-}
diff --git a/dom/system/gonk/SystemWorkerManager.h b/dom/system/gonk/SystemWorkerManager.h
deleted file mode 100644
index 625cda261b..0000000000
--- a/dom/system/gonk/SystemWorkerManager.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
-/* vim: set ts=2 et sw=2 tw=40: */
-/* Copyright 2012 Mozilla Foundation and Mozilla contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef mozilla_dom_system_b2g_systemworkermanager_h__
-#define mozilla_dom_system_b2g_systemworkermanager_h__
-
-#include "nsIInterfaceRequestor.h"
-#include "nsISystemWorkerManager.h"
-#include "nsIObserver.h"
-#include "nsCOMPtr.h"
-#include "nsXULAppAPI.h" // For XRE_GetProcessType
-
-class nsIWorkerHolder;
-
-namespace mozilla {
-
-namespace ipc {
- class KeyStore;
-}
-
-namespace dom {
-namespace gonk {
-
-class SystemWorkerManager final : public nsIObserver,
- public nsIInterfaceRequestor,
- public nsISystemWorkerManager
-{
-public:
- NS_DECL_ISUPPORTS
- NS_DECL_NSIOBSERVER
- NS_DECL_NSIINTERFACEREQUESTOR
- NS_DECL_NSISYSTEMWORKERMANAGER
-
- nsresult Init();
- void Shutdown();
-
- static already_AddRefed<SystemWorkerManager>
- FactoryCreate();
-
- static nsIInterfaceRequestor*
- GetInterfaceRequestor();
-
-private:
- SystemWorkerManager();
- ~SystemWorkerManager();
-
- nsresult InitWifi();
- nsresult InitKeyStore();
-
- nsCOMPtr<nsIWorkerHolder> mWifiWorker;
-
- RefPtr<mozilla::ipc::KeyStore> mKeyStore;
-
- bool mShutdown;
-};
-
-}
-}
-}
-
-#endif // mozilla_dom_system_b2g_systemworkermanager_h__
diff --git a/dom/system/gonk/TetheringService.js b/dom/system/gonk/TetheringService.js
deleted file mode 100644
index c5c4781806..0000000000
--- a/dom/system/gonk/TetheringService.js
+++ /dev/null
@@ -1,891 +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/FileUtils.jsm");
-Cu.import("resource://gre/modules/systemlibs.js");
-
-const TETHERINGSERVICE_CONTRACTID = "@mozilla.org/tethering/service;1";
-const TETHERINGSERVICE_CID =
- Components.ID("{527a4121-ee5a-4651-be9c-f46f59cf7c01}");
-
-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, "gMobileConnectionService",
- "@mozilla.org/mobileconnection/mobileconnectionservice;1",
- "nsIMobileConnectionService");
-
-XPCOMUtils.defineLazyGetter(this, "gRil", function() {
- try {
- return Cc["@mozilla.org/ril;1"].getService(Ci.nsIRadioInterfaceLayer);
- } catch (e) {}
-
- return null;
-});
-
-const TOPIC_MOZSETTINGS_CHANGED = "mozsettings-changed";
-const TOPIC_CONNECTION_STATE_CHANGED = "network-connection-state-changed";
-const TOPIC_PREF_CHANGED = "nsPref:changed";
-const TOPIC_XPCOM_SHUTDOWN = "xpcom-shutdown";
-const PREF_MANAGE_OFFLINE_STATUS = "network.gonk.manage-offline-status";
-const PREF_NETWORK_DEBUG_ENABLED = "network.debugging.enabled";
-
-const POSSIBLE_USB_INTERFACE_NAME = "rndis0,usb0";
-const DEFAULT_USB_INTERFACE_NAME = "rndis0";
-const DEFAULT_3G_INTERFACE_NAME = "rmnet0";
-const DEFAULT_WIFI_INTERFACE_NAME = "wlan0";
-
-// The kernel's proc entry for network lists.
-const KERNEL_NETWORK_ENTRY = "/sys/class/net";
-
-const TETHERING_TYPE_WIFI = "WiFi";
-const TETHERING_TYPE_USB = "USB";
-
-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 WIFI_CTRL_INTERFACE = "wl0.1";
-
-const NETWORK_INTERFACE_UP = "up";
-const NETWORK_INTERFACE_DOWN = "down";
-
-const TETHERING_STATE_ONGOING = "ongoing";
-const TETHERING_STATE_IDLE = "idle";
-const TETHERING_STATE_ACTIVE = "active";
-
-// Settings DB path for USB tethering.
-const SETTINGS_USB_ENABLED = "tethering.usb.enabled";
-const SETTINGS_USB_IP = "tethering.usb.ip";
-const SETTINGS_USB_PREFIX = "tethering.usb.prefix";
-const SETTINGS_USB_DHCPSERVER_STARTIP = "tethering.usb.dhcpserver.startip";
-const SETTINGS_USB_DHCPSERVER_ENDIP = "tethering.usb.dhcpserver.endip";
-const SETTINGS_USB_DNS1 = "tethering.usb.dns1";
-const SETTINGS_USB_DNS2 = "tethering.usb.dns2";
-
-// Settings DB path for WIFI tethering.
-const SETTINGS_WIFI_DHCPSERVER_STARTIP = "tethering.wifi.dhcpserver.startip";
-const SETTINGS_WIFI_DHCPSERVER_ENDIP = "tethering.wifi.dhcpserver.endip";
-
-// Settings DB patch for dun required setting.
-const SETTINGS_DUN_REQUIRED = "tethering.dun.required";
-
-// Default value for USB tethering.
-const DEFAULT_USB_IP = "192.168.0.1";
-const DEFAULT_USB_PREFIX = "24";
-const DEFAULT_USB_DHCPSERVER_STARTIP = "192.168.0.10";
-const DEFAULT_USB_DHCPSERVER_ENDIP = "192.168.0.30";
-
-const DEFAULT_DNS1 = "8.8.8.8";
-const DEFAULT_DNS2 = "8.8.4.4";
-
-const DEFAULT_WIFI_DHCPSERVER_STARTIP = "192.168.1.10";
-const DEFAULT_WIFI_DHCPSERVER_ENDIP = "192.168.1.30";
-
-const SETTINGS_DATA_DEFAULT_SERVICE_ID = "ril.data.defaultServiceId";
-const MOBILE_DUN_CONNECT_TIMEOUT = 30000;
-const MOBILE_DUN_RETRY_INTERVAL = 5000;
-const MOBILE_DUN_MAX_RETRIES = 5;
-
-var 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("-*- TetheringService: " + s + "\n");
- };
- } else {
- debug = function(s) {};
- }
-}
-updateDebug();
-
-function TetheringService() {
- Services.obs.addObserver(this, TOPIC_XPCOM_SHUTDOWN, false);
- Services.obs.addObserver(this, TOPIC_MOZSETTINGS_CHANGED, false);
- Services.obs.addObserver(this, TOPIC_CONNECTION_STATE_CHANGED, false);
- Services.prefs.addObserver(PREF_NETWORK_DEBUG_ENABLED, this, false);
- Services.prefs.addObserver(PREF_MANAGE_OFFLINE_STATUS, this, false);
-
- try {
- this._manageOfflineStatus =
- Services.prefs.getBoolPref(PREF_MANAGE_OFFLINE_STATUS);
- } catch(ex) {
- // Ignore.
- }
-
- this._dataDefaultServiceId = 0;
-
- // Possible usb tethering interfaces for different gonk platform.
- this.possibleInterface = POSSIBLE_USB_INTERFACE_NAME.split(",");
-
- // Default values for internal and external interfaces.
- this._tetheringInterface = {};
- this._tetheringInterface[TETHERING_TYPE_USB] = {
- externalInterface: DEFAULT_3G_INTERFACE_NAME,
- internalInterface: DEFAULT_USB_INTERFACE_NAME
- };
- this._tetheringInterface[TETHERING_TYPE_WIFI] = {
- externalInterface: DEFAULT_3G_INTERFACE_NAME,
- internalInterface: DEFAULT_WIFI_INTERFACE_NAME
- };
-
- this.tetheringSettings = {};
- this.initTetheringSettings();
-
- let settingsLock = gSettingsService.createLock();
- // Read the default service id for data call.
- settingsLock.get(SETTINGS_DATA_DEFAULT_SERVICE_ID, this);
-
- // Read usb tethering data from settings DB.
- settingsLock.get(SETTINGS_USB_IP, this);
- settingsLock.get(SETTINGS_USB_PREFIX, this);
- settingsLock.get(SETTINGS_USB_DHCPSERVER_STARTIP, this);
- settingsLock.get(SETTINGS_USB_DHCPSERVER_ENDIP, this);
- settingsLock.get(SETTINGS_USB_DNS1, this);
- settingsLock.get(SETTINGS_USB_DNS2, this);
- settingsLock.get(SETTINGS_USB_ENABLED, this);
-
- // Read wifi tethering data from settings DB.
- settingsLock.get(SETTINGS_WIFI_DHCPSERVER_STARTIP, this);
- settingsLock.get(SETTINGS_WIFI_DHCPSERVER_ENDIP, this);
-
- this._usbTetheringSettingsToRead = [SETTINGS_USB_IP,
- SETTINGS_USB_PREFIX,
- SETTINGS_USB_DHCPSERVER_STARTIP,
- SETTINGS_USB_DHCPSERVER_ENDIP,
- SETTINGS_USB_DNS1,
- SETTINGS_USB_DNS2,
- SETTINGS_USB_ENABLED,
- SETTINGS_WIFI_DHCPSERVER_STARTIP,
- SETTINGS_WIFI_DHCPSERVER_ENDIP];
-
- this.wantConnectionEvent = null;
-
- this.dunConnectTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
-
- this.dunRetryTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
-
- this._pendingTetheringRequests = [];
-}
-TetheringService.prototype = {
- classID: TETHERINGSERVICE_CID,
- classInfo: XPCOMUtils.generateCI({classID: TETHERINGSERVICE_CID,
- contractID: TETHERINGSERVICE_CONTRACTID,
- classDescription: "Tethering Service",
- interfaces: [Ci.nsITetheringService]}),
- QueryInterface: XPCOMUtils.generateQI([Ci.nsITetheringService,
- Ci.nsISupportsWeakReference,
- Ci.nsIObserver,
- Ci.nsISettingsServiceCallback]),
-
- // Flag to record the default client id for data call.
- _dataDefaultServiceId: null,
-
- // Number of usb tehering requests to be processed.
- _usbTetheringRequestCount: 0,
-
- // Usb tethering state.
- _usbTetheringAction: TETHERING_STATE_IDLE,
-
- // Tethering settings.
- tetheringSettings: null,
-
- // Tethering settings need to be read from settings DB.
- _usbTetheringSettingsToRead: null,
-
- // Previous usb tethering enabled state.
- _oldUsbTetheringEnabledState: null,
-
- // External and internal interface name.
- _tetheringInterface: null,
-
- // Dun connection timer.
- dunConnectTimer: null,
-
- // Dun connection retry times.
- dunRetryTimes: 0,
-
- // Dun retry timer.
- dunRetryTimer: null,
-
- // Pending tethering request to handle after dun is connected.
- _pendingTetheringRequests: null,
-
- // Flag to indicate wether wifi tethering is being processed.
- _wifiTetheringRequestOngoing: false,
-
- // Arguments for pending wifi tethering request.
- _pendingWifiTetheringRequestArgs: null,
-
- // The state of tethering.
- state: Ci.nsITetheringService.TETHERING_STATE_INACTIVE,
-
- // Flag to check if we can modify the Services.io.offline.
- _manageOfflineStatus: true,
-
- // nsIObserver
-
- observe: function(aSubject, aTopic, aData) {
- let network;
-
- switch(aTopic) {
- case TOPIC_PREF_CHANGED:
- if (aData === PREF_NETWORK_DEBUG_ENABLED) {
- updateDebug();
- }
- break;
- case TOPIC_MOZSETTINGS_CHANGED:
- if ("wrappedJSObject" in aSubject) {
- aSubject = aSubject.wrappedJSObject;
- }
- this.handle(aSubject.key, aSubject.value);
- break;
- case TOPIC_CONNECTION_STATE_CHANGED:
- network = aSubject.QueryInterface(Ci.nsINetworkInfo);
- debug("Network " + network.type + "/" + network.name +
- " changed state to " + network.state);
- this.onConnectionChanged(network);
- break;
- case TOPIC_XPCOM_SHUTDOWN:
- Services.obs.removeObserver(this, TOPIC_XPCOM_SHUTDOWN);
- Services.obs.removeObserver(this, TOPIC_MOZSETTINGS_CHANGED);
- Services.obs.removeObserver(this, TOPIC_CONNECTION_STATE_CHANGED);
- Services.prefs.removeObserver(PREF_NETWORK_DEBUG_ENABLED, this);
- Services.prefs.removeObserver(PREF_MANAGE_OFFLINE_STATUS, this);
-
- this.dunConnectTimer.cancel();
- this.dunRetryTimer.cancel();
- break;
- case PREF_MANAGE_OFFLINE_STATUS:
- try {
- this._manageOfflineStatus =
- Services.prefs.getBoolPref(PREF_MANAGE_OFFLINE_STATUS);
- } catch(ex) {
- // Ignore.
- }
- break;
- }
- },
-
- // nsISettingsServiceCallback
-
- handle: function(aName, aResult) {
- switch(aName) {
- case SETTINGS_DATA_DEFAULT_SERVICE_ID:
- this._dataDefaultServiceId = aResult || 0;
- debug("'_dataDefaultServiceId' is now " + this._dataDefaultServiceId);
- break;
- case SETTINGS_USB_ENABLED:
- this._oldUsbTetheringEnabledState = this.tetheringSettings[SETTINGS_USB_ENABLED];
- case SETTINGS_USB_IP:
- case SETTINGS_USB_PREFIX:
- case SETTINGS_USB_DHCPSERVER_STARTIP:
- case SETTINGS_USB_DHCPSERVER_ENDIP:
- case SETTINGS_USB_DNS1:
- case SETTINGS_USB_DNS2:
- case SETTINGS_WIFI_DHCPSERVER_STARTIP:
- case SETTINGS_WIFI_DHCPSERVER_ENDIP:
- if (aResult !== null) {
- this.tetheringSettings[aName] = aResult;
- }
- debug("'" + aName + "'" + " is now " + this.tetheringSettings[aName]);
- let index = this._usbTetheringSettingsToRead.indexOf(aName);
-
- if (index != -1) {
- this._usbTetheringSettingsToRead.splice(index, 1);
- }
-
- if (this._usbTetheringSettingsToRead.length) {
- debug("We haven't read completely the usb Tethering data from settings db.");
- break;
- }
-
- if (this._oldUsbTetheringEnabledState === this.tetheringSettings[SETTINGS_USB_ENABLED]) {
- debug("No changes for SETTINGS_USB_ENABLED flag. Nothing to do.");
- this.handlePendingWifiTetheringRequest();
- break;
- }
-
- this._usbTetheringRequestCount++;
- if (this._usbTetheringRequestCount === 1) {
- if (this._wifiTetheringRequestOngoing) {
- debug('USB tethering request is blocked by ongoing wifi tethering request.');
- } else {
- this.handleLastUsbTetheringRequest();
- }
- }
- break;
- };
- },
-
- handleError: function(aErrorMessage) {
- debug("There was an error while reading Tethering settings.");
- this.tetheringSettings = {};
- this.tetheringSettings[SETTINGS_USB_ENABLED] = false;
- },
-
- initTetheringSettings: function() {
- this.tetheringSettings[SETTINGS_USB_ENABLED] = false;
- this.tetheringSettings[SETTINGS_USB_IP] = DEFAULT_USB_IP;
- this.tetheringSettings[SETTINGS_USB_PREFIX] = DEFAULT_USB_PREFIX;
- this.tetheringSettings[SETTINGS_USB_DHCPSERVER_STARTIP] = DEFAULT_USB_DHCPSERVER_STARTIP;
- this.tetheringSettings[SETTINGS_USB_DHCPSERVER_ENDIP] = DEFAULT_USB_DHCPSERVER_ENDIP;
- this.tetheringSettings[SETTINGS_USB_DNS1] = DEFAULT_DNS1;
- this.tetheringSettings[SETTINGS_USB_DNS2] = DEFAULT_DNS2;
-
- this.tetheringSettings[SETTINGS_WIFI_DHCPSERVER_STARTIP] = DEFAULT_WIFI_DHCPSERVER_STARTIP;
- this.tetheringSettings[SETTINGS_WIFI_DHCPSERVER_ENDIP] = DEFAULT_WIFI_DHCPSERVER_ENDIP;
-
- this.tetheringSettings[SETTINGS_DUN_REQUIRED] =
- libcutils.property_get("ro.tethering.dun_required") === "1";
- },
-
- getNetworkInfo: function(aType, aServiceId) {
- for (let networkId in gNetworkManager.allNetworkInfo) {
- let networkInfo = gNetworkManager.allNetworkInfo[networkId];
- if (networkInfo.type == aType) {
- try {
- if (networkInfo instanceof Ci.nsIRilNetworkInfo) {
- let rilNetwork = networkInfo.QueryInterface(Ci.nsIRilNetworkInfo);
- if (rilNetwork.serviceId != aServiceId) {
- continue;
- }
- }
- } catch (e) {}
- return networkInfo;
- }
- }
- return null;
- },
-
- handleLastUsbTetheringRequest: function() {
- debug('handleLastUsbTetheringRequest... ' + this._usbTetheringRequestCount);
-
- if (this._usbTetheringRequestCount === 0) {
- if (this.wantConnectionEvent) {
- if (this.tetheringSettings[SETTINGS_USB_ENABLED]) {
- this.wantConnectionEvent.call(this);
- }
- this.wantConnectionEvent = null;
- }
- this.handlePendingWifiTetheringRequest();
- return;
- }
-
- // Cancel the accumlated count to 1 since we only care about the
- // last state.
- this._usbTetheringRequestCount = 1;
- this.handleUSBTetheringToggle(this.tetheringSettings[SETTINGS_USB_ENABLED]);
- this.wantConnectionEvent = null;
- },
-
- handlePendingWifiTetheringRequest: function() {
- if (this._pendingWifiTetheringRequestArgs) {
- this.setWifiTethering.apply(this, this._pendingWifiTetheringRequestArgs);
- this._pendingWifiTetheringRequestArgs = null;
- }
- },
-
- /**
- * Callback when dun connection fails to connect within timeout.
- */
- onDunConnectTimerTimeout: function() {
- while (this._pendingTetheringRequests.length > 0) {
- debug("onDunConnectTimerTimeout: callback without network info.");
- let callback = this._pendingTetheringRequests.shift();
- if (typeof callback === 'function') {
- callback();
- }
- }
- },
-
- setupDunConnection: function() {
- this.dunRetryTimer.cancel();
- let connection =
- gMobileConnectionService.getItemByServiceId(this._dataDefaultServiceId);
- let data = connection && connection.data;
- if (data && data.state === "registered") {
- let ril = gRil.getRadioInterface(this._dataDefaultServiceId);
-
- this.dunRetryTimes = 0;
- ril.setupDataCallByType(Ci.nsINetworkInfo.NETWORK_TYPE_MOBILE_DUN);
- this.dunConnectTimer.cancel();
- this.dunConnectTimer.
- initWithCallback(this.onDunConnectTimerTimeout.bind(this),
- MOBILE_DUN_CONNECT_TIMEOUT, Ci.nsITimer.TYPE_ONE_SHOT);
- return;
- }
-
- if (this.dunRetryTimes++ >= this.MOBILE_DUN_MAX_RETRIES) {
- debug("setupDunConnection: max retries reached.");
- this.dunRetryTimes = 0;
- // same as dun connect timeout.
- this.onDunConnectTimerTimeout();
- return;
- }
-
- debug("Data not ready, retry dun after " + MOBILE_DUN_RETRY_INTERVAL + " ms.");
- this.dunRetryTimer.
- initWithCallback(this.setupDunConnection.bind(this),
- MOBILE_DUN_RETRY_INTERVAL, Ci.nsITimer.TYPE_ONE_SHOT);
- },
-
- _dunActiveUsers: 0,
- handleDunConnection: function(aEnable, aCallback) {
- debug("handleDunConnection: " + aEnable);
- let dun = this.getNetworkInfo(
- Ci.nsINetworkInfo.NETWORK_TYPE_MOBILE_DUN, this._dataDefaultServiceId);
-
- if (!aEnable) {
- this._dunActiveUsers--;
- if (this._dunActiveUsers > 0) {
- debug("Dun still needed by others, do not disconnect.")
- return;
- }
-
- this.dunRetryTimes = 0;
- this.dunRetryTimer.cancel();
- this.dunConnectTimer.cancel();
- this._pendingTetheringRequests = [];
-
- if (dun && (dun.state == Ci.nsINetworkInfo.NETWORK_STATE_CONNECTED)) {
- gRil.getRadioInterface(this._dataDefaultServiceId)
- .deactivateDataCallByType(Ci.nsINetworkInfo.NETWORK_TYPE_MOBILE_DUN);
- }
- return;
- }
-
- this._dunActiveUsers++;
- if (!dun || (dun.state != Ci.nsINetworkInfo.NETWORK_STATE_CONNECTED)) {
- debug("DUN data call inactive, setup dun data call!")
- this._pendingTetheringRequests.push(aCallback);
- this.dunRetryTimes = 0;
- this.setupDunConnection();
-
- return;
- }
-
- this._tetheringInterface[TETHERING_TYPE_USB].externalInterface = dun.name;
- aCallback(dun);
- },
-
- handleUSBTetheringToggle: function(aEnable) {
- debug("handleUSBTetheringToggle: " + aEnable);
- if (aEnable &&
- (this._usbTetheringAction === TETHERING_STATE_ONGOING ||
- this._usbTetheringAction === TETHERING_STATE_ACTIVE)) {
- debug("Usb tethering already connecting/connected.");
- this._usbTetheringRequestCount = 0;
- this.handlePendingWifiTetheringRequest();
- return;
- }
-
- if (!aEnable &&
- this._usbTetheringAction === TETHERING_STATE_IDLE) {
- debug("Usb tethering already disconnected.");
- this._usbTetheringRequestCount = 0;
- this.handlePendingWifiTetheringRequest();
- return;
- }
-
- if (!aEnable) {
- this.tetheringSettings[SETTINGS_USB_ENABLED] = false;
- gNetworkService.enableUsbRndis(false, this.enableUsbRndisResult.bind(this));
- return;
- }
-
- this.tetheringSettings[SETTINGS_USB_ENABLED] = true;
- this._usbTetheringAction = TETHERING_STATE_ONGOING;
-
- if (this.tetheringSettings[SETTINGS_DUN_REQUIRED]) {
- this.handleDunConnection(true, (aNetworkInfo) => {
- if (!aNetworkInfo){
- this.usbTetheringResultReport(aEnable, "Dun connection failed");
- return;
- }
- this._tetheringInterface[TETHERING_TYPE_USB].externalInterface =
- aNetworkInfo.name;
- gNetworkService.enableUsbRndis(true, this.enableUsbRndisResult.bind(this));
- });
- return;
- }
-
- if (gNetworkManager.activeNetworkInfo) {
- this._tetheringInterface[TETHERING_TYPE_USB].externalInterface =
- gNetworkManager.activeNetworkInfo.name;
- } else {
- let mobile = this.getNetworkInfo(
- Ci.nsINetworkInfo.NETWORK_TYPE_MOBILE, this._dataDefaultServiceId);
- if (mobile && mobile.name) {
- this._tetheringInterface[TETHERING_TYPE_USB].externalInterface = mobile.name;
- }
- }
- gNetworkService.enableUsbRndis(true, this.enableUsbRndisResult.bind(this));
- },
-
- getUSBTetheringParameters: function(aEnable, aTetheringInterface) {
- let interfaceIp = this.tetheringSettings[SETTINGS_USB_IP];
- let prefix = this.tetheringSettings[SETTINGS_USB_PREFIX];
- let wifiDhcpStartIp = this.tetheringSettings[SETTINGS_WIFI_DHCPSERVER_STARTIP];
- let wifiDhcpEndIp = this.tetheringSettings[SETTINGS_WIFI_DHCPSERVER_ENDIP];
- let usbDhcpStartIp = this.tetheringSettings[SETTINGS_USB_DHCPSERVER_STARTIP];
- let usbDhcpEndIp = this.tetheringSettings[SETTINGS_USB_DHCPSERVER_ENDIP];
- let dns1 = this.tetheringSettings[SETTINGS_USB_DNS1];
- let dns2 = this.tetheringSettings[SETTINGS_USB_DNS2];
- let internalInterface = aTetheringInterface.internalInterface;
- let externalInterface = aTetheringInterface.externalInterface;
-
- // Using the default values here until application support these settings.
- if (interfaceIp == "" || prefix == "" ||
- wifiDhcpStartIp == "" || wifiDhcpEndIp == "" ||
- usbDhcpStartIp == "" || usbDhcpEndIp == "") {
- debug("Invalid subnet information.");
- return null;
- }
-
- return {
- ifname: internalInterface,
- ip: interfaceIp,
- prefix: prefix,
- wifiStartIp: wifiDhcpStartIp,
- wifiEndIp: wifiDhcpEndIp,
- usbStartIp: usbDhcpStartIp,
- usbEndIp: usbDhcpEndIp,
- dns1: dns1,
- dns2: dns2,
- internalIfname: internalInterface,
- externalIfname: externalInterface,
- enable: aEnable,
- link: aEnable ? NETWORK_INTERFACE_UP : NETWORK_INTERFACE_DOWN
- };
- },
-
- notifyError: function(aResetSettings, aCallback, aMsg) {
- if (aResetSettings) {
- let settingsLock = gSettingsService.createLock();
- // Disable wifi tethering with a useful error message for the user.
- settingsLock.set("tethering.wifi.enabled", false, null, aMsg);
- }
-
- debug("setWifiTethering: " + (aMsg ? aMsg : "success"));
-
- if (aCallback) {
- // Callback asynchronously to avoid netsted toggling.
- Services.tm.currentThread.dispatch(() => {
- aCallback.wifiTetheringEnabledChange(aMsg);
- }, Ci.nsIThread.DISPATCH_NORMAL);
- }
- },
-
- enableWifiTethering: function(aEnable, aConfig, aCallback) {
- // Fill in config's required fields.
- aConfig.ifname = this._tetheringInterface[TETHERING_TYPE_WIFI].internalInterface;
- aConfig.internalIfname = this._tetheringInterface[TETHERING_TYPE_WIFI].internalInterface;
- aConfig.externalIfname = this._tetheringInterface[TETHERING_TYPE_WIFI].externalInterface;
-
- this._wifiTetheringRequestOngoing = true;
- gNetworkService.setWifiTethering(aEnable, aConfig, (aError) => {
- // Change the tethering state to WIFI if there is no error.
- if (aEnable && !aError) {
- this.state = Ci.nsITetheringService.TETHERING_STATE_WIFI;
- } else {
- // If wifi thethering is disable, or any error happens,
- // then consider the following statements.
-
- // Check whether the state is USB now or not. If no then just change
- // it to INACTIVE, if yes then just keep it.
- // It means that don't let the disable or error of WIFI affect
- // the original active state.
- if (this.state != Ci.nsITetheringService.TETHERING_STATE_USB) {
- this.state = Ci.nsITetheringService.TETHERING_STATE_INACTIVE;
- }
-
- // Disconnect dun on error or when wifi tethering is disabled.
- if (this.tetheringSettings[SETTINGS_DUN_REQUIRED]) {
- this.handleDunConnection(false);
- }
- }
-
- if (this._manageOfflineStatus) {
- Services.io.offline = !this.isAnyConnected() &&
- (this.state ===
- Ci.nsITetheringService.TETHERING_STATE_INACTIVE);
- }
-
- let resetSettings = aError;
- debug('gNetworkService.setWifiTethering finished');
- this.notifyError(resetSettings, aCallback, aError);
- this._wifiTetheringRequestOngoing = false;
- if (this._usbTetheringRequestCount > 0) {
- debug('Perform pending USB tethering requests.');
- this.handleLastUsbTetheringRequest();
- }
- });
- },
-
- // Enable/disable WiFi tethering by sending commands to netd.
- setWifiTethering: function(aEnable, aInterfaceName, aConfig, aCallback) {
- debug("setWifiTethering: " + aEnable);
- if (!aInterfaceName) {
- this.notifyError(true, aCallback, "invalid network interface name");
- return;
- }
-
- if (!aConfig) {
- this.notifyError(true, aCallback, "invalid configuration");
- return;
- }
-
- if (this._usbTetheringRequestCount > 0) {
- // If there's still pending usb tethering request, save
- // the request params and redo |setWifiTethering| on
- // usb tethering task complete.
- debug('USB tethering request is being processed. Queue this wifi tethering request.');
- this._pendingWifiTetheringRequestArgs = Array.prototype.slice.call(arguments);
- debug('Pending args: ' + JSON.stringify(this._pendingWifiTetheringRequestArgs));
- return;
- }
-
- // Re-check again, test cases set this property later.
- this.tetheringSettings[SETTINGS_DUN_REQUIRED] =
- libcutils.property_get("ro.tethering.dun_required") === "1";
-
- if (!aEnable) {
- this.enableWifiTethering(false, aConfig, aCallback);
- return;
- }
-
- this._tetheringInterface[TETHERING_TYPE_WIFI].internalInterface =
- aInterfaceName;
-
- if (this.tetheringSettings[SETTINGS_DUN_REQUIRED]) {
- this.handleDunConnection(true, (aNetworkInfo) => {
- if (!aNetworkInfo) {
- this.notifyError(true, aCallback, "Dun connection failed");
- return;
- }
- this._tetheringInterface[TETHERING_TYPE_WIFI].externalInterface =
- aNetworkInfo.name;
- this.enableWifiTethering(true, aConfig, aCallback);
- });
- return;
- }
-
- let mobile = this.getNetworkInfo(
- Ci.nsINetworkInfo.NETWORK_TYPE_MOBILE, this._dataDefaultServiceId);
- // Update the real interface name
- if (mobile && mobile.name) {
- this._tetheringInterface[TETHERING_TYPE_WIFI].externalInterface = mobile.name;
- }
-
- this.enableWifiTethering(true, aConfig, aCallback);
- },
-
- // Enable/disable USB tethering by sending commands to netd.
- setUSBTethering: function(aEnable, aTetheringInterface, aCallback) {
- let params = this.getUSBTetheringParameters(aEnable, aTetheringInterface);
-
- if (params === null) {
- gNetworkService.enableUsbRndis(false, function() {
- this.usbTetheringResultReport(aEnable, "Invalid parameters");
- });
- return;
- }
-
- gNetworkService.setUSBTethering(aEnable, params, aCallback);
- },
-
- getUsbInterface: function() {
- // Find the rndis interface.
- for (let i = 0; i < this.possibleInterface.length; i++) {
- try {
- let file = new FileUtils.File(KERNEL_NETWORK_ENTRY + "/" +
- this.possibleInterface[i]);
- if (file.exists()) {
- return this.possibleInterface[i];
- }
- } catch (e) {
- debug("Not " + this.possibleInterface[i] + " interface.");
- }
- }
- debug("Can't find rndis interface in possible lists.");
- return DEFAULT_USB_INTERFACE_NAME;
- },
-
- enableUsbRndisResult: function(aSuccess, aEnable) {
- if (aSuccess) {
- // If enable is false, don't find usb interface cause it is already down,
- // just use the internal interface in settings.
- if (aEnable) {
- this._tetheringInterface[TETHERING_TYPE_USB].internalInterface =
- this.getUsbInterface();
- }
- this.setUSBTethering(aEnable,
- this._tetheringInterface[TETHERING_TYPE_USB],
- this.usbTetheringResultReport.bind(this, aEnable));
- } else {
- this.usbTetheringResultReport(aEnable, "enableUsbRndisResult failure");
- throw new Error("failed to set USB Function to adb");
- }
- },
-
- usbTetheringResultReport: function(aEnable, aError) {
- this._usbTetheringRequestCount--;
-
- let settingsLock = gSettingsService.createLock();
-
- debug('usbTetheringResultReport callback. enable: ' + aEnable +
- ', error: ' + aError);
-
- // Disable tethering settings when fail to enable it.
- if (aError) {
- this.tetheringSettings[SETTINGS_USB_ENABLED] = false;
- settingsLock.set("tethering.usb.enabled", false, null);
- // Skip others request when we found an error.
- this._usbTetheringRequestCount = 0;
- this._usbTetheringAction = TETHERING_STATE_IDLE;
- // If the thethering state is WIFI now, then just keep it,
- // if not, just change the state to INACTIVE.
- // It means that don't let the error of USB affect the original active state.
- if (this.state != Ci.nsITetheringService.TETHERING_STATE_WIFI) {
- this.state = Ci.nsITetheringService.TETHERING_STATE_INACTIVE;
- }
- if (this.tetheringSettings[SETTINGS_DUN_REQUIRED]) {
- this.handleDunConnection(false);
- }
- } else {
- if (aEnable) {
- this._usbTetheringAction = TETHERING_STATE_ACTIVE;
- this.state = Ci.nsITetheringService.TETHERING_STATE_USB;
- } else {
- this._usbTetheringAction = TETHERING_STATE_IDLE;
- // If the state is now WIFI, don't let the disable of USB affect it.
- if (this.state != Ci.nsITetheringService.TETHERING_STATE_WIFI) {
- this.state = Ci.nsITetheringService.TETHERING_STATE_INACTIVE;
- }
- if (this.tetheringSettings[SETTINGS_DUN_REQUIRED]) {
- this.handleDunConnection(false);
- }
- }
-
- if (this._manageOfflineStatus) {
- Services.io.offline = !this.isAnyConnected() &&
- (this.state ===
- Ci.nsITetheringService.TETHERING_STATE_INACTIVE);
- }
-
- this.handleLastUsbTetheringRequest();
- }
- },
-
- onConnectionChangedReport: function(aSuccess, aExternalIfname) {
- debug("onConnectionChangedReport result: success " + aSuccess);
-
- if (aSuccess) {
- // Update the external interface.
- this._tetheringInterface[TETHERING_TYPE_USB].externalInterface =
- aExternalIfname;
- debug("Change the interface name to " + aExternalIfname);
- }
- },
-
- onConnectionChanged: function(aNetworkInfo) {
- if (aNetworkInfo.state != Ci.nsINetworkInfo.NETWORK_STATE_CONNECTED) {
- debug("We are only interested in CONNECTED event");
- return;
- }
-
- if (this.tetheringSettings[SETTINGS_DUN_REQUIRED] &&
- aNetworkInfo.type === Ci.nsINetworkInfo.NETWORK_TYPE_MOBILE_DUN) {
- this.dunConnectTimer.cancel();
- debug("DUN data call connected, process callbacks.");
- while (this._pendingTetheringRequests.length > 0) {
- let callback = this._pendingTetheringRequests.shift();
- if (typeof callback === 'function') {
- callback(aNetworkInfo);
- }
- }
- return;
- }
-
- if (!this.tetheringSettings[SETTINGS_USB_ENABLED]) {
- debug("Usb tethering settings is not enabled");
- return;
- }
-
- if (this.tetheringSettings[SETTINGS_DUN_REQUIRED] &&
- aNetworkInfo.type === Ci.nsINetworkInfo.NETWORK_TYPE_MOBILE_DUN &&
- this._tetheringInterface[TETHERING_TYPE_USB].externalInterface ===
- aNetworkInfo.name) {
- debug("Dun required and dun interface is the same");
- return;
- }
-
- if (this._tetheringInterface[TETHERING_TYPE_USB].externalInterface ===
- gNetworkManager.activeNetworkInfo.name) {
- debug("The active interface is the same");
- return;
- }
-
- let previous = {
- internalIfname: this._tetheringInterface[TETHERING_TYPE_USB].internalInterface,
- externalIfname: this._tetheringInterface[TETHERING_TYPE_USB].externalInterface
- };
-
- let current = {
- internalIfname: this._tetheringInterface[TETHERING_TYPE_USB].internalInterface,
- externalIfname: aNetworkInfo.name
- };
-
- let callback = (() => {
- // Update external network interface.
- debug("Update upstream interface to " + aNetworkInfo.name);
- gNetworkService.updateUpStream(previous, current,
- this.onConnectionChangedReport.bind(this));
- });
-
- if (this._usbTetheringAction === TETHERING_STATE_ONGOING) {
- debug("Postpone the event and handle it when state is idle.");
- this.wantConnectionEvent = callback;
- return;
- }
- this.wantConnectionEvent = null;
-
- callback.call(this);
- },
-
- isAnyConnected: function() {
- let allNetworkInfo = gNetworkManager.allNetworkInfo;
- for (let networkId in allNetworkInfo) {
- if (allNetworkInfo.hasOwnProperty(networkId) &&
- allNetworkInfo[networkId].state === Ci.nsINetworkInfo.NETWORK_STATE_CONNECTED) {
- return true;
- }
- }
- return false;
- },
-};
-
-this.NSGetFactory = XPCOMUtils.generateNSGetFactory([TetheringService]);
diff --git a/dom/system/gonk/TetheringService.manifest b/dom/system/gonk/TetheringService.manifest
deleted file mode 100644
index b8f18dec1a..0000000000
--- a/dom/system/gonk/TetheringService.manifest
+++ /dev/null
@@ -1,4 +0,0 @@
-# TetheringService.js
-component {527a4121-ee5a-4651-be9c-f46f59cf7c01} TetheringService.js
-contract @mozilla.org/tethering/service;1 {527a4121-ee5a-4651-be9c-f46f59cf7c01}
-category profile-after-change TetheringService @mozilla.org/tethering/service;1
diff --git a/dom/system/gonk/TimeZoneSettingObserver.cpp b/dom/system/gonk/TimeZoneSettingObserver.cpp
deleted file mode 100644
index 512f799088..0000000000
--- a/dom/system/gonk/TimeZoneSettingObserver.cpp
+++ /dev/null
@@ -1,239 +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 "base/message_loop.h"
-#include "jsapi.h"
-#include "mozilla/dom/ScriptSettings.h"
-#include "mozilla/Attributes.h"
-#include "mozilla/ClearOnShutdown.h"
-#include "mozilla/Hal.h"
-#include "mozilla/Services.h"
-#include "mozilla/StaticPtr.h"
-#include "nsCOMPtr.h"
-#include "nsDebug.h"
-#include "nsIObserver.h"
-#include "nsIObserverService.h"
-#include "nsISettingsService.h"
-#include "nsJSUtils.h"
-#include "nsServiceManagerUtils.h"
-#include "nsString.h"
-#include "TimeZoneSettingObserver.h"
-#include "xpcpublic.h"
-#include "nsContentUtils.h"
-#include "nsPrintfCString.h"
-#include "mozilla/dom/BindingUtils.h"
-#include "mozilla/dom/SettingChangeNotificationBinding.h"
-
-#undef LOG
-#undef ERR
-#define LOG(args...) __android_log_print(ANDROID_LOG_INFO, "Time Zone Setting" , ## args)
-#define ERR(args...) __android_log_print(ANDROID_LOG_ERROR, "Time Zone Setting" , ## args)
-
-#define TIME_TIMEZONE "time.timezone"
-#define MOZSETTINGS_CHANGED "mozsettings-changed"
-
-using namespace mozilla;
-using namespace mozilla::dom;
-
-namespace {
-
-class TimeZoneSettingObserver : public nsIObserver
-{
-public:
- NS_DECL_ISUPPORTS
- NS_DECL_NSIOBSERVER
-
- TimeZoneSettingObserver();
- static nsresult SetTimeZone(const JS::Value &aValue, JSContext *aContext);
-
-protected:
- virtual ~TimeZoneSettingObserver();
-};
-
-class TimeZoneSettingCb final : public nsISettingsServiceCallback
-{
-public:
- NS_DECL_ISUPPORTS
-
- TimeZoneSettingCb() {}
-
- NS_IMETHOD Handle(const nsAString &aName, JS::Handle<JS::Value> aResult) {
-
- JSContext *cx = nsContentUtils::GetCurrentJSContext();
- NS_ENSURE_TRUE(cx, NS_OK);
-
- // If we don't have time.timezone value in the settings, we need
- // to initialize the settings based on the current system timezone
- // to make settings consistent with system. This usually happens
- // at the very first boot. After that, settings must have a value.
- if (aResult.isNull()) {
- // Get the current system time zone offset. Note that we need to
- // convert the value to a UTC representation in the format of
- // "UTC{+,-}hh:mm", so that the Gaia end can know how to interpret.
- // E.g., -480 is "UTC+08:00"; 630 is "UTC-10:30".
- int32_t timeZoneOffset = hal::GetTimezoneOffset();
- nsPrintfCString curTimeZone("UTC%+03d:%02d",
- -timeZoneOffset / 60,
- abs(timeZoneOffset) % 60);
-
- // Convert it to a JS string.
- NS_ConvertUTF8toUTF16 utf16Str(curTimeZone);
-
- JS::Rooted<JSString*> jsStr(cx, JS_NewUCStringCopyN(cx,
- utf16Str.get(),
- utf16Str.Length()));
- if (!jsStr) {
- return NS_ERROR_OUT_OF_MEMORY;
- }
-
- // Set the settings based on the current system timezone.
- nsCOMPtr<nsISettingsServiceLock> lock;
- nsCOMPtr<nsISettingsService> settingsService =
- do_GetService("@mozilla.org/settingsService;1");
- if (!settingsService) {
- ERR("Failed to get settingsLock service!");
- return NS_OK;
- }
- settingsService->CreateLock(nullptr, getter_AddRefs(lock));
- JS::Rooted<JS::Value> value(cx, JS::StringValue(jsStr));
- lock->Set(TIME_TIMEZONE, value, nullptr, nullptr);
- return NS_OK;
- }
-
- // Set the system timezone based on the current settings.
- if (aResult.isString()) {
- return TimeZoneSettingObserver::SetTimeZone(aResult, cx);
- }
-
- return NS_OK;
- }
-
- NS_IMETHOD HandleError(const nsAString &aName) {
- ERR("TimeZoneSettingCb::HandleError: %s\n", NS_LossyConvertUTF16toASCII(aName).get());
- return NS_OK;
- }
-
-protected:
- ~TimeZoneSettingCb() {}
-};
-
-NS_IMPL_ISUPPORTS(TimeZoneSettingCb, nsISettingsServiceCallback)
-
-TimeZoneSettingObserver::TimeZoneSettingObserver()
-{
- // Setup an observer to watch changes to the setting.
- nsCOMPtr<nsIObserverService> observerService = services::GetObserverService();
- if (!observerService) {
- ERR("GetObserverService failed");
- return;
- }
- nsresult rv;
- rv = observerService->AddObserver(this, MOZSETTINGS_CHANGED, false);
- if (NS_FAILED(rv)) {
- ERR("AddObserver failed");
- return;
- }
-
- // Read the 'time.timezone' setting in order to start with a known
- // value at boot time. The handle() will be called after reading.
- nsCOMPtr<nsISettingsServiceLock> lock;
- nsCOMPtr<nsISettingsService> settingsService =
- do_GetService("@mozilla.org/settingsService;1");
- if (!settingsService) {
- ERR("Failed to get settingsLock service!");
- return;
- }
- settingsService->CreateLock(nullptr, getter_AddRefs(lock));
- nsCOMPtr<nsISettingsServiceCallback> callback = new TimeZoneSettingCb();
- lock->Get(TIME_TIMEZONE, callback);
-}
-
-nsresult TimeZoneSettingObserver::SetTimeZone(const JS::Value &aValue, JSContext *aContext)
-{
- // Convert the JS value to a nsCString type.
- // The value should be a JS string like "America/Chicago" or "UTC-05:00".
- nsAutoJSString valueStr;
- if (!valueStr.init(aContext, aValue.toString())) {
- ERR("Failed to convert JS value to nsCString");
- return NS_ERROR_FAILURE;
- }
- NS_ConvertUTF16toUTF8 newTimezone(valueStr);
-
- // Hal expects opposite sign from general notations,
- // so we need to flip it.
- if (newTimezone.Find(NS_LITERAL_CSTRING("UTC+")) == 0) {
- if (!newTimezone.SetCharAt('-', 3)) {
- return NS_ERROR_FAILURE;
- }
- } else if (newTimezone.Find(NS_LITERAL_CSTRING("UTC-")) == 0) {
- if (!newTimezone.SetCharAt('+', 3)) {
- return NS_ERROR_FAILURE;
- }
- }
-
- // Set the timezone only when the system timezone is not identical.
- nsCString curTimezone = hal::GetTimezone();
- if (!curTimezone.Equals(newTimezone)) {
- hal::SetTimezone(newTimezone);
- }
-
- return NS_OK;
-}
-
-TimeZoneSettingObserver::~TimeZoneSettingObserver()
-{
- nsCOMPtr<nsIObserverService> observerService = services::GetObserverService();
- if (observerService) {
- observerService->RemoveObserver(this, MOZSETTINGS_CHANGED);
- }
-}
-
-NS_IMPL_ISUPPORTS(TimeZoneSettingObserver, nsIObserver)
-
-NS_IMETHODIMP
-TimeZoneSettingObserver::Observe(nsISupports *aSubject,
- const char *aTopic,
- const char16_t *aData)
-{
- if (strcmp(aTopic, MOZSETTINGS_CHANGED) != 0) {
- return NS_OK;
- }
-
- // Note that this function gets called for any and all settings changes,
- // so we need to carefully check if we have the one we're interested in.
- //
- // The string that we're interested in will be a JSON string that looks like:
- // {"key":"time.timezone","value":"America/Chicago"} or
- // {"key":"time.timezone","value":"UTC-05:00"}
-
- AutoSafeJSContext cx;
- RootedDictionary<SettingChangeNotification> setting(cx);
- if (!WrappedJSToDictionary(cx, aSubject, setting)) {
- return NS_OK;
- }
- if (!setting.mKey.EqualsASCII(TIME_TIMEZONE)) {
- return NS_OK;
- }
- if (!setting.mValue.isString()) {
- return NS_OK;
- }
-
- // Set the system timezone.
- return SetTimeZone(setting.mValue, cx);
-}
-
-} // namespace
-
-static mozilla::StaticRefPtr<TimeZoneSettingObserver> sTimeZoneSettingObserver;
-namespace mozilla {
-namespace system {
-void
-InitializeTimeZoneSettingObserver()
-{
- sTimeZoneSettingObserver = new TimeZoneSettingObserver();
- ClearOnShutdown(&sTimeZoneSettingObserver);
-}
-
-} // namespace system
-} // namespace mozilla
diff --git a/dom/system/gonk/TimeZoneSettingObserver.h b/dom/system/gonk/TimeZoneSettingObserver.h
deleted file mode 100644
index 08b7cebb3a..0000000000
--- a/dom/system/gonk/TimeZoneSettingObserver.h
+++ /dev/null
@@ -1,20 +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/. */
-
-#ifndef mozilla_system_timesetting_h__
-#define mozilla_system_timesetting_h__
-
-namespace mozilla {
-namespace system {
-
-// Initialize TimeZoneSettingObserver which observes the time zone change
-// event from settings service. When receiving the event, it modifies the
-// system time zone.
-void InitializeTimeZoneSettingObserver();
-
-} // namespace system
-} // namespace mozilla
-
-#endif // mozilla_system_timesetting_h__
-
diff --git a/dom/system/gonk/Volume.cpp b/dom/system/gonk/Volume.cpp
deleted file mode 100644
index f90c7b6933..0000000000
--- a/dom/system/gonk/Volume.cpp
+++ /dev/null
@@ -1,596 +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 "Volume.h"
-#include "VolumeCommand.h"
-#include "VolumeManager.h"
-#include "VolumeManagerLog.h"
-#include "nsIVolume.h"
-#include "nsXULAppAPI.h"
-
-#include <vold/ResponseCode.h>
-
-namespace mozilla {
-namespace system {
-
-#if DEBUG_VOLUME_OBSERVER
-void
-VolumeObserverList::Broadcast(Volume* const& aVolume)
-{
- uint32_t size = mObservers.Length();
- for (uint32_t i = 0; i < size; ++i) {
- LOG("VolumeObserverList::Broadcast to [%u] %p volume '%s'",
- i, mObservers[i], aVolume->NameStr());
- mObservers[i]->Notify(aVolume);
- }
-}
-#endif
-
-VolumeObserverList Volume::sEventObserverList;
-
-// We have a feature where volumes can be locked when mounted. This
-// is used to prevent a volume from being shared with the PC while
-// it is actively being used (say for storing an update image)
-//
-// We use WakeLocks (a poor choice of name, but it does what we want)
-// from the PowerManagerService to determine when we're locked.
-// In particular we'll create a wakelock called volume-NAME-GENERATION
-// (where NAME is the volume name, and GENERATION is its generation
-// number), and if this wakelock is locked, then we'll prevent a volume
-// from being shared.
-//
-// Implementation Details:
-//
-// Since the AutoMounter can only control when something gets mounted
-// and not when it gets unmounted (for example: a user pulls the SDCard)
-// and because Volume and nsVolume data structures are maintained on
-// separate threads, we have the potential for some race conditions.
-// We eliminate the race conditions by introducing the concept of a
-// generation number. Every time a volume transitions to the Mounted
-// state, it gets assigned a new generation number. Whenever the state
-// of a Volume changes, we send the updated state and current generation
-// number to the main thread where it gets updated in the nsVolume.
-//
-// Since WakeLocks can only be queried from the main-thread, the
-// nsVolumeService looks for WakeLock status changes, and forwards
-// the results to the IOThread.
-//
-// If the Volume (IOThread) receives a volume update where the generation
-// number mismatches, then the update is simply ignored.
-//
-// When a Volume (IOThread) initially becomes mounted, we assume it to
-// be locked until we get our first update from nsVolume (MainThread).
-static int32_t sMountGeneration = 0;
-
-static uint32_t sNextId = 1;
-
-// We don't get media inserted/removed events at startup. So we
-// assume it's present, and we'll be told that it's missing.
-Volume::Volume(const nsCSubstring& aName)
- : mMediaPresent(true),
- mState(nsIVolume::STATE_INIT),
- mName(aName),
- mMountGeneration(-1),
- mMountLocked(true), // Needs to agree with nsVolume::nsVolume
- mSharingEnabled(false),
- mFormatRequested(false),
- mMountRequested(false),
- mUnmountRequested(false),
- mCanBeShared(true),
- mIsSharing(false),
- mIsFormatting(false),
- mIsUnmounting(false),
- mIsRemovable(false),
- mIsHotSwappable(false),
- mId(sNextId++)
-{
- DBG("Volume %s: created", NameStr());
-}
-
-void
-Volume::Dump(const char* aLabel) const
-{
- LOG("%s: Volume: %s (%d) is %s and %s @ %s gen %d locked %d",
- aLabel,
- NameStr(),
- Id(),
- StateStr(),
- MediaPresent() ? "inserted" : "missing",
- MountPoint().get(),
- MountGeneration(),
- (int)IsMountLocked());
- LOG("%s: Sharing %s Mounting %s Formating %s Unmounting %s",
- aLabel,
- CanBeShared() ? (IsSharingEnabled() ? (IsSharing() ? "en-y" : "en-n")
- : "dis")
- : "x",
- IsMountRequested() ? "req" : "n",
- IsFormatRequested() ? (IsFormatting() ? "req-y" : "req-n")
- : (IsFormatting() ? "y" : "n"),
- IsUnmountRequested() ? (IsUnmounting() ? "req-y" : "req-n")
- : (IsUnmounting() ? "y" : "n"));
-}
-
-void
-Volume::ResolveAndSetMountPoint(const nsCSubstring& aMountPoint)
-{
- nsCString mountPoint(aMountPoint);
- char realPathBuf[PATH_MAX];
-
- // Call realpath so that we wind up with a path which is compatible with
- // functions like nsVolumeService::GetVolumeByPath.
-
- if (realpath(mountPoint.get(), realPathBuf) < 0) {
- // The path we were handed doesn't exist. Warn about it, but use it
- // anyways assuming that the user knows what they're doing.
-
- ERR("ResolveAndSetMountPoint: realpath on '%s' failed: %d",
- mountPoint.get(), errno);
- mMountPoint = mountPoint;
- } else {
- mMountPoint = realPathBuf;
- }
- DBG("Volume %s: Setting mountpoint to '%s'", NameStr(), mMountPoint.get());
-}
-
-void Volume::SetFakeVolume(const nsACString& aMountPoint)
-{
- this->mMountLocked = false;
- this->mCanBeShared = false;
- ResolveAndSetMountPoint(aMountPoint);
- SetState(nsIVolume::STATE_MOUNTED);
-}
-
-void
-Volume::SetIsSharing(bool aIsSharing)
-{
- if (aIsSharing == mIsSharing) {
- return;
- }
- mIsSharing = aIsSharing;
- LOG("Volume %s: IsSharing set to %d state %s",
- NameStr(), (int)mIsSharing, StateStr(mState));
- sEventObserverList.Broadcast(this);
-}
-
-void
-Volume::SetIsFormatting(bool aIsFormatting)
-{
- if (aIsFormatting == mIsFormatting) {
- return;
- }
- mIsFormatting = aIsFormatting;
- LOG("Volume %s: IsFormatting set to %d state %s",
- NameStr(), (int)mIsFormatting, StateStr(mState));
- if (mIsFormatting) {
- sEventObserverList.Broadcast(this);
- }
-}
-
-void
-Volume::SetIsUnmounting(bool aIsUnmounting)
-{
- if (aIsUnmounting == mIsUnmounting) {
- return;
- }
- mIsUnmounting = aIsUnmounting;
- LOG("Volume %s: IsUnmounting set to %d state %s",
- NameStr(), (int)mIsUnmounting, StateStr(mState));
- sEventObserverList.Broadcast(this);
-}
-
-void
-Volume::SetIsRemovable(bool aIsRemovable)
-{
- if (aIsRemovable == mIsRemovable) {
- return;
- }
- mIsRemovable = aIsRemovable;
- if (!mIsRemovable) {
- mIsHotSwappable = false;
- }
- LOG("Volume %s: IsRemovable set to %d state %s",
- NameStr(), (int)mIsRemovable, StateStr(mState));
- sEventObserverList.Broadcast(this);
-}
-
-void
-Volume::SetIsHotSwappable(bool aIsHotSwappable)
-{
- if (aIsHotSwappable == mIsHotSwappable) {
- return;
- }
- mIsHotSwappable = aIsHotSwappable;
- if (mIsHotSwappable) {
- mIsRemovable = true;
- }
- LOG("Volume %s: IsHotSwappable set to %d state %s",
- NameStr(), (int)mIsHotSwappable, StateStr(mState));
- sEventObserverList.Broadcast(this);
-}
-
-bool
-Volume::BoolConfigValue(const nsCString& aConfigValue, bool& aBoolValue)
-{
- if (aConfigValue.EqualsLiteral("1") ||
- aConfigValue.LowerCaseEqualsLiteral("true")) {
- aBoolValue = true;
- return true;
- }
- if (aConfigValue.EqualsLiteral("0") ||
- aConfigValue.LowerCaseEqualsLiteral("false")) {
- aBoolValue = false;
- return true;
- }
- return false;
-}
-
-void
-Volume::SetConfig(const nsCString& aConfigName, const nsCString& aConfigValue)
-{
- if (aConfigName.LowerCaseEqualsLiteral("removable")) {
- bool value = false;
- if (BoolConfigValue(aConfigValue, value)) {
- SetIsRemovable(value);
- } else {
- ERR("Volume %s: invalid value '%s' for configuration '%s'",
- NameStr(), aConfigValue.get(), aConfigName.get());
- }
- return;
- }
- if (aConfigName.LowerCaseEqualsLiteral("hotswappable")) {
- bool value = false;
- if (BoolConfigValue(aConfigValue, value)) {
- SetIsHotSwappable(value);
- } else {
- ERR("Volume %s: invalid value '%s' for configuration '%s'",
- NameStr(), aConfigValue.get(), aConfigName.get());
- }
- return;
- }
- ERR("Volume %s: invalid config '%s'", NameStr(), aConfigName.get());
-}
-
-void
-Volume::SetMediaPresent(bool aMediaPresent)
-{
- MOZ_ASSERT(XRE_IsParentProcess());
- MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
-
- // mMediaPresent is slightly redunant to the state, however
- // when media is removed (while Idle), we get the following:
- // 631 Volume sdcard /mnt/sdcard disk removed (179:0)
- // 605 Volume sdcard /mnt/sdcard state changed from 1 (Idle-Unmounted) to 0 (No-Media)
- //
- // And on media insertion, we get:
- // 630 Volume sdcard /mnt/sdcard disk inserted (179:0)
- // 605 Volume sdcard /mnt/sdcard state changed from 0 (No-Media) to 2 (Pending)
- // 605 Volume sdcard /mnt/sdcard state changed from 2 (Pending) to 1 (Idle-Unmounted)
- //
- // On media removal while the media is mounted:
- // 632 Volume sdcard /mnt/sdcard bad removal (179:1)
- // 605 Volume sdcard /mnt/sdcard state changed from 4 (Mounted) to 5 (Unmounting)
- // 605 Volume sdcard /mnt/sdcard state changed from 5 (Unmounting) to 1 (Idle-Unmounted)
- // 631 Volume sdcard /mnt/sdcard disk removed (179:0)
- // 605 Volume sdcard /mnt/sdcard state changed from 1 (Idle-Unmounted) to 0 (No-Media)
- //
- // When sharing with a PC, it goes Mounted -> Idle -> Shared
- // When unsharing with a PC, it goes Shared -> Idle -> Mounted
- //
- // The AutoMounter needs to know whether the media is present or not when
- // processing the Idle state.
-
- if (mMediaPresent == aMediaPresent) {
- return;
- }
-
- LOG("Volume: %s media %s", NameStr(), aMediaPresent ? "inserted" : "removed");
- mMediaPresent = aMediaPresent;
- sEventObserverList.Broadcast(this);
-}
-
-void
-Volume::SetSharingEnabled(bool aSharingEnabled)
-{
- mSharingEnabled = aSharingEnabled;
-
- LOG("SetSharingMode for volume %s to %d canBeShared = %d",
- NameStr(), (int)mSharingEnabled, (int)mCanBeShared);
- sEventObserverList.Broadcast(this);
-}
-
-void
-Volume::SetFormatRequested(bool aFormatRequested)
-{
- mFormatRequested = aFormatRequested;
-
- LOG("SetFormatRequested for volume %s to %d CanBeFormatted = %d",
- NameStr(), (int)mFormatRequested, (int)CanBeFormatted());
-}
-
-void
-Volume::SetMountRequested(bool aMountRequested)
-{
- mMountRequested = aMountRequested;
-
- LOG("SetMountRequested for volume %s to %d CanBeMounted = %d",
- NameStr(), (int)mMountRequested, (int)CanBeMounted());
-}
-
-void
-Volume::SetUnmountRequested(bool aUnmountRequested)
-{
- mUnmountRequested = aUnmountRequested;
-
- LOG("SetUnmountRequested for volume %s to %d CanBeMounted = %d",
- NameStr(), (int)mUnmountRequested, (int)CanBeMounted());
-}
-
-void
-Volume::SetState(Volume::STATE aNewState)
-{
- MOZ_ASSERT(XRE_IsParentProcess());
- MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
- if (aNewState == mState) {
- return;
- }
- if (aNewState == nsIVolume::STATE_MOUNTED) {
- mMountGeneration = ++sMountGeneration;
- LOG("Volume %s (%u): changing state from %s to %s @ '%s' (%d observers) "
- "mountGeneration = %d, locked = %d",
- NameStr(), mId, StateStr(mState),
- StateStr(aNewState), mMountPoint.get(), sEventObserverList.Length(),
- mMountGeneration, (int)mMountLocked);
- } else {
- LOG("Volume %s (%u): changing state from %s to %s (%d observers)",
- NameStr(), mId, StateStr(mState),
- StateStr(aNewState), sEventObserverList.Length());
- }
-
- switch (aNewState) {
- case nsIVolume::STATE_NOMEDIA:
- // Cover the startup case where we don't get insertion/removal events
- mMediaPresent = false;
- mIsSharing = false;
- mUnmountRequested = false;
- mMountRequested = false;
- mIsUnmounting = false;
- break;
-
- case nsIVolume::STATE_MOUNTED:
- case nsIVolume::STATE_MOUNT_FAIL:
- mMountRequested = false;
- mIsFormatting = false;
- mIsSharing = false;
- mIsUnmounting = false;
- break;
-
- case nsIVolume::STATE_FORMATTING:
- mFormatRequested = false;
- mIsFormatting = true;
- mIsSharing = false;
- mIsUnmounting = false;
- break;
-
- case nsIVolume::STATE_SHARED:
- case nsIVolume::STATE_SHAREDMNT:
- // Covers startup cases. Normally, mIsSharing would be set to true
- // when we issue the command to initiate the sharing process, but
- // it's conceivable that a volume could already be in a shared state
- // when b2g starts.
- mIsSharing = true;
- mIsUnmounting = false;
- mIsFormatting = false;
- break;
-
- case nsIVolume::STATE_UNMOUNTING:
- mIsUnmounting = true;
- mIsFormatting = false;
- mIsSharing = false;
- break;
-
- case nsIVolume::STATE_IDLE: // Fall through
- case nsIVolume::STATE_CHECKMNT: // Fall through
- default:
- break;
- }
- mState = aNewState;
- sEventObserverList.Broadcast(this);
-}
-
-void
-Volume::SetMountPoint(const nsCSubstring& aMountPoint)
-{
- MOZ_ASSERT(XRE_IsParentProcess());
- MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
-
- if (mMountPoint.Equals(aMountPoint)) {
- return;
- }
- ResolveAndSetMountPoint(aMountPoint);
-}
-
-void
-Volume::StartMount(VolumeResponseCallback* aCallback)
-{
- MOZ_ASSERT(XRE_IsParentProcess());
- MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
-
- StartCommand(new VolumeActionCommand(this, "mount", "", aCallback));
-}
-
-void
-Volume::StartUnmount(VolumeResponseCallback* aCallback)
-{
- MOZ_ASSERT(XRE_IsParentProcess());
- MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
-
- StartCommand(new VolumeActionCommand(this, "unmount", "force", aCallback));
-}
-
-void
-Volume::StartFormat(VolumeResponseCallback* aCallback)
-{
- MOZ_ASSERT(XRE_IsParentProcess());
- MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
-
- StartCommand(new VolumeActionCommand(this, "format", "", aCallback));
-}
-
-void
-Volume::StartShare(VolumeResponseCallback* aCallback)
-{
- MOZ_ASSERT(XRE_IsParentProcess());
- MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
-
- StartCommand(new VolumeActionCommand(this, "share", "ums", aCallback));
-}
-
-void
-Volume::StartUnshare(VolumeResponseCallback* aCallback)
-{
- MOZ_ASSERT(XRE_IsParentProcess());
- MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
-
- StartCommand(new VolumeActionCommand(this, "unshare", "ums", aCallback));
-}
-
-void
-Volume::StartCommand(VolumeCommand* aCommand)
-{
- MOZ_ASSERT(XRE_IsParentProcess());
- MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
-
- VolumeManager::PostCommand(aCommand);
-}
-
-//static
-void
-Volume::RegisterVolumeObserver(Volume::EventObserver* aObserver, const char* aName)
-{
- MOZ_ASSERT(XRE_IsParentProcess());
- MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
-
- sEventObserverList.AddObserver(aObserver);
-
- DBG("Added Volume Observer '%s' @%p, length = %u",
- aName, aObserver, sEventObserverList.Length());
-
- // Send an initial event to the observer (for each volume)
- size_t numVolumes = VolumeManager::NumVolumes();
- for (size_t volIndex = 0; volIndex < numVolumes; volIndex++) {
- RefPtr<Volume> vol = VolumeManager::GetVolume(volIndex);
- aObserver->Notify(vol);
- }
-}
-
-//static
-void
-Volume::UnregisterVolumeObserver(Volume::EventObserver* aObserver, const char* aName)
-{
- MOZ_ASSERT(XRE_IsParentProcess());
- MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
-
- sEventObserverList.RemoveObserver(aObserver);
-
- DBG("Removed Volume Observer '%s' @%p, length = %u",
- aName, aObserver, sEventObserverList.Length());
-}
-
-//static
-void
-Volume::UpdateMountLock(const nsACString& aVolumeName,
- const int32_t& aMountGeneration,
- const bool& aMountLocked)
-{
- MOZ_ASSERT(XRE_IsParentProcess());
- MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
-
- RefPtr<Volume> vol = VolumeManager::FindVolumeByName(aVolumeName);
- if (!vol || (vol->mMountGeneration != aMountGeneration)) {
- return;
- }
- if (vol->mMountLocked != aMountLocked) {
- vol->mMountLocked = aMountLocked;
- DBG("Volume::UpdateMountLock for '%s' to %d\n", vol->NameStr(), (int)aMountLocked);
- sEventObserverList.Broadcast(vol);
- }
-}
-
-void
-Volume::HandleVoldResponse(int aResponseCode, nsCWhitespaceTokenizer& aTokenizer)
-{
- MOZ_ASSERT(XRE_IsParentProcess());
- MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
-
- // The volume name will have already been parsed, and the tokenizer will point
- // to the token after the volume name
- switch (aResponseCode) {
- case ::ResponseCode::VolumeListResult: {
- // Each line will look something like:
- //
- // sdcard /mnt/sdcard 1
- //
- nsDependentCSubstring mntPoint(aTokenizer.nextToken());
- SetMountPoint(mntPoint);
- nsresult errCode;
- nsCString state(aTokenizer.nextToken());
- if (state.EqualsLiteral("X")) {
- // Special state for creating fake volumes which can't be shared.
- mCanBeShared = false;
- SetState(nsIVolume::STATE_MOUNTED);
- } else {
- SetState((STATE)state.ToInteger(&errCode));
- }
- break;
- }
-
- case ::ResponseCode::VolumeStateChange: {
- // Format of the line looks something like:
- //
- // Volume sdcard /mnt/sdcard state changed from 7 (Shared-Unmounted) to 1 (Idle-Unmounted)
- //
- // So we parse out the state after the string " to "
- while (aTokenizer.hasMoreTokens()) {
- nsAutoCString token(aTokenizer.nextToken());
- if (token.EqualsLiteral("to")) {
- nsresult errCode;
- token = aTokenizer.nextToken();
- STATE newState = (STATE)(token.ToInteger(&errCode));
- if (newState == nsIVolume::STATE_MOUNTED) {
- // We set the state to STATE_CHECKMNT here, and the once the
- // AutoMounter detects that the volume is actually accessible
- // then the AutoMounter will set the volume as STATE_MOUNTED.
- SetState(nsIVolume::STATE_CHECKMNT);
- } else {
- if (State() == nsIVolume::STATE_CHECKING && newState == nsIVolume::STATE_IDLE) {
- LOG("Mount of volume '%s' failed", NameStr());
- SetState(nsIVolume::STATE_MOUNT_FAIL);
- } else {
- SetState(newState);
- }
- }
- break;
- }
- }
- break;
- }
-
- case ::ResponseCode::VolumeDiskInserted:
- SetMediaPresent(true);
- break;
-
- case ::ResponseCode::VolumeDiskRemoved: // fall-thru
- case ::ResponseCode::VolumeBadRemoval:
- SetMediaPresent(false);
- break;
-
- default:
- LOG("Volume: %s unrecognized reponse code (ignored)", NameStr());
- break;
- }
-}
-
-} // namespace system
-} // namespace mozilla
diff --git a/dom/system/gonk/Volume.h b/dom/system/gonk/Volume.h
deleted file mode 100644
index 821292a9a4..0000000000
--- a/dom/system/gonk/Volume.h
+++ /dev/null
@@ -1,157 +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/. */
-
-#ifndef mozilla_system_volume_h__
-#define mozilla_system_volume_h__
-
-#include "VolumeCommand.h"
-#include "nsIVolume.h"
-#include "nsString.h"
-#include "mozilla/Observer.h"
-#include "nsISupportsImpl.h"
-#include "nsWhitespaceTokenizer.h"
-
-namespace mozilla {
-namespace system {
-
-/***************************************************************************
-*
-* There is an instance of the Volume class for each volume reported
-* from vold.
-*
-* Each volume originates from the /system/etv/vold.fstab file.
-*
-***************************************************************************/
-
-class Volume;
-
-#define DEBUG_VOLUME_OBSERVER 0
-
-#if DEBUG_VOLUME_OBSERVER
-class VolumeObserverList : public mozilla::ObserverList<Volume*>
-{
-public:
- void Broadcast(Volume* const& aVolume);
-};
-#else
-typedef mozilla::ObserverList<Volume*> VolumeObserverList;
-#endif
-
-class Volume final
-{
-public:
- NS_INLINE_DECL_REFCOUNTING(Volume)
-
- Volume(const nsCSubstring& aVolumeName);
-
- typedef long STATE; // States are now defined in nsIVolume.idl
-
- static const char* StateStr(STATE aState) { return NS_VolumeStateStr(aState); }
- const char* StateStr() const { return StateStr(mState); }
- STATE State() const { return mState; }
-
- const nsCString& Name() const { return mName; }
- const char* NameStr() const { return mName.get(); }
-
- void Dump(const char* aLabel) const;
-
- // The mount point is the name of the directory where the volume is mounted.
- // (i.e. path that leads to the files stored on the volume).
- const nsCString& MountPoint() const { return mMountPoint; }
-
- uint32_t Id() const { return mId; }
-
- int32_t MountGeneration() const { return mMountGeneration; }
- bool IsMountLocked() const { return mMountLocked; }
- bool MediaPresent() const { return mMediaPresent; }
- bool CanBeShared() const { return mCanBeShared; }
- bool CanBeFormatted() const { return CanBeShared(); }
- bool CanBeMounted() const { return CanBeShared(); }
- bool IsSharingEnabled() const { return mCanBeShared && mSharingEnabled; }
- bool IsFormatRequested() const { return CanBeFormatted() && mFormatRequested; }
- bool IsMountRequested() const { return CanBeMounted() && mMountRequested; }
- bool IsUnmountRequested() const { return CanBeMounted() && mUnmountRequested; }
- bool IsSharing() const { return mIsSharing; }
- bool IsFormatting() const { return mIsFormatting; }
- bool IsUnmounting() const { return mIsUnmounting; }
- bool IsRemovable() const { return mIsRemovable; }
- bool IsHotSwappable() const { return mIsHotSwappable; }
-
- void SetFakeVolume(const nsACString& aMountPoint);
-
- void SetSharingEnabled(bool aSharingEnabled);
- void SetFormatRequested(bool aFormatRequested);
- void SetMountRequested(bool aMountRequested);
- void SetUnmountRequested(bool aUnmountRequested);
-
- typedef mozilla::Observer<Volume *> EventObserver;
-
- // NOTE: that observers must live in the IOThread.
- static void RegisterVolumeObserver(EventObserver* aObserver, const char* aName);
- static void UnregisterVolumeObserver(EventObserver* aObserver, const char* aName);
-
-protected:
- ~Volume() {}
-
-private:
- friend class AutoMounter; // Calls StartXxx
- friend class nsVolume; // Calls UpdateMountLock
- friend class VolumeManager; // Calls HandleVoldResponse
- friend class VolumeListCallback; // Calls SetMountPoint, SetState
-
- // The StartXxx functions will queue up a command to the VolumeManager.
- // You can queue up as many commands as you like, and aCallback will
- // be called as each one completes.
- void StartMount(VolumeResponseCallback* aCallback);
- void StartUnmount(VolumeResponseCallback* aCallback);
- void StartFormat(VolumeResponseCallback* aCallback);
- void StartShare(VolumeResponseCallback* aCallback);
- void StartUnshare(VolumeResponseCallback* aCallback);
-
- void SetIsSharing(bool aIsSharing);
- void SetIsFormatting(bool aIsFormatting);
- void SetIsUnmounting(bool aIsUnmounting);
- void SetIsRemovable(bool aIsRemovable);
- void SetIsHotSwappable(bool aIsHotSwappable);
- void SetState(STATE aNewState);
- void SetMediaPresent(bool aMediaPresent);
- void SetMountPoint(const nsCSubstring& aMountPoint);
- void StartCommand(VolumeCommand* aCommand);
-
- void ResolveAndSetMountPoint(const nsCSubstring& aMountPoint);
-
- bool BoolConfigValue(const nsCString& aConfigValue, bool& aBoolValue);
- void SetConfig(const nsCString& aConfigName, const nsCString& aConfigValue);
-
- void HandleVoldResponse(int aResponseCode, nsCWhitespaceTokenizer& aTokenizer);
-
- static void UpdateMountLock(const nsACString& aVolumeName,
- const int32_t& aMountGeneration,
- const bool& aMountLocked);
-
- bool mMediaPresent;
- STATE mState;
- const nsCString mName;
- nsCString mMountPoint;
- int32_t mMountGeneration;
- bool mMountLocked;
- bool mSharingEnabled;
- bool mFormatRequested;
- bool mMountRequested;
- bool mUnmountRequested;
- bool mCanBeShared;
- bool mIsSharing;
- bool mIsFormatting;
- bool mIsUnmounting;
- bool mIsRemovable;
- bool mIsHotSwappable;
- uint32_t mId; // Unique ID (used by MTP)
-
- static VolumeObserverList sEventObserverList;
-};
-
-} // system
-} // mozilla
-
-#endif // mozilla_system_volumemanager_h__
diff --git a/dom/system/gonk/VolumeCommand.cpp b/dom/system/gonk/VolumeCommand.cpp
deleted file mode 100644
index 8095956a76..0000000000
--- a/dom/system/gonk/VolumeCommand.cpp
+++ /dev/null
@@ -1,85 +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 "nsString.h"
-#include "nsWhitespaceTokenizer.h"
-
-#include "Volume.h"
-#include "VolumeCommand.h"
-#include "VolumeManager.h"
-#include "VolumeManagerLog.h"
-
-namespace mozilla {
-namespace system {
-
-/***************************************************************************
-*
-* The VolumeActionCommand class is used to send commands which apply
-* to a particular volume.
-*
-* The following commands would fit into this category:
-*
-* volume mount <volname>
-* volume unmount <volname> [force]
-* volume format <volname>
-* volume share <volname> <method>
-* volume unshare <volname> <method>
-* volume shared <volname> <method>
-*
-* A typical response looks like:
-*
-* # vdc volume unshare sdcard ums
-* 605 Volume sdcard /mnt/sdcard state changed from 7 (Shared-Unmounted) to 1 (Idle-Unmounted)
-* 200 volume operation succeeded
-*
-* Note that the 600 series of responses are considered unsolicited and
-* are dealt with directly by the VolumeManager. This command will only
-* see the terminating response code (200 in the example above).
-*
-***************************************************************************/
-
-VolumeActionCommand::VolumeActionCommand(Volume* aVolume,
- const char* aAction,
- const char* aExtraArgs,
- VolumeResponseCallback* aCallback)
- : VolumeCommand(aCallback),
- mVolume(aVolume)
-{
- nsAutoCString cmd;
-
- cmd = "volume ";
- cmd += aAction;
- cmd += " ";
- cmd += aVolume->Name().get();
-
- // vold doesn't like trailing white space, so only add it if we really need to.
- if (aExtraArgs && (*aExtraArgs != '\0')) {
- cmd += " ";
- cmd += aExtraArgs;
- }
- SetCmd(cmd);
-}
-
-/***************************************************************************
-*
-* The VolumeListCommand class is used to send the "volume list" command to
-* vold.
-*
-* A typical response looks like:
-*
-* # vdc volume list
-* 110 sdcard /mnt/sdcard 4
-* 110 sdcard1 /mnt/sdcard/external_sd 4
-* 200 Volumes listed.
-*
-***************************************************************************/
-
-VolumeListCommand::VolumeListCommand(VolumeResponseCallback* aCallback)
- : VolumeCommand(NS_LITERAL_CSTRING("volume list"), aCallback)
-{
-}
-
-} // system
-} // mozilla
-
diff --git a/dom/system/gonk/VolumeCommand.h b/dom/system/gonk/VolumeCommand.h
deleted file mode 100644
index 022965b5e0..0000000000
--- a/dom/system/gonk/VolumeCommand.h
+++ /dev/null
@@ -1,204 +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/. */
-
-#ifndef mozilla_system_volumecommand_h__
-#define mozilla_system_volumecommand_h__
-
-#include "nsString.h"
-#include "nsISupportsImpl.h"
-#include "mozilla/RefPtr.h"
-#include <algorithm>
-#include <vold/ResponseCode.h>
-
-namespace mozilla {
-namespace system {
-
-class Volume;
-class VolumeCommand;
-
-/***************************************************************************
-*
-* The VolumeResponseCallback class is an abstract base class. The ResponseReceived
-* method will be called for each response received.
-*
-* Depending on the command, there may be multiple responses for the
-* command. Done() will return true if this is the last response.
-*
-* The responses from vold are all of the form:
-*
-* <ResponseCode> <String>
-*
-* Valid Response codes can be found in the vold/ResponseCode.h header.
-*
-***************************************************************************/
-
-class VolumeResponseCallback
-{
-protected:
- virtual ~VolumeResponseCallback() {}
-
-public:
- NS_INLINE_DECL_REFCOUNTING(VolumeResponseCallback)
- VolumeResponseCallback()
- : mResponseCode(0), mPending(false) {}
-
- bool Done() const
- {
- // Response codes from the 200, 400, and 500 series all indicated that
- // the command has completed.
-
- return (mResponseCode >= ::ResponseCode::CommandOkay)
- && (mResponseCode < ::ResponseCode::UnsolicitedInformational);
- }
-
- bool WasSuccessful() const
- {
- return mResponseCode == ::ResponseCode::CommandOkay;
- }
-
- bool IsPending() const { return mPending; }
- int ResponseCode() const { return mResponseCode; }
- const nsCString &ResponseStr() const { return mResponseStr; }
-
-protected:
- virtual void ResponseReceived(const VolumeCommand* aCommand) = 0;
-
-private:
- friend class VolumeCommand; // Calls HandleResponse and SetPending
-
- void HandleResponse(const VolumeCommand* aCommand,
- int aResponseCode,
- nsACString& aResponseStr)
- {
- mResponseCode = aResponseCode;
-#if ANDROID_VERSION >= 17
- // There's a sequence number here that we don't care about
- // We expect it to be 0. See VolumeCommand::SetCmd
- mResponseStr = Substring(aResponseStr, 2);
-#else
- mResponseStr = aResponseStr;
-#endif
- if (mResponseCode >= ::ResponseCode::CommandOkay) {
- // This is a final response.
- mPending = false;
- }
- ResponseReceived(aCommand);
- }
-
- void SetPending(bool aPending) { mPending = aPending; }
-
- int mResponseCode; // The response code parsed from vold
- nsCString mResponseStr; // The rest of the line.
- bool mPending; // Waiting for response?
-};
-
-/***************************************************************************
-*
-* The VolumeCommand class is an abstract base class used to encapsulate
-* volume commands send to vold.
-*
-* See VolumeManager.h for a list of the volume commands.
-*
-* Commands sent to vold need an explicit null character so we add one
-* to the command to ensure that it's included in the length.
-*
-* All of these commands are asynchronous in nature, and the
-* ResponseReceived callback will be called when a response is available.
-*
-***************************************************************************/
-
-class VolumeCommand
-{
-protected:
- virtual ~VolumeCommand() {}
-
-public:
- NS_INLINE_DECL_REFCOUNTING(VolumeCommand)
-
- VolumeCommand(VolumeResponseCallback* aCallback)
- : mBytesConsumed(0),
- mCallback(aCallback)
- {
- SetCmd(NS_LITERAL_CSTRING(""));
- }
-
- VolumeCommand(const nsACString& aCommand, VolumeResponseCallback* aCallback)
- : mBytesConsumed(0),
- mCallback(aCallback)
- {
- SetCmd(aCommand);
- }
-
- void SetCmd(const nsACString& aCommand)
- {
- mCmd.Truncate();
-#if ANDROID_VERSION >= 17
- // JB requires a sequence number at the beginning of messages.
- // It doesn't matter what we use, so we use 0.
- mCmd = "0 ";
-#endif
- mCmd.Append(aCommand);
- // Add a null character. We want this to be included in the length since
- // vold uses it to determine the end of the command.
- mCmd.Append('\0');
- }
-
- const char* CmdStr() const { return mCmd.get(); }
- const char* Data() const { return mCmd.Data() + mBytesConsumed; }
- size_t BytesConsumed() const { return mBytesConsumed; }
-
- size_t BytesRemaining() const
- {
- return mCmd.Length() - std::min(mCmd.Length(), mBytesConsumed);
- }
-
- void ConsumeBytes(size_t aNumBytes)
- {
- mBytesConsumed += std::min(BytesRemaining(), aNumBytes);
- }
-
-private:
- friend class VolumeManager; // Calls SetPending & HandleResponse
-
- void SetPending(bool aPending)
- {
- if (mCallback) {
- mCallback->SetPending(aPending);
- }
- }
-
- void HandleResponse(int aResponseCode, nsACString& aResponseStr)
- {
- if (mCallback) {
- mCallback->HandleResponse(this, aResponseCode, aResponseStr);
- }
- }
-
- nsCString mCmd; // Command being sent
- size_t mBytesConsumed; // How many bytes have been sent
-
- // Called when a response to the command is received.
- RefPtr<VolumeResponseCallback> mCallback;
-};
-
-class VolumeActionCommand : public VolumeCommand
-{
-public:
- VolumeActionCommand(Volume* aVolume, const char* aAction,
- const char* aExtraArgs, VolumeResponseCallback* aCallback);
-
-private:
- RefPtr<Volume> mVolume;
-};
-
-class VolumeListCommand : public VolumeCommand
-{
-public:
- VolumeListCommand(VolumeResponseCallback* aCallback);
-};
-
-} // system
-} // mozilla
-
-#endif // mozilla_system_volumecommand_h__
diff --git a/dom/system/gonk/VolumeManager.cpp b/dom/system/gonk/VolumeManager.cpp
deleted file mode 100644
index ddfa7af09e..0000000000
--- a/dom/system/gonk/VolumeManager.cpp
+++ /dev/null
@@ -1,591 +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 "VolumeManager.h"
-
-#include "Volume.h"
-#include "VolumeCommand.h"
-#include "VolumeManagerLog.h"
-#include "VolumeServiceTest.h"
-
-#include "nsWhitespaceTokenizer.h"
-#include "nsXULAppAPI.h"
-
-#include "base/message_loop.h"
-#include "base/task.h"
-#include "mozilla/Scoped.h"
-#include "mozilla/StaticPtr.h"
-
-#include <android/log.h>
-#include <cutils/sockets.h>
-#include <fcntl.h>
-#include <sys/socket.h>
-
-namespace mozilla {
-namespace system {
-
-static StaticRefPtr<VolumeManager> sVolumeManager;
-
-VolumeManager::STATE VolumeManager::mState = VolumeManager::UNINITIALIZED;
-VolumeManager::StateObserverList VolumeManager::mStateObserverList;
-
-/***************************************************************************/
-
-VolumeManager::VolumeManager()
- : LineWatcher('\0', kRcvBufSize),
- mSocket(-1),
- mCommandPending(false)
-{
- DBG("VolumeManager constructor called");
-}
-
-VolumeManager::~VolumeManager()
-{
-}
-
-//static
-void
-VolumeManager::Dump(const char* aLabel)
-{
- if (!sVolumeManager) {
- LOG("%s: sVolumeManager == null", aLabel);
- return;
- }
-
- VolumeArray::size_type numVolumes = NumVolumes();
- VolumeArray::index_type volIndex;
- for (volIndex = 0; volIndex < numVolumes; volIndex++) {
- RefPtr<Volume> vol = GetVolume(volIndex);
- vol->Dump(aLabel);
- }
-}
-
-//static
-size_t
-VolumeManager::NumVolumes()
-{
- if (!sVolumeManager) {
- return 0;
- }
- return sVolumeManager->mVolumeArray.Length();
-}
-
-//static
-already_AddRefed<Volume>
-VolumeManager::GetVolume(size_t aIndex)
-{
- MOZ_ASSERT(aIndex < NumVolumes());
- RefPtr<Volume> vol = sVolumeManager->mVolumeArray[aIndex];
- return vol.forget();
-}
-
-//static
-VolumeManager::STATE
-VolumeManager::State()
-{
- return mState;
-}
-
-//static
-const char *
-VolumeManager::StateStr(VolumeManager::STATE aState)
-{
- switch (aState) {
- case UNINITIALIZED: return "Uninitialized";
- case STARTING: return "Starting";
- case VOLUMES_READY: return "Volumes Ready";
- }
- return "???";
-}
-
-
-//static
-void
-VolumeManager::SetState(STATE aNewState)
-{
- if (mState != aNewState) {
- LOG("changing state from '%s' to '%s'",
- StateStr(mState), StateStr(aNewState));
- mState = aNewState;
- mStateObserverList.Broadcast(StateChangedEvent());
- }
-}
-
-//static
-void
-VolumeManager::RegisterStateObserver(StateObserver* aObserver)
-{
- mStateObserverList.AddObserver(aObserver);
-}
-
-//static
-void VolumeManager::UnregisterStateObserver(StateObserver* aObserver)
-{
- mStateObserverList.RemoveObserver(aObserver);
-}
-
-//static
-already_AddRefed<Volume>
-VolumeManager::FindVolumeByName(const nsCSubstring& aName)
-{
- if (!sVolumeManager) {
- return nullptr;
- }
- VolumeArray::size_type numVolumes = NumVolumes();
- VolumeArray::index_type volIndex;
- for (volIndex = 0; volIndex < numVolumes; volIndex++) {
- RefPtr<Volume> vol = GetVolume(volIndex);
- if (vol->Name().Equals(aName)) {
- return vol.forget();
- }
- }
- return nullptr;
-}
-
-//static
-already_AddRefed<Volume>
-VolumeManager::FindAddVolumeByName(const nsCSubstring& aName)
-{
- RefPtr<Volume> vol = FindVolumeByName(aName);
- if (vol) {
- return vol.forget();
- }
- // No volume found, create and add a new one.
- vol = new Volume(aName);
- sVolumeManager->mVolumeArray.AppendElement(vol);
- return vol.forget();
-}
-
-//static
-bool
-VolumeManager::RemoveVolumeByName(const nsCSubstring& aName)
-{
- if (!sVolumeManager) {
- return false;
- }
- VolumeArray::size_type numVolumes = NumVolumes();
- VolumeArray::index_type volIndex;
- for (volIndex = 0; volIndex < numVolumes; volIndex++) {
- RefPtr<Volume> vol = GetVolume(volIndex);
- if (vol->Name().Equals(aName)) {
- sVolumeManager->mVolumeArray.RemoveElementAt(volIndex);
- return true;
- }
- }
- // No volume found. Return false to indicate this.
- return false;
-}
-
-
-//static
-void VolumeManager::InitConfig()
-{
- MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
-
- // This function uses /system/etc/volume.cfg to add additional volumes
- // to the Volume Manager.
- //
- // This is useful on devices like the Nexus 4, which have no physical sd card
- // or dedicated partition.
- //
- // The format of the volume.cfg file is as follows:
- // create volume-name mount-point
- // configure volume-name preference preference-value
- // Blank lines and lines starting with the hash character "#" will be ignored.
-
- ScopedCloseFile fp;
- int n = 0;
- char line[255];
- const char *filename = "/system/etc/volume.cfg";
- if (!(fp = fopen(filename, "r"))) {
- LOG("Unable to open volume configuration file '%s' - ignoring", filename);
- return;
- }
- while(fgets(line, sizeof(line), fp)) {
- n++;
-
- if (line[0] == '#')
- continue;
-
- nsCString commandline(line);
- nsCWhitespaceTokenizer tokenizer(commandline);
- if (!tokenizer.hasMoreTokens()) {
- // Blank line - ignore
- continue;
- }
-
- nsCString command(tokenizer.nextToken());
- if (command.EqualsLiteral("create")) {
- if (!tokenizer.hasMoreTokens()) {
- ERR("No vol_name in %s line %d", filename, n);
- continue;
- }
- nsCString volName(tokenizer.nextToken());
- if (!tokenizer.hasMoreTokens()) {
- ERR("No mount point for volume '%s'. %s line %d",
- volName.get(), filename, n);
- continue;
- }
- nsCString mountPoint(tokenizer.nextToken());
- RefPtr<Volume> vol = FindAddVolumeByName(volName);
- vol->SetFakeVolume(mountPoint);
- continue;
- }
- if (command.EqualsLiteral("configure")) {
- if (!tokenizer.hasMoreTokens()) {
- ERR("No vol_name in %s line %d", filename, n);
- continue;
- }
- nsCString volName(tokenizer.nextToken());
- if (!tokenizer.hasMoreTokens()) {
- ERR("No configuration name specified for volume '%s'. %s line %d",
- volName.get(), filename, n);
- continue;
- }
- nsCString configName(tokenizer.nextToken());
- if (!tokenizer.hasMoreTokens()) {
- ERR("No value for configuration name '%s'. %s line %d",
- configName.get(), filename, n);
- continue;
- }
- nsCString configValue(tokenizer.nextToken());
- RefPtr<Volume> vol = FindVolumeByName(volName);
- if (vol) {
- vol->SetConfig(configName, configValue);
- } else {
- ERR("Invalid volume name '%s'.", volName.get());
- }
- continue;
- }
- if (command.EqualsLiteral("ignore")) {
- // This command is useful to remove volumes which are being tracked by
- // vold, but for which we have no interest.
- if (!tokenizer.hasMoreTokens()) {
- ERR("No vol_name in %s line %d", filename, n);
- continue;
- }
- nsCString volName(tokenizer.nextToken());
- RemoveVolumeByName(volName);
- continue;
- }
- ERR("Unrecognized command: '%s'", command.get());
- }
-}
-
-void
-VolumeManager::DefaultConfig()
-{
-
- VolumeManager::VolumeArray::size_type numVolumes = VolumeManager::NumVolumes();
- if (numVolumes == 0) {
- return;
- }
- if (numVolumes == 1) {
- // This is to cover early shipping phones like the Buri,
- // which had no internal storage, and only external sdcard.
- //
- // Phones line the nexus-4 which only have an internal
- // storage area will need to have a volume.cfg file with
- // removable set to false.
- RefPtr<Volume> vol = VolumeManager::GetVolume(0);
- vol->SetIsRemovable(true);
- vol->SetIsHotSwappable(true);
- return;
- }
- VolumeManager::VolumeArray::index_type volIndex;
- for (volIndex = 0; volIndex < numVolumes; volIndex++) {
- RefPtr<Volume> vol = VolumeManager::GetVolume(volIndex);
- if (!vol->Name().EqualsLiteral("sdcard")) {
- vol->SetIsRemovable(true);
- vol->SetIsHotSwappable(true);
- }
- }
-}
-
-class VolumeListCallback : public VolumeResponseCallback
-{
- virtual void ResponseReceived(const VolumeCommand* aCommand)
- {
- switch (ResponseCode()) {
- case ::ResponseCode::VolumeListResult: {
- // Each line will look something like:
- //
- // sdcard /mnt/sdcard 1
- //
- // So for each volume that we get back, we update any volumes that
- // we have of the same name, or add new ones if they don't exist.
- nsCWhitespaceTokenizer tokenizer(ResponseStr());
- nsDependentCSubstring volName(tokenizer.nextToken());
- RefPtr<Volume> vol = VolumeManager::FindAddVolumeByName(volName);
- vol->HandleVoldResponse(ResponseCode(), tokenizer);
- break;
- }
-
- case ::ResponseCode::CommandOkay: {
- // We've received the list of volumes. Now read the Volume.cfg
- // file to perform customizations, and then tell everybody
- // that we're ready for business.
- VolumeManager::DefaultConfig();
- VolumeManager::InitConfig();
- VolumeManager::Dump("READY");
- VolumeManager::SetState(VolumeManager::VOLUMES_READY);
- break;
- }
- }
- }
-};
-
-bool
-VolumeManager::OpenSocket()
-{
- SetState(STARTING);
- if ((mSocket.rwget() = socket_local_client("vold",
- ANDROID_SOCKET_NAMESPACE_RESERVED,
- SOCK_STREAM)) < 0) {
- ERR("Error connecting to vold: (%s) - will retry", strerror(errno));
- return false;
- }
- // add FD_CLOEXEC flag
- int flags = fcntl(mSocket.get(), F_GETFD);
- if (flags == -1) {
- return false;
- }
- flags |= FD_CLOEXEC;
- if (fcntl(mSocket.get(), F_SETFD, flags) == -1) {
- return false;
- }
- // set non-blocking
- if (fcntl(mSocket.get(), F_SETFL, O_NONBLOCK) == -1) {
- return false;
- }
- if (!MessageLoopForIO::current()->
- WatchFileDescriptor(mSocket.get(),
- true,
- MessageLoopForIO::WATCH_READ,
- &mReadWatcher,
- this)) {
- return false;
- }
-
- LOG("Connected to vold");
- PostCommand(new VolumeListCommand(new VolumeListCallback));
- return true;
-}
-
-//static
-void
-VolumeManager::PostCommand(VolumeCommand* aCommand)
-{
- if (!sVolumeManager) {
- ERR("VolumeManager not initialized. Dropping command '%s'", aCommand->Data());
- return;
- }
- aCommand->SetPending(true);
-
- DBG("Sending command '%s'", aCommand->Data());
- // vold can only process one command at a time, so add our command
- // to the end of the command queue.
- sVolumeManager->mCommands.push(aCommand);
- if (!sVolumeManager->mCommandPending) {
- // There aren't any commands currently being processed, so go
- // ahead and kick this one off.
- sVolumeManager->mCommandPending = true;
- sVolumeManager->WriteCommandData();
- }
-}
-
-/***************************************************************************
-* The WriteCommandData initiates sending of a command to vold. Since
-* we're running on the IOThread and not allowed to block, WriteCommandData
-* will write as much data as it can, and if not all of the data can be
-* written then it will setup a file descriptor watcher and
-* OnFileCanWriteWithoutBlocking will call WriteCommandData to write out
-* more of the command data.
-*/
-void
-VolumeManager::WriteCommandData()
-{
- if (mCommands.size() == 0) {
- return;
- }
-
- VolumeCommand* cmd = mCommands.front();
- if (cmd->BytesRemaining() == 0) {
- // All bytes have been written. We're waiting for a response.
- return;
- }
- // There are more bytes left to write. Try to write them all.
- ssize_t bytesWritten = write(mSocket.get(), cmd->Data(), cmd->BytesRemaining());
- if (bytesWritten < 0) {
- ERR("Failed to write %d bytes to vold socket", cmd->BytesRemaining());
- Restart();
- return;
- }
- DBG("Wrote %d bytes (of %d)", bytesWritten, cmd->BytesRemaining());
- cmd->ConsumeBytes(bytesWritten);
- if (cmd->BytesRemaining() == 0) {
- return;
- }
- // We were unable to write all of the command bytes. Setup a watcher
- // so we'll get called again when we can write without blocking.
- if (!MessageLoopForIO::current()->
- WatchFileDescriptor(mSocket.get(),
- false, // one-shot
- MessageLoopForIO::WATCH_WRITE,
- &mWriteWatcher,
- this)) {
- ERR("Failed to setup write watcher for vold socket");
- Restart();
- }
-}
-
-void
-VolumeManager::OnLineRead(int aFd, nsDependentCSubstring& aMessage)
-{
- MOZ_ASSERT(aFd == mSocket.get());
- char* endPtr;
- int responseCode = strtol(aMessage.Data(), &endPtr, 10);
- if (*endPtr == ' ') {
- endPtr++;
- }
-
- // Now fish out the rest of the line after the response code
- nsDependentCString responseLine(endPtr, aMessage.Length() - (endPtr - aMessage.Data()));
- DBG("Rcvd: %d '%s'", responseCode, responseLine.Data());
-
- if (responseCode >= ::ResponseCode::UnsolicitedInformational) {
- // These are unsolicited broadcasts. We intercept these and process
- // them ourselves
- HandleBroadcast(responseCode, responseLine);
- } else {
- // Everything else is considered to be part of the command response.
- if (mCommands.size() > 0) {
- VolumeCommand* cmd = mCommands.front();
- cmd->HandleResponse(responseCode, responseLine);
- if (responseCode >= ::ResponseCode::CommandOkay) {
- // That's a terminating response. We can remove the command.
- mCommands.pop();
- mCommandPending = false;
- // Start the next command, if there is one.
- WriteCommandData();
- }
- } else {
- ERR("Response with no command");
- }
- }
-}
-
-void
-VolumeManager::OnFileCanWriteWithoutBlocking(int aFd)
-{
- MOZ_ASSERT(aFd == mSocket.get());
- WriteCommandData();
-}
-
-void
-VolumeManager::HandleBroadcast(int aResponseCode, nsCString& aResponseLine)
-{
- // Format of the line is something like:
- //
- // Volume sdcard /mnt/sdcard state changed from 7 (Shared-Unmounted) to 1 (Idle-Unmounted)
- //
- // So we parse out the volume name and the state after the string " to "
- nsCWhitespaceTokenizer tokenizer(aResponseLine);
- tokenizer.nextToken(); // The word "Volume"
- nsDependentCSubstring volName(tokenizer.nextToken());
-
- RefPtr<Volume> vol = FindVolumeByName(volName);
- if (!vol) {
- return;
- }
- vol->HandleVoldResponse(aResponseCode, tokenizer);
-}
-
-void
-VolumeManager::Restart()
-{
- mReadWatcher.StopWatchingFileDescriptor();
- mWriteWatcher.StopWatchingFileDescriptor();
-
- while (!mCommands.empty()) {
- mCommands.pop();
- }
- mCommandPending = false;
- mSocket.dispose();
- Start();
-}
-
-//static
-void
-VolumeManager::Start()
-{
- MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
-
- if (!sVolumeManager) {
- return;
- }
- SetState(STARTING);
- if (!sVolumeManager->OpenSocket()) {
- // Socket open failed, try again in a second.
- MessageLoopForIO::current()->
- PostDelayedTask(NewRunnableFunction(VolumeManager::Start),
- 1000);
- }
-}
-
-void
-VolumeManager::OnError()
-{
- Restart();
-}
-
-/***************************************************************************/
-
-static void
-InitVolumeManagerIOThread()
-{
- MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
- MOZ_ASSERT(!sVolumeManager);
-
- sVolumeManager = new VolumeManager();
- VolumeManager::Start();
-
- InitVolumeServiceTestIOThread();
-}
-
-static void
-ShutdownVolumeManagerIOThread()
-{
- MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
-
- sVolumeManager = nullptr;
-}
-
-/**************************************************************************
-*
-* Public API
-*
-* Since the VolumeManager runs in IO Thread context, we need to switch
-* to IOThread context before we can do anything.
-*
-**************************************************************************/
-
-void
-InitVolumeManager()
-{
- XRE_GetIOMessageLoop()->PostTask(
- NewRunnableFunction(InitVolumeManagerIOThread));
-}
-
-void
-ShutdownVolumeManager()
-{
- ShutdownVolumeServiceTest();
-
- XRE_GetIOMessageLoop()->PostTask(
- NewRunnableFunction(ShutdownVolumeManagerIOThread));
-}
-
-} // system
-} // mozilla
diff --git a/dom/system/gonk/VolumeManager.h b/dom/system/gonk/VolumeManager.h
deleted file mode 100644
index 7c0503389f..0000000000
--- a/dom/system/gonk/VolumeManager.h
+++ /dev/null
@@ -1,192 +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/. */
-
-#ifndef mozilla_system_volumemanager_h__
-#define mozilla_system_volumemanager_h__
-
-#include <vector>
-#include <queue>
-
-#include "base/message_loop.h"
-#include "mozilla/FileUtils.h"
-#include "mozilla/Observer.h"
-#include "nsISupportsImpl.h"
-#include "nsString.h"
-#include "nsTArray.h"
-
-#include "Volume.h"
-#include "VolumeCommand.h"
-
-namespace mozilla {
-namespace system {
-
-/***************************************************************************
-*
-* All of the public API mentioned in this file (unless otherwise
-* mentioned) must run from the IOThread.
-*
-***************************************************************************/
-
-/***************************************************************************
-*
-* The VolumeManager class is a front-end for android's vold service.
-*
-* Vold uses a unix socket interface and accepts null-terminated string
-* commands. The following commands were determined by examining the vold
-* source code:
-*
-* volume list
-* volume mount <volname>
-* volume unmount <volname> [force]
-* volume debug [on|off]
-* volume format <volname>
-* volume share <volname> <method>
-* volume unshare <volname> <method>
-* volume shared <volname> <method>
-*
-* <volname> is the name of the volume as used in /system/etc/vold.fstab
-* <method> is ums
-*
-* dump
-*
-* share status <method> (Determines if a particular sharing method is available)
-* (GB only - not available in ICS)
-*
-* storage users (??? always crashes vold ???)
-*
-* asec list
-* asec ...lots more...
-*
-* obb list
-* obb ...lots more...
-*
-* xwarp enable
-* xwarp disable
-* xwarp status
-*
-* There is also a command line tool called vdc, which can be used to send
-* the above commands to vold.
-*
-* Currently, only the volume list, share/unshare, and mount/unmount
-* commands are being used.
-*
-***************************************************************************/
-
-class VolumeManager final : public MessageLoopForIO::LineWatcher
-{
- virtual ~VolumeManager();
-
-public:
- NS_INLINE_DECL_REFCOUNTING(VolumeManager)
-
- typedef nsTArray<RefPtr<Volume>> VolumeArray;
-
- VolumeManager();
-
- //-----------------------------------------------------------------------
- //
- // State related methods.
- //
- // The VolumeManager starts off in the STARTING state. Once a connection
- // is established with vold, it asks for a list of volumes, and once the
- // volume list has been received, then the VolumeManager enters the
- // VOLUMES_READY state.
- //
- // If vold crashes, then the VolumeManager will once again enter the
- // STARTING state and try to reestablish a connection with vold.
-
- enum STATE
- {
- UNINITIALIZED,
- STARTING,
- VOLUMES_READY
- };
-
- static STATE State();
- static const char* StateStr(STATE aState);
- static const char* StateStr() { return StateStr(State()); }
-
- class StateChangedEvent
- {
- public:
- StateChangedEvent() {}
- };
-
- typedef mozilla::Observer<StateChangedEvent> StateObserver;
- typedef mozilla::ObserverList<StateChangedEvent> StateObserverList;
-
- static void RegisterStateObserver(StateObserver* aObserver);
- static void UnregisterStateObserver(StateObserver* aObserver);
-
- //-----------------------------------------------------------------------
-
- static void Start();
- static void Dump(const char* aLabel);
-
- static VolumeArray::size_type NumVolumes();
- static already_AddRefed<Volume> GetVolume(VolumeArray::index_type aIndex);
- static already_AddRefed<Volume> FindVolumeByName(const nsCSubstring& aName);
- static already_AddRefed<Volume> FindAddVolumeByName(const nsCSubstring& aName);
- static bool RemoveVolumeByName(const nsCSubstring& aName);
- static void InitConfig();
-
- static void PostCommand(VolumeCommand* aCommand);
-
-protected:
-
- virtual void OnLineRead(int aFd, nsDependentCSubstring& aMessage);
- virtual void OnFileCanWriteWithoutBlocking(int aFd);
- virtual void OnError();
-
- static void DefaultConfig();
-
-private:
- bool OpenSocket();
-
- friend class VolumeListCallback; // Calls SetState
-
- static void SetState(STATE aNewState);
-
- void Restart();
- void WriteCommandData();
- void HandleBroadcast(int aResponseCode, nsCString& aResponseLine);
-
- typedef std::queue<RefPtr<VolumeCommand> > CommandQueue;
-
- static STATE mState;
- static StateObserverList mStateObserverList;
-
- static const int kRcvBufSize = 1024;
- ScopedClose mSocket;
- VolumeArray mVolumeArray;
- CommandQueue mCommands;
- bool mCommandPending;
- MessageLoopForIO::FileDescriptorWatcher mReadWatcher;
- MessageLoopForIO::FileDescriptorWatcher mWriteWatcher;
- RefPtr<VolumeResponseCallback> mBroadcastCallback;
-};
-
-/***************************************************************************
-*
-* The initialization/shutdown functions do not need to be called from
-* the IOThread context.
-*
-***************************************************************************/
-
-/**
- * Initialize the Volume Manager. On initialization, the VolumeManager will
- * attempt to connect with vold and collect the list of volumes that vold
- * knows about.
- */
-void InitVolumeManager();
-
-/**
- * Shuts down the Volume Manager.
- */
-void ShutdownVolumeManager();
-
-} // system
-} // mozilla
-
-#endif // mozilla_system_volumemanager_h__
diff --git a/dom/system/gonk/VolumeManagerLog.h b/dom/system/gonk/VolumeManagerLog.h
deleted file mode 100644
index 793f4889c9..0000000000
--- a/dom/system/gonk/VolumeManagerLog.h
+++ /dev/null
@@ -1,27 +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/. */
-
-#ifndef mozilla_system_volumemanagerlog_h__
-#define mozilla_system_volumemanagerlog_h__
-
-#undef USE_DEBUG
-#define USE_DEBUG 0
-
-#if !defined(VOLUME_MANAGER_LOG_TAG)
-#define VOLUME_MANAGER_LOG_TAG "VolumeManager"
-#endif
-
-#undef LOG
-#undef ERR
-#define LOG(args...) __android_log_print(ANDROID_LOG_INFO, VOLUME_MANAGER_LOG_TAG, ## args)
-#define ERR(args...) __android_log_print(ANDROID_LOG_ERROR, VOLUME_MANAGER_LOG_TAG, ## args)
-
-#undef DBG
-#if USE_DEBUG
-#define DBG(args...) __android_log_print(ANDROID_LOG_DEBUG, VOLUME_MANAGER_LOG_TAG, ## args)
-#else
-#define DBG(args...)
-#endif
-
-#endif // mozilla_system_volumemanagerlog_h__
diff --git a/dom/system/gonk/VolumeServiceIOThread.cpp b/dom/system/gonk/VolumeServiceIOThread.cpp
deleted file mode 100644
index 7eda843c00..0000000000
--- a/dom/system/gonk/VolumeServiceIOThread.cpp
+++ /dev/null
@@ -1,82 +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 "VolumeServiceIOThread.h"
-#include "base/message_loop.h"
-#include "nsVolumeService.h"
-#include "nsXULAppAPI.h"
-#include "Volume.h"
-#include "VolumeManager.h"
-
-namespace mozilla {
-namespace system {
-
-VolumeServiceIOThread::VolumeServiceIOThread(nsVolumeService* aVolumeService)
- : mVolumeService(aVolumeService)
-{
- MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
-
- VolumeManager::RegisterStateObserver(this);
- Volume::RegisterVolumeObserver(this, "VolumeServiceIOThread");
- UpdateAllVolumes();
-}
-
-VolumeServiceIOThread::~VolumeServiceIOThread()
-{
- MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
- Volume::UnregisterVolumeObserver(this, "VolumeServiceIOThread");
- VolumeManager::UnregisterStateObserver(this);
-}
-
-void
-VolumeServiceIOThread::Notify(Volume* const & aVolume)
-{
- MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
- if (VolumeManager::State() != VolumeManager::VOLUMES_READY) {
- return;
- }
- mVolumeService->UpdateVolumeIOThread(aVolume);
-}
-
-void
-VolumeServiceIOThread::Notify(const VolumeManager::StateChangedEvent& aEvent)
-{
- MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
- UpdateAllVolumes();
-}
-
-void
-VolumeServiceIOThread::UpdateAllVolumes()
-{
- MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
- if (VolumeManager::State() != VolumeManager::VOLUMES_READY) {
- return;
- }
- VolumeManager::VolumeArray::size_type numVolumes = VolumeManager::NumVolumes();
- VolumeManager::VolumeArray::index_type volIndex;
-
- for (volIndex = 0; volIndex < numVolumes; volIndex++) {
- RefPtr<Volume> vol = VolumeManager::GetVolume(volIndex);
- mVolumeService->UpdateVolumeIOThread(vol);
- }
-}
-
-static StaticRefPtr<VolumeServiceIOThread> sVolumeServiceIOThread;
-
-void
-InitVolumeServiceIOThread(nsVolumeService* const & aVolumeService)
-{
- MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
- sVolumeServiceIOThread = new VolumeServiceIOThread(aVolumeService);
-}
-
-void
-ShutdownVolumeServiceIOThread()
-{
- MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
- sVolumeServiceIOThread = nullptr;
-}
-
-} // system
-} // mozilla
diff --git a/dom/system/gonk/VolumeServiceIOThread.h b/dom/system/gonk/VolumeServiceIOThread.h
deleted file mode 100644
index 0c2a6a62f2..0000000000
--- a/dom/system/gonk/VolumeServiceIOThread.h
+++ /dev/null
@@ -1,49 +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/. */
-
-#ifndef mozilla_system_volumeserviceiothread_h__
-#define mozilla_system_volumeserviceiothread_h__
-
-#include "Volume.h"
-#include "VolumeManager.h"
-#include "mozilla/RefPtr.h"
-
-namespace mozilla {
-namespace system {
-
-class nsVolumeService;
-
-/***************************************************************************
-* The nsVolumeServiceIOThread is a companion class to the nsVolumeService
-* class, but whose methods are called from IOThread.
-*/
-class VolumeServiceIOThread : public VolumeManager::StateObserver,
- public Volume::EventObserver
-{
- ~VolumeServiceIOThread();
-
-public:
- NS_INLINE_DECL_REFCOUNTING(VolumeServiceIOThread)
-
- VolumeServiceIOThread(nsVolumeService* aVolumeService);
-
-private:
- void UpdateAllVolumes();
-
- virtual void Notify(const VolumeManager::StateChangedEvent& aEvent);
- virtual void Notify(Volume* const & aVolume);
-
- RefPtr<nsVolumeService> mVolumeService;
-};
-
-void InitVolumeServiceIOThread(nsVolumeService* const & aVolumeService);
-void ShutdownVolumeServiceIOThread();
-void FormatVolume(const nsCString& aVolume);
-void MountVolume(const nsCString& aVolume);
-void UnmountVolume(const nsCString& aVolume);
-
-} // system
-} // mozilla
-
-#endif // mozilla_system_volumeserviceiothread_h__
diff --git a/dom/system/gonk/VolumeServiceTest.cpp b/dom/system/gonk/VolumeServiceTest.cpp
deleted file mode 100644
index 4082e3889f..0000000000
--- a/dom/system/gonk/VolumeServiceTest.cpp
+++ /dev/null
@@ -1,202 +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 "VolumeServiceTest.h"
-
-#include "base/message_loop.h"
-#include "nsCOMPtr.h"
-#include "nsIObserver.h"
-#include "nsIObserverService.h"
-#include "nsServiceManagerUtils.h"
-#include "nsThreadUtils.h"
-#include "nsIVolume.h"
-#include "nsIVolumeService.h"
-#include "nsIVolumeStat.h"
-#include "nsXULAppAPI.h"
-
-#include "mozilla/Services.h"
-
-#undef VOLUME_MANAGER_LOG_TAG
-#define VOLUME_MANAGER_LOG_TAG "VolumeServiceTest"
-#include "VolumeManagerLog.h"
-
-using namespace mozilla::services;
-
-namespace mozilla {
-namespace system {
-
-#define TEST_NSVOLUME_OBSERVER 0
-
-#if TEST_NSVOLUME_OBSERVER
-
-/***************************************************************************
-* A test class to verify that the Observer stuff is working properly.
-*/
-class VolumeTestObserver : public nsIObserver
-{
-public:
- NS_DECL_ISUPPORTS
- NS_DECL_NSIOBSERVER
-
- VolumeTestObserver()
- {
- nsCOMPtr<nsIObserverService> obs = GetObserverService();
- if (!obs) {
- return;
- }
- obs->AddObserver(this, NS_VOLUME_STATE_CHANGED, false);
- }
- ~VolumeTestObserver()
- {
- nsCOMPtr<nsIObserverService> obs = GetObserverService();
- if (!obs) {
- return;
- }
- obs->RemoveObserver(this, NS_VOLUME_STATE_CHANGED);
- }
-
- void LogVolume(nsIVolume* vol)
- {
- nsString volName;
- nsString mountPoint;
- int32_t volState;
-
- vol->GetName(volName);
- vol->GetMountPoint(mountPoint);
- vol->GetState(&volState);
-
- LOG(" Volume: %s MountPoint: %s State: %s",
- NS_LossyConvertUTF16toASCII(volName).get(),
- NS_LossyConvertUTF16toASCII(mountPoint).get(),
- NS_VolumeStateStr(volState));
-
- nsCOMPtr<nsIVolumeStat> stat;
- nsresult rv = vol->GetStats(getter_AddRefs(stat));
- if (NS_SUCCEEDED(rv)) {
- int64_t totalBytes;
- int64_t freeBytes;
-
- stat->GetTotalBytes(&totalBytes);
- stat->GetFreeBytes(&freeBytes);
-
- LOG(" Total Space: %llu Mb Free Bytes: %llu Mb",
- totalBytes / (1024LL * 1024LL), freeBytes / (1024LL * 1024LL));
- }
- else {
- LOG(" Unable to retrieve stats");
- }
- }
-};
-static nsCOMPtr<VolumeTestObserver> sTestObserver;
-
-NS_IMPL_ISUPPORTS(VolumeTestObserver, nsIObserver)
-
-NS_IMETHODIMP
-VolumeTestObserver::Observe(nsISupports* aSubject,
- const char* aTopic,
- const char16_t* aData)
-{
- LOG("TestObserver: topic: %s", aTopic);
-
- if (strcmp(aTopic, NS_VOLUME_STATE_CHANGED) != 0) {
- return NS_OK;
- }
- nsCOMPtr<nsIVolume> vol = do_QueryInterface(aSubject);
- if (vol) {
- LogVolume(vol);
- }
-
- // Since this observe method was called then we know that the service
- // has been initialized so we can do the VolumeService tests.
-
- nsCOMPtr<nsIVolumeService> vs = do_GetService(NS_VOLUMESERVICE_CONTRACTID);
- if (!vs) {
- ERR("do_GetService('%s') failed", NS_VOLUMESERVICE_CONTRACTID);
- return NS_ERROR_FAILURE;
- }
-
- nsresult rv = vs->GetVolumeByName(NS_LITERAL_STRING("sdcard"), getter_AddRefs(vol));
- if (NS_SUCCEEDED(rv)) {
- LOG("GetVolumeByName( 'sdcard' ) succeeded (expected)");
- LogVolume(vol);
- } else {
- ERR("GetVolumeByName( 'sdcard' ) failed (unexpected)");
- }
-
- rv = vs->GetVolumeByName(NS_LITERAL_STRING("foo"), getter_AddRefs(vol));
- if (NS_SUCCEEDED(rv)) {
- ERR("GetVolumeByName( 'foo' ) succeeded (unexpected)");
- } else {
- LOG("GetVolumeByName( 'foo' ) failed (expected)");
- }
-
- rv = vs->GetVolumeByPath(NS_LITERAL_STRING("/mnt/sdcard"), getter_AddRefs(vol));
- if (NS_SUCCEEDED(rv)) {
- LOG("GetVolumeByPath( '/mnt/sdcard' ) succeeded (expected)");
- LogVolume(vol);
- } else {
- ERR("GetVolumeByPath( '/mnt/sdcard' ) failed (unexpected");
- }
-
- rv = vs->GetVolumeByPath(NS_LITERAL_STRING("/mnt/sdcard/foo"), getter_AddRefs(vol));
- if (NS_SUCCEEDED(rv)) {
- LOG("GetVolumeByPath( '/mnt/sdcard/foo' ) succeeded (expected)");
- LogVolume(vol);
- } else {
- LOG("GetVolumeByPath( '/mnt/sdcard/foo' ) failed (unexpected)");
- }
-
- rv = vs->GetVolumeByPath(NS_LITERAL_STRING("/mnt/sdcardfoo"), getter_AddRefs(vol));
- if (NS_SUCCEEDED(rv)) {
- ERR("GetVolumeByPath( '/mnt/sdcardfoo' ) succeeded (unexpected)");
- } else {
- LOG("GetVolumeByPath( '/mnt/sdcardfoo' ) failed (expected)");
- }
-
- return NS_OK;
-}
-
-class InitVolumeServiceTestIO : public Runnable
-{
-public:
- NS_IMETHOD Run() override
- {
- MOZ_ASSERT(NS_IsMainThread());
-
- DBG("InitVolumeServiceTest called");
- nsCOMPtr<nsIVolumeService> vs = do_GetService(NS_VOLUMESERVICE_CONTRACTID);
- if (!vs) {
- ERR("do_GetService('%s') failed", NS_VOLUMESERVICE_CONTRACTID);
- return NS_ERROR_FAILURE;
- }
- sTestObserver = new VolumeTestObserver();
-
- return NS_OK;
- }
-};
-#endif // TEST_NSVOLUME_OBSERVER
-
-void
-InitVolumeServiceTestIOThread()
-{
- MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
-
-#if TEST_NSVOLUME_OBSERVER
- // Now that the volume manager is initialized we can go
- // ahead and do our test (on main thread).
- NS_DispatchToMainThread(new InitVolumeServiceTestIO());
-#endif
-}
-
-void
-ShutdownVolumeServiceTest()
-{
-#if TEST_NSVOLUME_OBSERVER
- DBG("ShutdownVolumeServiceTestIOThread called");
- sTestObserver = nullptr;
-#endif
-}
-
-} // system
-} // mozilla
diff --git a/dom/system/gonk/VolumeServiceTest.h b/dom/system/gonk/VolumeServiceTest.h
deleted file mode 100644
index 71a92bf6c6..0000000000
--- a/dom/system/gonk/VolumeServiceTest.h
+++ /dev/null
@@ -1,19 +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/. */
-
-#ifndef mozilla_system_volumeservicetest_h__
-#define mozilla_system_volumeservicetest_h__
-
-
-namespace mozilla {
-namespace system {
-
-void InitVolumeServiceTestIOThread();
-void ShutdownVolumeServiceTest();
-
-} // system
-} // mozilla
-
-#endif // mozilla_system_volumeservicetest_h__
-
diff --git a/dom/system/gonk/android_audio/AudioSystem.h b/dom/system/gonk/android_audio/AudioSystem.h
deleted file mode 100644
index d5841eaaa6..0000000000
--- a/dom/system/gonk/android_audio/AudioSystem.h
+++ /dev/null
@@ -1,1134 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_AUDIOSYSTEM_H_
-#define ANDROID_AUDIOSYSTEM_H_
-
-#pragma GCC visibility push(default)
-
-#include <utils/RefBase.h>
-#include <utils/threads.h>
-#include "IAudioFlinger.h"
-
-#ifndef VANILLA_ANDROID
-/* request to open a direct output with get_output() (by opposition to
- * sharing an output with other AudioTracks)
- */
-typedef enum {
- AUDIO_POLICY_OUTPUT_FLAG_INDIRECT = 0x0,
- AUDIO_POLICY_OUTPUT_FLAG_DIRECT = 0x1
-} audio_policy_output_flags_t;
-
-/* device categories used for audio_policy->set_force_use() */
-typedef enum {
- AUDIO_POLICY_FORCE_NONE,
- AUDIO_POLICY_FORCE_SPEAKER,
- AUDIO_POLICY_FORCE_HEADPHONES,
- AUDIO_POLICY_FORCE_BT_SCO,
- AUDIO_POLICY_FORCE_BT_A2DP,
- AUDIO_POLICY_FORCE_WIRED_ACCESSORY,
- AUDIO_POLICY_FORCE_BT_CAR_DOCK,
- AUDIO_POLICY_FORCE_BT_DESK_DOCK,
- AUDIO_POLICY_FORCE_ANALOG_DOCK,
- AUDIO_POLICY_FORCE_DIGITAL_DOCK,
- AUDIO_POLICY_FORCE_NO_BT_A2DP,
- AUDIO_POLICY_FORCE_CFG_CNT,
- AUDIO_POLICY_FORCE_CFG_MAX = AUDIO_POLICY_FORCE_CFG_CNT - 1,
-
- AUDIO_POLICY_FORCE_DEFAULT = AUDIO_POLICY_FORCE_NONE,
-} audio_policy_forced_cfg_t;
-
-/* usages used for audio_policy->set_force_use() */
-typedef enum {
- AUDIO_POLICY_FORCE_FOR_COMMUNICATION,
- AUDIO_POLICY_FORCE_FOR_MEDIA,
- AUDIO_POLICY_FORCE_FOR_RECORD,
- AUDIO_POLICY_FORCE_FOR_DOCK,
-
- AUDIO_POLICY_FORCE_USE_CNT,
- AUDIO_POLICY_FORCE_USE_MAX = AUDIO_POLICY_FORCE_USE_CNT - 1,
-} audio_policy_force_use_t;
-
-typedef enum {
- AUDIO_STREAM_DEFAULT = -1,
- AUDIO_STREAM_VOICE_CALL = 0,
- AUDIO_STREAM_SYSTEM = 1,
- AUDIO_STREAM_RING = 2,
- AUDIO_STREAM_MUSIC = 3,
- AUDIO_STREAM_ALARM = 4,
- AUDIO_STREAM_NOTIFICATION = 5,
- AUDIO_STREAM_BLUETOOTH_SCO = 6,
- AUDIO_STREAM_ENFORCED_AUDIBLE = 7, /* Sounds that cannot be muted by user and must be routed to speaker */
- AUDIO_STREAM_DTMF = 8,
- AUDIO_STREAM_TTS = 9,
-#if ANDROID_VERSION < 19
- AUDIO_STREAM_FM = 10,
-#endif
-
- AUDIO_STREAM_CNT,
- AUDIO_STREAM_MAX = AUDIO_STREAM_CNT - 1,
-} audio_stream_type_t;
-
-/* PCM sub formats */
-typedef enum {
- AUDIO_FORMAT_PCM_SUB_16_BIT = 0x1, /* DO NOT CHANGE - PCM signed 16 bits */
- AUDIO_FORMAT_PCM_SUB_8_BIT = 0x2, /* DO NOT CHANGE - PCM unsigned 8 bits */
- AUDIO_FORMAT_PCM_SUB_32_BIT = 0x3, /* PCM signed .31 fixed point */
- AUDIO_FORMAT_PCM_SUB_8_24_BIT = 0x4, /* PCM signed 7.24 fixed point */
-} audio_format_pcm_sub_fmt_t;
-
-/* Audio format consists in a main format field (upper 8 bits) and a sub format
- * field (lower 24 bits).
- *
- * The main format indicates the main codec type. The sub format field
- * indicates options and parameters for each format. The sub format is mainly
- * used for record to indicate for instance the requested bitrate or profile.
- * It can also be used for certain formats to give informations not present in
- * the encoded audio stream (e.g. octet alignement for AMR).
- */
-typedef enum {
- AUDIO_FORMAT_INVALID = 0xFFFFFFFFUL,
- AUDIO_FORMAT_DEFAULT = 0,
- AUDIO_FORMAT_PCM = 0x00000000UL, /* DO NOT CHANGE */
- AUDIO_FORMAT_MP3 = 0x01000000UL,
- AUDIO_FORMAT_AMR_NB = 0x02000000UL,
- AUDIO_FORMAT_AMR_WB = 0x03000000UL,
- AUDIO_FORMAT_AAC = 0x04000000UL,
- AUDIO_FORMAT_HE_AAC_V1 = 0x05000000UL,
- AUDIO_FORMAT_HE_AAC_V2 = 0x06000000UL,
- AUDIO_FORMAT_VORBIS = 0x07000000UL,
- AUDIO_FORMAT_MAIN_MASK = 0xFF000000UL,
- AUDIO_FORMAT_SUB_MASK = 0x00FFFFFFUL,
-
- /* Aliases */
- AUDIO_FORMAT_PCM_16_BIT = (AUDIO_FORMAT_PCM |
- AUDIO_FORMAT_PCM_SUB_16_BIT),
- AUDIO_FORMAT_PCM_8_BIT = (AUDIO_FORMAT_PCM |
- AUDIO_FORMAT_PCM_SUB_8_BIT),
- AUDIO_FORMAT_PCM_32_BIT = (AUDIO_FORMAT_PCM |
- AUDIO_FORMAT_PCM_SUB_32_BIT),
- AUDIO_FORMAT_PCM_8_24_BIT = (AUDIO_FORMAT_PCM |
- AUDIO_FORMAT_PCM_SUB_8_24_BIT),
-} audio_format_t;
-
-typedef enum {
- /* output channels */
- AUDIO_CHANNEL_OUT_FRONT_LEFT = 0x1,
- AUDIO_CHANNEL_OUT_FRONT_RIGHT = 0x2,
- AUDIO_CHANNEL_OUT_FRONT_CENTER = 0x4,
- AUDIO_CHANNEL_OUT_LOW_FREQUENCY = 0x8,
- AUDIO_CHANNEL_OUT_BACK_LEFT = 0x10,
- AUDIO_CHANNEL_OUT_BACK_RIGHT = 0x20,
- AUDIO_CHANNEL_OUT_FRONT_LEFT_OF_CENTER = 0x40,
- AUDIO_CHANNEL_OUT_FRONT_RIGHT_OF_CENTER = 0x80,
- AUDIO_CHANNEL_OUT_BACK_CENTER = 0x100,
- AUDIO_CHANNEL_OUT_SIDE_LEFT = 0x200,
- AUDIO_CHANNEL_OUT_SIDE_RIGHT = 0x400,
- AUDIO_CHANNEL_OUT_TOP_CENTER = 0x800,
- AUDIO_CHANNEL_OUT_TOP_FRONT_LEFT = 0x1000,
- AUDIO_CHANNEL_OUT_TOP_FRONT_CENTER = 0x2000,
- AUDIO_CHANNEL_OUT_TOP_FRONT_RIGHT = 0x4000,
- AUDIO_CHANNEL_OUT_TOP_BACK_LEFT = 0x8000,
- AUDIO_CHANNEL_OUT_TOP_BACK_CENTER = 0x10000,
- AUDIO_CHANNEL_OUT_TOP_BACK_RIGHT = 0x20000,
-
- AUDIO_CHANNEL_OUT_MONO = AUDIO_CHANNEL_OUT_FRONT_LEFT,
- AUDIO_CHANNEL_OUT_STEREO = (AUDIO_CHANNEL_OUT_FRONT_LEFT |
- AUDIO_CHANNEL_OUT_FRONT_RIGHT),
- AUDIO_CHANNEL_OUT_QUAD = (AUDIO_CHANNEL_OUT_FRONT_LEFT |
- AUDIO_CHANNEL_OUT_FRONT_RIGHT |
- AUDIO_CHANNEL_OUT_BACK_LEFT |
- AUDIO_CHANNEL_OUT_BACK_RIGHT),
- AUDIO_CHANNEL_OUT_SURROUND = (AUDIO_CHANNEL_OUT_FRONT_LEFT |
- AUDIO_CHANNEL_OUT_FRONT_RIGHT |
- AUDIO_CHANNEL_OUT_FRONT_CENTER |
- AUDIO_CHANNEL_OUT_BACK_CENTER),
- AUDIO_CHANNEL_OUT_5POINT1 = (AUDIO_CHANNEL_OUT_FRONT_LEFT |
- AUDIO_CHANNEL_OUT_FRONT_RIGHT |
- AUDIO_CHANNEL_OUT_FRONT_CENTER |
- AUDIO_CHANNEL_OUT_LOW_FREQUENCY |
- AUDIO_CHANNEL_OUT_BACK_LEFT |
- AUDIO_CHANNEL_OUT_BACK_RIGHT),
- // matches the correct AudioFormat.CHANNEL_OUT_7POINT1_SURROUND definition for 7.1
- AUDIO_CHANNEL_OUT_7POINT1 = (AUDIO_CHANNEL_OUT_FRONT_LEFT |
- AUDIO_CHANNEL_OUT_FRONT_RIGHT |
- AUDIO_CHANNEL_OUT_FRONT_CENTER |
- AUDIO_CHANNEL_OUT_LOW_FREQUENCY |
- AUDIO_CHANNEL_OUT_BACK_LEFT |
- AUDIO_CHANNEL_OUT_BACK_RIGHT |
- AUDIO_CHANNEL_OUT_SIDE_LEFT |
- AUDIO_CHANNEL_OUT_SIDE_RIGHT),
- AUDIO_CHANNEL_OUT_ALL = (AUDIO_CHANNEL_OUT_FRONT_LEFT |
- AUDIO_CHANNEL_OUT_FRONT_RIGHT |
- AUDIO_CHANNEL_OUT_FRONT_CENTER |
- AUDIO_CHANNEL_OUT_LOW_FREQUENCY |
- AUDIO_CHANNEL_OUT_BACK_LEFT |
- AUDIO_CHANNEL_OUT_BACK_RIGHT |
- AUDIO_CHANNEL_OUT_FRONT_LEFT_OF_CENTER |
- AUDIO_CHANNEL_OUT_FRONT_RIGHT_OF_CENTER |
- AUDIO_CHANNEL_OUT_BACK_CENTER|
- AUDIO_CHANNEL_OUT_SIDE_LEFT|
- AUDIO_CHANNEL_OUT_SIDE_RIGHT|
- AUDIO_CHANNEL_OUT_TOP_CENTER|
- AUDIO_CHANNEL_OUT_TOP_FRONT_LEFT|
- AUDIO_CHANNEL_OUT_TOP_FRONT_CENTER|
- AUDIO_CHANNEL_OUT_TOP_FRONT_RIGHT|
- AUDIO_CHANNEL_OUT_TOP_BACK_LEFT|
- AUDIO_CHANNEL_OUT_TOP_BACK_CENTER|
- AUDIO_CHANNEL_OUT_TOP_BACK_RIGHT),
-
- /* input channels */
- AUDIO_CHANNEL_IN_LEFT = 0x4,
- AUDIO_CHANNEL_IN_RIGHT = 0x8,
- AUDIO_CHANNEL_IN_FRONT = 0x10,
- AUDIO_CHANNEL_IN_BACK = 0x20,
- AUDIO_CHANNEL_IN_LEFT_PROCESSED = 0x40,
- AUDIO_CHANNEL_IN_RIGHT_PROCESSED = 0x80,
- AUDIO_CHANNEL_IN_FRONT_PROCESSED = 0x100,
- AUDIO_CHANNEL_IN_BACK_PROCESSED = 0x200,
- AUDIO_CHANNEL_IN_PRESSURE = 0x400,
- AUDIO_CHANNEL_IN_X_AXIS = 0x800,
- AUDIO_CHANNEL_IN_Y_AXIS = 0x1000,
- AUDIO_CHANNEL_IN_Z_AXIS = 0x2000,
- AUDIO_CHANNEL_IN_VOICE_UPLINK = 0x4000,
- AUDIO_CHANNEL_IN_VOICE_DNLINK = 0x8000,
-
- AUDIO_CHANNEL_IN_MONO = AUDIO_CHANNEL_IN_FRONT,
- AUDIO_CHANNEL_IN_STEREO = (AUDIO_CHANNEL_IN_LEFT | AUDIO_CHANNEL_IN_RIGHT),
- AUDIO_CHANNEL_IN_ALL = (AUDIO_CHANNEL_IN_LEFT |
- AUDIO_CHANNEL_IN_RIGHT |
- AUDIO_CHANNEL_IN_FRONT |
- AUDIO_CHANNEL_IN_BACK|
- AUDIO_CHANNEL_IN_LEFT_PROCESSED |
- AUDIO_CHANNEL_IN_RIGHT_PROCESSED |
- AUDIO_CHANNEL_IN_FRONT_PROCESSED |
- AUDIO_CHANNEL_IN_BACK_PROCESSED|
- AUDIO_CHANNEL_IN_PRESSURE |
- AUDIO_CHANNEL_IN_X_AXIS |
- AUDIO_CHANNEL_IN_Y_AXIS |
- AUDIO_CHANNEL_IN_Z_AXIS |
- AUDIO_CHANNEL_IN_VOICE_UPLINK |
- AUDIO_CHANNEL_IN_VOICE_DNLINK),
-} audio_channels_t;
-
-#if ANDROID_VERSION >= 17
-typedef enum {
- AUDIO_MODE_INVALID = -2,
- AUDIO_MODE_CURRENT = -1,
- AUDIO_MODE_NORMAL = 0,
- AUDIO_MODE_RINGTONE = 1,
- AUDIO_MODE_IN_CALL = 2,
- AUDIO_MODE_IN_COMMUNICATION = 3,
-
- AUDIO_MODE_CNT,
- AUDIO_MODE_MAX = AUDIO_MODE_CNT - 1,
-} audio_mode_t;
-#endif
-#endif
-
-#if ANDROID_VERSION < 17
-typedef enum {
- AUDIO_DEVICE_NONE = 0x0,
- /* output devices */
- AUDIO_DEVICE_OUT_EARPIECE = 0x1,
- AUDIO_DEVICE_OUT_SPEAKER = 0x2,
- AUDIO_DEVICE_OUT_WIRED_HEADSET = 0x4,
- AUDIO_DEVICE_OUT_WIRED_HEADPHONE = 0x8,
- AUDIO_DEVICE_OUT_BLUETOOTH_SCO = 0x10,
- AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET = 0x20,
- AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT = 0x40,
- AUDIO_DEVICE_OUT_BLUETOOTH_A2DP = 0x80,
- AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES = 0x100,
- AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER = 0x200,
- AUDIO_DEVICE_OUT_AUX_DIGITAL = 0x400,
- AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET = 0x800,
- AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET = 0x1000,
- AUDIO_DEVICE_OUT_FM = 0x2000,
- AUDIO_DEVICE_OUT_ANC_HEADSET = 0x4000,
- AUDIO_DEVICE_OUT_ANC_HEADPHONE = 0x8000,
- AUDIO_DEVICE_OUT_FM_TX = 0x10000,
- AUDIO_DEVICE_OUT_DIRECTOUTPUT = 0x20000,
- AUDIO_DEVICE_OUT_PROXY = 0x40000,
- AUDIO_DEVICE_OUT_DEFAULT = 0x80000,
- AUDIO_DEVICE_OUT_ALL = (AUDIO_DEVICE_OUT_EARPIECE |
- AUDIO_DEVICE_OUT_SPEAKER |
- AUDIO_DEVICE_OUT_WIRED_HEADSET |
- AUDIO_DEVICE_OUT_WIRED_HEADPHONE |
- AUDIO_DEVICE_OUT_BLUETOOTH_SCO |
- AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET |
- AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT |
- AUDIO_DEVICE_OUT_BLUETOOTH_A2DP |
- AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES |
- AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER |
- AUDIO_DEVICE_OUT_AUX_DIGITAL |
- AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET |
- AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET |
- AUDIO_DEVICE_OUT_FM |
- AUDIO_DEVICE_OUT_ANC_HEADSET |
- AUDIO_DEVICE_OUT_ANC_HEADPHONE |
- AUDIO_DEVICE_OUT_FM_TX |
- AUDIO_DEVICE_OUT_DIRECTOUTPUT |
- AUDIO_DEVICE_OUT_PROXY |
- AUDIO_DEVICE_OUT_DEFAULT),
- AUDIO_DEVICE_OUT_ALL_A2DP = (AUDIO_DEVICE_OUT_BLUETOOTH_A2DP |
- AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES |
- AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER),
- AUDIO_DEVICE_OUT_ALL_SCO = (AUDIO_DEVICE_OUT_BLUETOOTH_SCO |
- AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET |
- AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT),
- /* input devices */
- AUDIO_DEVICE_IN_COMMUNICATION = 0x100000,
- AUDIO_DEVICE_IN_AMBIENT = 0x200000,
- AUDIO_DEVICE_IN_BUILTIN_MIC = 0x400000,
- AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET = 0x800000,
- AUDIO_DEVICE_IN_WIRED_HEADSET = 0x1000000,
- AUDIO_DEVICE_IN_AUX_DIGITAL = 0x2000000,
- AUDIO_DEVICE_IN_VOICE_CALL = 0x4000000,
- AUDIO_DEVICE_IN_BACK_MIC = 0x8000000,
- AUDIO_DEVICE_IN_ANC_HEADSET = 0x10000000,
- AUDIO_DEVICE_IN_FM_RX = 0x20000000,
- AUDIO_DEVICE_IN_FM_RX_A2DP = 0x40000000,
- AUDIO_DEVICE_IN_DEFAULT = 0x80000000,
-
- AUDIO_DEVICE_IN_ALL = (AUDIO_DEVICE_IN_COMMUNICATION |
- AUDIO_DEVICE_IN_AMBIENT |
- AUDIO_DEVICE_IN_BUILTIN_MIC |
- AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET |
- AUDIO_DEVICE_IN_WIRED_HEADSET |
- AUDIO_DEVICE_IN_AUX_DIGITAL |
- AUDIO_DEVICE_IN_VOICE_CALL |
- AUDIO_DEVICE_IN_BACK_MIC |
- AUDIO_DEVICE_IN_ANC_HEADSET |
- AUDIO_DEVICE_IN_FM_RX |
- AUDIO_DEVICE_IN_FM_RX_A2DP |
- AUDIO_DEVICE_IN_DEFAULT),
- AUDIO_DEVICE_IN_ALL_SCO = AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET,
-} audio_devices_t;
-#elif ANDROID_VERSION < 21
-enum {
- AUDIO_DEVICE_NONE = 0x0,
- /* reserved bits */
- AUDIO_DEVICE_BIT_IN = 0x80000000,
- AUDIO_DEVICE_BIT_DEFAULT = 0x40000000,
- /* output devices */
- AUDIO_DEVICE_OUT_EARPIECE = 0x1,
- AUDIO_DEVICE_OUT_SPEAKER = 0x2,
- AUDIO_DEVICE_OUT_WIRED_HEADSET = 0x4,
- AUDIO_DEVICE_OUT_WIRED_HEADPHONE = 0x8,
- AUDIO_DEVICE_OUT_BLUETOOTH_SCO = 0x10,
- AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET = 0x20,
- AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT = 0x40,
- AUDIO_DEVICE_OUT_BLUETOOTH_A2DP = 0x80,
- AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES = 0x100,
- AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER = 0x200,
- AUDIO_DEVICE_OUT_AUX_DIGITAL = 0x400,
- AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET = 0x800,
- AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET = 0x1000,
- AUDIO_DEVICE_OUT_USB_ACCESSORY = 0x2000,
- AUDIO_DEVICE_OUT_USB_DEVICE = 0x4000,
- AUDIO_DEVICE_OUT_REMOTE_SUBMIX = 0x8000,
- AUDIO_DEVICE_OUT_ANC_HEADSET = 0x10000,
- AUDIO_DEVICE_OUT_ANC_HEADPHONE = 0x20000,
- AUDIO_DEVICE_OUT_PROXY = 0x40000,
- AUDIO_DEVICE_OUT_FM = 0x80000,
- AUDIO_DEVICE_OUT_FM_TX = 0x100000,
- AUDIO_DEVICE_OUT_DEFAULT = AUDIO_DEVICE_BIT_DEFAULT,
- AUDIO_DEVICE_OUT_ALL = (AUDIO_DEVICE_OUT_EARPIECE |
- AUDIO_DEVICE_OUT_SPEAKER |
- AUDIO_DEVICE_OUT_WIRED_HEADSET |
- AUDIO_DEVICE_OUT_WIRED_HEADPHONE |
- AUDIO_DEVICE_OUT_BLUETOOTH_SCO |
- AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET |
- AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT |
- AUDIO_DEVICE_OUT_BLUETOOTH_A2DP |
- AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES |
- AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER |
- AUDIO_DEVICE_OUT_AUX_DIGITAL |
- AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET |
- AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET |
- AUDIO_DEVICE_OUT_USB_ACCESSORY |
- AUDIO_DEVICE_OUT_USB_DEVICE |
- AUDIO_DEVICE_OUT_REMOTE_SUBMIX |
- AUDIO_DEVICE_OUT_ANC_HEADSET |
- AUDIO_DEVICE_OUT_ANC_HEADPHONE |
- AUDIO_DEVICE_OUT_PROXY |
- AUDIO_DEVICE_OUT_FM |
- AUDIO_DEVICE_OUT_FM_TX |
- AUDIO_DEVICE_OUT_DEFAULT),
- AUDIO_DEVICE_OUT_ALL_A2DP = (AUDIO_DEVICE_OUT_BLUETOOTH_A2DP |
- AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES |
- AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER),
- AUDIO_DEVICE_OUT_ALL_SCO = (AUDIO_DEVICE_OUT_BLUETOOTH_SCO |
- AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET |
- AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT),
- AUDIO_DEVICE_OUT_ALL_USB = (AUDIO_DEVICE_OUT_USB_ACCESSORY |
- AUDIO_DEVICE_OUT_USB_DEVICE),
-
- /* input devices */
- AUDIO_DEVICE_IN_COMMUNICATION = AUDIO_DEVICE_BIT_IN | 0x1,
- AUDIO_DEVICE_IN_AMBIENT = AUDIO_DEVICE_BIT_IN | 0x2,
- AUDIO_DEVICE_IN_BUILTIN_MIC = AUDIO_DEVICE_BIT_IN | 0x4,
- AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET = AUDIO_DEVICE_BIT_IN | 0x8,
- AUDIO_DEVICE_IN_WIRED_HEADSET = AUDIO_DEVICE_BIT_IN | 0x10,
- AUDIO_DEVICE_IN_AUX_DIGITAL = AUDIO_DEVICE_BIT_IN | 0x20,
- AUDIO_DEVICE_IN_VOICE_CALL = AUDIO_DEVICE_BIT_IN | 0x40,
- AUDIO_DEVICE_IN_BACK_MIC = AUDIO_DEVICE_BIT_IN | 0x80,
- AUDIO_DEVICE_IN_REMOTE_SUBMIX = AUDIO_DEVICE_BIT_IN | 0x100,
- AUDIO_DEVICE_IN_ANLG_DOCK_HEADSET = AUDIO_DEVICE_BIT_IN | 0x200,
- AUDIO_DEVICE_IN_DGTL_DOCK_HEADSET = AUDIO_DEVICE_BIT_IN | 0x400,
- AUDIO_DEVICE_IN_USB_ACCESSORY = AUDIO_DEVICE_BIT_IN | 0x800,
- AUDIO_DEVICE_IN_USB_DEVICE = AUDIO_DEVICE_BIT_IN | 0x1000,
- AUDIO_DEVICE_IN_ANC_HEADSET = AUDIO_DEVICE_BIT_IN | 0x2000,
- AUDIO_DEVICE_IN_PROXY = AUDIO_DEVICE_BIT_IN | 0x4000,
- AUDIO_DEVICE_IN_FM_RX = AUDIO_DEVICE_BIT_IN | 0x8000,
- AUDIO_DEVICE_IN_FM_RX_A2DP = AUDIO_DEVICE_BIT_IN | 0x10000,
- AUDIO_DEVICE_IN_DEFAULT = AUDIO_DEVICE_BIT_IN | AUDIO_DEVICE_BIT_DEFAULT,
-
- AUDIO_DEVICE_IN_ALL = (AUDIO_DEVICE_IN_COMMUNICATION |
- AUDIO_DEVICE_IN_AMBIENT |
- AUDIO_DEVICE_IN_BUILTIN_MIC |
- AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET |
- AUDIO_DEVICE_IN_WIRED_HEADSET |
- AUDIO_DEVICE_IN_AUX_DIGITAL |
- AUDIO_DEVICE_IN_VOICE_CALL |
- AUDIO_DEVICE_IN_BACK_MIC |
- AUDIO_DEVICE_IN_REMOTE_SUBMIX |
- AUDIO_DEVICE_IN_ANLG_DOCK_HEADSET |
- AUDIO_DEVICE_IN_DGTL_DOCK_HEADSET |
- AUDIO_DEVICE_IN_USB_ACCESSORY |
- AUDIO_DEVICE_IN_USB_DEVICE |
- AUDIO_DEVICE_IN_ANC_HEADSET |
- AUDIO_DEVICE_IN_FM_RX |
- AUDIO_DEVICE_IN_FM_RX_A2DP |
- AUDIO_DEVICE_IN_PROXY |
- AUDIO_DEVICE_IN_DEFAULT),
- AUDIO_DEVICE_IN_ALL_SCO = AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET,
-};
-
-typedef uint32_t audio_devices_t;
-#else
-enum {
- AUDIO_DEVICE_NONE = 0x0,
- /* reserved bits */
- AUDIO_DEVICE_BIT_IN = 0x80000000,
- AUDIO_DEVICE_BIT_DEFAULT = 0x40000000,
- /* output devices */
- AUDIO_DEVICE_OUT_EARPIECE = 0x1,
- AUDIO_DEVICE_OUT_SPEAKER = 0x2,
- AUDIO_DEVICE_OUT_WIRED_HEADSET = 0x4,
- AUDIO_DEVICE_OUT_WIRED_HEADPHONE = 0x8,
- AUDIO_DEVICE_OUT_BLUETOOTH_SCO = 0x10,
- AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET = 0x20,
- AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT = 0x40,
- AUDIO_DEVICE_OUT_BLUETOOTH_A2DP = 0x80,
- AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES = 0x100,
- AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER = 0x200,
- AUDIO_DEVICE_OUT_AUX_DIGITAL = 0x400,
- AUDIO_DEVICE_OUT_HDMI = AUDIO_DEVICE_OUT_AUX_DIGITAL,
- /* uses an analog connection (multiplexed over the USB connector pins for instance) */
- AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET = 0x800,
- AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET = 0x1000,
- /* USB accessory mode: your Android device is a USB device and the dock is a USB host */
- AUDIO_DEVICE_OUT_USB_ACCESSORY = 0x2000,
- /* USB host mode: your Android device is a USB host and the dock is a USB device */
- AUDIO_DEVICE_OUT_USB_DEVICE = 0x4000,
- AUDIO_DEVICE_OUT_REMOTE_SUBMIX = 0x8000,
- /* Telephony voice TX path */
- AUDIO_DEVICE_OUT_TELEPHONY_TX = 0x10000,
- /* Analog jack with line impedance detected */
- AUDIO_DEVICE_OUT_LINE = 0x20000,
- /* HDMI Audio Return Channel */
- AUDIO_DEVICE_OUT_HDMI_ARC = 0x40000,
- /* S/PDIF out */
- AUDIO_DEVICE_OUT_SPDIF = 0x80000,
- /* FM transmitter out */
- AUDIO_DEVICE_OUT_FM = 0x100000,
- /* Line out for av devices */
- AUDIO_DEVICE_OUT_AUX_LINE = 0x200000,
- /* limited-output speaker device for acoustic safety */
- AUDIO_DEVICE_OUT_SPEAKER_SAFE = 0x400000,
- AUDIO_DEVICE_OUT_DEFAULT = AUDIO_DEVICE_BIT_DEFAULT,
- AUDIO_DEVICE_OUT_ALL = (AUDIO_DEVICE_OUT_EARPIECE |
- AUDIO_DEVICE_OUT_SPEAKER |
- AUDIO_DEVICE_OUT_WIRED_HEADSET |
- AUDIO_DEVICE_OUT_WIRED_HEADPHONE |
- AUDIO_DEVICE_OUT_BLUETOOTH_SCO |
- AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET |
- AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT |
- AUDIO_DEVICE_OUT_BLUETOOTH_A2DP |
- AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES |
- AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER |
- AUDIO_DEVICE_OUT_AUX_DIGITAL |
- AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET |
- AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET |
- AUDIO_DEVICE_OUT_USB_ACCESSORY |
- AUDIO_DEVICE_OUT_USB_DEVICE |
- AUDIO_DEVICE_OUT_REMOTE_SUBMIX |
- AUDIO_DEVICE_OUT_TELEPHONY_TX |
- AUDIO_DEVICE_OUT_LINE |
- AUDIO_DEVICE_OUT_HDMI_ARC |
- AUDIO_DEVICE_OUT_SPDIF |
- AUDIO_DEVICE_OUT_FM |
- AUDIO_DEVICE_OUT_AUX_LINE |
- AUDIO_DEVICE_OUT_SPEAKER_SAFE |
- AUDIO_DEVICE_OUT_DEFAULT),
- AUDIO_DEVICE_OUT_ALL_A2DP = (AUDIO_DEVICE_OUT_BLUETOOTH_A2DP |
- AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES |
- AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER),
- AUDIO_DEVICE_OUT_ALL_SCO = (AUDIO_DEVICE_OUT_BLUETOOTH_SCO |
- AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET |
- AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT),
- AUDIO_DEVICE_OUT_ALL_USB = (AUDIO_DEVICE_OUT_USB_ACCESSORY |
- AUDIO_DEVICE_OUT_USB_DEVICE),
- /* input devices */
- AUDIO_DEVICE_IN_COMMUNICATION = AUDIO_DEVICE_BIT_IN | 0x1,
- AUDIO_DEVICE_IN_AMBIENT = AUDIO_DEVICE_BIT_IN | 0x2,
- AUDIO_DEVICE_IN_BUILTIN_MIC = AUDIO_DEVICE_BIT_IN | 0x4,
- AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET = AUDIO_DEVICE_BIT_IN | 0x8,
- AUDIO_DEVICE_IN_WIRED_HEADSET = AUDIO_DEVICE_BIT_IN | 0x10,
- AUDIO_DEVICE_IN_AUX_DIGITAL = AUDIO_DEVICE_BIT_IN | 0x20,
- AUDIO_DEVICE_IN_HDMI = AUDIO_DEVICE_IN_AUX_DIGITAL,
- /* Telephony voice RX path */
- AUDIO_DEVICE_IN_VOICE_CALL = AUDIO_DEVICE_BIT_IN | 0x40,
- AUDIO_DEVICE_IN_BACK_MIC = AUDIO_DEVICE_BIT_IN | 0x80,
- AUDIO_DEVICE_IN_REMOTE_SUBMIX = AUDIO_DEVICE_BIT_IN | 0x100,
- AUDIO_DEVICE_IN_ANLG_DOCK_HEADSET = AUDIO_DEVICE_BIT_IN | 0x200,
- AUDIO_DEVICE_IN_DGTL_DOCK_HEADSET = AUDIO_DEVICE_BIT_IN | 0x400,
- AUDIO_DEVICE_IN_USB_ACCESSORY = AUDIO_DEVICE_BIT_IN | 0x800,
- AUDIO_DEVICE_IN_USB_DEVICE = AUDIO_DEVICE_BIT_IN | 0x1000,
- /* FM tuner input */
- AUDIO_DEVICE_IN_FM_TUNER = AUDIO_DEVICE_BIT_IN | 0x2000,
- /* TV tuner input */
- AUDIO_DEVICE_IN_TV_TUNER = AUDIO_DEVICE_BIT_IN | 0x4000,
- /* Analog jack with line impedance detected */
- AUDIO_DEVICE_IN_LINE = AUDIO_DEVICE_BIT_IN | 0x8000,
- /* S/PDIF in */
- AUDIO_DEVICE_IN_SPDIF = AUDIO_DEVICE_BIT_IN | 0x10000,
- AUDIO_DEVICE_IN_BLUETOOTH_A2DP = AUDIO_DEVICE_BIT_IN | 0x20000,
- AUDIO_DEVICE_IN_LOOPBACK = AUDIO_DEVICE_BIT_IN | 0x40000,
- AUDIO_DEVICE_IN_DEFAULT = AUDIO_DEVICE_BIT_IN | AUDIO_DEVICE_BIT_DEFAULT,
- AUDIO_DEVICE_IN_ALL = (AUDIO_DEVICE_IN_COMMUNICATION |
- AUDIO_DEVICE_IN_AMBIENT |
- AUDIO_DEVICE_IN_BUILTIN_MIC |
- AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET |
- AUDIO_DEVICE_IN_WIRED_HEADSET |
- AUDIO_DEVICE_IN_AUX_DIGITAL |
- AUDIO_DEVICE_IN_VOICE_CALL |
- AUDIO_DEVICE_IN_BACK_MIC |
- AUDIO_DEVICE_IN_REMOTE_SUBMIX |
- AUDIO_DEVICE_IN_ANLG_DOCK_HEADSET |
- AUDIO_DEVICE_IN_DGTL_DOCK_HEADSET |
- AUDIO_DEVICE_IN_USB_ACCESSORY |
- AUDIO_DEVICE_IN_USB_DEVICE |
- AUDIO_DEVICE_IN_FM_TUNER |
- AUDIO_DEVICE_IN_TV_TUNER |
- AUDIO_DEVICE_IN_LINE |
- AUDIO_DEVICE_IN_SPDIF |
- AUDIO_DEVICE_IN_BLUETOOTH_A2DP |
- AUDIO_DEVICE_IN_LOOPBACK |
- AUDIO_DEVICE_IN_DEFAULT),
- AUDIO_DEVICE_IN_ALL_SCO = AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET,
- AUDIO_DEVICE_IN_ALL_USB = (AUDIO_DEVICE_IN_USB_ACCESSORY |
- AUDIO_DEVICE_IN_USB_DEVICE),
-};
-
-typedef uint32_t audio_devices_t;
-#endif
-
-static inline bool audio_is_output_device(uint32_t device)
-{
-#if ANDROID_VERSION < 17
- if ((__builtin_popcount(device) == 1) && ((device & ~AUDIO_DEVICE_OUT_ALL) == 0))
- return true;
- else
- return false;
-#else
- if (((device & AUDIO_DEVICE_BIT_IN) == 0) &&
- (__builtin_popcount(device) == 1) && ((device & ~AUDIO_DEVICE_OUT_ALL) == 0))
- return true;
- else
- return false;
-#endif
-}
-
-/* device connection states used for audio_policy->set_device_connection_state()
- * */
-typedef enum {
- AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
- AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
-
- AUDIO_POLICY_DEVICE_STATE_CNT,
- AUDIO_POLICY_DEVICE_STATE_MAX = AUDIO_POLICY_DEVICE_STATE_CNT - 1,
-} audio_policy_dev_state_t;
-
-namespace android {
-
-typedef void (*audio_error_callback)(status_t err);
-typedef int audio_io_handle_t;
-
-class IAudioPolicyService;
-class String8;
-
-class AudioSystem
-{
-public:
-
- enum stream_type {
- DEFAULT =-1,
- VOICE_CALL = 0,
- SYSTEM = 1,
- RING = 2,
- MUSIC = 3,
- ALARM = 4,
- NOTIFICATION = 5,
- BLUETOOTH_SCO = 6,
- ENFORCED_AUDIBLE = 7, // Sounds that cannot be muted by user and must be routed to speaker
- DTMF = 8,
- TTS = 9,
- FM = 10,
- NUM_STREAM_TYPES
- };
-
- // Audio sub formats (see AudioSystem::audio_format).
- enum pcm_sub_format {
- PCM_SUB_16_BIT = 0x1, // must be 1 for backward compatibility
- PCM_SUB_8_BIT = 0x2, // must be 2 for backward compatibility
- };
-
- // MP3 sub format field definition : can use 11 LSBs in the same way as MP3 frame header to specify
- // bit rate, stereo mode, version...
- enum mp3_sub_format {
- //TODO
- };
-
- // AMR NB/WB sub format field definition: specify frame block interleaving, bandwidth efficient or octet aligned,
- // encoding mode for recording...
- enum amr_sub_format {
- //TODO
- };
-
- // AAC sub format field definition: specify profile or bitrate for recording...
- enum aac_sub_format {
- //TODO
- };
-
- // VORBIS sub format field definition: specify quality for recording...
- enum vorbis_sub_format {
- //TODO
- };
-
- // Audio format consists in a main format field (upper 8 bits) and a sub format field (lower 24 bits).
- // The main format indicates the main codec type. The sub format field indicates options and parameters
- // for each format. The sub format is mainly used for record to indicate for instance the requested bitrate
- // or profile. It can also be used for certain formats to give informations not present in the encoded
- // audio stream (e.g. octet alignement for AMR).
- enum audio_format {
- INVALID_FORMAT = -1,
- FORMAT_DEFAULT = 0,
- PCM = 0x00000000, // must be 0 for backward compatibility
- MP3 = 0x01000000,
- AMR_NB = 0x02000000,
- AMR_WB = 0x03000000,
- AAC = 0x04000000,
- HE_AAC_V1 = 0x05000000,
- HE_AAC_V2 = 0x06000000,
- VORBIS = 0x07000000,
- EVRC = 0x08000000,
- QCELP = 0x09000000,
- VOIP_PCM_INPUT = 0x0A000000,
- MAIN_FORMAT_MASK = 0xFF000000,
- SUB_FORMAT_MASK = 0x00FFFFFF,
- // Aliases
- PCM_16_BIT = (PCM|PCM_SUB_16_BIT),
- PCM_8_BIT = (PCM|PCM_SUB_8_BIT)
- };
-
-
- // Channel mask definitions must be kept in sync with JAVA values in /media/java/android/media/AudioFormat.java
- enum audio_channels {
- // output channels
- CHANNEL_OUT_FRONT_LEFT = 0x4,
- CHANNEL_OUT_FRONT_RIGHT = 0x8,
- CHANNEL_OUT_FRONT_CENTER = 0x10,
- CHANNEL_OUT_LOW_FREQUENCY = 0x20,
- CHANNEL_OUT_BACK_LEFT = 0x40,
- CHANNEL_OUT_BACK_RIGHT = 0x80,
- CHANNEL_OUT_FRONT_LEFT_OF_CENTER = 0x100,
- CHANNEL_OUT_FRONT_RIGHT_OF_CENTER = 0x200,
- CHANNEL_OUT_BACK_CENTER = 0x400,
- CHANNEL_OUT_MONO = CHANNEL_OUT_FRONT_LEFT,
- CHANNEL_OUT_STEREO = (CHANNEL_OUT_FRONT_LEFT | CHANNEL_OUT_FRONT_RIGHT),
- CHANNEL_OUT_QUAD = (CHANNEL_OUT_FRONT_LEFT | CHANNEL_OUT_FRONT_RIGHT |
- CHANNEL_OUT_BACK_LEFT | CHANNEL_OUT_BACK_RIGHT),
- CHANNEL_OUT_SURROUND = (CHANNEL_OUT_FRONT_LEFT | CHANNEL_OUT_FRONT_RIGHT |
- CHANNEL_OUT_FRONT_CENTER | CHANNEL_OUT_BACK_CENTER),
- CHANNEL_OUT_5POINT1 = (CHANNEL_OUT_FRONT_LEFT | CHANNEL_OUT_FRONT_RIGHT |
- CHANNEL_OUT_FRONT_CENTER | CHANNEL_OUT_LOW_FREQUENCY | CHANNEL_OUT_BACK_LEFT | CHANNEL_OUT_BACK_RIGHT),
- CHANNEL_OUT_7POINT1 = (CHANNEL_OUT_FRONT_LEFT | CHANNEL_OUT_FRONT_RIGHT |
- CHANNEL_OUT_FRONT_CENTER | CHANNEL_OUT_LOW_FREQUENCY | CHANNEL_OUT_BACK_LEFT | CHANNEL_OUT_BACK_RIGHT |
- CHANNEL_OUT_FRONT_LEFT_OF_CENTER | CHANNEL_OUT_FRONT_RIGHT_OF_CENTER),
- CHANNEL_OUT_ALL = (CHANNEL_OUT_FRONT_LEFT | CHANNEL_OUT_FRONT_RIGHT |
- CHANNEL_OUT_FRONT_CENTER | CHANNEL_OUT_LOW_FREQUENCY | CHANNEL_OUT_BACK_LEFT | CHANNEL_OUT_BACK_RIGHT |
- CHANNEL_OUT_FRONT_LEFT_OF_CENTER | CHANNEL_OUT_FRONT_RIGHT_OF_CENTER | CHANNEL_OUT_BACK_CENTER),
-
- // input channels
- CHANNEL_IN_LEFT = 0x4,
- CHANNEL_IN_RIGHT = 0x8,
- CHANNEL_IN_FRONT = 0x10,
- CHANNEL_IN_BACK = 0x20,
- CHANNEL_IN_LEFT_PROCESSED = 0x40,
- CHANNEL_IN_RIGHT_PROCESSED = 0x80,
- CHANNEL_IN_FRONT_PROCESSED = 0x100,
- CHANNEL_IN_BACK_PROCESSED = 0x200,
- CHANNEL_IN_PRESSURE = 0x400,
- CHANNEL_IN_X_AXIS = 0x800,
- CHANNEL_IN_Y_AXIS = 0x1000,
- CHANNEL_IN_Z_AXIS = 0x2000,
- CHANNEL_IN_VOICE_UPLINK = 0x4000,
- CHANNEL_IN_VOICE_DNLINK = 0x8000,
- CHANNEL_IN_MONO = CHANNEL_IN_FRONT,
- CHANNEL_IN_STEREO = (CHANNEL_IN_LEFT | CHANNEL_IN_RIGHT),
- CHANNEL_IN_ALL = (CHANNEL_IN_LEFT | CHANNEL_IN_RIGHT | CHANNEL_IN_FRONT | CHANNEL_IN_BACK|
- CHANNEL_IN_LEFT_PROCESSED | CHANNEL_IN_RIGHT_PROCESSED | CHANNEL_IN_FRONT_PROCESSED | CHANNEL_IN_BACK_PROCESSED|
- CHANNEL_IN_PRESSURE | CHANNEL_IN_X_AXIS | CHANNEL_IN_Y_AXIS | CHANNEL_IN_Z_AXIS |
- CHANNEL_IN_VOICE_UPLINK | CHANNEL_IN_VOICE_DNLINK)
- };
-
- enum audio_mode {
- MODE_INVALID = -2,
- MODE_CURRENT = -1,
- MODE_NORMAL = 0,
- MODE_RINGTONE,
- MODE_IN_CALL,
- MODE_IN_COMMUNICATION,
- NUM_MODES // not a valid entry, denotes end-of-list
- };
-
- enum audio_in_acoustics {
- AGC_ENABLE = 0x0001,
- AGC_DISABLE = 0,
- NS_ENABLE = 0x0002,
- NS_DISABLE = 0,
- TX_IIR_ENABLE = 0x0004,
- TX_DISABLE = 0
- };
-
- // special audio session values
- enum audio_sessions {
- SESSION_OUTPUT_STAGE = -1, // session for effects attached to a particular output stream
- // (value must be less than 0)
- SESSION_OUTPUT_MIX = 0, // session for effects applied to output mix. These effects can
- // be moved by audio policy manager to another output stream
- // (value must be 0)
- };
-
- /* These are static methods to control the system-wide AudioFlinger
- * only privileged processes can have access to them
- */
-
- // mute/unmute microphone
- static status_t muteMicrophone(bool state);
- static status_t isMicrophoneMuted(bool *state);
-
- // set/get master volume
- static status_t setMasterVolume(float value);
- static status_t getMasterVolume(float* volume);
- // mute/unmute audio outputs
- static status_t setMasterMute(bool mute);
- static status_t getMasterMute(bool* mute);
-
- // set/get stream volume on specified output
- static status_t setStreamVolume(int stream, float value, int output);
- static status_t getStreamVolume(int stream, float* volume, int output);
-
- // mute/unmute stream
- static status_t setStreamMute(int stream, bool mute);
- static status_t getStreamMute(int stream, bool* mute);
-
- // set audio mode in audio hardware (see AudioSystem::audio_mode)
- static status_t setMode(int mode);
-
- // returns true in *state if tracks are active on the specified stream
- static status_t isStreamActive(int stream, bool *state);
-
- // set/get audio hardware parameters. The function accepts a list of parameters
- // key value pairs in the form: key1=value1;key2=value2;...
- // Some keys are reserved for standard parameters (See AudioParameter class).
- static status_t setParameters(audio_io_handle_t ioHandle, const String8& keyValuePairs);
- static String8 getParameters(audio_io_handle_t ioHandle, const String8& keys);
-
- static void setErrorCallback(audio_error_callback cb);
-
- // helper function to obtain AudioFlinger service handle
- static const sp<IAudioFlinger>& get_audio_flinger();
-
- static float linearToLog(int volume);
- static int logToLinear(float volume);
-
- static status_t getOutputSamplingRate(int* samplingRate, int stream = DEFAULT);
- static status_t getOutputFrameCount(int* frameCount, int stream = DEFAULT);
- static status_t getOutputLatency(uint32_t* latency, int stream = DEFAULT);
-
- static bool routedToA2dpOutput(int streamType);
-
- static status_t getInputBufferSize(uint32_t sampleRate, int format, int channelCount,
- size_t* buffSize);
-
- static status_t setVoiceVolume(float volume);
-
- // return the number of audio frames written by AudioFlinger to audio HAL and
- // audio dsp to DAC since the output on which the specificed stream is playing
- // has exited standby.
- // returned status (from utils/Errors.h) can be:
- // - NO_ERROR: successful operation, halFrames and dspFrames point to valid data
- // - INVALID_OPERATION: Not supported on current hardware platform
- // - BAD_VALUE: invalid parameter
- // NOTE: this feature is not supported on all hardware platforms and it is
- // necessary to check returned status before using the returned values.
- static status_t getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames, int stream = DEFAULT);
-
- static unsigned int getInputFramesLost(audio_io_handle_t ioHandle);
-
- static int newAudioSessionId();
- //
- // AudioPolicyService interface
- //
-
- enum audio_devices {
- // output devices
- DEVICE_OUT_EARPIECE = 0x1,
- DEVICE_OUT_SPEAKER = 0x2,
- DEVICE_OUT_WIRED_HEADSET = 0x4,
- DEVICE_OUT_WIRED_HEADPHONE = 0x8,
- DEVICE_OUT_BLUETOOTH_SCO = 0x10,
- DEVICE_OUT_BLUETOOTH_SCO_HEADSET = 0x20,
- DEVICE_OUT_BLUETOOTH_SCO_CARKIT = 0x40,
- DEVICE_OUT_BLUETOOTH_A2DP = 0x80,
- DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES = 0x100,
- DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER = 0x200,
- DEVICE_OUT_AUX_DIGITAL = 0x400,
- DEVICE_OUT_DEFAULT = 0x8000,
- DEVICE_OUT_ALL = (DEVICE_OUT_EARPIECE | DEVICE_OUT_SPEAKER | DEVICE_OUT_WIRED_HEADSET |
- DEVICE_OUT_WIRED_HEADPHONE | DEVICE_OUT_BLUETOOTH_SCO | DEVICE_OUT_BLUETOOTH_SCO_HEADSET |
- DEVICE_OUT_BLUETOOTH_SCO_CARKIT | DEVICE_OUT_BLUETOOTH_A2DP | DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES |
- DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER | DEVICE_OUT_AUX_DIGITAL | DEVICE_OUT_DEFAULT),
- DEVICE_OUT_ALL_A2DP = (DEVICE_OUT_BLUETOOTH_A2DP | DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES |
- DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER),
-
- // input devices
- DEVICE_IN_COMMUNICATION = 0x10000,
- DEVICE_IN_AMBIENT = 0x20000,
- DEVICE_IN_BUILTIN_MIC = 0x40000,
- DEVICE_IN_BLUETOOTH_SCO_HEADSET = 0x80000,
- DEVICE_IN_WIRED_HEADSET = 0x100000,
- DEVICE_IN_AUX_DIGITAL = 0x200000,
- DEVICE_IN_VOICE_CALL = 0x400000,
- DEVICE_IN_BACK_MIC = 0x800000,
- DEVICE_IN_DEFAULT = 0x80000000,
-
- DEVICE_IN_ALL = (DEVICE_IN_COMMUNICATION | DEVICE_IN_AMBIENT | DEVICE_IN_BUILTIN_MIC |
- DEVICE_IN_BLUETOOTH_SCO_HEADSET | DEVICE_IN_WIRED_HEADSET | DEVICE_IN_AUX_DIGITAL |
- DEVICE_IN_VOICE_CALL | DEVICE_IN_BACK_MIC | DEVICE_IN_DEFAULT)
- };
-
- // device connection states used for setDeviceConnectionState()
- enum device_connection_state {
- DEVICE_STATE_UNAVAILABLE,
- DEVICE_STATE_AVAILABLE,
- NUM_DEVICE_STATES
- };
-
- // request to open a direct output with getOutput() (by opposition to sharing an output with other AudioTracks)
- enum output_flags {
- OUTPUT_FLAG_INDIRECT = 0x0,
- OUTPUT_FLAG_DIRECT = 0x1
- };
-
- // device categories used for setForceUse()
- enum forced_config {
- FORCE_NONE,
- FORCE_SPEAKER,
- FORCE_HEADPHONES,
- FORCE_BT_SCO,
- FORCE_BT_A2DP,
- FORCE_WIRED_ACCESSORY,
- FORCE_BT_CAR_DOCK,
- FORCE_BT_DESK_DOCK,
- FORCE_ANALOG_DOCK,
- FORCE_DIGITAL_DOCK,
- FORCE_NO_BT_A2DP,
- NUM_FORCE_CONFIG,
- FORCE_DEFAULT = FORCE_NONE
- };
-
- // usages used for setForceUse()
- enum force_use {
- FOR_COMMUNICATION,
- FOR_MEDIA,
- FOR_RECORD,
- FOR_DOCK,
- NUM_FORCE_USE
- };
-
- // types of io configuration change events received with ioConfigChanged()
- enum io_config_event {
- OUTPUT_OPENED,
- OUTPUT_CLOSED,
- OUTPUT_CONFIG_CHANGED,
- INPUT_OPENED,
- INPUT_CLOSED,
- INPUT_CONFIG_CHANGED,
- STREAM_CONFIG_CHANGED,
- NUM_CONFIG_EVENTS
- };
-
- // audio output descritor used to cache output configurations in client process to avoid frequent calls
- // through IAudioFlinger
- class OutputDescriptor {
- public:
- OutputDescriptor()
- : samplingRate(0), format(0), channels(0), frameCount(0), latency(0) {}
-
- uint32_t samplingRate;
- int32_t format;
- int32_t channels;
- size_t frameCount;
- uint32_t latency;
- };
-
- //
- // IAudioPolicyService interface (see AudioPolicyInterface for method descriptions)
- //
- static status_t setDeviceConnectionState(audio_devices device, device_connection_state state, const char *device_address);
- static device_connection_state getDeviceConnectionState(audio_devices device, const char *device_address);
- static status_t setPhoneState(int state);
-#if ANDROID_VERSION >= 17
- static status_t setPhoneState(audio_mode_t state);
-#endif
- static status_t setRingerMode(uint32_t mode, uint32_t mask);
-#ifdef VANILLA_ANDROID
- static status_t setForceUse(force_use usage, forced_config config);
- static forced_config getForceUse(force_use usage);
- static audio_io_handle_t getOutput(stream_type stream,
- uint32_t samplingRate = 0,
- uint32_t format = FORMAT_DEFAULT,
- uint32_t channels = CHANNEL_OUT_STEREO,
- output_flags flags = OUTPUT_FLAG_INDIRECT);
- static status_t setDeviceConnectionState(audio_devices_t device, audio_policy_dev_state_t state, const char *device_address);
- static status_t setFmVolume(float volume);
- static audio_policy_dev_state_t getDeviceConnectionState(audio_devices_t device, const char *device_address);
-#else
- static status_t setForceUse(force_use usage, forced_config config) __attribute__((weak));
- static forced_config getForceUse(force_use usage) __attribute__((weak));
- static audio_io_handle_t getOutput(stream_type stream,
- uint32_t samplingRate = 0,
- uint32_t format = FORMAT_DEFAULT,
- uint32_t channels = CHANNEL_OUT_STEREO,
- output_flags flags = OUTPUT_FLAG_INDIRECT) __attribute__((weak));
-
- static status_t setForceUse(audio_policy_force_use_t usage, audio_policy_forced_cfg_t config) __attribute__((weak));
- static audio_policy_forced_cfg_t getForceUse(audio_policy_force_use_t usage) __attribute__((weak));
- static audio_io_handle_t getOutput(audio_stream_type_t stream,
- uint32_t samplingRate = 0,
- uint32_t format = AUDIO_FORMAT_DEFAULT,
- uint32_t channels = AUDIO_CHANNEL_OUT_STEREO,
- audio_policy_output_flags_t flags = AUDIO_POLICY_OUTPUT_FLAG_INDIRECT) __attribute__((weak));
- static status_t setDeviceConnectionState(audio_devices_t device, audio_policy_dev_state_t state, const char *device_address) __attribute__((weak));
- static status_t setFmVolume(float volume) __attribute__((weak));
- static audio_policy_dev_state_t getDeviceConnectionState(audio_devices_t device, const char *device_address) __attribute__((weak));
-
-#endif
- static status_t startOutput(audio_io_handle_t output,
- AudioSystem::stream_type stream,
- int session = 0);
- static status_t stopOutput(audio_io_handle_t output,
- AudioSystem::stream_type stream,
- int session = 0);
- static void releaseOutput(audio_io_handle_t output);
- static audio_io_handle_t getInput(int inputSource,
- uint32_t samplingRate = 0,
- uint32_t format = FORMAT_DEFAULT,
- uint32_t channels = CHANNEL_IN_MONO,
- audio_in_acoustics acoustics = (audio_in_acoustics)0);
- static status_t startInput(audio_io_handle_t input);
- static status_t stopInput(audio_io_handle_t input);
- static void releaseInput(audio_io_handle_t input);
- static status_t initStreamVolume(stream_type stream,
- int indexMin,
- int indexMax);
- static status_t initStreamVolume(audio_stream_type_t stream,
- int indexMin,
- int indexMax);
- static status_t setStreamVolumeIndex(stream_type stream, int index);
- static status_t setStreamVolumeIndex(audio_stream_type_t stream, int index);
-#if ANDROID_VERSION >= 17
- static status_t setStreamVolumeIndex(audio_stream_type_t stream,
- int index,
- audio_devices_t device);
- static status_t getStreamVolumeIndex(audio_stream_type_t stream,
- int *index,
- audio_devices_t device);
-#endif
- static status_t getStreamVolumeIndex(stream_type stream, int *index);
- static status_t getStreamVolumeIndex(audio_stream_type_t stream, int *index);
-
- static uint32_t getStrategyForStream(stream_type stream);
-#if ANDROID_VERSION >= 17
- static audio_devices_t getDevicesForStream(audio_stream_type_t stream);
-#endif
-
- static audio_io_handle_t getOutputForEffect(effect_descriptor_t *desc);
- static status_t registerEffect(effect_descriptor_t *desc,
- audio_io_handle_t output,
- uint32_t strategy,
- int session,
- int id);
- static status_t unregisterEffect(int id);
-
- static const sp<IAudioPolicyService>& get_audio_policy_service();
-
- // ----------------------------------------------------------------------------
-
- static uint32_t popCount(uint32_t u);
- static bool isOutputDevice(audio_devices device);
- static bool isInputDevice(audio_devices device);
- static bool isA2dpDevice(audio_devices device);
- static bool isBluetoothScoDevice(audio_devices device);
- static bool isSeperatedStream(stream_type stream);
- static bool isLowVisibility(stream_type stream);
- static bool isOutputChannel(uint32_t channel);
- static bool isInputChannel(uint32_t channel);
- static bool isValidFormat(uint32_t format);
- static bool isLinearPCM(uint32_t format);
- static bool isModeInCall();
-
-#if ANDROID_VERSION >= 21
- class AudioPortCallback : public RefBase
- {
- public:
-
- AudioPortCallback() {}
- virtual ~AudioPortCallback() {}
-
- virtual void onAudioPortListUpdate() = 0;
- virtual void onAudioPatchListUpdate() = 0;
- virtual void onServiceDied() = 0;
-
- };
-
- static void setAudioPortCallback(sp<AudioPortCallback> callBack);
-#endif
-
-private:
-
- class AudioFlingerClient: public IBinder::DeathRecipient, public BnAudioFlingerClient
- {
- public:
- AudioFlingerClient() {
- }
-
- // DeathRecipient
- virtual void binderDied(const wp<IBinder>& who);
-
- // IAudioFlingerClient
-
- // indicate a change in the configuration of an output or input: keeps the cached
- // values for output/input parameters upto date in client process
- virtual void ioConfigChanged(int event, int ioHandle, void *param2);
- };
-
- class AudioPolicyServiceClient: public IBinder::DeathRecipient
- {
- public:
- AudioPolicyServiceClient() {
- }
-
- // DeathRecipient
- virtual void binderDied(const wp<IBinder>& who);
- };
-
- static sp<AudioFlingerClient> gAudioFlingerClient;
- static sp<AudioPolicyServiceClient> gAudioPolicyServiceClient;
- friend class AudioFlingerClient;
- friend class AudioPolicyServiceClient;
-
- static Mutex gLock;
- static sp<IAudioFlinger> gAudioFlinger;
- static audio_error_callback gAudioErrorCallback;
-
- static size_t gInBuffSize;
- // previous parameters for recording buffer size queries
- static uint32_t gPrevInSamplingRate;
- static int gPrevInFormat;
- static int gPrevInChannelCount;
-
- static sp<IAudioPolicyService> gAudioPolicyService;
-
- // mapping between stream types and outputs
- static DefaultKeyedVector<int, audio_io_handle_t> gStreamOutputMap;
- // list of output descritor containing cached parameters (sampling rate, framecount, channel count...)
- static DefaultKeyedVector<audio_io_handle_t, OutputDescriptor *> gOutputs;
-};
-
-class AudioParameter {
-
-public:
- AudioParameter() {}
- AudioParameter(const String8& keyValuePairs);
- virtual ~AudioParameter();
-
- // reserved parameter keys for changing standard parameters with setParameters() function.
- // Using these keys is mandatory for AudioFlinger to properly monitor audio output/input
- // configuration changes and act accordingly.
- // keyRouting: to change audio routing, value is an int in AudioSystem::audio_devices
- // keySamplingRate: to change sampling rate routing, value is an int
- // keyFormat: to change audio format, value is an int in AudioSystem::audio_format
- // keyChannels: to change audio channel configuration, value is an int in AudioSystem::audio_channels
- // keyFrameCount: to change audio output frame count, value is an int
- // keyInputSource: to change audio input source, value is an int in audio_source
- // (defined in media/mediarecorder.h)
- static const char *keyRouting;
- static const char *keySamplingRate;
- static const char *keyFormat;
- static const char *keyChannels;
- static const char *keyFrameCount;
- static const char *keyInputSource;
-
- String8 toString();
-
- status_t add(const String8& key, const String8& value);
- status_t addInt(const String8& key, const int value);
- status_t addFloat(const String8& key, const float value);
-
- status_t remove(const String8& key);
-
- status_t get(const String8& key, String8& value);
- status_t getInt(const String8& key, int& value);
- status_t getFloat(const String8& key, float& value);
- status_t getAt(size_t index, String8& key, String8& value);
-
- size_t size() { return mParameters.size(); }
-
-private:
- String8 mKeyValuePairs;
- KeyedVector <String8, String8> mParameters;
-};
-
-}; // namespace android
-
-#pragma GCC visibility pop
-
-#endif /*ANDROID_AUDIOSYSTEM_H_*/
diff --git a/dom/system/gonk/android_audio/AudioTrack.h b/dom/system/gonk/android_audio/AudioTrack.h
deleted file mode 100644
index 6f8c6bb28c..0000000000
--- a/dom/system/gonk/android_audio/AudioTrack.h
+++ /dev/null
@@ -1,489 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_AUDIOTRACK_H
-#define ANDROID_AUDIOTRACK_H
-
-#include <stdint.h>
-#include <sys/types.h>
-
-#include "IAudioFlinger.h"
-#include "IAudioTrack.h"
-#include "AudioSystem.h"
-
-#include <utils/RefBase.h>
-#include <utils/Errors.h>
-#include <binder/IInterface.h>
-#include <binder/IMemory.h>
-#include <utils/threads.h>
-
-
-namespace android {
-
-// ----------------------------------------------------------------------------
-
-class audio_track_cblk_t;
-
-// ----------------------------------------------------------------------------
-
-class AudioTrack
-{
-public:
- enum channel_index {
- MONO = 0,
- LEFT = 0,
- RIGHT = 1
- };
-
- /* Events used by AudioTrack callback function (audio_track_cblk_t).
- */
- enum event_type {
- EVENT_MORE_DATA = 0, // Request to write more data to PCM buffer.
- EVENT_UNDERRUN = 1, // PCM buffer underrun occured.
- EVENT_LOOP_END = 2, // Sample loop end was reached; playback restarted from loop start if loop count was not 0.
- EVENT_MARKER = 3, // Playback head is at the specified marker position (See setMarkerPosition()).
- EVENT_NEW_POS = 4, // Playback head is at a new position (See setPositionUpdatePeriod()).
- EVENT_BUFFER_END = 5 // Playback head is at the end of the buffer.
- };
-
- /* Create Buffer on the stack and pass it to obtainBuffer()
- * and releaseBuffer().
- */
-
- class Buffer
- {
- public:
- enum {
- MUTE = 0x00000001
- };
- uint32_t flags;
- int channelCount;
- int format;
- size_t frameCount;
- size_t size;
- union {
- void* raw;
- short* i16;
- int8_t* i8;
- };
- };
-
-
- /* As a convenience, if a callback is supplied, a handler thread
- * is automatically created with the appropriate priority. This thread
- * invokes the callback when a new buffer becomes availlable or an underrun condition occurs.
- * Parameters:
- *
- * event: type of event notified (see enum AudioTrack::event_type).
- * user: Pointer to context for use by the callback receiver.
- * info: Pointer to optional parameter according to event type:
- * - EVENT_MORE_DATA: pointer to AudioTrack::Buffer struct. The callback must not write
- * more bytes than indicated by 'size' field and update 'size' if less bytes are
- * written.
- * - EVENT_UNDERRUN: unused.
- * - EVENT_LOOP_END: pointer to an int indicating the number of loops remaining.
- * - EVENT_MARKER: pointer to an uin32_t containing the marker position in frames.
- * - EVENT_NEW_POS: pointer to an uin32_t containing the new position in frames.
- * - EVENT_BUFFER_END: unused.
- */
-
- typedef void (*callback_t)(int event, void* user, void *info);
-
- /* Returns the minimum frame count required for the successful creation of
- * an AudioTrack object.
- * Returned status (from utils/Errors.h) can be:
- * - NO_ERROR: successful operation
- * - NO_INIT: audio server or audio hardware not initialized
- */
-
- static status_t getMinFrameCount(int* frameCount,
- int streamType =-1,
- uint32_t sampleRate = 0);
-
- /* Constructs an uninitialized AudioTrack. No connection with
- * AudioFlinger takes place.
- */
- AudioTrack();
-
- /* Creates an audio track and registers it with AudioFlinger.
- * Once created, the track needs to be started before it can be used.
- * Unspecified values are set to the audio hardware's current
- * values.
- *
- * Parameters:
- *
- * streamType: Select the type of audio stream this track is attached to
- * (e.g. AudioSystem::MUSIC).
- * sampleRate: Track sampling rate in Hz.
- * format: Audio format (e.g AudioSystem::PCM_16_BIT for signed
- * 16 bits per sample).
- * channels: Channel mask: see AudioSystem::audio_channels.
- * frameCount: Total size of track PCM buffer in frames. This defines the
- * latency of the track.
- * flags: Reserved for future use.
- * cbf: Callback function. If not null, this function is called periodically
- * to request new PCM data.
- * notificationFrames: The callback function is called each time notificationFrames PCM
- * frames have been comsumed from track input buffer.
- * user Context for use by the callback receiver.
- */
-
- AudioTrack( int streamType,
- uint32_t sampleRate = 0,
- int format = 0,
- int channels = 0,
- int frameCount = 0,
- uint32_t flags = 0,
- callback_t cbf = 0,
- void* user = 0,
- int notificationFrames = 0,
- int sessionId = 0);
-
- /* Creates an audio track and registers it with AudioFlinger. With this constructor,
- * The PCM data to be rendered by AudioTrack is passed in a shared memory buffer
- * identified by the argument sharedBuffer. This prototype is for static buffer playback.
- * PCM data must be present into memory before the AudioTrack is started.
- * The Write() and Flush() methods are not supported in this case.
- * It is recommented to pass a callback function to be notified of playback end by an
- * EVENT_UNDERRUN event.
- */
-
- AudioTrack( int streamType,
- uint32_t sampleRate = 0,
- int format = 0,
- int channels = 0,
- const sp<IMemory>& sharedBuffer = 0,
- uint32_t flags = 0,
- callback_t cbf = 0,
- void* user = 0,
- int notificationFrames = 0,
- int sessionId = 0);
-
- /* Terminates the AudioTrack and unregisters it from AudioFlinger.
- * Also destroys all resources assotiated with the AudioTrack.
- */
- ~AudioTrack();
-
-
- /* Initialize an uninitialized AudioTrack.
- * Returned status (from utils/Errors.h) can be:
- * - NO_ERROR: successful intialization
- * - INVALID_OPERATION: AudioTrack is already intitialized
- * - BAD_VALUE: invalid parameter (channels, format, sampleRate...)
- * - NO_INIT: audio server or audio hardware not initialized
- * */
- status_t set(int streamType =-1,
- uint32_t sampleRate = 0,
- int format = 0,
- int channels = 0,
- int frameCount = 0,
- uint32_t flags = 0,
- callback_t cbf = 0,
- void* user = 0,
- int notificationFrames = 0,
- const sp<IMemory>& sharedBuffer = 0,
- bool threadCanCallJava = false,
- int sessionId = 0);
-
-
- /* Result of constructing the AudioTrack. This must be checked
- * before using any AudioTrack API (except for set()), using
- * an uninitialized AudioTrack produces undefined results.
- * See set() method above for possible return codes.
- */
- status_t initCheck() const;
-
- /* Returns this track's latency in milliseconds.
- * This includes the latency due to AudioTrack buffer size, AudioMixer (if any)
- * and audio hardware driver.
- */
- uint32_t latency() const;
-
- /* getters, see constructor */
-
- int streamType() const;
- int format() const;
- int channelCount() const;
- uint32_t frameCount() const;
- int frameSize() const;
- sp<IMemory>& sharedBuffer();
-
-
- /* After it's created the track is not active. Call start() to
- * make it active. If set, the callback will start being called.
- */
- void start();
-
- /* Stop a track. If set, the callback will cease being called and
- * obtainBuffer returns STOPPED. Note that obtainBuffer() still works
- * and will fill up buffers until the pool is exhausted.
- */
- void stop();
- bool stopped() const;
-
- /* flush a stopped track. All pending buffers are discarded.
- * This function has no effect if the track is not stoped.
- */
- void flush();
-
- /* Pause a track. If set, the callback will cease being called and
- * obtainBuffer returns STOPPED. Note that obtainBuffer() still works
- * and will fill up buffers until the pool is exhausted.
- */
- void pause();
-
- /* mute or unmutes this track.
- * While mutted, the callback, if set, is still called.
- */
- void mute(bool);
- bool muted() const;
-
-
- /* set volume for this track, mostly used for games' sound effects
- * left and right volumes. Levels must be <= 1.0.
- */
- status_t setVolume(float left, float right);
- void getVolume(float* left, float* right);
-
- /* set the send level for this track. An auxiliary effect should be attached
- * to the track with attachEffect(). Level must be <= 1.0.
- */
- status_t setAuxEffectSendLevel(float level);
- void getAuxEffectSendLevel(float* level);
-
- /* set sample rate for this track, mostly used for games' sound effects
- */
- status_t setSampleRate(int sampleRate);
- uint32_t getSampleRate();
-
- /* Enables looping and sets the start and end points of looping.
- *
- * Parameters:
- *
- * loopStart: loop start expressed as the number of PCM frames played since AudioTrack start.
- * loopEnd: loop end expressed as the number of PCM frames played since AudioTrack start.
- * loopCount: number of loops to execute. Calling setLoop() with loopCount == 0 cancels any pending or
- * active loop. loopCount = -1 means infinite looping.
- *
- * For proper operation the following condition must be respected:
- * (loopEnd-loopStart) <= framecount()
- */
- status_t setLoop(uint32_t loopStart, uint32_t loopEnd, int loopCount);
- status_t getLoop(uint32_t *loopStart, uint32_t *loopEnd, int *loopCount);
-
-
- /* Sets marker position. When playback reaches the number of frames specified, a callback with event
- * type EVENT_MARKER is called. Calling setMarkerPosition with marker == 0 cancels marker notification
- * callback.
- * If the AudioTrack has been opened with no callback function associated, the operation will fail.
- *
- * Parameters:
- *
- * marker: marker position expressed in frames.
- *
- * Returned status (from utils/Errors.h) can be:
- * - NO_ERROR: successful operation
- * - INVALID_OPERATION: the AudioTrack has no callback installed.
- */
- status_t setMarkerPosition(uint32_t marker);
- status_t getMarkerPosition(uint32_t *marker);
-
-
- /* Sets position update period. Every time the number of frames specified has been played,
- * a callback with event type EVENT_NEW_POS is called.
- * Calling setPositionUpdatePeriod with updatePeriod == 0 cancels new position notification
- * callback.
- * If the AudioTrack has been opened with no callback function associated, the operation will fail.
- *
- * Parameters:
- *
- * updatePeriod: position update notification period expressed in frames.
- *
- * Returned status (from utils/Errors.h) can be:
- * - NO_ERROR: successful operation
- * - INVALID_OPERATION: the AudioTrack has no callback installed.
- */
- status_t setPositionUpdatePeriod(uint32_t updatePeriod);
- status_t getPositionUpdatePeriod(uint32_t *updatePeriod);
-
-
- /* Sets playback head position within AudioTrack buffer. The new position is specified
- * in number of frames.
- * This method must be called with the AudioTrack in paused or stopped state.
- * Note that the actual position set is <position> modulo the AudioTrack buffer size in frames.
- * Therefore using this method makes sense only when playing a "static" audio buffer
- * as opposed to streaming.
- * The getPosition() method on the other hand returns the total number of frames played since
- * playback start.
- *
- * Parameters:
- *
- * position: New playback head position within AudioTrack buffer.
- *
- * Returned status (from utils/Errors.h) can be:
- * - NO_ERROR: successful operation
- * - INVALID_OPERATION: the AudioTrack is not stopped.
- * - BAD_VALUE: The specified position is beyond the number of frames present in AudioTrack buffer
- */
- status_t setPosition(uint32_t position);
- status_t getPosition(uint32_t *position);
-
- /* Forces AudioTrack buffer full condition. When playing a static buffer, this method avoids
- * rewriting the buffer before restarting playback after a stop.
- * This method must be called with the AudioTrack in paused or stopped state.
- *
- * Returned status (from utils/Errors.h) can be:
- * - NO_ERROR: successful operation
- * - INVALID_OPERATION: the AudioTrack is not stopped.
- */
- status_t reload();
-
- /* returns a handle on the audio output used by this AudioTrack.
- *
- * Parameters:
- * none.
- *
- * Returned value:
- * handle on audio hardware output
- */
- audio_io_handle_t getOutput();
-
- /* returns the unique ID associated to this track.
- *
- * Parameters:
- * none.
- *
- * Returned value:
- * AudioTrack ID.
- */
- int getSessionId();
-
-
- /* Attach track auxiliary output to specified effect. Used effectId = 0
- * to detach track from effect.
- *
- * Parameters:
- *
- * effectId: effectId obtained from AudioEffect::id().
- *
- * Returned status (from utils/Errors.h) can be:
- * - NO_ERROR: successful operation
- * - INVALID_OPERATION: the effect is not an auxiliary effect.
- * - BAD_VALUE: The specified effect ID is invalid
- */
- status_t attachAuxEffect(int effectId);
-
- /* obtains a buffer of "frameCount" frames. The buffer must be
- * filled entirely. If the track is stopped, obtainBuffer() returns
- * STOPPED instead of NO_ERROR as long as there are buffers availlable,
- * at which point NO_MORE_BUFFERS is returned.
- * Buffers will be returned until the pool (buffercount())
- * is exhausted, at which point obtainBuffer() will either block
- * or return WOULD_BLOCK depending on the value of the "blocking"
- * parameter.
- */
-
- enum {
- NO_MORE_BUFFERS = 0x80000001,
- STOPPED = 1
- };
-
- status_t obtainBuffer(Buffer* audioBuffer, int32_t waitCount);
- void releaseBuffer(Buffer* audioBuffer);
-
-
- /* As a convenience we provide a write() interface to the audio buffer.
- * This is implemented on top of lockBuffer/unlockBuffer. For best
- * performance
- *
- */
- ssize_t write(const void* buffer, size_t size);
-
- /*
- * Dumps the state of an audio track.
- */
- status_t dump(int fd, const Vector<String16>& args) const;
-
-private:
- /* copying audio tracks is not allowed */
- AudioTrack(const AudioTrack& other);
- AudioTrack& operator = (const AudioTrack& other);
-
- /* a small internal class to handle the callback */
- class AudioTrackThread : public Thread
- {
- public:
- AudioTrackThread(AudioTrack& receiver, bool bCanCallJava = false);
- private:
- friend class AudioTrack;
- virtual bool threadLoop();
- virtual status_t readyToRun();
- virtual void onFirstRef();
- AudioTrack& mReceiver;
- Mutex mLock;
- };
-
- bool processAudioBuffer(const sp<AudioTrackThread>& thread);
- status_t createTrack(int streamType,
- uint32_t sampleRate,
- int format,
- int channelCount,
- int frameCount,
- uint32_t flags,
- const sp<IMemory>& sharedBuffer,
- audio_io_handle_t output,
- bool enforceFrameCount);
-
- sp<IAudioTrack> mAudioTrack;
- sp<IMemory> mCblkMemory;
- sp<AudioTrackThread> mAudioTrackThread;
-
- float mVolume[2];
- float mSendLevel;
- uint32_t mFrameCount;
-
- audio_track_cblk_t* mCblk;
- uint8_t mStreamType;
- uint8_t mFormat;
- uint8_t mChannelCount;
- uint8_t mMuted;
- uint32_t mChannels;
- status_t mStatus;
- uint32_t mLatency;
-
- volatile int32_t mActive;
-
- callback_t mCbf;
- void* mUserData;
- uint32_t mNotificationFramesReq; // requested number of frames between each notification callback
- uint32_t mNotificationFramesAct; // actual number of frames between each notification callback
- sp<IMemory> mSharedBuffer;
- int mLoopCount;
- uint32_t mRemainingFrames;
- uint32_t mMarkerPosition;
- bool mMarkerReached;
- uint32_t mNewPosition;
- uint32_t mUpdatePeriod;
- uint32_t mFlags;
- int mSessionId;
- int mAuxEffectId;
- uint32_t mPadding[8];
-};
-
-
-}; // namespace android
-
-#endif // ANDROID_AUDIOTRACK_H
diff --git a/dom/system/gonk/android_audio/EffectApi.h b/dom/system/gonk/android_audio/EffectApi.h
deleted file mode 100644
index 729545d0c0..0000000000
--- a/dom/system/gonk/android_audio/EffectApi.h
+++ /dev/null
@@ -1,798 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_EFFECTAPI_H_
-#define ANDROID_EFFECTAPI_H_
-
-#include <errno.h>
-#include <stdint.h>
-#include <sys/types.h>
-
-#if __cplusplus
-extern "C" {
-#endif
-
-/////////////////////////////////////////////////
-// Effect control interface
-/////////////////////////////////////////////////
-
-// The effect control interface is exposed by each effect engine implementation. It consists of
-// a set of functions controlling the configuration, activation and process of the engine.
-// The functions are grouped in a structure of type effect_interface_s:
-// struct effect_interface_s {
-// effect_process_t process;
-// effect_command_t command;
-// };
-
-
-// effect_interface_t: Effect control interface handle.
-// The effect_interface_t serves two purposes regarding the implementation of the effect engine:
-// - 1 it is the address of a pointer to an effect_interface_s structure where the functions
-// of the effect control API for a particular effect are located.
-// - 2 it is the address of the context of a particular effect instance.
-// A typical implementation in the effect library would define a structure as follows:
-// struct effect_module_s {
-// const struct effect_interface_s *itfe;
-// effect_config_t config;
-// effect_context_t context;
-// }
-// The implementation of EffectCreate() function would then allocate a structure of this
-// type and return its address as effect_interface_t
-typedef struct effect_interface_s **effect_interface_t;
-
-
-// Effect API version 1.0
-#define EFFECT_API_VERSION 0x0100 // Format 0xMMmm MM: Major version, mm: minor version
-
-// Maximum length of character strings in structures defines by this API.
-#define EFFECT_STRING_LEN_MAX 64
-
-//
-//--- Effect descriptor structure effect_descriptor_t
-//
-
-// Unique effect ID (can be generated from the following site:
-// http://www.itu.int/ITU-T/asn1/uuid.html)
-// This format is used for both "type" and "uuid" fields of the effect descriptor structure.
-// - When used for effect type and the engine is implementing and effect corresponding to a standard
-// OpenSL ES interface, this ID must be the one defined in OpenSLES_IID.h for that interface.
-// - When used as uuid, it should be a unique UUID for this particular implementation.
-typedef struct effect_uuid_s {
- uint32_t timeLow;
- uint16_t timeMid;
- uint16_t timeHiAndVersion;
- uint16_t clockSeq;
- uint8_t node[6];
-} effect_uuid_t;
-
-// NULL UUID definition (matches SL_IID_NULL_)
-#define EFFECT_UUID_INITIALIZER { 0xec7178ec, 0xe5e1, 0x4432, 0xa3f4, \
- { 0x46, 0x57, 0xe6, 0x79, 0x52, 0x10 } }
-static const effect_uuid_t EFFECT_UUID_NULL_ = EFFECT_UUID_INITIALIZER;
-const effect_uuid_t * const EFFECT_UUID_NULL = &EFFECT_UUID_NULL_;
-const char * const EFFECT_UUID_NULL_STR = "ec7178ec-e5e1-4432-a3f4-4657e6795210";
-
-// The effect descriptor contains necessary information to facilitate the enumeration of the effect
-// engines present in a library.
-typedef struct effect_descriptor_s {
- effect_uuid_t type; // UUID of to the OpenSL ES interface implemented by this effect
- effect_uuid_t uuid; // UUID for this particular implementation
- uint16_t apiVersion; // Version of the effect API implemented: matches EFFECT_API_VERSION
- uint32_t flags; // effect engine capabilities/requirements flags (see below)
- uint16_t cpuLoad; // CPU load indication (see below)
- uint16_t memoryUsage; // Data Memory usage (see below)
- char name[EFFECT_STRING_LEN_MAX]; // human readable effect name
- char implementor[EFFECT_STRING_LEN_MAX]; // human readable effect implementor name
-} effect_descriptor_t;
-
-// CPU load and memory usage indication: each effect implementation must provide an indication of
-// its CPU and memory usage for the audio effect framework to limit the number of effects
-// instantiated at a given time on a given platform.
-// The CPU load is expressed in 0.1 MIPS units as estimated on an ARM9E core (ARMv5TE) with 0 WS.
-// The memory usage is expressed in KB and includes only dynamically allocated memory
-
-// Definitions for flags field of effect descriptor.
-// +---------------------------+-----------+-----------------------------------
-// | description | bits | values
-// +---------------------------+-----------+-----------------------------------
-// | connection mode | 0..1 | 0 insert: after track process
-// | | | 1 auxiliary: connect to track auxiliary
-// | | | output and use send level
-// | | | 2 replace: replaces track process function;
-// | | | must implement SRC, volume and mono to stereo.
-// | | | 3 reserved
-// +---------------------------+-----------+-----------------------------------
-// | insertion preference | 2..4 | 0 none
-// | | | 1 first of the chain
-// | | | 2 last of the chain
-// | | | 3 exclusive (only effect in the insert chain)
-// | | | 4..7 reserved
-// +---------------------------+-----------+-----------------------------------
-// | Volume management | 5..6 | 0 none
-// | | | 1 implements volume control
-// | | | 2 requires volume indication
-// | | | 3 reserved
-// +---------------------------+-----------+-----------------------------------
-// | Device indication | 7..8 | 0 none
-// | | | 1 requires device updates
-// | | | 2..3 reserved
-// +---------------------------+-----------+-----------------------------------
-// | Sample input mode | 9..10 | 0 direct: process() function or EFFECT_CMD_CONFIGURE
-// | | | command must specify a buffer descriptor
-// | | | 1 provider: process() function uses the
-// | | | bufferProvider indicated by the
-// | | | EFFECT_CMD_CONFIGURE command to request input.
-// | | | buffers.
-// | | | 2 both: both input modes are supported
-// | | | 3 reserved
-// +---------------------------+-----------+-----------------------------------
-// | Sample output mode | 11..12 | 0 direct: process() function or EFFECT_CMD_CONFIGURE
-// | | | command must specify a buffer descriptor
-// | | | 1 provider: process() function uses the
-// | | | bufferProvider indicated by the
-// | | | EFFECT_CMD_CONFIGURE command to request output
-// | | | buffers.
-// | | | 2 both: both output modes are supported
-// | | | 3 reserved
-// +---------------------------+-----------+-----------------------------------
-// | Hardware acceleration | 13..15 | 0 No hardware acceleration
-// | | | 1 non tunneled hw acceleration: the process() function
-// | | | reads the samples, send them to HW accelerated
-// | | | effect processor, reads back the processed samples
-// | | | and returns them to the output buffer.
-// | | | 2 tunneled hw acceleration: the process() function is
-// | | | transparent. The effect interface is only used to
-// | | | control the effect engine. This mode is relevant for
-// | | | global effects actually applied by the audio
-// | | | hardware on the output stream.
-// +---------------------------+-----------+-----------------------------------
-// | Audio Mode indication | 16..17 | 0 none
-// | | | 1 requires audio mode updates
-// | | | 2..3 reserved
-// +---------------------------+-----------+-----------------------------------
-
-// Insert mode
-#define EFFECT_FLAG_TYPE_MASK 0x00000003
-#define EFFECT_FLAG_TYPE_INSERT 0x00000000
-#define EFFECT_FLAG_TYPE_AUXILIARY 0x00000001
-#define EFFECT_FLAG_TYPE_REPLACE 0x00000002
-
-// Insert preference
-#define EFFECT_FLAG_INSERT_MASK 0x0000001C
-#define EFFECT_FLAG_INSERT_ANY 0x00000000
-#define EFFECT_FLAG_INSERT_FIRST 0x00000004
-#define EFFECT_FLAG_INSERT_LAST 0x00000008
-#define EFFECT_FLAG_INSERT_EXCLUSIVE 0x0000000C
-
-
-// Volume control
-#define EFFECT_FLAG_VOLUME_MASK 0x00000060
-#define EFFECT_FLAG_VOLUME_CTRL 0x00000020
-#define EFFECT_FLAG_VOLUME_IND 0x00000040
-#define EFFECT_FLAG_VOLUME_NONE 0x00000000
-
-// Device indication
-#define EFFECT_FLAG_DEVICE_MASK 0x00000180
-#define EFFECT_FLAG_DEVICE_IND 0x00000080
-#define EFFECT_FLAG_DEVICE_NONE 0x00000000
-
-// Sample input modes
-#define EFFECT_FLAG_INPUT_MASK 0x00000600
-#define EFFECT_FLAG_INPUT_DIRECT 0x00000000
-#define EFFECT_FLAG_INPUT_PROVIDER 0x00000200
-#define EFFECT_FLAG_INPUT_BOTH 0x00000400
-
-// Sample output modes
-#define EFFECT_FLAG_OUTPUT_MASK 0x00001800
-#define EFFECT_FLAG_OUTPUT_DIRECT 0x00000000
-#define EFFECT_FLAG_OUTPUT_PROVIDER 0x00000800
-#define EFFECT_FLAG_OUTPUT_BOTH 0x00001000
-
-// Hardware acceleration mode
-#define EFFECT_FLAG_HW_ACC_MASK 0x00006000
-#define EFFECT_FLAG_HW_ACC_SIMPLE 0x00002000
-#define EFFECT_FLAG_HW_ACC_TUNNEL 0x00004000
-
-// Audio mode indication
-#define EFFECT_FLAG_AUDIO_MODE_MASK 0x00018000
-#define EFFECT_FLAG_AUDIO_MODE_IND 0x00008000
-#define EFFECT_FLAG_AUDIO_MODE_NONE 0x00000000
-
-// Forward definition of type audio_buffer_t
-typedef struct audio_buffer_s audio_buffer_t;
-
-////////////////////////////////////////////////////////////////////////////////
-//
-// Function: process
-//
-// Description: Effect process function. Takes input samples as specified
-// (count and location) in input buffer descriptor and output processed
-// samples as specified in output buffer descriptor. If the buffer descriptor
-// is not specified the function must use either the buffer or the
-// buffer provider function installed by the EFFECT_CMD_CONFIGURE command.
-// The effect framework will call the process() function after the EFFECT_CMD_ENABLE
-// command is received and until the EFFECT_CMD_DISABLE is received. When the engine
-// receives the EFFECT_CMD_DISABLE command it should turn off the effect gracefully
-// and when done indicate that it is OK to stop calling the process() function by
-// returning the -ENODATA status.
-//
-// NOTE: the process() function implementation should be "real-time safe" that is
-// it should not perform blocking calls: malloc/free, sleep, read/write/open/close,
-// pthread_cond_wait/pthread_mutex_lock...
-//
-// Input:
-// effect_interface_t: handle to the effect interface this function
-// is called on.
-// inBuffer: buffer descriptor indicating where to read samples to process.
-// If NULL, use the configuration passed by EFFECT_CMD_CONFIGURE command.
-//
-// inBuffer: buffer descriptor indicating where to write processed samples.
-// If NULL, use the configuration passed by EFFECT_CMD_CONFIGURE command.
-//
-// Output:
-// returned value: 0 successful operation
-// -ENODATA the engine has finished the disable phase and the framework
-// can stop calling process()
-// -EINVAL invalid interface handle or
-// invalid input/output buffer description
-////////////////////////////////////////////////////////////////////////////////
-typedef int32_t (*effect_process_t)(effect_interface_t self,
- audio_buffer_t *inBuffer,
- audio_buffer_t *outBuffer);
-
-////////////////////////////////////////////////////////////////////////////////
-//
-// Function: command
-//
-// Description: Send a command and receive a response to/from effect engine.
-//
-// Input:
-// effect_interface_t: handle to the effect interface this function
-// is called on.
-// cmdCode: command code: the command can be a standardized command defined in
-// effect_command_e (see below) or a proprietary command.
-// cmdSize: size of command in bytes
-// pCmdData: pointer to command data
-// pReplyData: pointer to reply data
-//
-// Input/Output:
-// replySize: maximum size of reply data as input
-// actual size of reply data as output
-//
-// Output:
-// returned value: 0 successful operation
-// -EINVAL invalid interface handle or
-// invalid command/reply size or format according to command code
-// The return code should be restricted to indicate problems related to the this
-// API specification. Status related to the execution of a particular command should be
-// indicated as part of the reply field.
-//
-// *pReplyData updated with command response
-//
-////////////////////////////////////////////////////////////////////////////////
-typedef int32_t (*effect_command_t)(effect_interface_t self,
- uint32_t cmdCode,
- uint32_t cmdSize,
- void *pCmdData,
- uint32_t *replySize,
- void *pReplyData);
-
-
-// Effect control interface definition
-struct effect_interface_s {
- effect_process_t process;
- effect_command_t command;
-};
-
-
-//
-//--- Standardized command codes for command() function
-//
-enum effect_command_e {
- EFFECT_CMD_INIT, // initialize effect engine
- EFFECT_CMD_CONFIGURE, // configure effect engine (see effect_config_t)
- EFFECT_CMD_RESET, // reset effect engine
- EFFECT_CMD_ENABLE, // enable effect process
- EFFECT_CMD_DISABLE, // disable effect process
- EFFECT_CMD_SET_PARAM, // set parameter immediately (see effect_param_t)
- EFFECT_CMD_SET_PARAM_DEFERRED, // set parameter deferred
- EFFECT_CMD_SET_PARAM_COMMIT, // commit previous set parameter deferred
- EFFECT_CMD_GET_PARAM, // get parameter
- EFFECT_CMD_SET_DEVICE, // set audio device (see audio_device_e)
- EFFECT_CMD_SET_VOLUME, // set volume
- EFFECT_CMD_SET_AUDIO_MODE, // set the audio mode (normal, ring, ...)
- EFFECT_CMD_FIRST_PROPRIETARY = 0x10000 // first proprietary command code
-};
-
-//==================================================================================================
-// command: EFFECT_CMD_INIT
-//--------------------------------------------------------------------------------------------------
-// description:
-// Initialize effect engine: All configurations return to default
-//--------------------------------------------------------------------------------------------------
-// command format:
-// size: 0
-// data: N/A
-//--------------------------------------------------------------------------------------------------
-// reply format:
-// size: sizeof(int)
-// data: status
-//==================================================================================================
-// command: EFFECT_CMD_CONFIGURE
-//--------------------------------------------------------------------------------------------------
-// description:
-// Apply new audio parameters configurations for input and output buffers
-//--------------------------------------------------------------------------------------------------
-// command format:
-// size: sizeof(effect_config_t)
-// data: effect_config_t
-//--------------------------------------------------------------------------------------------------
-// reply format:
-// size: sizeof(int)
-// data: status
-//==================================================================================================
-// command: EFFECT_CMD_RESET
-//--------------------------------------------------------------------------------------------------
-// description:
-// Reset the effect engine. Keep configuration but resets state and buffer content
-//--------------------------------------------------------------------------------------------------
-// command format:
-// size: 0
-// data: N/A
-//--------------------------------------------------------------------------------------------------
-// reply format:
-// size: 0
-// data: N/A
-//==================================================================================================
-// command: EFFECT_CMD_ENABLE
-//--------------------------------------------------------------------------------------------------
-// description:
-// Enable the process. Called by the framework before the first call to process()
-//--------------------------------------------------------------------------------------------------
-// command format:
-// size: 0
-// data: N/A
-//--------------------------------------------------------------------------------------------------
-// reply format:
-// size: sizeof(int)
-// data: status
-//==================================================================================================
-// command: EFFECT_CMD_DISABLE
-//--------------------------------------------------------------------------------------------------
-// description:
-// Disable the process. Called by the framework after the last call to process()
-//--------------------------------------------------------------------------------------------------
-// command format:
-// size: 0
-// data: N/A
-//--------------------------------------------------------------------------------------------------
-// reply format:
-// size: sizeof(int)
-// data: status
-//==================================================================================================
-// command: EFFECT_CMD_SET_PARAM
-//--------------------------------------------------------------------------------------------------
-// description:
-// Set a parameter and apply it immediately
-//--------------------------------------------------------------------------------------------------
-// command format:
-// size: sizeof(effect_param_t) + size of param and value
-// data: effect_param_t + param + value. See effect_param_t definition below for value offset
-//--------------------------------------------------------------------------------------------------
-// reply format:
-// size: sizeof(int)
-// data: status
-//==================================================================================================
-// command: EFFECT_CMD_SET_PARAM_DEFERRED
-//--------------------------------------------------------------------------------------------------
-// description:
-// Set a parameter but apply it only when receiving EFFECT_CMD_SET_PARAM_COMMIT command
-//--------------------------------------------------------------------------------------------------
-// command format:
-// size: sizeof(effect_param_t) + size of param and value
-// data: effect_param_t + param + value. See effect_param_t definition below for value offset
-//--------------------------------------------------------------------------------------------------
-// reply format:
-// size: 0
-// data: N/A
-//==================================================================================================
-// command: EFFECT_CMD_SET_PARAM_COMMIT
-//--------------------------------------------------------------------------------------------------
-// description:
-// Apply all previously received EFFECT_CMD_SET_PARAM_DEFERRED commands
-//--------------------------------------------------------------------------------------------------
-// command format:
-// size: 0
-// data: N/A
-//--------------------------------------------------------------------------------------------------
-// reply format:
-// size: sizeof(int)
-// data: status
-//==================================================================================================
-// command: EFFECT_CMD_GET_PARAM
-//--------------------------------------------------------------------------------------------------
-// description:
-// Get a parameter value
-//--------------------------------------------------------------------------------------------------
-// command format:
-// size: sizeof(effect_param_t) + size of param
-// data: effect_param_t + param
-//--------------------------------------------------------------------------------------------------
-// reply format:
-// size: sizeof(effect_param_t) + size of param and value
-// data: effect_param_t + param + value. See effect_param_t definition below for value offset
-//==================================================================================================
-// command: EFFECT_CMD_SET_DEVICE
-//--------------------------------------------------------------------------------------------------
-// description:
-// Set the rendering device the audio output path is connected to. See audio_device_e for device
-// values.
-// The effect implementation must set EFFECT_FLAG_DEVICE_IND flag in its descriptor to receive this
-// command when the device changes
-//--------------------------------------------------------------------------------------------------
-// command format:
-// size: sizeof(uint32_t)
-// data: audio_device_e
-//--------------------------------------------------------------------------------------------------
-// reply format:
-// size: 0
-// data: N/A
-//==================================================================================================
-// command: EFFECT_CMD_SET_VOLUME
-//--------------------------------------------------------------------------------------------------
-// description:
-// Set and get volume. Used by audio framework to delegate volume control to effect engine.
-// The effect implementation must set EFFECT_FLAG_VOLUME_IND or EFFECT_FLAG_VOLUME_CTRL flag in
-// its descriptor to receive this command before every call to process() function
-// If EFFECT_FLAG_VOLUME_CTRL flag is set in the effect descriptor, the effect engine must return
-// the volume that should be applied before the effect is processed. The overall volume (the volume
-// actually applied by the effect engine multiplied by the returned value) should match the value
-// indicated in the command.
-//--------------------------------------------------------------------------------------------------
-// command format:
-// size: n * sizeof(uint32_t)
-// data: volume for each channel defined in effect_config_t for output buffer expressed in
-// 8.24 fixed point format
-//--------------------------------------------------------------------------------------------------
-// reply format:
-// size: n * sizeof(uint32_t) / 0
-// data: - if EFFECT_FLAG_VOLUME_CTRL is set in effect descriptor:
-// volume for each channel defined in effect_config_t for output buffer expressed in
-// 8.24 fixed point format
-// - if EFFECT_FLAG_VOLUME_CTRL is not set in effect descriptor:
-// N/A
-// It is legal to receive a null pointer as pReplyData in which case the effect framework has
-// delegated volume control to another effect
-//==================================================================================================
-// command: EFFECT_CMD_SET_AUDIO_MODE
-//--------------------------------------------------------------------------------------------------
-// description:
-// Set the audio mode. The effect implementation must set EFFECT_FLAG_AUDIO_MODE_IND flag in its
-// descriptor to receive this command when the audio mode changes.
-//--------------------------------------------------------------------------------------------------
-// command format:
-// size: sizeof(uint32_t)
-// data: audio_mode_e
-//--------------------------------------------------------------------------------------------------
-// reply format:
-// size: 0
-// data: N/A
-//==================================================================================================
-// command: EFFECT_CMD_FIRST_PROPRIETARY
-//--------------------------------------------------------------------------------------------------
-// description:
-// All proprietary effect commands must use command codes above this value. The size and format of
-// command and response fields is free in this case
-//==================================================================================================
-
-
-// Audio buffer descriptor used by process(), bufferProvider() functions and buffer_config_t
-// structure. Multi-channel audio is always interleaved. The channel order is from LSB to MSB with
-// regard to the channel mask definition in audio_channels_e e.g :
-// Stereo: left, right
-// 5 point 1: front left, front right, front center, low frequency, back left, back right
-// The buffer size is expressed in frame count, a frame being composed of samples for all
-// channels at a given time. Frame size for unspecified format (AUDIO_FORMAT_OTHER) is 8 bit by
-// definition
-struct audio_buffer_s {
- size_t frameCount; // number of frames in buffer
- union {
- void* raw; // raw pointer to start of buffer
- int32_t* s32; // pointer to signed 32 bit data at start of buffer
- int16_t* s16; // pointer to signed 16 bit data at start of buffer
- uint8_t* u8; // pointer to unsigned 8 bit data at start of buffer
- };
-};
-
-// The buffer_provider_s structure contains functions that can be used
-// by the effect engine process() function to query and release input
-// or output audio buffer.
-// The getBuffer() function is called to retrieve a buffer where data
-// should read from or written to by process() function.
-// The releaseBuffer() function MUST be called when the buffer retrieved
-// with getBuffer() is not needed anymore.
-// The process function should use the buffer provider mechanism to retrieve
-// input or output buffer if the inBuffer or outBuffer passed as argument is NULL
-// and the buffer configuration (buffer_config_t) given by the EFFECT_CMD_CONFIGURE
-// command did not specify an audio buffer.
-
-typedef int32_t (* buffer_function_t)(void *cookie, audio_buffer_t *buffer);
-
-typedef struct buffer_provider_s {
- buffer_function_t getBuffer; // retrieve next buffer
- buffer_function_t releaseBuffer; // release used buffer
- void *cookie; // for use by client of buffer provider functions
-} buffer_provider_t;
-
-
-// The buffer_config_s structure specifies the input or output audio format
-// to be used by the effect engine. It is part of the effect_config_t
-// structure that defines both input and output buffer configurations and is
-// passed by the EFFECT_CMD_CONFIGURE command.
-typedef struct buffer_config_s {
- audio_buffer_t buffer; // buffer for use by process() function if not passed explicitly
- uint32_t samplingRate; // sampling rate
- uint32_t channels; // channel mask (see audio_channels_e)
- buffer_provider_t bufferProvider; // buffer provider
- uint8_t format; // Audio format (see audio_format_e)
- uint8_t accessMode; // read/write or accumulate in buffer (effect_buffer_access_e)
- uint16_t mask; // indicates which of the above fields is valid
-} buffer_config_t;
-
-// Sample format
-enum audio_format_e {
- SAMPLE_FORMAT_PCM_S15, // PCM signed 16 bits
- SAMPLE_FORMAT_PCM_U8, // PCM unsigned 8 bits
- SAMPLE_FORMAT_PCM_S7_24, // PCM signed 7.24 fixed point representation
- SAMPLE_FORMAT_OTHER // other format (e.g. compressed)
-};
-
-// Channel mask
-enum audio_channels_e {
- CHANNEL_FRONT_LEFT = 0x1, // front left channel
- CHANNEL_FRONT_RIGHT = 0x2, // front right channel
- CHANNEL_FRONT_CENTER = 0x4, // front center channel
- CHANNEL_LOW_FREQUENCY = 0x8, // low frequency channel
- CHANNEL_BACK_LEFT = 0x10, // back left channel
- CHANNEL_BACK_RIGHT = 0x20, // back right channel
- CHANNEL_FRONT_LEFT_OF_CENTER = 0x40, // front left of center channel
- CHANNEL_FRONT_RIGHT_OF_CENTER = 0x80, // front right of center channel
- CHANNEL_BACK_CENTER = 0x100, // back center channel
- CHANNEL_MONO = CHANNEL_FRONT_LEFT,
- CHANNEL_STEREO = (CHANNEL_FRONT_LEFT | CHANNEL_FRONT_RIGHT),
- CHANNEL_QUAD = (CHANNEL_FRONT_LEFT | CHANNEL_FRONT_RIGHT |
- CHANNEL_BACK_LEFT | CHANNEL_BACK_RIGHT),
- CHANNEL_SURROUND = (CHANNEL_FRONT_LEFT | CHANNEL_FRONT_RIGHT |
- CHANNEL_FRONT_CENTER | CHANNEL_BACK_CENTER),
- CHANNEL_5POINT1 = (CHANNEL_FRONT_LEFT | CHANNEL_FRONT_RIGHT |
- CHANNEL_FRONT_CENTER | CHANNEL_LOW_FREQUENCY | CHANNEL_BACK_LEFT | CHANNEL_BACK_RIGHT),
- CHANNEL_7POINT1 = (CHANNEL_FRONT_LEFT | CHANNEL_FRONT_RIGHT |
- CHANNEL_FRONT_CENTER | CHANNEL_LOW_FREQUENCY | CHANNEL_BACK_LEFT | CHANNEL_BACK_RIGHT |
- CHANNEL_FRONT_LEFT_OF_CENTER | CHANNEL_FRONT_RIGHT_OF_CENTER),
-};
-
-// Render device
-enum audio_device_e {
- DEVICE_EARPIECE = 0x1, // earpiece
- DEVICE_SPEAKER = 0x2, // speaker
- DEVICE_WIRED_HEADSET = 0x4, // wired headset, with microphone
- DEVICE_WIRED_HEADPHONE = 0x8, // wired headphone, without microphone
- DEVICE_BLUETOOTH_SCO = 0x10, // generic bluetooth SCO
- DEVICE_BLUETOOTH_SCO_HEADSET = 0x20, // bluetooth SCO headset
- DEVICE_BLUETOOTH_SCO_CARKIT = 0x40, // bluetooth SCO car kit
- DEVICE_BLUETOOTH_A2DP = 0x80, // generic bluetooth A2DP
- DEVICE_BLUETOOTH_A2DP_HEADPHONES = 0x100, // bluetooth A2DP headphones
- DEVICE_BLUETOOTH_A2DP_SPEAKER = 0x200, // bluetooth A2DP speakers
- DEVICE_AUX_DIGITAL = 0x400, // digital output
- DEVICE_EXTERNAL_SPEAKER = 0x800 // external speaker (stereo and High quality)
-};
-
-#if ANDROID_VERSION < 17
-// Audio mode
-enum audio_mode_e {
- AUDIO_MODE_NORMAL, // device idle
- AUDIO_MODE_RINGTONE, // device ringing
- AUDIO_MODE_IN_CALL // audio call connected (VoIP or telephony)
-};
-#endif
-
-// Values for "accessMode" field of buffer_config_t:
-// overwrite, read only, accumulate (read/modify/write)
-enum effect_buffer_access_e {
- EFFECT_BUFFER_ACCESS_WRITE,
- EFFECT_BUFFER_ACCESS_READ,
- EFFECT_BUFFER_ACCESS_ACCUMULATE
-
-};
-
-// Values for bit field "mask" in buffer_config_t. If a bit is set, the corresponding field
-// in buffer_config_t must be taken into account when executing the EFFECT_CMD_CONFIGURE command
-#define EFFECT_CONFIG_BUFFER 0x0001 // buffer field must be taken into account
-#define EFFECT_CONFIG_SMP_RATE 0x0002 // samplingRate field must be taken into account
-#define EFFECT_CONFIG_CHANNELS 0x0004 // channels field must be taken into account
-#define EFFECT_CONFIG_FORMAT 0x0008 // format field must be taken into account
-#define EFFECT_CONFIG_ACC_MODE 0x0010 // accessMode field must be taken into account
-#define EFFECT_CONFIG_PROVIDER 0x0020 // bufferProvider field must be taken into account
-#define EFFECT_CONFIG_ALL (EFFECT_CONFIG_BUFFER | EFFECT_CONFIG_SMP_RATE | \
- EFFECT_CONFIG_CHANNELS | EFFECT_CONFIG_FORMAT | \
- EFFECT_CONFIG_ACC_MODE | EFFECT_CONFIG_PROVIDER)
-
-
-// effect_config_s structure describes the format of the pCmdData argument of EFFECT_CMD_CONFIGURE
-// command to configure audio parameters and buffers for effect engine input and output.
-typedef struct effect_config_s {
- buffer_config_t inputCfg;
- buffer_config_t outputCfg;;
-} effect_config_t;
-
-
-// effect_param_s structure describes the format of the pCmdData argument of EFFECT_CMD_SET_PARAM
-// command and pCmdData and pReplyData of EFFECT_CMD_GET_PARAM command.
-// psize and vsize represent the actual size of parameter and value.
-//
-// NOTE: the start of value field inside the data field is always on a 32 bit boundary:
-//
-// +-----------+
-// | status | sizeof(int)
-// +-----------+
-// | psize | sizeof(int)
-// +-----------+
-// | vsize | sizeof(int)
-// +-----------+
-// | | | |
-// ~ parameter ~ > psize |
-// | | | > ((psize - 1)/sizeof(int) + 1) * sizeof(int)
-// +-----------+ |
-// | padding | |
-// +-----------+
-// | | |
-// ~ value ~ > vsize
-// | | |
-// +-----------+
-
-typedef struct effect_param_s {
- int32_t status; // Transaction status (unused for command, used for reply)
- uint32_t psize; // Parameter size
- uint32_t vsize; // Value size
- char data[]; // Start of Parameter + Value data
-} effect_param_t;
-
-
-/////////////////////////////////////////////////
-// Effect library interface
-/////////////////////////////////////////////////
-
-// An effect library is required to implement and expose the following functions
-// to enable effect enumeration and instantiation. The name of these functions must be as
-// specified here as the effect framework will get the function address with dlsym():
-//
-// - effect_QueryNumberEffects_t EffectQueryNumberEffects;
-// - effect_QueryEffect_t EffectQueryEffect;
-// - effect_CreateEffect_t EffectCreate;
-// - effect_ReleaseEffect_t EffectRelease;
-
-
-////////////////////////////////////////////////////////////////////////////////
-//
-// Function: EffectQueryNumberEffects
-//
-// Description: Returns the number of different effects exposed by the
-// library. Each effect must have a unique effect uuid (see
-// effect_descriptor_t). This function together with EffectQueryEffect()
-// is used to enumerate all effects present in the library.
-//
-// Input/Output:
-// pNumEffects: address where the number of effects should be returned.
-//
-// Output:
-// returned value: 0 successful operation.
-// -ENODEV library failed to initialize
-// -EINVAL invalid pNumEffects
-// *pNumEffects: updated with number of effects in library
-//
-////////////////////////////////////////////////////////////////////////////////
-typedef int32_t (*effect_QueryNumberEffects_t)(uint32_t *pNumEffects);
-
-////////////////////////////////////////////////////////////////////////////////
-//
-// Function: EffectQueryEffect
-//
-// Description: Returns the descriptor of the effect engine which index is
-// given as first argument.
-// See effect_descriptor_t for details on effect descriptors.
-// This function together with EffectQueryNumberEffects() is used to enumerate all
-// effects present in the library. The enumeration sequence is:
-// EffectQueryNumberEffects(&num_effects);
-// for (i = 0; i < num_effects; i++)
-// EffectQueryEffect(i,...);
-//
-// Input/Output:
-// index: index of the effect
-// pDescriptor: address where to return the effect descriptor.
-//
-// Output:
-// returned value: 0 successful operation.
-// -ENODEV library failed to initialize
-// -EINVAL invalid pDescriptor or index
-// -ENOSYS effect list has changed since last execution of
-// EffectQueryNumberEffects()
-// -ENOENT no more effect available
-// *pDescriptor: updated with the effect descriptor.
-//
-////////////////////////////////////////////////////////////////////////////////
-typedef int32_t (*effect_QueryEffect_t)(uint32_t index,
- effect_descriptor_t *pDescriptor);
-
-////////////////////////////////////////////////////////////////////////////////
-//
-// Function: EffectCreate
-//
-// Description: Creates an effect engine of the specified type and returns an
-// effect control interface on this engine. The function will allocate the
-// resources for an instance of the requested effect engine and return
-// a handle on the effect control interface.
-//
-// Input:
-// uuid: pointer to the effect uuid.
-// sessionId: audio session to which this effect instance will be attached. All effects
-// created with the same session ID are connected in series and process the same signal
-// stream. Knowing that two effects are part of the same effect chain can help the
-// library implement some kind of optimizations.
-// ioId: identifies the output or input stream this effect is directed to at audio HAL.
-// For future use especially with tunneled HW accelerated effects
-//
-// Input/Output:
-// pInterface: address where to return the effect interface.
-//
-// Output:
-// returned value: 0 successful operation.
-// -ENODEV library failed to initialize
-// -EINVAL invalid pEffectUuid or pInterface
-// -ENOENT no effect with this uuid found
-// *pInterface: updated with the effect interface handle.
-//
-////////////////////////////////////////////////////////////////////////////////
-typedef int32_t (*effect_CreateEffect_t)(effect_uuid_t *uuid,
- int32_t sessionId,
- int32_t ioId,
- effect_interface_t *pInterface);
-
-////////////////////////////////////////////////////////////////////////////////
-//
-// Function: EffectRelease
-//
-// Description: Releases the effect engine whose handle is given as argument.
-// All resources allocated to this particular instance of the effect are
-// released.
-//
-// Input:
-// interface: handle on the effect interface to be released.
-//
-// Output:
-// returned value: 0 successful operation.
-// -ENODEV library failed to initialize
-// -EINVAL invalid interface handle
-//
-////////////////////////////////////////////////////////////////////////////////
-typedef int32_t (*effect_ReleaseEffect_t)(effect_interface_t interface);
-
-
-#if __cplusplus
-} // extern "C"
-#endif
-
-
-#endif /*ANDROID_EFFECTAPI_H_*/
diff --git a/dom/system/gonk/android_audio/IAudioFlinger.h b/dom/system/gonk/android_audio/IAudioFlinger.h
deleted file mode 100644
index b10d3ab937..0000000000
--- a/dom/system/gonk/android_audio/IAudioFlinger.h
+++ /dev/null
@@ -1,184 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_IAUDIOFLINGER_H
-#define ANDROID_IAUDIOFLINGER_H
-
-#include <stdint.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-#include <utils/RefBase.h>
-#include <utils/Errors.h>
-#include <binder/IInterface.h>
-#include "IAudioTrack.h"
-#include "IAudioRecord.h"
-#include "IAudioFlingerClient.h"
-#include "EffectApi.h"
-#include "IEffect.h"
-#include "IEffectClient.h"
-#include <utils/String8.h>
-
-namespace android {
-
-// ----------------------------------------------------------------------------
-
-class IAudioFlinger : public IInterface
-{
-public:
- DECLARE_META_INTERFACE(AudioFlinger);
-
- /* create an audio track and registers it with AudioFlinger.
- * return null if the track cannot be created.
- */
- virtual sp<IAudioTrack> createTrack(
- pid_t pid,
- int streamType,
- uint32_t sampleRate,
- int format,
- int channelCount,
- int frameCount,
- uint32_t flags,
- const sp<IMemory>& sharedBuffer,
- int output,
- int *sessionId,
- status_t *status) = 0;
-
- virtual sp<IAudioRecord> openRecord(
- pid_t pid,
- int input,
- uint32_t sampleRate,
- int format,
- int channelCount,
- int frameCount,
- uint32_t flags,
- int *sessionId,
- status_t *status) = 0;
-
- /* query the audio hardware state. This state never changes,
- * and therefore can be cached.
- */
- virtual uint32_t sampleRate(int output) const = 0;
- virtual int channelCount(int output) const = 0;
- virtual int format(int output) const = 0;
- virtual size_t frameCount(int output) const = 0;
- virtual uint32_t latency(int output) const = 0;
-
- /* set/get the audio hardware state. This will probably be used by
- * the preference panel, mostly.
- */
- virtual status_t setMasterVolume(float value) = 0;
- virtual status_t setMasterMute(bool muted) = 0;
-
- virtual float masterVolume() const = 0;
- virtual bool masterMute() const = 0;
-
- /* set/get stream type state. This will probably be used by
- * the preference panel, mostly.
- */
- virtual status_t setStreamVolume(int stream, float value, int output) = 0;
- virtual status_t setStreamMute(int stream, bool muted) = 0;
-
- virtual float streamVolume(int stream, int output) const = 0;
- virtual bool streamMute(int stream) const = 0;
-
- // set audio mode
- virtual status_t setMode(int mode) = 0;
-
- // mic mute/state
- virtual status_t setMicMute(bool state) = 0;
- virtual bool getMicMute() const = 0;
-
- // is any track active on this stream?
- virtual bool isStreamActive(int stream) const = 0;
-
- virtual status_t setParameters(int ioHandle, const String8& keyValuePairs) = 0;
- virtual String8 getParameters(int ioHandle, const String8& keys) = 0;
-
- // register a current process for audio output change notifications
- virtual void registerClient(const sp<IAudioFlingerClient>& client) = 0;
-
- // retrieve the audio recording buffer size
- virtual size_t getInputBufferSize(uint32_t sampleRate, int format, int channelCount) = 0;
-
- virtual int openOutput(uint32_t *pDevices,
- uint32_t *pSamplingRate,
- uint32_t *pFormat,
- uint32_t *pChannels,
- uint32_t *pLatencyMs,
- uint32_t flags) = 0;
- virtual int openDuplicateOutput(int output1, int output2) = 0;
- virtual status_t closeOutput(int output) = 0;
- virtual status_t suspendOutput(int output) = 0;
- virtual status_t restoreOutput(int output) = 0;
-
- virtual int openInput(uint32_t *pDevices,
- uint32_t *pSamplingRate,
- uint32_t *pFormat,
- uint32_t *pChannels,
- uint32_t acoustics) = 0;
- virtual status_t closeInput(int input) = 0;
-
- virtual status_t setStreamOutput(uint32_t stream, int output) = 0;
-
- virtual status_t setVoiceVolume(float volume) = 0;
-
- virtual status_t getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames, int output) = 0;
-
- virtual unsigned int getInputFramesLost(int ioHandle) = 0;
-
- virtual int newAudioSessionId() = 0;
-
- virtual status_t loadEffectLibrary(const char *libPath, int *handle) = 0;
-
- virtual status_t unloadEffectLibrary(int handle) = 0;
-
- virtual status_t queryNumberEffects(uint32_t *numEffects) = 0;
-
- virtual status_t queryEffect(uint32_t index, effect_descriptor_t *pDescriptor) = 0;
-
- virtual status_t getEffectDescriptor(effect_uuid_t *pEffectUUID, effect_descriptor_t *pDescriptor) = 0;
-
- virtual sp<IEffect> createEffect(pid_t pid,
- effect_descriptor_t *pDesc,
- const sp<IEffectClient>& client,
- int32_t priority,
- int output,
- int sessionId,
- status_t *status,
- int *id,
- int *enabled) = 0;
-
- virtual status_t moveEffects(int session, int srcOutput, int dstOutput) = 0;
-};
-
-
-// ----------------------------------------------------------------------------
-
-class BnAudioFlinger : public BnInterface<IAudioFlinger>
-{
-public:
- virtual status_t onTransact( uint32_t code,
- const Parcel& data,
- Parcel* reply,
- uint32_t flags = 0);
-};
-
-// ----------------------------------------------------------------------------
-
-}; // namespace android
-
-#endif // ANDROID_IAUDIOFLINGER_H
diff --git a/dom/system/gonk/android_audio/IAudioFlingerClient.h b/dom/system/gonk/android_audio/IAudioFlingerClient.h
deleted file mode 100644
index aa0cdcff1e..0000000000
--- a/dom/system/gonk/android_audio/IAudioFlingerClient.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_IAUDIOFLINGERCLIENT_H
-#define ANDROID_IAUDIOFLINGERCLIENT_H
-
-
-#include <utils/RefBase.h>
-#include <binder/IInterface.h>
-#include <utils/KeyedVector.h>
-
-namespace android {
-
-// ----------------------------------------------------------------------------
-
-class IAudioFlingerClient : public IInterface
-{
-public:
- DECLARE_META_INTERFACE(AudioFlingerClient);
-
- // Notifies a change of audio input/output configuration.
- virtual void ioConfigChanged(int event, int ioHandle, void *param2) = 0;
-
-};
-
-
-// ----------------------------------------------------------------------------
-
-class BnAudioFlingerClient : public BnInterface<IAudioFlingerClient>
-{
-public:
- virtual status_t onTransact( uint32_t code,
- const Parcel& data,
- Parcel* reply,
- uint32_t flags = 0);
-};
-
-// ----------------------------------------------------------------------------
-
-}; // namespace android
-
-#endif // ANDROID_IAUDIOFLINGERCLIENT_H
diff --git a/dom/system/gonk/android_audio/IAudioRecord.h b/dom/system/gonk/android_audio/IAudioRecord.h
deleted file mode 100644
index 46735def2f..0000000000
--- a/dom/system/gonk/android_audio/IAudioRecord.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef IAUDIORECORD_H_
-#define IAUDIORECORD_H_
-
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <utils/RefBase.h>
-#include <utils/Errors.h>
-#include <binder/IInterface.h>
-#include <binder/IMemory.h>
-
-
-namespace android {
-
-// ----------------------------------------------------------------------------
-
-class IAudioRecord : public IInterface
-{
-public:
- DECLARE_META_INTERFACE(AudioRecord);
-
- /* After it's created the track is not active. Call start() to
- * make it active. If set, the callback will start being called.
- */
- virtual status_t start() = 0;
-
- /* Stop a track. If set, the callback will cease being called and
- * obtainBuffer will return an error. Buffers that are already released
- * will be processed, unless flush() is called.
- */
- virtual void stop() = 0;
-
- /* get this tracks control block */
- virtual sp<IMemory> getCblk() const = 0;
-};
-
-// ----------------------------------------------------------------------------
-
-class BnAudioRecord : public BnInterface<IAudioRecord>
-{
-public:
- virtual status_t onTransact( uint32_t code,
- const Parcel& data,
- Parcel* reply,
- uint32_t flags = 0);
-};
-
-// ----------------------------------------------------------------------------
-
-}; // namespace android
-
-#endif /*IAUDIORECORD_H_*/
diff --git a/dom/system/gonk/android_audio/IAudioTrack.h b/dom/system/gonk/android_audio/IAudioTrack.h
deleted file mode 100644
index 47d530be5b..0000000000
--- a/dom/system/gonk/android_audio/IAudioTrack.h
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_IAUDIOTRACK_H
-#define ANDROID_IAUDIOTRACK_H
-
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <utils/RefBase.h>
-#include <utils/Errors.h>
-#include <binder/IInterface.h>
-#include <binder/IMemory.h>
-
-
-namespace android {
-
-// ----------------------------------------------------------------------------
-
-class IAudioTrack : public IInterface
-{
-public:
- DECLARE_META_INTERFACE(AudioTrack);
-
- /* After it's created the track is not active. Call start() to
- * make it active. If set, the callback will start being called.
- */
- virtual status_t start() = 0;
-
- /* Stop a track. If set, the callback will cease being called and
- * obtainBuffer will return an error. Buffers that are already released
- * will be processed, unless flush() is called.
- */
- virtual void stop() = 0;
-
- /* flush a stopped track. All pending buffers are discarded.
- * This function has no effect if the track is not stoped.
- */
- virtual void flush() = 0;
-
- /* mute or unmutes this track.
- * While mutted, the callback, if set, is still called.
- */
- virtual void mute(bool) = 0;
-
- /* Pause a track. If set, the callback will cease being called and
- * obtainBuffer will return an error. Buffers that are already released
- * will be processed, unless flush() is called.
- */
- virtual void pause() = 0;
-
- /* Attach track auxiliary output to specified effect. Use effectId = 0
- * to detach track from effect.
- */
- virtual status_t attachAuxEffect(int effectId) = 0;
-
- /* get this tracks control block */
- virtual sp<IMemory> getCblk() const = 0;
-};
-
-// ----------------------------------------------------------------------------
-
-class BnAudioTrack : public BnInterface<IAudioTrack>
-{
-public:
- virtual status_t onTransact( uint32_t code,
- const Parcel& data,
- Parcel* reply,
- uint32_t flags = 0);
-};
-
-// ----------------------------------------------------------------------------
-
-}; // namespace android
-
-#endif // ANDROID_IAUDIOTRACK_H
diff --git a/dom/system/gonk/android_audio/IEffect.h b/dom/system/gonk/android_audio/IEffect.h
deleted file mode 100644
index ff04869e06..0000000000
--- a/dom/system/gonk/android_audio/IEffect.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_IEFFECT_H
-#define ANDROID_IEFFECT_H
-
-#include <utils/RefBase.h>
-#include <binder/IInterface.h>
-#include <binder/Parcel.h>
-#include <binder/IMemory.h>
-
-namespace android {
-
-class IEffect: public IInterface
-{
-public:
- DECLARE_META_INTERFACE(Effect);
-
- virtual status_t enable() = 0;
-
- virtual status_t disable() = 0;
-
- virtual status_t command(uint32_t cmdCode,
- uint32_t cmdSize,
- void *pCmdData,
- uint32_t *pReplySize,
- void *pReplyData) = 0;
-
- virtual void disconnect() = 0;
-
- virtual sp<IMemory> getCblk() const = 0;
-};
-
-// ----------------------------------------------------------------------------
-
-class BnEffect: public BnInterface<IEffect>
-{
-public:
- virtual status_t onTransact( uint32_t code,
- const Parcel& data,
- Parcel* reply,
- uint32_t flags = 0);
-};
-
-}; // namespace android
-
-#endif // ANDROID_IEFFECT_H
diff --git a/dom/system/gonk/android_audio/IEffectClient.h b/dom/system/gonk/android_audio/IEffectClient.h
deleted file mode 100644
index 2f78c98f17..0000000000
--- a/dom/system/gonk/android_audio/IEffectClient.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_IEFFECTCLIENT_H
-#define ANDROID_IEFFECTCLIENT_H
-
-#include <utils/RefBase.h>
-#include <binder/IInterface.h>
-#include <binder/Parcel.h>
-#include <binder/IMemory.h>
-
-namespace android {
-
-class IEffectClient: public IInterface
-{
-public:
- DECLARE_META_INTERFACE(EffectClient);
-
- virtual void controlStatusChanged(bool controlGranted) = 0;
- virtual void enableStatusChanged(bool enabled) = 0;
- virtual void commandExecuted(uint32_t cmdCode,
- uint32_t cmdSize,
- void *pCmdData,
- uint32_t replySize,
- void *pReplyData) = 0;
-};
-
-// ----------------------------------------------------------------------------
-
-class BnEffectClient: public BnInterface<IEffectClient>
-{
-public:
- virtual status_t onTransact( uint32_t code,
- const Parcel& data,
- Parcel* reply,
- uint32_t flags = 0);
-};
-
-}; // namespace android
-
-#endif // ANDROID_IEFFECTCLIENT_H
diff --git a/dom/system/gonk/moz.build b/dom/system/gonk/moz.build
deleted file mode 100644
index 229baaab4e..0000000000
--- a/dom/system/gonk/moz.build
+++ /dev/null
@@ -1,107 +0,0 @@
-# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
-# vim: set filetype=python:
-# Copyright 2013 Mozilla Foundation and Mozilla contributors
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-XPIDL_SOURCES += [
- 'nsIAudioManager.idl',
- 'nsINetworkInterface.idl',
- 'nsINetworkInterfaceListService.idl',
- 'nsINetworkManager.idl',
- 'nsINetworkService.idl',
- 'nsINetworkWorker.idl',
- 'nsISystemWorkerManager.idl',
- 'nsITetheringService.idl',
- 'nsIVolume.idl',
- 'nsIVolumeMountLock.idl',
- 'nsIVolumeService.idl',
- 'nsIVolumeStat.idl',
- 'nsIWorkerHolder.idl',
-]
-
-XPIDL_MODULE = 'dom_system_gonk'
-
-EXPORTS += [
- 'GeolocationUtil.h',
- 'GonkGPSGeolocationProvider.h',
- 'nsVolume.h',
- 'nsVolumeService.h',
- 'SystemProperty.h',
-]
-UNIFIED_SOURCES += [
- 'AudioChannelManager.cpp',
- 'AudioManager.cpp',
- 'AutoMounter.cpp',
- 'AutoMounterSetting.cpp',
- 'GeolocationUtil.cpp',
- 'GonkGPSGeolocationProvider.cpp',
- 'MozMtpDatabase.cpp',
- 'MozMtpServer.cpp',
- 'MozMtpStorage.cpp',
- 'NetIdManager.cpp',
- 'NetworkUtils.cpp',
- 'NetworkWorker.cpp',
- 'nsVolume.cpp',
- 'nsVolumeMountLock.cpp',
- 'nsVolumeService.cpp',
- 'nsVolumeStat.cpp',
- 'OpenFileFinder.cpp',
- 'SystemProperty.cpp',
- 'SystemWorkerManager.cpp',
- 'TimeZoneSettingObserver.cpp',
- 'Volume.cpp',
- 'VolumeCommand.cpp',
- 'VolumeManager.cpp',
- 'VolumeServiceIOThread.cpp',
- 'VolumeServiceTest.cpp',
-]
-
-if CONFIG['ANDROID_VERSION'] >= '17':
- LOCAL_INCLUDES += ['%' + '%s/frameworks/av/media/mtp' % CONFIG['ANDROID_SOURCE']]
-else:
- LOCAL_INCLUDES += ['%' + '%s/frameworks/base/media/mtp' % CONFIG['ANDROID_SOURCE']]
-
-if CONFIG['ENABLE_TESTS']:
- XPCSHELL_TESTS_MANIFESTS += ['tests/xpcshell.ini']
-
-EXTRA_COMPONENTS += [
- 'NetworkInterfaceListService.js',
- 'NetworkInterfaceListService.manifest',
- 'NetworkManager.js',
- 'NetworkManager.manifest',
- 'NetworkService.js',
- 'NetworkService.manifest',
- 'TetheringService.js',
- 'TetheringService.manifest',
-]
-EXTRA_JS_MODULES += [
- 'systemlibs.js',
-]
-
-include('/ipc/chromium/chromium-config.mozbuild')
-
-DEFINES['HAVE_ANDROID_OS'] = True
-
-LOCAL_INCLUDES += [
- '/dom/base',
- '/dom/bluetooth/common',
- '/dom/geolocation',
- '/dom/wifi',
-]
-
-FINAL_LIBRARY = 'xul'
-
-FINAL_TARGET_FILES.modules.workers += [
- 'worker_buf.js',
-]
diff --git a/dom/system/gonk/mozstumbler/MozStumbler.cpp b/dom/system/gonk/mozstumbler/MozStumbler.cpp
deleted file mode 100644
index 61e09e7057..0000000000
--- a/dom/system/gonk/mozstumbler/MozStumbler.cpp
+++ /dev/null
@@ -1,426 +0,0 @@
-/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
-/* 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/. */
-
-#include "MozStumbler.h"
-#include "nsDataHashtable.h"
-#include "nsGeoPosition.h"
-#include "nsNetCID.h"
-#include "nsPrintfCString.h"
-#include "StumblerLogging.h"
-#include "WriteStumbleOnThread.h"
-#include "../GeolocationUtil.h"
-
-#include "nsIInterfaceRequestor.h"
-#include "nsIInterfaceRequestorUtils.h"
-#include "nsIMobileConnectionInfo.h"
-#include "nsIMobileConnectionService.h"
-#include "nsIMobileCellInfo.h"
-#include "nsIMobileNetworkInfo.h"
-#include "nsINetworkInterface.h"
-#include "nsIRadioInterfaceLayer.h"
-
-using namespace mozilla;
-using namespace mozilla::dom;
-
-
-NS_IMPL_ISUPPORTS(StumblerInfo, nsICellInfoListCallback, nsIWifiScanResultsReady)
-
-class RequestCellInfoEvent : public Runnable {
-public:
- RequestCellInfoEvent(StumblerInfo *callback)
- : mRequestCallback(callback)
- {}
-
- NS_IMETHOD Run() override {
- MOZ_ASSERT(NS_IsMainThread());
- // Get Cell Info
- nsCOMPtr<nsIMobileConnectionService> service =
- do_GetService(NS_MOBILE_CONNECTION_SERVICE_CONTRACTID);
-
- if (!service) {
- STUMBLER_ERR("Stumbler-can not get nsIMobileConnectionService \n");
- return NS_OK;
- }
- nsCOMPtr<nsIMobileConnection> connection;
- uint32_t numberOfRilServices = 1, cellInfoNum = 0;
-
- service->GetNumItems(&numberOfRilServices);
- for (uint32_t rilNum = 0; rilNum < numberOfRilServices; rilNum++) {
- service->GetItemByServiceId(rilNum /* Client Id */, getter_AddRefs(connection));
- if (!connection) {
- STUMBLER_ERR("Stumbler-can not get nsIMobileConnection by ServiceId %d \n", rilNum);
- } else {
- cellInfoNum++;
- connection->GetCellInfoList(mRequestCallback);
- }
- }
- mRequestCallback->SetCellInfoResponsesExpected(cellInfoNum);
-
- // Get Wifi AP Info
- nsCOMPtr<nsIInterfaceRequestor> ir = do_GetService("@mozilla.org/telephony/system-worker-manager;1");
- nsCOMPtr<nsIWifi> wifi = do_GetInterface(ir);
- if (!wifi) {
- mRequestCallback->SetWifiInfoResponseReceived();
- STUMBLER_ERR("Stumbler-can not get nsIWifi interface\n");
- return NS_OK;
- }
- wifi->GetWifiScanResults(mRequestCallback);
- return NS_OK;
- }
-private:
- RefPtr<StumblerInfo> mRequestCallback;
-};
-
-void
-MozStumble(nsGeoPosition* position)
-{
- if (WriteStumbleOnThread::IsFileWaitingForUpload()) {
- nsCOMPtr<nsIEventTarget> target = do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID);
- MOZ_ASSERT(target);
- // Knowing that file is waiting to upload, and no collection will take place,
- // just trigger the thread with an empty string.
- nsCOMPtr<nsIRunnable> event = new WriteStumbleOnThread(EmptyCString());
- target->Dispatch(event, NS_DISPATCH_NORMAL);
- return;
- }
-
- nsCOMPtr<nsIDOMGeoPositionCoords> coords;
- position->GetCoords(getter_AddRefs(coords));
- if (!coords) {
- return;
- }
-
- double latitude, longitude;
- coords->GetLatitude(&latitude);
- coords->GetLongitude(&longitude);
-
- const double kMinChangeInMeters = 30;
- static int64_t lastTime_ms = 0;
- static double sLastLat = 0;
- static double sLastLon = 0;
- double delta = -1.0;
- int64_t timediff = (PR_Now() / PR_USEC_PER_MSEC) - lastTime_ms;
-
- if (0 != sLastLon || 0 != sLastLat) {
- delta = CalculateDeltaInMeter(latitude, longitude, sLastLat, sLastLon);
- }
- STUMBLER_DBG("Stumbler-Location. [%f , %f] time_diff:%lld, delta : %f\n",
- longitude, latitude, timediff, delta);
-
- // Consecutive GPS locations must be 30 meters and 3 seconds apart
- if (lastTime_ms == 0 || ((timediff >= STUMBLE_INTERVAL_MS) && (delta > kMinChangeInMeters))){
- lastTime_ms = (PR_Now() / PR_USEC_PER_MSEC);
- sLastLat = latitude;
- sLastLon = longitude;
- RefPtr<StumblerInfo> requestCallback = new StumblerInfo(position);
- RefPtr<RequestCellInfoEvent> runnable = new RequestCellInfoEvent(requestCallback);
- NS_DispatchToMainThread(runnable);
- } else {
- STUMBLER_DBG("Stumbler-GPS locations less than 30 meters and 3 seconds. Ignore!\n");
- }
-}
-
-void
-StumblerInfo::SetWifiInfoResponseReceived()
-{
- mIsWifiInfoResponseReceived = true;
-
- if (mIsWifiInfoResponseReceived && mCellInfoResponsesReceived == mCellInfoResponsesExpected) {
- STUMBLER_DBG("Call DumpStumblerInfo from SetWifiInfoResponseReceived\n");
- DumpStumblerInfo();
- }
-}
-
-void
-StumblerInfo::SetCellInfoResponsesExpected(uint8_t count)
-{
- mCellInfoResponsesExpected = count;
- STUMBLER_DBG("SetCellInfoNum (%d)\n", count);
-
- if (mIsWifiInfoResponseReceived && mCellInfoResponsesReceived == mCellInfoResponsesExpected) {
- STUMBLER_DBG("Call DumpStumblerInfo from SetCellInfoResponsesExpected\n");
- DumpStumblerInfo();
- }
-}
-
-
-#define TEXT_LAT NS_LITERAL_CSTRING("latitude")
-#define TEXT_LON NS_LITERAL_CSTRING("longitude")
-#define TEXT_ACC NS_LITERAL_CSTRING("accuracy")
-#define TEXT_ALT NS_LITERAL_CSTRING("altitude")
-#define TEXT_ALTACC NS_LITERAL_CSTRING("altitudeAccuracy")
-#define TEXT_HEAD NS_LITERAL_CSTRING("heading")
-#define TEXT_SPD NS_LITERAL_CSTRING("speed")
-
-nsresult
-StumblerInfo::LocationInfoToString(nsACString& aLocDesc)
-{
- nsCOMPtr<nsIDOMGeoPositionCoords> coords;
- mPosition->GetCoords(getter_AddRefs(coords));
- if (!coords) {
- return NS_ERROR_FAILURE;
- }
-
- nsDataHashtable<nsCStringHashKey, double> info;
-
- double val;
- coords->GetLatitude(&val);
- info.Put(TEXT_LAT, val);
- coords->GetLongitude(&val);
- info.Put(TEXT_LON, val);
- coords->GetAccuracy(&val);
- info.Put(TEXT_ACC, val);
- coords->GetAltitude(&val);
- info.Put(TEXT_ALT, val);
- coords->GetAltitudeAccuracy(&val);
- info.Put(TEXT_ALTACC, val);
- coords->GetHeading(&val);
- info.Put(TEXT_HEAD, val);
- coords->GetSpeed(&val);
- info.Put(TEXT_SPD, val);
-
- for (auto it = info.Iter(); !it.Done(); it.Next()) {
- const nsACString& key = it.Key();
- val = it.UserData();
- if (!IsNaN(val)) {
- aLocDesc += nsPrintfCString("\"%s\":%f,", key.BeginReading(), val);
- }
- }
-
- aLocDesc += nsPrintfCString("\"timestamp\":%lld,", PR_Now() / PR_USEC_PER_MSEC).get();
- return NS_OK;
-}
-
-#define TEXT_RADIOTYPE NS_LITERAL_CSTRING("radioType")
-#define TEXT_MCC NS_LITERAL_CSTRING("mobileCountryCode")
-#define TEXT_MNC NS_LITERAL_CSTRING("mobileNetworkCode")
-#define TEXT_LAC NS_LITERAL_CSTRING("locationAreaCode")
-#define TEXT_CID NS_LITERAL_CSTRING("cellId")
-#define TEXT_PSC NS_LITERAL_CSTRING("psc")
-#define TEXT_STRENGTH_ASU NS_LITERAL_CSTRING("asu")
-#define TEXT_STRENGTH_DBM NS_LITERAL_CSTRING("signalStrength")
-#define TEXT_REGISTERED NS_LITERAL_CSTRING("serving")
-#define TEXT_TIMEING_ADVANCE NS_LITERAL_CSTRING("timingAdvance")
-
-template <class T> void
-ExtractCommonNonCDMACellInfoItems(nsCOMPtr<T>& cell, nsDataHashtable<nsCStringHashKey, int32_t>& info)
-{
- int32_t mcc, mnc, cid, sig;
-
- cell->GetMcc(&mcc);
- cell->GetMnc(&mnc);
- cell->GetCid(&cid);
- cell->GetSignalStrength(&sig);
-
- info.Put(TEXT_MCC, mcc);
- info.Put(TEXT_MNC, mnc);
- info.Put(TEXT_CID, cid);
- info.Put(TEXT_STRENGTH_ASU, sig);
-}
-
-void
-StumblerInfo::CellNetworkInfoToString(nsACString& aCellDesc)
-{
- aCellDesc += "\"cellTowers\": [";
-
- for (uint32_t idx = 0; idx < mCellInfo.Length() ; idx++) {
- const char* radioType = 0;
- int32_t type;
- mCellInfo[idx]->GetType(&type);
- bool registered;
- mCellInfo[idx]->GetRegistered(&registered);
- if (idx) {
- aCellDesc += ",{";
- } else {
- aCellDesc += "{";
- }
-
- STUMBLER_DBG("type=%d\n", type);
-
- nsDataHashtable<nsCStringHashKey, int32_t> info;
- info.Put(TEXT_REGISTERED, registered);
-
- if(type == nsICellInfo::CELL_INFO_TYPE_GSM) {
- radioType = "gsm";
- nsCOMPtr<nsIGsmCellInfo> gsmCellInfo = do_QueryInterface(mCellInfo[idx]);
- ExtractCommonNonCDMACellInfoItems(gsmCellInfo, info);
- int32_t lac;
- gsmCellInfo->GetLac(&lac);
- info.Put(TEXT_LAC, lac);
- } else if (type == nsICellInfo::CELL_INFO_TYPE_WCDMA) {
- radioType = "wcdma";
- nsCOMPtr<nsIWcdmaCellInfo> wcdmaCellInfo = do_QueryInterface(mCellInfo[idx]);
- ExtractCommonNonCDMACellInfoItems(wcdmaCellInfo, info);
- int32_t lac, psc;
- wcdmaCellInfo->GetLac(&lac);
- wcdmaCellInfo->GetPsc(&psc);
- info.Put(TEXT_LAC, lac);
- info.Put(TEXT_PSC, psc);
- } else if (type == nsICellInfo::CELL_INFO_TYPE_CDMA) {
- radioType = "cdma";
- nsCOMPtr<nsICdmaCellInfo> cdmaCellInfo = do_QueryInterface(mCellInfo[idx]);
- int32_t mnc, lac, cid, sig;
- cdmaCellInfo->GetSystemId(&mnc);
- cdmaCellInfo->GetNetworkId(&lac);
- cdmaCellInfo->GetBaseStationId(&cid);
- info.Put(TEXT_MNC, mnc);
- info.Put(TEXT_LAC, lac);
- info.Put(TEXT_CID, cid);
-
- cdmaCellInfo->GetEvdoDbm(&sig);
- if (sig < 0 || sig == nsICellInfo::UNKNOWN_VALUE) {
- cdmaCellInfo->GetCdmaDbm(&sig);
- }
- if (sig > -1 && sig != nsICellInfo::UNKNOWN_VALUE) {
- sig *= -1;
- info.Put(TEXT_STRENGTH_DBM, sig);
- }
- } else if (type == nsICellInfo::CELL_INFO_TYPE_LTE) {
- radioType = "lte";
- nsCOMPtr<nsILteCellInfo> lteCellInfo = do_QueryInterface(mCellInfo[idx]);
- ExtractCommonNonCDMACellInfoItems(lteCellInfo, info);
- int32_t lac, timingAdvance, pcid, rsrp;
- lteCellInfo->GetTac(&lac);
- lteCellInfo->GetTimingAdvance(&timingAdvance);
- lteCellInfo->GetPcid(&pcid);
- lteCellInfo->GetRsrp(&rsrp);
- info.Put(TEXT_LAC, lac);
- info.Put(TEXT_TIMEING_ADVANCE, timingAdvance);
- info.Put(TEXT_PSC, pcid);
- if (rsrp != nsICellInfo::UNKNOWN_VALUE) {
- info.Put(TEXT_STRENGTH_DBM, rsrp * -1);
- }
- }
-
- aCellDesc += nsPrintfCString("\"%s\":\"%s\"", TEXT_RADIOTYPE.get(), radioType);
- for (auto it = info.Iter(); !it.Done(); it.Next()) {
- const nsACString& key = it.Key();
- int32_t value = it.UserData();
- if (value != nsICellInfo::UNKNOWN_VALUE) {
- aCellDesc += nsPrintfCString(",\"%s\":%d", key.BeginReading(), value);
- }
- }
-
- aCellDesc += "}";
- }
- aCellDesc += "]";
-}
-
-void
-StumblerInfo::DumpStumblerInfo()
-{
- if (!mIsWifiInfoResponseReceived || mCellInfoResponsesReceived != mCellInfoResponsesExpected) {
- STUMBLER_DBG("CellInfoReceived=%d (Expected=%d), WifiInfoResponseReceived=%d\n",
- mCellInfoResponsesReceived, mCellInfoResponsesExpected, mIsWifiInfoResponseReceived);
- return;
- }
- mIsWifiInfoResponseReceived = false;
- mCellInfoResponsesReceived = 0;
-
- nsAutoCString desc;
- nsresult rv = LocationInfoToString(desc);
- if (NS_WARN_IF(NS_FAILED(rv))) {
- STUMBLER_ERR("LocationInfoToString failed, skip this dump");
- return;
- }
-
- CellNetworkInfoToString(desc);
- desc += mWifiDesc;
-
- STUMBLER_DBG("dispatch write event to thread\n");
- nsCOMPtr<nsIEventTarget> target = do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID);
- MOZ_ASSERT(target);
-
- nsCOMPtr<nsIRunnable> event = new WriteStumbleOnThread(desc);
- target->Dispatch(event, NS_DISPATCH_NORMAL);
-}
-
-NS_IMETHODIMP
-StumblerInfo::NotifyGetCellInfoList(uint32_t count, nsICellInfo** aCellInfos)
-{
- MOZ_ASSERT(NS_IsMainThread());
- STUMBLER_DBG("There are %d cellinfo in the result\n", count);
-
- for (uint32_t i = 0; i < count; i++) {
- mCellInfo.AppendElement(aCellInfos[i]);
- }
- mCellInfoResponsesReceived++;
- DumpStumblerInfo();
- return NS_OK;
-}
-
-NS_IMETHODIMP StumblerInfo::NotifyGetCellInfoListFailed(const nsAString& error)
-{
- MOZ_ASSERT(NS_IsMainThread());
- mCellInfoResponsesReceived++;
- STUMBLER_ERR("NotifyGetCellInfoListFailedm CellInfoReadyNum=%d, mCellInfoResponsesExpected=%d, mIsWifiInfoResponseReceived=%d",
- mCellInfoResponsesReceived, mCellInfoResponsesExpected, mIsWifiInfoResponseReceived);
- DumpStumblerInfo();
- return NS_OK;
-}
-
-NS_IMETHODIMP
-StumblerInfo::Onready(uint32_t count, nsIWifiScanResult** results)
-{
- MOZ_ASSERT(NS_IsMainThread());
- STUMBLER_DBG("There are %d wifiAPinfo in the result\n",count);
-
- mWifiDesc += ",\"wifiAccessPoints\": [";
- bool firstItem = true;
- for (uint32_t i = 0 ; i < count ; i++) {
- nsString ssid;
- results[i]->GetSsid(ssid);
- if (ssid.IsEmpty()) {
- STUMBLER_DBG("no ssid, skip this AP\n");
- continue;
- }
-
- if (ssid.Length() >= 6) {
- if (StringEndsWith(ssid, NS_LITERAL_STRING("_nomap"))) {
- STUMBLER_DBG("end with _nomap. skip this AP(ssid :%s)\n", ssid.get());
- continue;
- }
- }
-
- if (firstItem) {
- mWifiDesc += "{";
- firstItem = false;
- } else {
- mWifiDesc += ",{";
- }
-
- // mac address
- nsString bssid;
- results[i]->GetBssid(bssid);
- // 00:00:00:00:00:00 --> 000000000000
- bssid.StripChars(":");
- mWifiDesc += "\"macAddress\":\"";
- mWifiDesc += NS_ConvertUTF16toUTF8(bssid);
-
- uint32_t signal;
- results[i]->GetSignalStrength(&signal);
- mWifiDesc += "\",\"signalStrength\":";
- mWifiDesc.AppendInt(signal);
-
- mWifiDesc += "}";
- }
- mWifiDesc += "]";
-
- mIsWifiInfoResponseReceived = true;
- DumpStumblerInfo();
- return NS_OK;
-}
-
-NS_IMETHODIMP
-StumblerInfo::Onfailure()
-{
- MOZ_ASSERT(NS_IsMainThread());
- STUMBLER_ERR("GetWifiScanResults Onfailure\n");
- mIsWifiInfoResponseReceived = true;
- DumpStumblerInfo();
- return NS_OK;
-}
-
diff --git a/dom/system/gonk/mozstumbler/MozStumbler.h b/dom/system/gonk/mozstumbler/MozStumbler.h
deleted file mode 100644
index 41ee4e5e14..0000000000
--- a/dom/system/gonk/mozstumbler/MozStumbler.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
-/* 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/. */
-
-#ifndef mozilla_system_mozstumbler_h__
-#define mozilla_system_mozstumbler_h__
-
-#include "nsIDOMEventTarget.h"
-#include "nsICellInfo.h"
-#include "nsIWifi.h"
-
-#define STUMBLE_INTERVAL_MS 3000
-
-class nsGeoPosition;
-
-void MozStumble(nsGeoPosition* position);
-
-class StumblerInfo final : public nsICellInfoListCallback,
- public nsIWifiScanResultsReady
-{
-public:
- NS_DECL_THREADSAFE_ISUPPORTS
- NS_DECL_NSICELLINFOLISTCALLBACK
- NS_DECL_NSIWIFISCANRESULTSREADY
-
- explicit StumblerInfo(nsGeoPosition* position)
- : mPosition(position), mCellInfoResponsesExpected(0), mCellInfoResponsesReceived(0), mIsWifiInfoResponseReceived(0)
- {}
- void SetWifiInfoResponseReceived();
- void SetCellInfoResponsesExpected(uint8_t count);
-
-private:
- ~StumblerInfo() {}
- void DumpStumblerInfo();
- nsresult LocationInfoToString(nsACString& aLocDesc);
- void CellNetworkInfoToString(nsACString& aCellDesc);
- nsTArray<RefPtr<nsICellInfo>> mCellInfo;
- nsCString mWifiDesc;
- RefPtr<nsGeoPosition> mPosition;
- int mCellInfoResponsesExpected;
- int mCellInfoResponsesReceived;
- bool mIsWifiInfoResponseReceived;
-};
-#endif // mozilla_system_mozstumbler_h__
-
diff --git a/dom/system/gonk/mozstumbler/StumblerLogging.cpp b/dom/system/gonk/mozstumbler/StumblerLogging.cpp
deleted file mode 100644
index acf23b3b19..0000000000
--- a/dom/system/gonk/mozstumbler/StumblerLogging.cpp
+++ /dev/null
@@ -1,13 +0,0 @@
-/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
-/* 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/. */
-
-#include "StumblerLogging.h"
-
-mozilla::LogModule* GetLog()
-{
- static mozilla::LazyLogModule log("mozstumbler");
- return log;
-}
diff --git a/dom/system/gonk/mozstumbler/StumblerLogging.h b/dom/system/gonk/mozstumbler/StumblerLogging.h
deleted file mode 100644
index 038f44f8fd..0000000000
--- a/dom/system/gonk/mozstumbler/StumblerLogging.h
+++ /dev/null
@@ -1,18 +0,0 @@
-/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
-/* 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/. */
-
-#ifndef STUMBLERLOGGING_H
-#define STUMBLERLOGGING_H
-
-#include "mozilla/Logging.h"
-
-mozilla::LogModule* GetLog();
-
-#define STUMBLER_DBG(arg, ...) MOZ_LOG(GetLog(), mozilla::LogLevel::Debug, ("STUMBLER - %s: " arg, __func__, ##__VA_ARGS__))
-#define STUMBLER_LOG(arg, ...) MOZ_LOG(GetLog(), mozilla::LogLevel::Info, ("STUMBLER - %s: " arg, __func__, ##__VA_ARGS__))
-#define STUMBLER_ERR(arg, ...) MOZ_LOG(GetLog(), mozilla::LogLevel::Error, ("STUMBLER -%s: " arg, __func__, ##__VA_ARGS__))
-
-#endif
diff --git a/dom/system/gonk/mozstumbler/UploadStumbleRunnable.cpp b/dom/system/gonk/mozstumbler/UploadStumbleRunnable.cpp
deleted file mode 100644
index d97aa97123..0000000000
--- a/dom/system/gonk/mozstumbler/UploadStumbleRunnable.cpp
+++ /dev/null
@@ -1,151 +0,0 @@
-/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
-/* 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/. */
-
-#include "UploadStumbleRunnable.h"
-#include "StumblerLogging.h"
-#include "mozilla/dom/Event.h"
-#include "nsIInputStream.h"
-#include "nsIScriptSecurityManager.h"
-#include "nsIURLFormatter.h"
-#include "nsIXMLHttpRequest.h"
-#include "nsNetUtil.h"
-#include "nsVariant.h"
-
-UploadStumbleRunnable::UploadStumbleRunnable(nsIInputStream* aUploadData)
-: mUploadInputStream(aUploadData)
-{
-}
-
-NS_IMETHODIMP
-UploadStumbleRunnable::Run()
-{
- MOZ_ASSERT(NS_IsMainThread());
- nsresult rv = Upload();
- if (NS_FAILED(rv)) {
- WriteStumbleOnThread::UploadEnded(false);
- }
- return NS_OK;
-}
-
-nsresult
-UploadStumbleRunnable::Upload()
-{
- nsresult rv;
- RefPtr<nsVariant> variant = new nsVariant();
-
- rv = variant->SetAsISupports(mUploadInputStream);
- NS_ENSURE_SUCCESS(rv, rv);
-
- nsCOMPtr<nsIXMLHttpRequest> xhr = do_CreateInstance(NS_XMLHTTPREQUEST_CONTRACTID, &rv);
- NS_ENSURE_SUCCESS(rv, rv);
-
- nsCOMPtr<nsIScriptSecurityManager> secman =
- do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv);
- NS_ENSURE_SUCCESS(rv, rv);
-
- nsCOMPtr<nsIPrincipal> systemPrincipal;
- rv = secman->GetSystemPrincipal(getter_AddRefs(systemPrincipal));
- NS_ENSURE_SUCCESS(rv, rv);
-
- rv = xhr->Init(systemPrincipal, nullptr, nullptr, nullptr);
- NS_ENSURE_SUCCESS(rv, rv);
-
- nsCOMPtr<nsIURLFormatter> formatter =
- do_CreateInstance("@mozilla.org/toolkit/URLFormatterService;1", &rv);
- NS_ENSURE_SUCCESS(rv, rv);
- nsString url;
- rv = formatter->FormatURLPref(NS_LITERAL_STRING("geo.stumbler.url"), url);
- NS_ENSURE_SUCCESS(rv, rv);
-
- rv = xhr->Open(NS_LITERAL_CSTRING("POST"), NS_ConvertUTF16toUTF8(url), false, EmptyString(), EmptyString());
- NS_ENSURE_SUCCESS(rv, rv);
-
- xhr->SetRequestHeader(NS_LITERAL_CSTRING("Content-Type"), NS_LITERAL_CSTRING("gzip"));
- xhr->SetMozBackgroundRequest(true);
- // 60s timeout
- xhr->SetTimeout(60 * 1000);
-
- nsCOMPtr<EventTarget> target(do_QueryInterface(xhr));
- RefPtr<nsIDOMEventListener> listener = new UploadEventListener(xhr);
-
- const char* const sEventStrings[] = {
- // nsIXMLHttpRequestEventTarget event types
- "abort",
- "error",
- "load",
- "timeout"
- };
-
- for (uint32_t index = 0; index < MOZ_ARRAY_LENGTH(sEventStrings); index++) {
- nsAutoString eventType = NS_ConvertASCIItoUTF16(sEventStrings[index]);
- rv = target->AddEventListener(eventType, listener, false);
- NS_ENSURE_SUCCESS(rv, rv);
- }
-
- rv = xhr->Send(variant);
- NS_ENSURE_SUCCESS(rv, rv);
-
- return NS_OK;
-}
-
-NS_IMPL_ISUPPORTS(UploadEventListener, nsIDOMEventListener)
-
-UploadEventListener::UploadEventListener(nsIXMLHttpRequest* aXHR)
-: mXHR(aXHR)
-{
-}
-
-NS_IMETHODIMP
-UploadEventListener::HandleEvent(nsIDOMEvent* aEvent)
-{
- nsString type;
- if (NS_FAILED(aEvent->GetType(type))) {
- STUMBLER_ERR("Failed to get event type");
- WriteStumbleOnThread::UploadEnded(false);
- return NS_ERROR_FAILURE;
- }
-
- if (type.EqualsLiteral("load")) {
- STUMBLER_DBG("Got load Event\n");
- } else if (type.EqualsLiteral("error") && mXHR) {
- STUMBLER_ERR("Upload Error");
- } else {
- STUMBLER_DBG("Receive %s Event", NS_ConvertUTF16toUTF8(type).get());
- }
-
- uint32_t statusCode = 0;
- bool doDelete = false;
- if (!mXHR) {
- return NS_OK;
- }
- nsresult rv = mXHR->GetStatus(&statusCode);
- if (NS_SUCCEEDED(rv)) {
- STUMBLER_DBG("statuscode %d \n", statusCode);
- }
-
- if (200 == statusCode || 400 == statusCode) {
- doDelete = true;
- }
-
- WriteStumbleOnThread::UploadEnded(doDelete);
- nsCOMPtr<EventTarget> target(do_QueryInterface(mXHR));
-
- const char* const sEventStrings[] = {
- // nsIXMLHttpRequestEventTarget event types
- "abort",
- "error",
- "load",
- "timeout"
- };
-
- for (uint32_t index = 0; index < MOZ_ARRAY_LENGTH(sEventStrings); index++) {
- nsAutoString eventType = NS_ConvertASCIItoUTF16(sEventStrings[index]);
- rv = target->RemoveEventListener(eventType, this, false);
- }
-
- mXHR = nullptr;
- return NS_OK;
-}
diff --git a/dom/system/gonk/mozstumbler/UploadStumbleRunnable.h b/dom/system/gonk/mozstumbler/UploadStumbleRunnable.h
deleted file mode 100644
index 462665a869..0000000000
--- a/dom/system/gonk/mozstumbler/UploadStumbleRunnable.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
-/* 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/. */
-
-
-#ifndef UPLOADSTUMBLERUNNABLE_H
-#define UPLOADSTUMBLERUNNABLE_H
-
-#include "nsIDOMEventListener.h"
-
-class nsIXMLHttpRequest;
-class nsIInputStream;
-
-/*
- This runnable is managed by WriteStumbleOnThread only, see that class
- for how this is scheduled.
- */
-class UploadStumbleRunnable final : public Runnable
-{
-public:
- explicit UploadStumbleRunnable(nsIInputStream* aUploadInputStream);
-
- NS_IMETHOD Run() override;
-private:
- virtual ~UploadStumbleRunnable() {}
- nsCOMPtr<nsIInputStream> mUploadInputStream;
- nsresult Upload();
-};
-
-
-class UploadEventListener : public nsIDOMEventListener
-{
-public:
- UploadEventListener(nsIXMLHttpRequest* aXHR);
-
- NS_DECL_ISUPPORTS
- NS_DECL_NSIDOMEVENTLISTENER
-
-protected:
- virtual ~UploadEventListener() {}
- nsCOMPtr<nsIXMLHttpRequest> mXHR;
-};
-
-#endif
diff --git a/dom/system/gonk/mozstumbler/WriteStumbleOnThread.cpp b/dom/system/gonk/mozstumbler/WriteStumbleOnThread.cpp
deleted file mode 100644
index e58e771c4d..0000000000
--- a/dom/system/gonk/mozstumbler/WriteStumbleOnThread.cpp
+++ /dev/null
@@ -1,321 +0,0 @@
-/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
-/* 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/. */
-
-#include "WriteStumbleOnThread.h"
-#include "StumblerLogging.h"
-#include "UploadStumbleRunnable.h"
-#include "nsDumpUtils.h"
-#include "nsGZFileWriter.h"
-#include "nsIFileStreams.h"
-#include "nsIInputStream.h"
-#include "nsPrintfCString.h"
-
-#define MAXFILESIZE_KB (15 * 1024)
-#define ONEDAY_IN_MSEC (24 * 60 * 60 * 1000)
-#define MAX_UPLOAD_ATTEMPTS 20
-
-mozilla::Atomic<bool> WriteStumbleOnThread::sIsFileWaitingForUpload(false);
-mozilla::Atomic<bool> WriteStumbleOnThread::sIsAlreadyRunning(false);
-WriteStumbleOnThread::UploadFreqGuard WriteStumbleOnThread::sUploadFreqGuard = {0};
-
-#define FILENAME_INPROGRESS NS_LITERAL_CSTRING("stumbles.json.gz")
-#define FILENAME_COMPLETED NS_LITERAL_CSTRING("stumbles.done.json.gz")
-#define OUTPUT_DIR NS_LITERAL_CSTRING("mozstumbler")
-
-class DeleteRunnable : public Runnable
-{
- public:
- DeleteRunnable() {}
-
- NS_IMETHOD
- Run() override
- {
- nsCOMPtr<nsIFile> tmpFile;
- nsresult rv = nsDumpUtils::OpenTempFile(FILENAME_COMPLETED,
- getter_AddRefs(tmpFile),
- OUTPUT_DIR,
- nsDumpUtils::CREATE);
- if (NS_SUCCEEDED(rv)) {
- tmpFile->Remove(true);
- }
- // critically, this sets this flag to false so writing can happen again
- WriteStumbleOnThread::sIsAlreadyRunning = false;
- WriteStumbleOnThread::sIsFileWaitingForUpload = false;
- return NS_OK;
- }
-
- private:
- ~DeleteRunnable() {}
-};
-
-bool
-WriteStumbleOnThread::IsFileWaitingForUpload()
-{
- return sIsFileWaitingForUpload;
-}
-
-void
-WriteStumbleOnThread::UploadEnded(bool deleteUploadFile)
-{
- if (!deleteUploadFile) {
- sIsAlreadyRunning = false;
- return;
- }
-
- nsCOMPtr<nsIEventTarget> target = do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID);
- MOZ_ASSERT(target);
- nsCOMPtr<nsIRunnable> event = new DeleteRunnable();
- target->Dispatch(event, NS_DISPATCH_NORMAL);
-}
-
-void
-WriteStumbleOnThread::WriteJSON(Partition aPart)
-{
- MOZ_ASSERT(!NS_IsMainThread());
-
- nsCOMPtr<nsIFile> tmpFile;
- nsresult rv;
- rv = nsDumpUtils::OpenTempFile(FILENAME_INPROGRESS, getter_AddRefs(tmpFile),
- OUTPUT_DIR, nsDumpUtils::CREATE);
- if (NS_WARN_IF(NS_FAILED(rv))) {
- STUMBLER_ERR("Open a file for stumble failed");
- return;
- }
-
- RefPtr<nsGZFileWriter> gzWriter = new nsGZFileWriter(nsGZFileWriter::Append);
- rv = gzWriter->Init(tmpFile);
- if (NS_WARN_IF(NS_FAILED(rv))) {
- STUMBLER_ERR("gzWriter init failed");
- return;
- }
-
- /*
- The json format is like below.
- {items:[
- {item},
- {item},
- {item}
- ]}
- */
-
- // Need to add "]}" after the last item
- if (aPart == Partition::End) {
- rv = gzWriter->Write("]}");
- if (NS_WARN_IF(NS_FAILED(rv))) {
- STUMBLER_ERR("gzWriter Write failed");
- }
-
- rv = gzWriter->Finish();
- if (NS_WARN_IF(NS_FAILED(rv))) {
- STUMBLER_ERR("ostream finish failed");
- }
-
- nsCOMPtr<nsIFile> targetFile;
- nsresult rv = nsDumpUtils::OpenTempFile(FILENAME_COMPLETED, getter_AddRefs(targetFile),
- OUTPUT_DIR, nsDumpUtils::CREATE);
- nsAutoString targetFilename;
- rv = targetFile->GetLeafName(targetFilename);
- if (NS_WARN_IF(NS_FAILED(rv))) {
- STUMBLER_ERR("Get Filename failed");
- return;
- }
- rv = targetFile->Remove(true);
- if (NS_WARN_IF(NS_FAILED(rv))) {
- STUMBLER_ERR("Remove File failed");
- return;
- }
- // Rename tmpfile
- rv = tmpFile->MoveTo(/* directory */ nullptr, targetFilename);
- if (NS_WARN_IF(NS_FAILED(rv))) {
- STUMBLER_ERR("Rename File failed");
- return;
- }
- return;
- }
-
- // Need to add "{items:[" before the first item
- if (aPart == Partition::Begining) {
- rv = gzWriter->Write("{\"items\":[{");
- if (NS_WARN_IF(NS_FAILED(rv))) {
- STUMBLER_ERR("ostream write begining failed");
- }
- } else if (aPart == Partition::Middle) {
- rv = gzWriter->Write(",{");
- if (NS_WARN_IF(NS_FAILED(rv))) {
- STUMBLER_ERR("ostream write middle failed");
- }
- }
- rv = gzWriter->Write(mDesc.get());
- if (NS_WARN_IF(NS_FAILED(rv))) {
- STUMBLER_ERR("ostream write mDesc failed");
- }
- // one item is ended with '}' (e.g. {item})
- rv = gzWriter->Write("}");
- if (NS_WARN_IF(NS_FAILED(rv))) {
- STUMBLER_ERR("ostream write end failed");
- }
-
- rv = gzWriter->Finish();
- if (NS_WARN_IF(NS_FAILED(rv))) {
- STUMBLER_ERR("ostream finish failed");
- }
-
- // check if it is the end of this file
- int64_t fileSize = 0;
- rv = tmpFile->GetFileSize(&fileSize);
- if (NS_WARN_IF(NS_FAILED(rv))) {
- STUMBLER_ERR("GetFileSize failed");
- return;
- }
- if (fileSize >= MAXFILESIZE_KB) {
- WriteJSON(Partition::End);
- return;
- }
-}
-
-WriteStumbleOnThread::Partition
-WriteStumbleOnThread::GetWritePosition()
-{
- MOZ_ASSERT(!NS_IsMainThread());
-
- nsCOMPtr<nsIFile> tmpFile;
- nsresult rv = nsDumpUtils::OpenTempFile(FILENAME_INPROGRESS, getter_AddRefs(tmpFile),
- OUTPUT_DIR, nsDumpUtils::CREATE);
- if (NS_WARN_IF(NS_FAILED(rv))) {
- STUMBLER_ERR("Open a file for stumble failed");
- return Partition::Unknown;
- }
-
- int64_t fileSize = 0;
- rv = tmpFile->GetFileSize(&fileSize);
- if (NS_WARN_IF(NS_FAILED(rv))) {
- STUMBLER_ERR("GetFileSize failed");
- return Partition::Unknown;
- }
-
- if (fileSize == 0) {
- return Partition::Begining;
- } else if (fileSize >= MAXFILESIZE_KB) {
- return Partition::End;
- } else {
- return Partition::Middle;
- }
-}
-
-NS_IMETHODIMP
-WriteStumbleOnThread::Run()
-{
- MOZ_ASSERT(!NS_IsMainThread());
-
- bool b = sIsAlreadyRunning.exchange(true);
- if (b) {
- return NS_OK;
- }
-
- UploadFileStatus status = GetUploadFileStatus();
-
- if (UploadFileStatus::NoFile != status) {
- if (UploadFileStatus::ExistsAndReadyToUpload == status) {
- sIsFileWaitingForUpload = true;
- Upload();
- return NS_OK;
- }
- } else {
- Partition partition = GetWritePosition();
- if (partition == Partition::Unknown) {
- STUMBLER_ERR("GetWritePosition failed, skip once");
- } else {
- WriteJSON(partition);
- }
- }
-
- sIsFileWaitingForUpload = false;
- sIsAlreadyRunning = false;
- return NS_OK;
-}
-
-
-/*
- If the upload file exists, then check if it is one day old.
- • if it is a day old -> ExistsAndReadyToUpload
- • if it is less than the current day old -> Exists
- • otherwise -> NoFile
-
- The Exists case means that the upload and the stumbling is rate limited
- per-day to the size of the one file.
- */
-WriteStumbleOnThread::UploadFileStatus
-WriteStumbleOnThread::GetUploadFileStatus()
-{
- nsCOMPtr<nsIFile> tmpFile;
- nsresult rv = nsDumpUtils::OpenTempFile(FILENAME_COMPLETED, getter_AddRefs(tmpFile),
- OUTPUT_DIR, nsDumpUtils::CREATE);
- int64_t fileSize;
- rv = tmpFile->GetFileSize(&fileSize);
- if (NS_WARN_IF(NS_FAILED(rv))) {
- STUMBLER_ERR("GetFileSize failed");
- return UploadFileStatus::NoFile;
- }
- if (fileSize <= 0) {
- tmpFile->Remove(true);
- return UploadFileStatus::NoFile;
- }
-
- PRTime lastModifiedTime;
- tmpFile->GetLastModifiedTime(&lastModifiedTime);
- if ((PR_Now() / PR_USEC_PER_MSEC) - lastModifiedTime >= ONEDAY_IN_MSEC) {
- return UploadFileStatus::ExistsAndReadyToUpload;
- }
- return UploadFileStatus::Exists;
-}
-
-void
-WriteStumbleOnThread::Upload()
-{
- MOZ_ASSERT(!NS_IsMainThread());
-
- time_t seconds = time(0);
- int day = seconds / (60 * 60 * 24);
-
- if (sUploadFreqGuard.daySinceEpoch < day) {
- sUploadFreqGuard.daySinceEpoch = day;
- sUploadFreqGuard.attempts = 0;
- }
-
- sUploadFreqGuard.attempts++;
- if (sUploadFreqGuard.attempts > MAX_UPLOAD_ATTEMPTS) {
- STUMBLER_ERR("Too many upload attempts today");
- sIsAlreadyRunning = false;
- return;
- }
-
- nsCOMPtr<nsIFile> tmpFile;
- nsresult rv = nsDumpUtils::OpenTempFile(FILENAME_COMPLETED, getter_AddRefs(tmpFile),
- OUTPUT_DIR, nsDumpUtils::CREATE);
- int64_t fileSize;
- rv = tmpFile->GetFileSize(&fileSize);
- if (NS_WARN_IF(NS_FAILED(rv))) {
- STUMBLER_ERR("GetFileSize failed");
- sIsAlreadyRunning = false;
- return;
- }
-
- if (fileSize <= 0) {
- sIsAlreadyRunning = false;
- return;
- }
-
- // prepare json into nsIInputStream
- nsCOMPtr<nsIInputStream> inStream;
- rv = NS_NewLocalFileInputStream(getter_AddRefs(inStream), tmpFile);
- if (NS_FAILED(rv)) {
- sIsAlreadyRunning = false;
- return;
- }
-
- RefPtr<nsIRunnable> uploader = new UploadStumbleRunnable(inStream);
- NS_DispatchToMainThread(uploader);
-}
diff --git a/dom/system/gonk/mozstumbler/WriteStumbleOnThread.h b/dom/system/gonk/mozstumbler/WriteStumbleOnThread.h
deleted file mode 100644
index 104cf9bdd8..0000000000
--- a/dom/system/gonk/mozstumbler/WriteStumbleOnThread.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
-/* 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/. */
-
-#ifndef WriteStumbleOnThread_H
-#define WriteStumbleOnThread_H
-
-#include "mozilla/Atomics.h"
-
-class DeleteRunnable;
-
-/*
- This class is the entry point to stumbling, in that it
- receives the location+cell+wifi string and writes it
- to disk, or instead, it calls UploadStumbleRunnable
- to upload the data.
-
- Writes will happen until the file is a max size, then stop.
- Uploads will happen only when the file is one day old.
- The purpose of these decisions is to have very simple rate-limiting
- on the writes, as well as the uploads.
-
- There is only one file active; it is either being used for writing,
- or for uploading. If the file is ready for uploading, no further
- writes will take place until this file has been uploaded.
- This can mean writing might not take place for days until the uploaded
- file is processed. This is correct by-design.
-
- A notable limitation is that the upload is triggered by a location event,
- this is used as an arbitrary and simple trigger. In future, there are
- better events that can be used, such as detecting network activity.
-
- This thread is guarded so that only one instance is active (see the
- mozilla::Atomics used for this).
- */
-class WriteStumbleOnThread : public mozilla::Runnable
-{
-public:
- explicit WriteStumbleOnThread(const nsCString& aDesc)
- : mDesc(aDesc)
- {}
-
- NS_IMETHOD Run() override;
-
- static void UploadEnded(bool deleteUploadFile);
-
- // Used externally to determine if cell+wifi scans should happen
- // (returns false for that case).
- static bool IsFileWaitingForUpload();
-
-private:
- friend class DeleteRunnable;
-
- enum class Partition {
- Begining,
- Middle,
- End,
- Unknown
- };
-
- enum class UploadFileStatus {
- NoFile, Exists, ExistsAndReadyToUpload
- };
-
- ~WriteStumbleOnThread() {}
-
- Partition GetWritePosition();
- UploadFileStatus GetUploadFileStatus();
- void WriteJSON(Partition aPart);
- void Upload();
-
- nsCString mDesc;
-
- // Only run one instance of this
- static mozilla::Atomic<bool> sIsAlreadyRunning;
-
- static mozilla::Atomic<bool> sIsFileWaitingForUpload;
-
- // Limit the upload attempts per day. If the device is rebooted
- // this resets the allowed attempts, which is acceptable.
- struct UploadFreqGuard {
- int attempts;
- int daySinceEpoch;
- };
- static UploadFreqGuard sUploadFreqGuard;
-
-};
-
-#endif
diff --git a/dom/system/gonk/nsIAudioManager.idl b/dom/system/gonk/nsIAudioManager.idl
deleted file mode 100644
index c2eb62b213..0000000000
--- a/dom/system/gonk/nsIAudioManager.idl
+++ /dev/null
@@ -1,58 +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, builtinclass, uuid(df31c280-1ef1-11e5-867f-0800200c9a66)]
-interface nsIAudioManager : nsISupports
-{
- /**
- * Microphone muted?
- */
- attribute boolean microphoneMuted;
-
- /**
- * Set the phone's audio mode.
- */
- const long PHONE_STATE_INVALID = -2;
- const long PHONE_STATE_CURRENT = -1;
- const long PHONE_STATE_NORMAL = 0;
- const long PHONE_STATE_RINGTONE = 1;
- const long PHONE_STATE_IN_CALL = 2;
- const long PHONE_STATE_IN_COMMUNICATION = 3;
-
- attribute long phoneState;
-
- /**
- * Configure a particular device ("force") to be used for one of the uses
- * (communication, media playback, etc.)
- */
- const long FORCE_NONE = 0; // the default
- const long FORCE_SPEAKER = 1;
- const long FORCE_HEADPHONES = 2;
- const long FORCE_BT_SCO = 3;
- const long FORCE_BT_A2DP = 4;
- const long FORCE_WIRED_ACCESSORY = 5;
- const long FORCE_BT_CAR_DOCK = 6;
- const long FORCE_BT_DESK_DOCK = 7;
- const long FORCE_ANALOG_DOCK = 8;
- const long FORCE_DIGITAL_DOCK = 9;
- const long FORCE_NO_BT_A2DP = 10;
- const long USE_COMMUNICATION = 0;
- const long USE_MEDIA = 1;
- const long USE_RECORD = 2;
- const long USE_DOCK = 3;
-
- void setForceForUse(in long usage, in long force);
- long getForceForUse(in long usage);
-
- /**
- * These functions would be used when we enable the new volume control API
- * (mozAudioChannelManager). The range of volume index is from 0 to N.
- * More details on : https://gist.github.com/evanxd/41d8e2d91c5201a42bfa
- */
- void setAudioChannelVolume(in unsigned long channel, in unsigned long index);
- unsigned long getAudioChannelVolume(in unsigned long channel);
- unsigned long getMaxAudioChannelVolume(in unsigned long channel);
-};
diff --git a/dom/system/gonk/nsIDataCallInterfaceService.idl b/dom/system/gonk/nsIDataCallInterfaceService.idl
deleted file mode 100644
index c387879fa0..0000000000
--- a/dom/system/gonk/nsIDataCallInterfaceService.idl
+++ /dev/null
@@ -1,268 +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(6b66446a-7000-438f-8e1b-b56b4cbf4fa9)]
-interface nsIDataCall : nsISupports
-{
- /**
- * Data call fail cause. One of the nsIDataCallInterface.DATACALL_FAIL_*
- * values.
- */
- readonly attribute long failCause;
-
- /**
- * If failCause != nsIDataCallInterface.DATACALL_FAIL_NONE, this field
- * indicates the suggested retry back-off timer. The unit is milliseconds.
- */
- readonly attribute long suggestedRetryTime;
-
- /**
- * Context ID, uniquely identifies this call.
- */
- readonly attribute long cid;
-
- /**
- * Data call network state. One of the nsIDataCallInterface.DATACALL_STATE_*
- * values.
- */
- readonly attribute long active;
-
- /**
- * Data call connection type. One of the
- * nsIDataCallInterface.DATACALL_PDP_TYPE_* values.
- */
- readonly attribute long pdpType;
-
- /**
- * The network interface name.
- */
- readonly attribute DOMString ifname;
-
- /**
- * A space-delimited list of addresses with optional "/" prefix length.
- */
- readonly attribute DOMString addresses;
-
- /**
- * A space-delimited list of DNS server addresses.
- */
- readonly attribute DOMString dnses;
-
- /**
- * A space-delimited list of default gateway addresses.
- */
- readonly attribute DOMString gateways;
-
- /**
- * A space-delimited list of Proxy Call State Control Function addresses for
- * IMS client.
- */
- readonly attribute DOMString pcscf;
-
- /**
- * MTU received from network, -1 if not set or invalid.
- */
- readonly attribute long mtu;
-};
-
-[scriptable, uuid(e119c54b-9354-4ad6-a1ee-18608bde9320)]
-interface nsIDataCallInterfaceListener : nsISupports
-{
- /**
- * Notify data call interface listeners about unsolicited data call state
- * changes.
- */
- void notifyDataCallListChanged(in uint32_t count,
- [array, size_is(count)] in nsIDataCall
- dataCalls);
-};
-
-[scriptable, uuid(db0b640a-3b3a-4f48-84dc-256e176876c2)]
-interface nsIDataCallCallback : nsISupports
-{
- /**
- * Called when setupDataCall() returns succesfully.
- */
- void notifySetupDataCallSuccess(in nsIDataCall dataCall);
-
- /**
- * Called when getDataCallList() returns succesfully.
- */
- void notifyGetDataCallListSuccess(in uint32_t count,
- [array, size_is(count)] in nsIDataCall
- dataCalls);
- /**
- * Called when request returns succesfully.
- */
- void notifySuccess();
-
- /**
- * Called when request returns error.
- */
- void notifyError(in AString errorMsg);
-};
-
-[scriptable, uuid(ec219021-8623-4b9f-aba5-4db58c60684f)]
-interface nsIDataCallInterface : nsISupports
-{
- /**
- * Data fail causes, defined in TS 24.008.
- */
- const long DATACALL_FAIL_NONE = 0;
- const long DATACALL_FAIL_OPERATOR_BARRED = 0x08;
- const long DATACALL_FAIL_INSUFFICIENT_RESOURCES = 0x1A;
- const long DATACALL_FAIL_MISSING_UKNOWN_APN = 0x1B;
- const long DATACALL_FAIL_UNKNOWN_PDP_ADDRESS_TYPE = 0x1C;
- const long DATACALL_FAIL_USER_AUTHENTICATION = 0x1D;
- const long DATACALL_FAIL_ACTIVATION_REJECT_GGSN = 0x1E;
- const long DATACALL_FAIL_ACTIVATION_REJECT_UNSPECIFIED = 0x1F;
- const long DATACALL_FAIL_SERVICE_OPTION_NOT_SUPPORTED = 0x20;
- const long DATACALL_FAIL_SERVICE_OPTION_NOT_SUBSCRIBED = 0x21;
- const long DATACALL_FAIL_SERVICE_OPTION_OUT_OF_ORDER = 0x22;
- const long DATACALL_FAIL_NSAPI_IN_USE = 0x23;
- const long DATACALL_FAIL_ONLY_IPV4_ALLOWED = 0x32;
- const long DATACALL_FAIL_ONLY_IPV6_ALLOWED = 0x33;
- const long DATACALL_FAIL_ONLY_SINGLE_BEARER_ALLOWED = 0x34;
- const long DATACALL_FAIL_PROTOCOL_ERRORS = 0x6F;
- /* Not mentioned in the specification */
- const long DATACALL_FAIL_VOICE_REGISTRATION_FAIL = -1;
- const long DATACALL_FAIL_DATA_REGISTRATION_FAIL = -2;
- const long DATACALL_FAIL_SIGNAL_LOST = -3;
- const long DATACALL_FAIL_PREF_RADIO_TECH_CHANGED = -4;
- const long DATACALL_FAIL_RADIO_POWER_OFF = -5;
- const long DATACALL_FAIL_TETHERED_CALL_ACTIVE = -6;
- const long DATACALL_FAIL_ERROR_UNSPECIFIED = 0xFFFF;
-
- /**
- * Data call network state.
- */
- const long DATACALL_STATE_INACTIVE = 0;
- const long DATACALL_STATE_ACTIVE_DOWN = 1;
- const long DATACALL_STATE_ACTIVE_UP = 2;
-
- /**
- * Data call authentication type. Must match the values in ril_consts
- * RIL_DATACALL_AUTH_TO_GECKO array.
- */
- const long DATACALL_AUTH_NONE = 0;
- const long DATACALL_AUTH_PAP = 1;
- const long DATACALL_AUTH_CHAP = 2;
- const long DATACALL_AUTH_PAP_OR_CHAP = 3;
-
- /**
- * Data call protocol type. Must match the values in ril_consts
- * RIL_DATACALL_PDP_TYPES array.
- */
- const long DATACALL_PDP_TYPE_IPV4 = 0;
- const long DATACALL_PDP_TYPE_IPV4V6 = 1;
- const long DATACALL_PDP_TYPE_IPV6 = 2;
-
- /**
- * Reason for deactivating data call.
- */
- const long DATACALL_DEACTIVATE_NO_REASON = 0;
- const long DATACALL_DEACTIVATE_RADIO_SHUTDOWN = 1;
-
- /**
- * Setup data call.
- *
- * @param apn
- * Apn to connect to.
- * @param username
- * Username for apn.
- * @param password
- * Password for apn.
- * @param authType
- * Authentication type. One of the DATACALL_AUTH_* values.
- * @param pdpType
- * Connection type. One of the DATACALL_PDP_TYPE_* values.
- * @param nsIDataCallCallback
- * Called when request is finished.
- *
- * If successful, the notifySetupDataCallSuccess() will be called with the
- * new nsIDataCall.
- *
- * Otherwise, the notifyError() will be called, and the error will be either
- * 'RadioNotAvailable', 'OpNotAllowedBeforeRegToNw',
- * 'OpNotAllowedDuringVoiceCall', 'RequestNotSupported' or 'GenericFailure'.
- */
- void setupDataCall(in AString apn, in AString username,
- in AString password, in long authType,
- in long pdpType,
- in nsIDataCallCallback callback);
-
- /**
- * Deactivate data call.
- *
- * @param cid
- * Context id.
- * @param reason
- * Disconnect Reason. One of the DATACALL_DEACTIVATE_* values.
- * @param nsIDataCallCallback
- * Called when request is finished.
- *
- * If successful, the notifySuccess() will be called.
- *
- * Otherwise, the notifyError() will be called, and the error will be either
- * 'RadioNotAvailable' or 'GenericFailure'.
- */
- void deactivateDataCall(in long cid,
- in long reason,
- in nsIDataCallCallback callback);
-
- /**
- * Get current data call list.
- *
- * @param nsIDataCallCallback
- * Called when request is finished.
- *
- * If successful, the notifyGetDataCallListSuccess() will be called with the
- * list of nsIDataCall(s).
- *
- * Otherwise, the notifyError() will be called, and the error will be either
- * 'RadioNotAvailable' or 'GenericFailure'.
- */
- void getDataCallList(in nsIDataCallCallback callback);
-
- /**
- * Set data registration state.
- *
- * @param attach
- * whether to attach data registration or not.
- * @param nsIDataCallCallback
- * Called when request is finished.
- *
- * If successful, the notifySuccess() will be called.
- *
- * Otherwise, the notifyError() will be called, and the error will be either
- * 'RadioNotAvailable', 'SubscriptionNotAvailable' or 'GenericFailure'.
- */
- void setDataRegistration(in boolean attach,
- in nsIDataCallCallback callback);
-
- /**
- * Register to receive unsolicited events from this nsIDataCallInterface.
- */
- void registerListener(in nsIDataCallInterfaceListener listener);
-
- /**
- * Unregister to stop receiving unsolicited events from this
- * nsIDataCallInterface.
- */
- void unregisterListener(in nsIDataCallInterfaceListener listener);
-};
-
-[scriptable, uuid(64700406-7429-4743-a6ae-f82e9877fd0d)]
-interface nsIDataCallInterfaceService : nsISupports
-{
- /**
- * Get the corresponding data call interface.
- *
- * @param clientId
- * clientId of the data call interface to get.
- */
- nsIDataCallInterface getDataCallInterface(in long clientId);
-}; \ No newline at end of file
diff --git a/dom/system/gonk/nsIDataCallManager.idl b/dom/system/gonk/nsIDataCallManager.idl
deleted file mode 100644
index de8477801b..0000000000
--- a/dom/system/gonk/nsIDataCallManager.idl
+++ /dev/null
@@ -1,81 +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 "nsINetworkInterface.idl"
-
-[scriptable, uuid(b8bcd6aa-5b06-4362-a68c-317878429e51)]
-interface nsIRilNetworkInfo : nsINetworkInfo
-{
- readonly attribute unsigned long serviceId;
- readonly attribute DOMString iccId;
-
- /* The following attributes are for MMS proxy settings. */
- readonly attribute DOMString mmsc; // Empty string if not set.
- readonly attribute DOMString mmsProxy; // Empty string if not set.
- readonly attribute long mmsPort; // -1 if not set.
-
- /**
- * Get the list of pcscf addresses, could be IPv4 or IPv6.
- *
- * @param count
- * The length of the list of pcscf addresses.
- *
- * @returns the list of pcscf addresses.
- */
- void getPcscf([optional] out unsigned long count,
- [array, size_is(count), retval] out wstring pcscf);
-};
-
-[scriptable, function, uuid(cb2f0f5b-67f4-4c14-93e8-01e66b630464)]
-interface nsIDeactivateDataCallsCallback : nsISupports
-{
- /**
- * Callback function used to notify when all data calls are disconnected.
- */
- void notifyDataCallsDisconnected();
-};
-
-[scriptable, uuid(e3feec20-36b4-47de-a7a5-e32a65f20186)]
-interface nsIDataCallHandler : nsISupports
-{
- /**
- * PDP APIs
- *
- * @param networkType
- * Mobile network type, that is,
- * nsINetworkInterface.NETWORK_TYPE_MOBILE or one of the
- * nsINetworkInterface.NETWORK_TYPE_MOBILE_* values.
- */
- void setupDataCallByType(in long networkType);
- void deactivateDataCallByType(in long networkType);
- long getDataCallStateByType(in long networkType);
-
- /**
- * Deactivate all data calls.
- *
- * @param callback
- * Callback to notify when all data calls are disconnected.
- */
- void deactivateDataCalls(in nsIDeactivateDataCallsCallback callback);
-
- /**
- * Called to reconsider data call state.
- */
- void updateRILNetworkInterface();
-};
-
-[scriptable, uuid(2c46e37d-88dc-4d25-bb37-e1c0d3e9cb5f)]
-interface nsIDataCallManager : nsISupports
-{
- readonly attribute long dataDefaultServiceId;
-
- /**
- * Get the corresponding data call handler.
- *
- * @param clientId
- * clientId of the data call handler to get.
- */
- nsIDataCallHandler getDataCallHandler(in unsigned long clientId);
-}; \ No newline at end of file
diff --git a/dom/system/gonk/nsIGonkDataCallInterfaceService.idl b/dom/system/gonk/nsIGonkDataCallInterfaceService.idl
deleted file mode 100644
index 240ca6bab3..0000000000
--- a/dom/system/gonk/nsIGonkDataCallInterfaceService.idl
+++ /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/. */
-
-#include "nsIDataCallInterfaceService.idl"
-
-[scriptable, uuid(f008d00c-e2b8-49b2-8f88-19111577938e)]
-interface nsIGonkDataCallInterfaceService : nsIDataCallInterfaceService
-{
- /**
- * Called by RadioInterface or lower layer to notify about data call list
- * changes.
- */
- void notifyDataCallListChanged(in unsigned long clientId,
- in uint32_t count,
- [array, size_is(count)] in nsIDataCall
- dataCalls);
-}; \ No newline at end of file
diff --git a/dom/system/gonk/nsINetworkInterface.idl b/dom/system/gonk/nsINetworkInterface.idl
deleted file mode 100644
index bd40e751a1..0000000000
--- a/dom/system/gonk/nsINetworkInterface.idl
+++ /dev/null
@@ -1,108 +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(4816a559-5620-4cb5-8433-ff0b25e6622f)]
-interface nsINetworkInfo : nsISupports
-{
- const long NETWORK_STATE_UNKNOWN = -1;
- const long NETWORK_STATE_CONNECTING = 0;
- const long NETWORK_STATE_CONNECTED = 1;
- const long NETWORK_STATE_DISCONNECTING = 2;
- const long NETWORK_STATE_DISCONNECTED = 3;
- const long NETWORK_STATE_ENABLED = 4;
- const long NETWORK_STATE_DISABLED = 5;
-
- /**
- * Current network state, one of the NETWORK_STATE_* constants.
- *
- * When this changes, network interface implementations notify with
- * updateNetworkInterface() API.
- */
- readonly attribute long state;
-
- const long NETWORK_TYPE_UNKNOWN = -1;
- const long NETWORK_TYPE_WIFI = 0;
- const long NETWORK_TYPE_MOBILE = 1;
- const long NETWORK_TYPE_MOBILE_MMS = 2;
- const long NETWORK_TYPE_MOBILE_SUPL = 3;
- const long NETWORK_TYPE_WIFI_P2P = 4;
- const long NETWORK_TYPE_MOBILE_IMS = 5;
- const long NETWORK_TYPE_MOBILE_DUN = 6;
- const long NETWORK_TYPE_MOBILE_FOTA = 7;
- const long NETWORK_TYPE_ETHERNET = 8;
-
- /**
- * Network type. One of the NETWORK_TYPE_* constants.
- */
- readonly attribute long type;
-
- /**
- * Interface name of the network interface this network info belongs to.
- */
- readonly attribute DOMString name;
-
- /**
- * Get the list of ip addresses and prefix lengths, ip address could be IPv4
- * or IPv6, typically 1 IPv4 or 1 IPv6 or one of each.
- *
- * @param ips
- * The list of ip addresses retrieved.
- * @param prefixLengths
- * The list of prefix lengths retrieved.
- *
- * @returns the length of the lists.
- */
- void getAddresses([array, size_is(count)] out wstring ips,
- [array, size_is(count)] out unsigned long prefixLengths,
- [retval] out unsigned long count);
-
- /**
- * Get the list of gateways, could be IPv4 or IPv6, typically 1 IPv4 or 1
- * IPv6 or one of each.
- *
- * @param count
- * The length of the list of gateways
- *
- * @returns the list of gateways.
- */
- void getGateways([optional] out unsigned long count,
- [array, size_is(count), retval] out wstring gateways);
-
- /**
- * Get the list of dnses, could be IPv4 or IPv6.
- *
- * @param count
- * The length of the list of dnses.
- *
- * @returns the list of dnses.
- */
- void getDnses([optional] out unsigned long count,
- [array, size_is(count), retval] out wstring dnses);
-};
-
-[scriptable, uuid(8b1345fa-b34c-41b3-8d21-09f961bf8887)]
-interface nsINetworkInterface : nsISupports
-{
- /**
- * The network information about this network interface.
- */
- readonly attribute nsINetworkInfo info;
-
- /**
- * The host name of the http proxy server.
- */
- readonly attribute DOMString httpProxyHost;
-
- /*
- * The port number of the http proxy server.
- */
- readonly attribute long httpProxyPort;
-
- /*
- * The Maximun Transmit Unit for this network interface, -1 if not set.
- */
- readonly attribute long mtu;
-};
diff --git a/dom/system/gonk/nsINetworkInterfaceListService.idl b/dom/system/gonk/nsINetworkInterfaceListService.idl
deleted file mode 100644
index 0c224842e4..0000000000
--- a/dom/system/gonk/nsINetworkInterfaceListService.idl
+++ /dev/null
@@ -1,40 +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, uuid(55779d32-1e28-4f43-af87-09d04bc3cce9)]
-interface nsINetworkInterfaceList : nsISupports
-{
- /**
- * Number of the network interfaces that is available.
- */
- long getNumberOfInterface();
-
- /**
- * Get the i-th interface info info from the list.
- * @param interfaceIndex index of interface, from 0 to number of interface - 1.
- */
- nsINetworkInfo getInterfaceInfo(in long interfaceIndex);
-};
-
-[scriptable, uuid(21d7fc8b-28c4-4a4f-a15e-1f9defbc2cec)]
-interface nsINetworkInterfaceListService : nsISupports
-{
- const long LIST_NOT_INCLUDE_MMS_INTERFACES = (1 << 0);
- const long LIST_NOT_INCLUDE_SUPL_INTERFACES = (1 << 1);
- const long LIST_NOT_INCLUDE_IMS_INTERFACES = (1 << 2);
- const long LIST_NOT_INCLUDE_DUN_INTERFACES = (1 << 3);
- const long LIST_NOT_INCLUDE_FOTA_INTERFACES = (1 << 4);
-
- /**
- * Obtain a list of network interfaces that satisfy the specified condition.
- * @param condition flags that specify the interfaces to be returned. This
- * can be OR combination of LIST_* flags, or zero to make all available
- * interfaces returned.
- */
- nsINetworkInterfaceList getDataInterfaceList(in long condition);
-};
diff --git a/dom/system/gonk/nsINetworkManager.idl b/dom/system/gonk/nsINetworkManager.idl
deleted file mode 100644
index 0da1237969..0000000000
--- a/dom/system/gonk/nsINetworkManager.idl
+++ /dev/null
@@ -1,135 +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;
-interface nsINetworkInterface;
-
-/**
- * Manage network interfaces.
- */
-[scriptable, uuid(1ba9346b-53b5-4660-9dc6-58f0b258d0a6)]
-interface nsINetworkManager : nsISupports
-{
- /**
- * Register the given network interface with the network manager.
- *
- * Consumers will be notified with the 'network-interface-registered'
- * observer notification.
- *
- * Throws if there's already an interface registered with the same network id.
- *
- * @param network
- * Network interface to register.
- */
- void registerNetworkInterface(in nsINetworkInterface network);
-
- /**
- * Update the routes and DNSes according the state of the given network.
- *
- * Consumers will be notified with the 'network-connection-state-changed'
- * observer notification.
- *
- * Throws an exception if the specified network interface object isn't
- * registered.
- *
- * @param network
- * Network interface to update.
- */
- void updateNetworkInterface(in nsINetworkInterface network);
-
- /**
- * Unregister the given network interface from the network manager.
- *
- * Consumers will be notified with the 'network-interface-unregistered'
- * observer notification.
- *
- * Throws an exception if the specified network interface object isn't
- * registered.
- *
- * @param network
- * Network interface to unregister.
- */
- void unregisterNetworkInterface(in nsINetworkInterface network);
-
- /**
- * Object containing all known network information, keyed by their
- * network id. Network id is composed of a sub-id + '-' + network
- * type. For mobile network types, sub-id is 'ril' + service id; for
- * non-mobile network types, sub-id is always 'device'.
- */
- readonly attribute jsval allNetworkInfo;
-
- /**
- * Priority list of network types. An array of
- * nsINetworkInterface::NETWORK_TYPE_* constants.
- *
- * The piror position of the type indicates the higher priority. The priority
- * is used to determine route when there are multiple connected networks.
- */
- attribute jsval networkTypePriorityList;
-
- /**
- * The preferred network type. One of the
- * nsINetworkInterface::NETWORK_TYPE_* constants.
- *
- * This attribute is used for setting default route to favor
- * interfaces with given type. This can be overriden by calling
- * overrideDefaultRoute().
- */
- attribute long preferredNetworkType;
-
- /**
- * The network information of the network interface handling all network
- * traffic.
- *
- * When this changes, the 'network-active-changed' observer
- * notification is dispatched.
- */
- readonly attribute nsINetworkInfo activeNetworkInfo;
-
- /**
- * Override the default behaviour for preferredNetworkType and route
- * all network traffic through the the specified interface.
- *
- * Consumers can observe changes to the active network by subscribing to
- * the 'network-active-changed' observer notification.
- *
- * @param network
- * Network to route all network traffic to. If this is null,
- * a previous override is canceled.
- */
- long overrideActive(in nsINetworkInterface network);
-
- /**
- * Add host route to the specified network into routing table.
- *
- * @param network
- * The network information for the host to be routed to.
- * @param host
- * The host to be added.
- * The host will be resolved in advance if it's not an ip-address.
- *
- * @return a Promise
- * resolved if added; rejected, otherwise.
- */
- jsval addHostRoute(in nsINetworkInfo network,
- in DOMString host);
-
- /**
- * Remove host route to the specified network from routing table.
- *
- * @param network
- * The network information for the routing to be removed from.
- * @param host
- * The host routed to the network.
- * The host will be resolved in advance if it's not an ip-address.
- *
- * @return a Promise
- * resolved if removed; rejected, otherwise.
- */
- jsval removeHostRoute(in nsINetworkInfo network,
- in DOMString host);
-};
diff --git a/dom/system/gonk/nsINetworkService.idl b/dom/system/gonk/nsINetworkService.idl
deleted file mode 100644
index 50a4684945..0000000000
--- a/dom/system/gonk/nsINetworkService.idl
+++ /dev/null
@@ -1,619 +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(91824160-fb25-11e1-a21f-0800200c9a66)]
-interface nsIWifiTetheringCallback : nsISupports
-{
- /**
- * Callback function used to report status to WifiManager.
- *
- * @param error
- * An error message if the operation wasn't successful,
- * or `null` if it was.
- */
- void wifiTetheringEnabledChange(in jsval error);
-};
-
-[scriptable, function, uuid(9c128e68-5e4b-4626-bb88-84ec54cce5d8)]
-interface nsINetworkStatsCallback : nsISupports
-{
- void networkStatsAvailable(in boolean success,
- in unsigned long rxBytes,
- in unsigned long txBytes,
- in unsigned long long timestamp);
-};
-
-[scriptable, function, uuid(0706bfa2-ac2d-11e2-9a8d-7b6d988d4767)]
-interface nsINetworkUsageAlarmCallback : nsISupports
-{
- void networkUsageAlarmResult(in jsval error);
-};
-
-[scriptable, function, uuid(9ede8720-f8bc-11e2-b778-0800200c9a66)]
-interface nsIWifiOperationModeCallback : nsISupports
-{
- /**
- * Callback function used to report result to WifiManager.
- *
- * @param error
- * An error message if the operation wasn't successful,
- * or `null` if it was.
- */
- void wifiOperationModeResult(in jsval error);
-};
-
-[scriptable, function, uuid(097878b0-19fc-11e3-8ffd-0800200c9a66)]
-interface nsISetDhcpServerCallback : nsISupports
-{
- /**
- * Callback function used to report the DHCP server set result
- *
- * @param error
- * An error message if the operation wasn't successful,
- * or `null` if it was.
- */
- void dhcpServerResult(in jsval error);
-};
-
-[scriptable, function, uuid(32407c50-46c7-11e3-8f96-0800200c9a66)]
-interface nsIUsbTetheringCallback : nsISupports
-{
- /**
- * Callback function used to report status of enabling usb tethering.
- *
- * @param error
- * An error message if the operation wasn't successful,
- * or `null` if it was.
- */
- void usbTetheringEnabledChange(in jsval error);
-};
-
-[scriptable, function, uuid(055fd560-46ad-11e3-8f96-0800200c9a66)]
-interface nsIEnableUsbRndisCallback : nsISupports
-{
- /**
- * Callback function used to report the status of enabling/disabling usb rndis.
- *
- * @param success
- * Boolean to indicate the operation is successful or not.
- * @param enable
- * Boolean to indicate if we are enabling or disabling usb rndis.
- */
- void enableUsbRndisResult(in boolean success, in boolean enable);
-};
-
-[scriptable, function, uuid(4f08cc30-46ad-11e3-8f96-0800200c9a66)]
-interface nsIUpdateUpStreamCallback : nsISupports
-{
- /**
- * Callback function used to report the result of updating upstream.
- *
- * @param success
- * Boolean to indicate the operation is successful or not.
- * @param externalIfname
- * The external interface name.
- */
- void updateUpStreamResult(in boolean success, in DOMString externalIfname);
-};
-
-[scriptable, function, uuid(eedca6c0-1310-11e4-9191-0800200c9a66)]
-interface nsISetDnsCallback : nsISupports
-{
- /**
- * Callback function used to report the result of setting DNS server.
- *
- * @param error
- * An error message if the operation wasn't successful,
- * or `null` if it was.
- */
- void setDnsResult(in jsval error);
-};
-
-[scriptable, function, uuid(5d0e1a60-1187-11e4-9191-0800200c9a66)]
-interface nsINativeCommandCallback : nsISupports
-{
- /**
- * Callback function used to report the result of a network native command.
- *
- * @param success
- * Boolean to indicate the operation is successful or not.
- */
- void nativeCommandResult(in boolean success);
-};
-
-[scriptable, function, uuid(694abb80-1187-11e4-9191-0800200c9a66)]
-interface nsIDhcpRequestCallback : nsISupports
-{
- /**
- * Callback function used to report the result of DHCP client request.
- *
- * @param success
- * Boolean to indicate the operation is successful or not.
- *
- * @param dhcpInfo
- * An object to represent the successful DHCP request:
- *
- * - gateway_str: string
- * - dns1_str: string
- * - dns2_str: string
- * - mask_str: string
- * - server_str: string
- * - vendor_str: string
- * - lease: long
- * - mask: long
- * - ipaddr: long
- * - gateway: long
- * - dns1: long
- * - dns2: long
- * - server: long
- */
- void dhcpRequestResult(in boolean success, in jsval dhcpInfo);
-};
-
-[scriptable, function, uuid(88e3ee22-f1b3-4fa0-8a5d-793fb827c42c)]
-interface nsIGetInterfacesCallback : nsISupports
-{
- /**
- * Callback function used to return the list of existing network interfaces.
- *
- * @param success
- * Boolean to indicate the operation is successful or not.
- * @param interfaceList
- * An array of interface name.
- */
- void getInterfacesResult(in boolean success, in jsval interfaceList);
-};
-
-[scriptable, function, uuid(064e02a3-d2c0-42c5-a293-1efa84056100)]
-interface nsIGetInterfaceConfigCallback : nsISupports
-{
- /**
- * Callback function used to return the network config of a given interface.
- *
- * @param success
- * Boolean to indicate the operation is successful or not.
- * @param result
- * .ip: Ip address.
- * .prefix: mask length.
- * .link: network link properties.
- * .mac: mac address.
- */
- void getInterfaceConfigResult(in boolean success, in jsval result);
-};
-
-[scriptable, function, uuid(b370f360-6ba8-4517-a4f9-31e8f004ee91)]
-interface nsISetInterfaceConfigCallback : nsISupports
-{
- /**
- * Callback function used to set network config for a specified interface.
- *
- * @param success
- * Boolean to indicate the operation is successful or not.
- */
- void setInterfaceConfigResult(in boolean success);
-};
-
-/**
- * Provide network services.
- */
-[scriptable, uuid(e16fe98f-9f63-48fe-82ba-8d1a1b7c6a57)]
-interface nsINetworkService : nsISupports
-{
- const long MODIFY_ROUTE_ADD = 0;
- const long MODIFY_ROUTE_REMOVE = 1;
-
- /**
- * Enable or disable Wifi Tethering
- *
- * @param enabled
- * Boolean that indicates whether tethering should be enabled (true) or disabled (false).
- * @param config
- * The Wifi Tethering configuration from settings db.
- * @param callback
- * Callback function used to report status to WifiManager.
- */
- void setWifiTethering(in boolean enabled,
- in jsval config,
- in nsIWifiTetheringCallback callback);
-
- /**
- * Enable or disable DHCP server
- *
- * @param enabled
- * Boolean that indicates enabling or disabling DHCP server.
- *
- * @param config
- * Config used to enable the DHCP server. It contains
- * .startIp start of the ip lease range (string)
- * .endIp end of the ip lease range (string)
- * .serverIp ip of the DHCP server (string)
- * .maskLength the length of the subnet mask
- * .ifname the interface name
- *
- * As for disabling the DHCP server, put this value |null|.
- *
- * @param callback
- * Callback function used to report status.
- */
- void setDhcpServer(in boolean enabled,
- in jsval config,
- in nsISetDhcpServerCallback callback);
-
-
- /**
- * Retrieve network interface stats.
- *
- * @param networkName
- * Select the Network interface to request estats.
- *
- * @param callback
- * Callback to notify result and provide stats, connectionType
- * and the date when stats are retrieved
- */
- void getNetworkInterfaceStats(in DOMString networkName, in nsINetworkStatsCallback callback);
-
- /**
- * Set Alarm of usage per interface
- *
- * @param networkName
- * Select the Network interface to set an alarm.
- *
- * @param threshold
- * Amount of data that will trigger the alarm.
- *
- * @param callback
- * Callback to notify the result.
- *
- * @return false if there is no interface registered for the networkType param.
- */
- boolean setNetworkInterfaceAlarm(in DOMString networkName,
- in long long threshold,
- in nsINetworkUsageAlarmCallback callback);
-
- /**
- * Reload Wifi firmware to specific operation mode.
- *
- * @param interfaceName
- * Wifi Network interface name.
- *
- * @param mode
- * AP - Access pointer mode.
- * P2P - Peer to peer connection mode.
- * STA - Station mode.
- *
- * @param callback
- * Callback to notify Wifi firmware reload result.
- */
- void setWifiOperationMode(in DOMString interfaceName,
- in DOMString mode,
- in nsIWifiOperationModeCallback callback);
-
- /**
- * Set USB tethering.
- *
- * @param enabled
- * Boolean to indicate we are going to enable or disable usb tethering.
- * @param config
- * The usb tethering configuration.
- * @param callback
- * Callback function used to report the result enabling/disabling usb tethering.
- */
- void setUSBTethering(in boolean enabled,
- in jsval config,
- in nsIUsbTetheringCallback callback);
-
- /**
- * Reset routing table.
- *
- * @param interfaceName
- * The name of the network interface we want to remove from the routing
- * table.
- *
- * @param callback
- * Callback to notify the result of resetting routing table.
- */
- void resetRoutingTable(in DOMString interfaceName,
- in nsINativeCommandCallback callback);
-
- /**
- * Set DNS.
- *
- * @param interfaceName
- * The network interface name of the DNS we want to set.
- * @param dnsesCount
- * Number of elements in dnses.
- * @param dnses
- * Dnses to set.
- * @param gatewaysCount
- * Number of elements in gateways.
- * @param gateways
- * Gateways for the dnses, the most suitable, usually the one with the
- * same address family, will be selected for each dns.
- *
- * @param callback
- * Callback to notify the result of setting DNS server.
- */
- void setDNS(in DOMString interfaceName,
- in unsigned long dnsesCount,
- [array, size_is(dnsesCount)] in wstring dnses,
- in unsigned long gatewaysCount,
- [array, size_is(gatewaysCount)] in wstring gateways,
- in nsISetDnsCallback callback);
-
- /**
- * Set default route.
- *
- * @param interfaceName
- * The network interface name of the default route we want to set.
- * @param count
- * Number of elements in gateways.
- * @param gateways
- * Default gateways for setting default route.
- *
- * @param callback
- * Callback to notify the result of setting default route.
- */
- void setDefaultRoute(in DOMString interfaceName,
- in unsigned long count,
- [array, size_is(count)] in wstring gateways,
- in nsINativeCommandCallback callback);
-
- /**
- * Remove default route.
- *
- * @param interfaceName
- * The network interface name of the default route we want to remove.
- * @param count
- * Number of elements in gateways.
- * @param gatways
- * Default gateways for removing default route.
- *
- * @param callback
- * Callback to notify the result of removing default route.
- */
- void removeDefaultRoute(in DOMString interfaceName,
- in unsigned long count,
- [array, size_is(count)] in wstring gateways,
- in nsINativeCommandCallback callback);
-
- /**
- * Modify route.
- *
- * @param action
- * nsINetworkService.MODIFY_ROUTE_ADD to add route and
- * nsINetworkService.MODIFY_ROUTE_REMOVE to remove.
- * @param interfaceName
- * Network interface name for the output of the host route.
- * @param host
- * Host ip we want to remove route for.
- * @param prefixLength
- * The prefix length of the route we'd like to modify.
- * @param [optional] gateway
- * Gateway ip for the output of the host route.
- *
- * @return A deferred promise that resolves on success or rejects with a
- * specified reason otherwise.
- */
- jsval modifyRoute(in long action,
- in DOMString interfaceName,
- in DOMString host,
- in long prefixLength,
- [optional] in DOMString gateway);
-
- /**
- * Add route to secondary routing table.
- *
- * @param interfaceName
- * The network interface for this route.
- * @param route
- * The route info should have the following fields:
- * .ip: destination ip address
- * .prefix: destination prefix
- * .gateway: gateway ip address
- */
- void addSecondaryRoute(in DOMString interfaceName, in jsval route,
- in nsINativeCommandCallback callback);
-
- /**
- * Remove route from secondary routing table.
- *
- * @param interfaceName
- * The network interface for the route we want to remove.
- * @param route
- * The route info should have the following fields:
- * .ip: destination ip address
- * .prefix: destination prefix
- * .gateway: gateway ip address
- */
- void removeSecondaryRoute(in DOMString interfaceName, in jsval route,
- in nsINativeCommandCallback callback);
-
- /**
- * Enable or disable usb rndis.
- *
- * @param enable
- * Boolean to indicate we want enable or disable usb rndis.
- * @param callback
- * Callback function to report the result.
- */
- void enableUsbRndis(in boolean enable,
- in nsIEnableUsbRndisCallback callback);
-
- /**
- * Update upstream.
- *
- * @param previous
- * The previous internal and external interface.
- * @param current
- * The current internal and external interface.
- * @param callback
- * Callback function to report the result.
- */
- void updateUpStream(in jsval previous,
- in jsval current,
- in nsIUpdateUpStreamCallback callback);
-
- /*
- * Obtain interfaces list.
- *
- * @param callback
- * Callback function to return the result.
- */
- void getInterfaces(in nsIGetInterfacesCallback callback);
-
- /**
- * Get config of a network interface.
- *
- * @param ifname
- * Target interface.
- * @param callback
- * Callback function to report the result.
- */
- void getInterfaceConfig(in DOMString ifname, in nsIGetInterfaceConfigCallback callback);
-
- /**
- * Set config for a network interface.
- *
- * @param config
- * .ifname: Target interface.
- * .ip: Ip address.
- * .prefix: mask length.
- * .link: network link properties.
- * @param callback
- * Callback function to report the result.
- */
- void setInterfaceConfig(in jsval config, in nsISetInterfaceConfigCallback callback);
-
- /**
- * Configure a network interface.
- *
- * @param config
- * An object containing the detail that we want to configure the interface:
- *
- * - ifname: string
- * - ipaddr: long
- * - mask: long
- * - gateway: long
- * - dns1: long
- * - dns2: long
- *
- * @param callback
- * Callback to notify the result of configurating network interface.
- */
- void configureInterface(in jsval config,
- in nsINativeCommandCallback callback);
-
- /**
- * Issue a DHCP client request.
- *
- * @param networkInterface
- * The network interface which we wnat to do the DHCP request on.
- *
- * @param callback
- * Callback to notify the result of the DHCP request.
- */
- void dhcpRequest(in DOMString interfaceName,
- in nsIDhcpRequestCallback callback);
-
- /**
- * Stop Dhcp daemon.
- *
- * @param ifname
- * Target interface.
- *
- * @param callback
- * Callback to notify the result of stopping dhcp request.
- */
- void stopDhcp(in DOMString ifname,
- in nsINativeCommandCallback callback);
-
- /**
- * Enable a network interface.
- *
- * @param networkInterface
- * The network interface name which we want to enable.
- *
- * @param callback
- * Callback to notify the result of disabling network interface.
- */
- void enableInterface(in DOMString interfaceName,
- in nsINativeCommandCallback callback);
-
- /**
- * Disable a network interface.
- *
- * @param networkInterface
- * The network interface name which we want to disable.
- *
- * @param callback
- * Callback to notify the result of disabling network interface.
- */
- void disableInterface(in DOMString interfaceName,
- in nsINativeCommandCallback callback);
-
- /**
- * Reset all connections on a specified network interface.
- *
- * @param interfaceName
- * The network interface name which we want to reset.
- *
- * @param callback
- * Callback to notify the result of resetting connections.
- */
- void resetConnections(in DOMString interfaceName,
- in nsINativeCommandCallback callback);
-
- /**
- * Create network (required to call prior to any networking operation).
- *
- * @param interfaceName
- * The network interface name which we want to create network for.
- *
- * @param callback
- * Callback to notify the result of creating network.
- */
- void createNetwork(in DOMString interfaceName,
- in nsINativeCommandCallback callback);
-
- /**
- * Destroy network.
- *
- * @param interfaceName
- * The network interface name of the network we want to destroy.
- *
- * @param callback
- * Callback to notify the result of destroying network.
- */
- void destroyNetwork(in DOMString interfaceName,
- in nsINativeCommandCallback callback);
-
- /**
- * Query the netId associated with given network interface name.
- *
- * @param interfaceName
- * The network interface name which we want to query.
- *
- * @return A deferred promise that resolves with a string to indicate.
- * the queried netId on success and rejects if the interface name
- * is invalid.
- *
- */
- jsval getNetId(in DOMString interfaceName);
-
- /**
- * Set maximum transmission unit on a network interface.
- *
- * @param interfaceName
- * The name of the network interface that we want to set mtu.
- * @param mtu
- * Size of maximum tranmission unit.
- *
- * @param callback
- * Callback to notify the result of setting mtu.
- */
- void setMtu(in DOMString interfaceName, in long mtu,
- in nsINativeCommandCallback callback);
-};
diff --git a/dom/system/gonk/nsINetworkWorker.idl b/dom/system/gonk/nsINetworkWorker.idl
deleted file mode 100644
index 8fe19be69c..0000000000
--- a/dom/system/gonk/nsINetworkWorker.idl
+++ /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/. */
-
-#include "nsISupports.idl"
-
-[scriptable, uuid(98e31d3b-6cad-4cab-b4b3-4afff566ea65)]
-interface nsINetworkEventListener : nsISupports {
- void onEvent(in jsval result);
-};
-
-[scriptable, uuid(f9d9c694-0aac-4f9a-98ac-7788f954239a)]
-interface nsINetworkWorker : nsISupports {
- void start(in nsINetworkEventListener listener);
- void shutdown();
- [implicit_jscontext]
- void postMessage(in jsval options);
-};
diff --git a/dom/system/gonk/nsIRadioInterfaceLayer.idl b/dom/system/gonk/nsIRadioInterfaceLayer.idl
deleted file mode 100644
index 168fe38940..0000000000
--- a/dom/system/gonk/nsIRadioInterfaceLayer.idl
+++ /dev/null
@@ -1,53 +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 nsIIccInfo;
-interface nsIMobileConnectionInfo;
-interface nsIMobileMessageCallback;
-
-[scriptable, function, uuid(3bc96351-53b0-47a1-a888-c74c64b60f25)]
-interface nsIRilSendWorkerMessageCallback : nsISupports
-{
- boolean handleResponse(in jsval response);
-};
-
-[scriptable, uuid(1a3ef88a-e4d1-11e4-8512-176220f2b32b)]
-interface nsIRadioInterface : nsISupports
-{
- /**
- * PDP APIs
- *
- * @param networkType
- * Mobile network type, that is, nsINetworkInterface.NETWORK_TYPE_MOBILE
- * or one of the nsINetworkInterface.NETWORK_TYPE_MOBILE_* values.
- */
- void setupDataCallByType(in long networkType);
- void deactivateDataCallByType(in long networkType);
- long getDataCallStateByType(in long networkType);
-
- void updateRILNetworkInterface();
-
- void sendWorkerMessage(in DOMString type,
- [optional] in jsval message,
- [optional] in nsIRilSendWorkerMessageCallback callback);
-};
-
-%{C++
-#define NS_RADIOINTERFACELAYER_CID \
- { 0x2d831c8d, 0x6017, 0x435b, \
- { 0xa8, 0x0c, 0xe5, 0xd4, 0x22, 0x81, 0x0c, 0xea } }
-#define NS_RADIOINTERFACELAYER_CONTRACTID "@mozilla.org/ril;1"
-%}
-
-[scriptable, uuid(09730e0d-75bb-4f21-8540-062a2eadc8ff)]
-interface nsIRadioInterfaceLayer : nsISupports
-{
- readonly attribute unsigned long numRadioInterfaces;
-
- nsIRadioInterface getRadioInterface(in unsigned long clientId);
-
- void setMicrophoneMuted(in boolean muted);
-};
diff --git a/dom/system/gonk/nsISystemWorkerManager.idl b/dom/system/gonk/nsISystemWorkerManager.idl
deleted file mode 100644
index a77e253e4b..0000000000
--- a/dom/system/gonk/nsISystemWorkerManager.idl
+++ /dev/null
@@ -1,16 +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"
-
-/**
- * Information about networks that is exposed to network manager API consumers.
- */
-[scriptable, builtinclass, uuid(4984b669-0ee0-4809-ae96-3358a325a6b0)]
-interface nsISystemWorkerManager : nsISupports
-{
- [implicit_jscontext]
- void registerRilWorker(in unsigned long aClientId,
- in jsval aWorker);
-};
diff --git a/dom/system/gonk/nsITetheringService.idl b/dom/system/gonk/nsITetheringService.idl
deleted file mode 100644
index 530ab0069d..0000000000
--- a/dom/system/gonk/nsITetheringService.idl
+++ /dev/null
@@ -1,39 +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 nsINetworkInterface;
-interface nsIWifiTetheringCallback;
-
-[scriptable, uuid(779de2d3-6d29-4ee6-b069-6251839f757a)]
-interface nsITetheringService : nsISupports
-{
- const long TETHERING_STATE_INACTIVE = 0;
- const long TETHERING_STATE_WIFI = 1;
- const long TETHERING_STATE_USB = 2;
-
- /**
- * Current tethering state. One of the TETHERING_STATE_* constants.
- */
- readonly attribute long state;
-
- /**
- * Enable or disable Wifi Tethering.
- *
- * @param enabled
- * Boolean that indicates whether tethering should be enabled (true) or
- * disabled (false).
- * @param interfaceName
- * The Wifi network interface name for internal interface.
- * @param config
- * The Wifi Tethering configuration from settings db.
- * @param callback
- * Callback function used to report status to WifiManager.
- */
- void setWifiTethering(in boolean enabled,
- in DOMString interfaceName,
- in jsval config,
- in nsIWifiTetheringCallback callback);
-}; \ No newline at end of file
diff --git a/dom/system/gonk/nsIVolume.idl b/dom/system/gonk/nsIVolume.idl
deleted file mode 100644
index 60785f0a42..0000000000
--- a/dom/system/gonk/nsIVolume.idl
+++ /dev/null
@@ -1,114 +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 "nsIVolumeStat.idl"
-
-[scriptable, uuid(EE752CB8-8FD7-11E4-A602-70221D5D46B0)]
-interface nsIVolume : nsISupports
-{
- // These MUST match the states from android's system/vold/Volume.h header
- // Note: Changes made to the STATE_xxx names should also be reflected in the
- // NS_VolumeStateStr function found in Volume.cpp
- const long STATE_INIT = -1;
- const long STATE_NOMEDIA = 0;
- const long STATE_IDLE = 1;
- const long STATE_PENDING = 2;
- const long STATE_CHECKING = 3;
- const long STATE_MOUNTED = 4;
- const long STATE_UNMOUNTING = 5;
- const long STATE_FORMATTING = 6;
- const long STATE_SHARED = 7;
- const long STATE_SHAREDMNT = 8;
- const long STATE_CHECKMNT = 100;
- const long STATE_MOUNT_FAIL = 101;
-
- // The name of the volume. Often there is only one volume, called sdcard.
- // But some phones support multiple volumes.
- readonly attribute DOMString name;
-
- // The mount point is the path on the system where the volume is mounted
- // and is only valid when state == STATE_MOUNTED.
- readonly attribute DOMString mountPoint;
-
- // Reflects the current state of the volume, using STATE_xxx constants
- // from above.
- readonly attribute long state;
-
- // mountGeneration is a unique number which is used distinguish between
- // periods of time that a volume is in the mounted state. Each time a
- // volume transitions to the mounted state, the mountGeneration will
- // be different from the last time it transitioned to the mounted state.
- readonly attribute long mountGeneration;
-
- // While a volume is mounted, it can be locked, preventing it from being
- // shared with the PC. To lock a volume, acquire an MozWakeLock
- // using the name of this attribute. Note that mountLockName changes
- // every time the mountGeneration changes, so you'll need to reacquire
- // the wakelock every time the volume becomes mounted.
- readonly attribute DOMString mountLockName;
-
- // Determines if a mountlock is currently being held against this volume.
- readonly attribute boolean isMountLocked;
-
- // Determines if media is actually present or not. Note, that when an sdcard
- // is ejected, it may go through several tranistory states before finally
- // arriving at STATE_NOMEDIA. So isMediaPresent may be false even when the
- // current state isn't STATE_NOMEDIA.
- readonly attribute boolean isMediaPresent;
-
- // Determines if the volume is currently being shared. This covers off
- // more than just state == STATE_SHARED. isSharing will return true from the
- // time that the volume leaves the mounted state, until it gets back to
- // mounted, nomedia, or formatting states. This attribute is to allow
- // device storage to suppress unwanted 'unavailable' status when
- // transitioning from mounted to sharing and back again.
- readonly attribute boolean isSharing;
-
- // Determines if the volume is currently formatting. This sets true once
- // mFormatRequest == true and mState == STATE_MOUNTED, and sets false
- // once the volume has been formatted and mounted again.
- readonly attribute boolean isFormatting;
-
- readonly attribute boolean isUnmounting;
-
- nsIVolumeStat getStats();
-
- // Formats the volume in IO thread, if the volume is ready to be formatted.
- // Automounter will unmount it, format it and then mount it again.
- void format();
-
- // Mounts the volume in IO thread, if the volume is already unmounted.
- // Automounter will mount it. Otherwise Automounter will skip this.
- void mount();
-
- // Unmounts the volume in IO thread, if the volume is already mounted.
- // Automounter will unmount it. Otherwise Automounter will skip this.
- void unmount();
-
- // Whether this is a fake volume.
- readonly attribute boolean isFake;
-
- // Whether this is a removable volume
- readonly attribute boolean isRemovable;
-
- // Whether this is a hot-swappable volume
- readonly attribute boolean isHotSwappable;
-
-};
-
-%{C++
-// For use with the ObserverService
-#define NS_VOLUME_STATE_CHANGED "volume-state-changed"
-#define NS_VOLUME_REMOVED "volume-removed"
-
-namespace mozilla {
-namespace system {
-
-// Convert a state into a loggable/printable string.
-const char* NS_VolumeStateStr(int32_t aState);
-
-} // system
-} // mozilla
-%}
diff --git a/dom/system/gonk/nsIVolumeMountLock.idl b/dom/system/gonk/nsIVolumeMountLock.idl
deleted file mode 100644
index 0a9a1a5c28..0000000000
--- a/dom/system/gonk/nsIVolumeMountLock.idl
+++ /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/. */
-
-#include "nsISupports.idl"
-
-[scriptable, uuid(44449f34-5ca1-4aff-bce6-22c79263de24)]
-interface nsIVolumeMountLock : nsISupports
-{
- void unlock();
-};
-
diff --git a/dom/system/gonk/nsIVolumeService.idl b/dom/system/gonk/nsIVolumeService.idl
deleted file mode 100644
index d3752e2019..0000000000
--- a/dom/system/gonk/nsIVolumeService.idl
+++ /dev/null
@@ -1,36 +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 "nsIVolume.idl"
-#include "nsIVolumeMountLock.idl"
-
-interface nsIArray;
-
-[scriptable, uuid(cfbf9880-cba5-11e4-8830-0800200c9a66)]
-interface nsIVolumeService : nsISupports
-{
- nsIVolume getVolumeByName(in DOMString volName);
- nsIVolume getVolumeByPath(in DOMString path);
- nsIVolume createOrGetVolumeByPath(in DOMString path);
-
- nsIVolumeMountLock createMountLock(in DOMString volName);
-
- nsIArray getVolumeNames();
-
- void Dump(in DOMString label);
-
- /* for test case only to simulate sdcard insertion/removal */
- void createFakeVolume(in DOMString name, in DOMString path);
- void SetFakeVolumeState(in DOMString name, in long state);
-
- /* for test case only to test removal of storage area */
- void removeFakeVolume(in DOMString name);
-};
-
-%{C++
-#define NS_VOLUMESERVICE_CID \
- {0x7c179fb7, 0x67a0, 0x43a3, {0x93, 0x37, 0x29, 0x4e, 0x03, 0x60, 0xb8, 0x58}}
-#define NS_VOLUMESERVICE_CONTRACTID "@mozilla.org/telephony/volume-service;1"
-%}
diff --git a/dom/system/gonk/nsIVolumeStat.idl b/dom/system/gonk/nsIVolumeStat.idl
deleted file mode 100644
index 1d725689d3..0000000000
--- a/dom/system/gonk/nsIVolumeStat.idl
+++ /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/. */
-
-#include "nsISupports.idl"
-
-[scriptable, uuid(b4c050d0-c57a-11e1-9b21-0800200c9a66)]
-interface nsIVolumeStat : nsISupports
-{
- readonly attribute long long totalBytes;
- readonly attribute long long freeBytes;
-};
diff --git a/dom/system/gonk/nsIWorkerHolder.idl b/dom/system/gonk/nsIWorkerHolder.idl
deleted file mode 100644
index e5cc82c9e3..0000000000
--- a/dom/system/gonk/nsIWorkerHolder.idl
+++ /dev/null
@@ -1,11 +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(c04f3102-1ce8-4d57-9c27-8aece9c2740a)]
-interface nsIWorkerHolder : nsISupports
-{
- readonly attribute jsval worker;
-};
diff --git a/dom/system/gonk/nsVolume.cpp b/dom/system/gonk/nsVolume.cpp
deleted file mode 100644
index 77a1628e43..0000000000
--- a/dom/system/gonk/nsVolume.cpp
+++ /dev/null
@@ -1,467 +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 "nsVolume.h"
-
-#include "base/message_loop.h"
-#include "base/task.h"
-#include "nsIPowerManagerService.h"
-#include "nsISupportsUtils.h"
-#include "nsIVolume.h"
-#include "nsServiceManagerUtils.h"
-#include "nsThreadUtils.h"
-#include "nsVolumeStat.h"
-#include "nsXULAppAPI.h"
-#include "Volume.h"
-#include "AutoMounter.h"
-#include "VolumeManager.h"
-
-#undef VOLUME_MANAGER_LOG_TAG
-#define VOLUME_MANAGER_LOG_TAG "nsVolume"
-#include "VolumeManagerLog.h"
-
-namespace mozilla {
-namespace system {
-
-const char *
-NS_VolumeStateStr(int32_t aState)
-{
- switch (aState) {
- case nsIVolume::STATE_INIT: return "Init";
- case nsIVolume::STATE_NOMEDIA: return "NoMedia";
- case nsIVolume::STATE_IDLE: return "Idle";
- case nsIVolume::STATE_PENDING: return "Pending";
- case nsIVolume::STATE_CHECKING: return "Checking";
- case nsIVolume::STATE_MOUNTED: return "Mounted";
- case nsIVolume::STATE_UNMOUNTING: return "Unmounting";
- case nsIVolume::STATE_FORMATTING: return "Formatting";
- case nsIVolume::STATE_SHARED: return "Shared";
- case nsIVolume::STATE_SHAREDMNT: return "Shared-Mounted";
- case nsIVolume::STATE_CHECKMNT: return "Check-Mounted";
- case nsIVolume::STATE_MOUNT_FAIL: return "Mount-Fail";
- }
- return "???";
-}
-
-// While nsVolumes can only be used on the main thread, in the
-// UpdateVolumeRunnable constructor (which is called from IOThread) we
-// allocate an nsVolume which is then passed to MainThread. Since we
-// have a situation where we allocate on one thread and free on another
-// we use a thread safe AddRef implementation.
-NS_IMPL_ISUPPORTS(nsVolume, nsIVolume)
-
-nsVolume::nsVolume(const Volume* aVolume)
- : mName(NS_ConvertUTF8toUTF16(aVolume->Name())),
- mMountPoint(NS_ConvertUTF8toUTF16(aVolume->MountPoint())),
- mState(aVolume->State()),
- mMountGeneration(aVolume->MountGeneration()),
- mMountLocked(aVolume->IsMountLocked()),
- mIsFake(!aVolume->CanBeShared()),
- mIsMediaPresent(aVolume->MediaPresent()),
- mIsSharing(aVolume->IsSharing()),
- mIsFormatting(aVolume->IsFormatting()),
- mIsUnmounting(aVolume->IsUnmounting()),
- mIsRemovable(aVolume->IsRemovable()),
- mIsHotSwappable(aVolume->IsHotSwappable())
-{
-}
-
-nsVolume::nsVolume(const nsVolume* aVolume)
- : mName(aVolume->mName),
- mMountPoint(aVolume->mMountPoint),
- mState(aVolume->mState),
- mMountGeneration(aVolume->mMountGeneration),
- mMountLocked(aVolume->mMountLocked),
- mIsFake(aVolume->mIsFake),
- mIsMediaPresent(aVolume->mIsMediaPresent),
- mIsSharing(aVolume->mIsSharing),
- mIsFormatting(aVolume->mIsFormatting),
- mIsUnmounting(aVolume->mIsUnmounting),
- mIsRemovable(aVolume->mIsRemovable),
- mIsHotSwappable(aVolume->mIsHotSwappable)
-{
-}
-
-void nsVolume::Dump(const char* aLabel) const
-{
- LOG("%s: Volume: %s is %s and %s @ %s gen %d locked %d",
- aLabel,
- NameStr().get(),
- StateStr(),
- IsMediaPresent() ? "inserted" : "missing",
- MountPointStr().get(),
- MountGeneration(),
- (int)IsMountLocked());
- LOG("%s: IsSharing %s IsFormating %s IsUnmounting %s",
- aLabel,
- (IsSharing() ? "y" : "n"),
- (IsFormatting() ? "y" : "n"),
- (IsUnmounting() ? "y" : "n"));
-}
-
-bool nsVolume::Equals(nsIVolume* aVolume)
-{
- nsString volName;
- aVolume->GetName(volName);
- if (!mName.Equals(volName)) {
- return false;
- }
-
- nsString volMountPoint;
- aVolume->GetMountPoint(volMountPoint);
- if (!mMountPoint.Equals(volMountPoint)) {
- return false;
- }
-
- int32_t volState;
- aVolume->GetState(&volState);
- if (mState != volState){
- return false;
- }
-
- int32_t volMountGeneration;
- aVolume->GetMountGeneration(&volMountGeneration);
- if (mMountGeneration != volMountGeneration) {
- return false;
- }
-
- bool volIsMountLocked;
- aVolume->GetIsMountLocked(&volIsMountLocked);
- if (mMountLocked != volIsMountLocked) {
- return false;
- }
-
- bool isFake;
- aVolume->GetIsFake(&isFake);
- if (mIsFake != isFake) {
- return false;
- }
-
- bool isSharing;
- aVolume->GetIsSharing(&isSharing);
- if (mIsSharing != isSharing) {
- return false;
- }
-
- bool isFormatting;
- aVolume->GetIsFormatting(&isFormatting);
- if (mIsFormatting != isFormatting) {
- return false;
- }
-
- bool isUnmounting;
- aVolume->GetIsUnmounting(&isUnmounting);
- if (mIsUnmounting != isUnmounting) {
- return false;
- }
-
- bool isRemovable;
- aVolume->GetIsRemovable(&isRemovable);
- if (mIsRemovable != isRemovable) {
- return false;
- }
-
- bool isHotSwappable;
- aVolume->GetIsHotSwappable(&isHotSwappable);
- if (mIsHotSwappable != isHotSwappable) {
- return false;
- }
-
- return true;
-}
-
-NS_IMETHODIMP nsVolume::GetIsMediaPresent(bool* aIsMediaPresent)
-{
- *aIsMediaPresent = mIsMediaPresent;
- return NS_OK;
-}
-
-NS_IMETHODIMP nsVolume::GetIsMountLocked(bool* aIsMountLocked)
-{
- *aIsMountLocked = mMountLocked;
- return NS_OK;
-}
-
-NS_IMETHODIMP nsVolume::GetIsSharing(bool* aIsSharing)
-{
- *aIsSharing = mIsSharing;
- return NS_OK;
-}
-
-NS_IMETHODIMP nsVolume::GetIsFormatting(bool* aIsFormatting)
-{
- *aIsFormatting = mIsFormatting;
- return NS_OK;
-}
-
-NS_IMETHODIMP nsVolume::GetIsUnmounting(bool* aIsUnmounting)
-{
- *aIsUnmounting = mIsUnmounting;
- return NS_OK;
-}
-
-NS_IMETHODIMP nsVolume::GetName(nsAString& aName)
-{
- aName = mName;
- return NS_OK;
-}
-
-NS_IMETHODIMP nsVolume::GetMountGeneration(int32_t* aMountGeneration)
-{
- *aMountGeneration = mMountGeneration;
- return NS_OK;
-}
-
-NS_IMETHODIMP nsVolume::GetMountLockName(nsAString& aMountLockName)
-{
- aMountLockName = NS_LITERAL_STRING("volume-") + Name();
- aMountLockName.AppendPrintf("-%d", mMountGeneration);
-
- return NS_OK;
-}
-
-NS_IMETHODIMP nsVolume::GetMountPoint(nsAString& aMountPoint)
-{
- aMountPoint = mMountPoint;
- return NS_OK;
-}
-
-NS_IMETHODIMP nsVolume::GetState(int32_t* aState)
-{
- *aState = mState;
- return NS_OK;
-}
-
-NS_IMETHODIMP nsVolume::GetStats(nsIVolumeStat **aResult)
-{
- if (mState != STATE_MOUNTED) {
- return NS_ERROR_NOT_AVAILABLE;
- }
-
- NS_IF_ADDREF(*aResult = new nsVolumeStat(mMountPoint));
- return NS_OK;
-}
-
-NS_IMETHODIMP nsVolume::GetIsFake(bool *aIsFake)
-{
- *aIsFake = mIsFake;
- return NS_OK;
-}
-
-NS_IMETHODIMP nsVolume::GetIsRemovable(bool *aIsRemovable)
-{
- *aIsRemovable = mIsRemovable;
- return NS_OK;
-}
-
-NS_IMETHODIMP nsVolume::GetIsHotSwappable(bool *aIsHotSwappable)
-{
- *aIsHotSwappable = mIsHotSwappable;
- return NS_OK;
-}
-
-NS_IMETHODIMP nsVolume::Format()
-{
- MOZ_ASSERT(XRE_IsParentProcess());
-
- XRE_GetIOMessageLoop()->PostTask(
- NewRunnableFunction(FormatVolumeIOThread, NameStr()));
-
- return NS_OK;
-}
-
-/* static */
-void nsVolume::FormatVolumeIOThread(const nsCString& aVolume)
-{
- MOZ_ASSERT(XRE_IsParentProcess());
-
- MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
- if (VolumeManager::State() != VolumeManager::VOLUMES_READY) {
- return;
- }
-
- AutoMounterFormatVolume(aVolume);
-}
-
-NS_IMETHODIMP nsVolume::Mount()
-{
- MOZ_ASSERT(XRE_IsParentProcess());
-
- XRE_GetIOMessageLoop()->PostTask(
- NewRunnableFunction(MountVolumeIOThread, NameStr()));
-
- return NS_OK;
-}
-
-/* static */
-void nsVolume::MountVolumeIOThread(const nsCString& aVolume)
-{
- MOZ_ASSERT(XRE_IsParentProcess());
-
- MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
- if (VolumeManager::State() != VolumeManager::VOLUMES_READY) {
- return;
- }
-
- AutoMounterMountVolume(aVolume);
-}
-
-NS_IMETHODIMP nsVolume::Unmount()
-{
- MOZ_ASSERT(XRE_IsParentProcess());
-
- XRE_GetIOMessageLoop()->PostTask(
- NewRunnableFunction(UnmountVolumeIOThread, NameStr()));
-
- return NS_OK;
-}
-
-/* static */
-void nsVolume::UnmountVolumeIOThread(const nsCString& aVolume)
-{
- MOZ_ASSERT(XRE_IsParentProcess());
-
- MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
- if (VolumeManager::State() != VolumeManager::VOLUMES_READY) {
- return;
- }
-
- AutoMounterUnmountVolume(aVolume);
-}
-
-void
-nsVolume::LogState() const
-{
- if (mState == nsIVolume::STATE_MOUNTED) {
- LOG("nsVolume: %s state %s @ '%s' gen %d locked %d fake %d "
- "media %d sharing %d formatting %d unmounting %d removable %d hotswappable %d",
- NameStr().get(), StateStr(), MountPointStr().get(),
- MountGeneration(), (int)IsMountLocked(), (int)IsFake(),
- (int)IsMediaPresent(), (int)IsSharing(),
- (int)IsFormatting(), (int)IsUnmounting(),
- (int)IsRemovable(), (int)IsHotSwappable());
- return;
- }
-
- LOG("nsVolume: %s state %s", NameStr().get(), StateStr());
-}
-
-void nsVolume::UpdateMountLock(nsVolume* aOldVolume)
-{
- MOZ_ASSERT(NS_IsMainThread());
-
- bool oldMountLocked = aOldVolume ? aOldVolume->mMountLocked : false;
- if (mState != nsIVolume::STATE_MOUNTED) {
- // Since we're not in the mounted state, we need to
- // forgot whatever mount generation we may have had.
- mMountGeneration = -1;
- mMountLocked = oldMountLocked;
- return;
- }
-
- int32_t oldMountGeneration = aOldVolume ? aOldVolume->mMountGeneration : -1;
- if (mMountGeneration == oldMountGeneration) {
- // No change in mount generation, nothing else to do
- mMountLocked = oldMountLocked;
- return;
- }
-
- if (!XRE_IsParentProcess()) {
- // Child processes just track the state, not maintain it.
- return;
- }
-
- // Notify the Volume on IOThread whether the volume is locked or not.
- nsCOMPtr<nsIPowerManagerService> pmService =
- do_GetService(POWERMANAGERSERVICE_CONTRACTID);
- if (!pmService) {
- return;
- }
- nsString mountLockName;
- GetMountLockName(mountLockName);
- nsString mountLockState;
- pmService->GetWakeLockState(mountLockName, mountLockState);
- UpdateMountLock(mountLockState);
-}
-
-void
-nsVolume::UpdateMountLock(const nsAString& aMountLockState)
-{
- MOZ_ASSERT(XRE_IsParentProcess());
- MOZ_ASSERT(NS_IsMainThread());
-
- // There are 3 states, unlocked, locked-background, and locked-foreground
- // I figured it was easier to use negtive logic and compare for unlocked.
- UpdateMountLock(!aMountLockState.EqualsLiteral("unlocked"));
-}
-
-void
-nsVolume::UpdateMountLock(bool aMountLocked)
-{
- MOZ_ASSERT(XRE_IsParentProcess());
- MOZ_ASSERT(NS_IsMainThread());
-
- if (aMountLocked == mMountLocked) {
- return;
- }
- // The locked/unlocked state changed. Tell IOThread about it.
- mMountLocked = aMountLocked;
- LogState();
- XRE_GetIOMessageLoop()->PostTask(
- NewRunnableFunction(Volume::UpdateMountLock,
- NS_LossyConvertUTF16toASCII(Name()),
- MountGeneration(), aMountLocked));
-}
-
-void
-nsVolume::SetIsFake(bool aIsFake)
-{
- mIsFake = aIsFake;
- if (mIsFake) {
- // The media is always present for fake volumes.
- mIsMediaPresent = true;
- MOZ_ASSERT(!mIsSharing);
- }
-}
-
-void
-nsVolume::SetIsRemovable(bool aIsRemovable)
-{
- mIsRemovable = aIsRemovable;
- if (!mIsRemovable) {
- mIsHotSwappable = false;
- }
-}
-
-void
-nsVolume::SetIsHotSwappable(bool aIsHotSwappable)
-{
- mIsHotSwappable = aIsHotSwappable;
- if (mIsHotSwappable) {
- mIsRemovable = true;
- }
-}
-
-void
-nsVolume::SetState(int32_t aState)
-{
- static int32_t sMountGeneration = 0;
-
- MOZ_ASSERT(XRE_IsParentProcess());
- MOZ_ASSERT(NS_IsMainThread());
- MOZ_ASSERT(IsFake());
-
- if (aState == mState) {
- return;
- }
-
- if (aState == nsIVolume::STATE_MOUNTED) {
- mMountGeneration = ++sMountGeneration;
- }
-
- mState = aState;
-}
-
-} // system
-} // mozilla
diff --git a/dom/system/gonk/nsVolume.h b/dom/system/gonk/nsVolume.h
deleted file mode 100644
index 88be425f6c..0000000000
--- a/dom/system/gonk/nsVolume.h
+++ /dev/null
@@ -1,114 +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/. */
-
-#ifndef mozilla_system_nsvolume_h__
-#define mozilla_system_nsvolume_h__
-
-#include "nsCOMPtr.h"
-#include "nsIVolume.h"
-#include "nsString.h"
-#include "nsTArray.h"
-
-namespace mozilla {
-namespace system {
-
-class Volume;
-
-class nsVolume : public nsIVolume
-{
-public:
- NS_DECL_THREADSAFE_ISUPPORTS
- NS_DECL_NSIVOLUME
-
- // This constructor is used by the UpdateVolumeRunnable constructor
- nsVolume(const Volume* aVolume);
-
- // This constructor is used by nsVolumeService::SetFakeVolumeState
- nsVolume(const nsVolume* aVolume);
-
- // This constructor is used by ContentChild::RecvFileSystemUpdate which is
- // used to update the volume cache maintained in the child process.
- nsVolume(const nsAString& aName, const nsAString& aMountPoint,
- const int32_t& aState, const int32_t& aMountGeneration,
- const bool& aIsMediaPresent, const bool& aIsSharing,
- const bool& aIsFormatting, const bool& aIsFake,
- const bool& aIsUnmounting, const bool& aIsRemovable,
- const bool& aIsHotSwappable)
- : mName(aName),
- mMountPoint(aMountPoint),
- mState(aState),
- mMountGeneration(aMountGeneration),
- mMountLocked(false),
- mIsFake(aIsFake),
- mIsMediaPresent(aIsMediaPresent),
- mIsSharing(aIsSharing),
- mIsFormatting(aIsFormatting),
- mIsUnmounting(aIsUnmounting),
- mIsRemovable(aIsRemovable),
- mIsHotSwappable(aIsHotSwappable)
- {
- }
-
- bool Equals(nsIVolume* aVolume);
- void UpdateMountLock(nsVolume* aOldVolume);
-
- void LogState() const;
-
- const nsString& Name() const { return mName; }
- nsCString NameStr() const { return NS_LossyConvertUTF16toASCII(mName); }
-
- void Dump(const char* aLabel) const;
-
- int32_t MountGeneration() const { return mMountGeneration; }
- bool IsMountLocked() const { return mMountLocked; }
-
- const nsString& MountPoint() const { return mMountPoint; }
- nsCString MountPointStr() const { return NS_LossyConvertUTF16toASCII(mMountPoint); }
-
- int32_t State() const { return mState; }
- const char* StateStr() const { return NS_VolumeStateStr(mState); }
-
- bool IsFake() const { return mIsFake; }
- bool IsMediaPresent() const { return mIsMediaPresent; }
- bool IsSharing() const { return mIsSharing; }
- bool IsFormatting() const { return mIsFormatting; }
- bool IsUnmounting() const { return mIsUnmounting; }
- bool IsRemovable() const { return mIsRemovable; }
- bool IsHotSwappable() const { return mIsHotSwappable; }
-
- typedef nsTArray<RefPtr<nsVolume> > Array;
-
-private:
- virtual ~nsVolume() {} // MozExternalRefCountType complains if this is non-virtual
-
- friend class nsVolumeService; // Calls the following XxxMountLock functions
- void UpdateMountLock(const nsAString& aMountLockState);
- void UpdateMountLock(bool aMountLocked);
-
- void SetIsFake(bool aIsFake);
- void SetIsRemovable(bool aIsRemovable);
- void SetIsHotSwappable(bool aIsHotSwappble);
- void SetState(int32_t aState);
- static void FormatVolumeIOThread(const nsCString& aVolume);
- static void MountVolumeIOThread(const nsCString& aVolume);
- static void UnmountVolumeIOThread(const nsCString& aVolume);
-
- nsString mName;
- nsString mMountPoint;
- int32_t mState;
- int32_t mMountGeneration;
- bool mMountLocked;
- bool mIsFake;
- bool mIsMediaPresent;
- bool mIsSharing;
- bool mIsFormatting;
- bool mIsUnmounting;
- bool mIsRemovable;
- bool mIsHotSwappable;
-};
-
-} // system
-} // mozilla
-
-#endif // mozilla_system_nsvolume_h__
diff --git a/dom/system/gonk/nsVolumeMountLock.cpp b/dom/system/gonk/nsVolumeMountLock.cpp
deleted file mode 100644
index 288c0f6892..0000000000
--- a/dom/system/gonk/nsVolumeMountLock.cpp
+++ /dev/null
@@ -1,171 +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 "nsVolumeMountLock.h"
-
-#include "mozilla/dom/ContentChild.h"
-#include "mozilla/Services.h"
-
-#include "nsIObserverService.h"
-#include "nsIPowerManagerService.h"
-#include "nsIVolume.h"
-#include "nsIVolumeService.h"
-#include "nsString.h"
-#include "nsXULAppAPI.h"
-
-#undef VOLUME_MANAGER_LOG_TAG
-#define VOLUME_MANAGER_LOG_TAG "nsVolumeMountLock"
-#include "VolumeManagerLog.h"
-#include "nsServiceManagerUtils.h"
-#include "mozilla/dom/power/PowerManagerService.h"
-
-using namespace mozilla::dom;
-using namespace mozilla::services;
-
-namespace mozilla {
-namespace system {
-
-NS_IMPL_ISUPPORTS(nsVolumeMountLock, nsIVolumeMountLock,
- nsIObserver, nsISupportsWeakReference)
-
-// static
-already_AddRefed<nsVolumeMountLock>
-nsVolumeMountLock::Create(const nsAString& aVolumeName)
-{
- DBG("nsVolumeMountLock::Create called");
-
- RefPtr<nsVolumeMountLock> mountLock = new nsVolumeMountLock(aVolumeName);
- nsresult rv = mountLock->Init();
- NS_ENSURE_SUCCESS(rv, nullptr);
-
- return mountLock.forget();
-}
-
-nsVolumeMountLock::nsVolumeMountLock(const nsAString& aVolumeName)
- : mVolumeName(aVolumeName),
- mVolumeGeneration(-1),
- mUnlocked(false)
-{
-}
-
-//virtual
-nsVolumeMountLock::~nsVolumeMountLock()
-{
- Unlock();
-}
-
-nsresult nsVolumeMountLock::Init()
-{
- LOG("nsVolumeMountLock created for '%s'",
- NS_LossyConvertUTF16toASCII(mVolumeName).get());
-
- // Add ourselves as an Observer. It's important that we use a weak
- // reference here. If we used a strong reference, then that reference
- // would prevent this object from being destructed.
- nsCOMPtr<nsIObserverService> obs = GetObserverService();
- obs->AddObserver(this, NS_VOLUME_STATE_CHANGED, true /*weak*/);
-
- // Get the initial mountGeneration and grab a lock.
- nsCOMPtr<nsIVolumeService> vs = do_GetService(NS_VOLUMESERVICE_CONTRACTID);
- NS_ENSURE_TRUE(vs, NS_ERROR_FAILURE);
-
- nsCOMPtr<nsIVolume> vol;
- nsresult rv = vs->GetVolumeByName(mVolumeName, getter_AddRefs(vol));
- if (NS_WARN_IF(NS_FAILED(rv))) {
- return rv;
- }
- rv = vol->GetMountGeneration(&mVolumeGeneration);
- NS_ENSURE_SUCCESS(rv, rv);
-
- return Lock(vol);
-}
-
-NS_IMETHODIMP nsVolumeMountLock::Unlock()
-{
- LOG("nsVolumeMountLock released for '%s'",
- NS_LossyConvertUTF16toASCII(mVolumeName).get());
-
- mUnlocked = true;
- mWakeLock = nullptr;
-
- // While we don't really need to remove weak observers, we do so anyways
- // since it will reduce the number of times Observe gets called.
- nsCOMPtr<nsIObserverService> obs = GetObserverService();
- obs->RemoveObserver(this, NS_VOLUME_STATE_CHANGED);
- return NS_OK;
-}
-
-NS_IMETHODIMP nsVolumeMountLock::Observe(nsISupports* aSubject, const char* aTopic, const char16_t* aData)
-{
- if (strcmp(aTopic, NS_VOLUME_STATE_CHANGED) != 0) {
- return NS_OK;
- }
- if (mUnlocked) {
- // We're not locked anymore, so we don't need to look at the notifications.
- return NS_OK;
- }
-
- nsCOMPtr<nsIVolume> vol = do_QueryInterface(aSubject);
- if (!vol) {
- return NS_OK;
- }
- nsString volName;
- vol->GetName(volName);
- if (!volName.Equals(mVolumeName)) {
- return NS_OK;
- }
- int32_t state;
- nsresult rv = vol->GetState(&state);
- NS_ENSURE_SUCCESS(rv, rv);
-
- if (state != nsIVolume::STATE_MOUNTED) {
- mWakeLock = nullptr;
- mVolumeGeneration = -1;
- return NS_OK;
- }
-
- int32_t mountGeneration;
- rv = vol->GetMountGeneration(&mountGeneration);
- NS_ENSURE_SUCCESS(rv, rv);
-
- DBG("nsVolumeMountLock::Observe mountGeneration = %d mVolumeGeneration = %d",
- mountGeneration, mVolumeGeneration);
-
- if (mVolumeGeneration == mountGeneration) {
- return NS_OK;
- }
-
- // The generation changed, which means that any wakelock we may have
- // been holding is now invalid. Grab a new wakelock for the new generation
- // number.
-
- mWakeLock = nullptr;
- mVolumeGeneration = mountGeneration;
-
- return Lock(vol);
-}
-
-nsresult
-nsVolumeMountLock::Lock(nsIVolume* aVolume)
-{
- RefPtr<power::PowerManagerService> pmService =
- power::PowerManagerService::GetInstance();
- NS_ENSURE_TRUE(pmService, NS_ERROR_FAILURE);
-
- nsString mountLockName;
- aVolume->GetMountLockName(mountLockName);
-
- ErrorResult err;
- mWakeLock = pmService->NewWakeLock(mountLockName, nullptr, err);
- if (err.Failed()) {
- return err.StealNSResult();
- }
-
- LOG("nsVolumeMountLock acquired for '%s' gen %d",
- NS_LossyConvertUTF16toASCII(mVolumeName).get(), mVolumeGeneration);
- return NS_OK;
-}
-
-} // namespace system
-} // namespace mozilla
diff --git a/dom/system/gonk/nsVolumeMountLock.h b/dom/system/gonk/nsVolumeMountLock.h
deleted file mode 100644
index caf5b2ad51..0000000000
--- a/dom/system/gonk/nsVolumeMountLock.h
+++ /dev/null
@@ -1,56 +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/. */
-
-#ifndef mozilla_system_nsvolumemountlock_h__
-#define mozilla_system_nsvolumemountlock_h__
-
-#include "nsIVolumeMountLock.h"
-
-#include "mozilla/dom/WakeLock.h"
-#include "nsIObserver.h"
-#include "nsString.h"
-#include "nsTArray.h"
-#include "nsWeakReference.h"
-
-class nsIVolume;
-
-namespace mozilla {
-namespace system {
-
-/* The VolumeMountLock is designed so that it can be used in the Child or
- * Parent process. While the VolumeMountLock object exists, then the
- * VolumeManager/AutoMounter will prevent a mounted volume from being
- * shared with the PC.
- */
-
-class nsVolumeMountLock final : public nsIVolumeMountLock,
- public nsIObserver,
- public nsSupportsWeakReference
-{
-public:
- NS_DECL_ISUPPORTS
- NS_DECL_NSIOBSERVER
- NS_DECL_NSIVOLUMEMOUNTLOCK
-
- static already_AddRefed<nsVolumeMountLock> Create(const nsAString& volumeName);
-
- const nsString& VolumeName() const { return mVolumeName; }
-
-private:
- nsVolumeMountLock(const nsAString& aVolumeName);
- ~nsVolumeMountLock();
-
- nsresult Init();
- nsresult Lock(nsIVolume* aVolume);
-
- RefPtr<dom::WakeLock> mWakeLock;
- nsString mVolumeName;
- int32_t mVolumeGeneration;
- bool mUnlocked;
-};
-
-} // namespace system
-} // namespace mozilla
-
-#endif // mozilla_system_nsvolumemountlock_h__
diff --git a/dom/system/gonk/nsVolumeService.cpp b/dom/system/gonk/nsVolumeService.cpp
deleted file mode 100644
index 48d95c26a7..0000000000
--- a/dom/system/gonk/nsVolumeService.cpp
+++ /dev/null
@@ -1,553 +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 "nsVolumeService.h"
-
-#include "Volume.h"
-#include "VolumeManager.h"
-#include "VolumeServiceIOThread.h"
-
-#include "nsCOMPtr.h"
-#include "nsDependentSubstring.h"
-#include "nsIDOMWakeLockListener.h"
-#include "nsIMutableArray.h"
-#include "nsIObserver.h"
-#include "nsIObserverService.h"
-#include "nsIPowerManagerService.h"
-#include "nsISupportsPrimitives.h"
-#include "nsISupportsUtils.h"
-#include "nsIVolume.h"
-#include "nsIVolumeService.h"
-#include "nsLocalFile.h"
-#include "nsServiceManagerUtils.h"
-#include "nsString.h"
-#include "nsTArray.h"
-#include "nsThreadUtils.h"
-#include "nsVolumeMountLock.h"
-#include "nsXULAppAPI.h"
-#include "mozilla/dom/ContentChild.h"
-#include "mozilla/Services.h"
-#include "base/task.h"
-
-#undef VOLUME_MANAGER_LOG_TAG
-#define VOLUME_MANAGER_LOG_TAG "nsVolumeService"
-#include "VolumeManagerLog.h"
-
-#include <stdlib.h>
-
-using namespace mozilla::dom;
-using namespace mozilla::services;
-
-namespace mozilla {
-namespace system {
-
-NS_IMPL_ISUPPORTS(nsVolumeService,
- nsIVolumeService,
- nsIDOMMozWakeLockListener)
-
-StaticRefPtr<nsVolumeService> nsVolumeService::sSingleton;
-
-// static
-already_AddRefed<nsVolumeService>
-nsVolumeService::GetSingleton()
-{
- MOZ_ASSERT(NS_IsMainThread());
-
- if (!sSingleton) {
- sSingleton = new nsVolumeService();
- }
- RefPtr<nsVolumeService> volumeService = sSingleton.get();
- return volumeService.forget();
-}
-
-// static
-void
-nsVolumeService::Shutdown()
-{
- if (!sSingleton) {
- return;
- }
- if (!XRE_IsParentProcess()) {
- sSingleton = nullptr;
- return;
- }
-
- nsCOMPtr<nsIPowerManagerService> pmService =
- do_GetService(POWERMANAGERSERVICE_CONTRACTID);
- if (pmService) {
- pmService->RemoveWakeLockListener(sSingleton.get());
- }
-
- XRE_GetIOMessageLoop()->PostTask(
- NewRunnableFunction(ShutdownVolumeServiceIOThread));
-
- sSingleton = nullptr;
-}
-
-nsVolumeService::nsVolumeService()
- : mArrayMonitor("nsVolumeServiceArray"),
- mGotVolumesFromParent(false)
-{
- sSingleton = this;
-
- if (!XRE_IsParentProcess()) {
- // VolumeServiceIOThread and the WakeLock listener should only run in the
- // parent, so we return early.
- return;
- }
-
- // Startup the IOThread side of things. The actual volume changes
- // are captured by the IOThread and forwarded to main thread.
- XRE_GetIOMessageLoop()->PostTask(
- NewRunnableFunction(InitVolumeServiceIOThread, this));
-
- nsCOMPtr<nsIPowerManagerService> pmService =
- do_GetService(POWERMANAGERSERVICE_CONTRACTID);
- if (!pmService) {
- return;
- }
- pmService->AddWakeLockListener(this);
-}
-
-nsVolumeService::~nsVolumeService()
-{
-}
-
-// Callback for nsIDOMMozWakeLockListener
-NS_IMETHODIMP
-nsVolumeService::Callback(const nsAString& aTopic, const nsAString& aState)
-{
- CheckMountLock(aTopic, aState);
- return NS_OK;
-}
-
-void nsVolumeService::DumpNoLock(const char* aLabel)
-{
- mArrayMonitor.AssertCurrentThreadOwns();
-
- nsVolume::Array::size_type numVolumes = mVolumeArray.Length();
-
- if (numVolumes == 0) {
- LOG("%s: No Volumes!", aLabel);
- return;
- }
- nsVolume::Array::index_type volIndex;
- for (volIndex = 0; volIndex < numVolumes; volIndex++) {
- RefPtr<nsVolume> vol = mVolumeArray[volIndex];
- vol->Dump(aLabel);
- }
-}
-
-NS_IMETHODIMP
-nsVolumeService::Dump(const nsAString& aLabel)
-{
- MonitorAutoLock autoLock(mArrayMonitor);
- DumpNoLock(NS_LossyConvertUTF16toASCII(aLabel).get());
- return NS_OK;
-}
-
-NS_IMETHODIMP nsVolumeService::GetVolumeByName(const nsAString& aVolName, nsIVolume **aResult)
-{
- MonitorAutoLock autoLock(mArrayMonitor);
-
- RefPtr<nsVolume> vol = FindVolumeByName(aVolName);
- if (!vol) {
- return NS_ERROR_NOT_AVAILABLE;
- }
-
- vol.forget(aResult);
- return NS_OK;
-}
-
-NS_IMETHODIMP
-nsVolumeService::GetVolumeByPath(const nsAString& aPath, nsIVolume **aResult)
-{
- NS_ConvertUTF16toUTF8 utf8Path(aPath);
- char realPathBuf[PATH_MAX];
-
- while (realpath(utf8Path.get(), realPathBuf) < 0) {
- if (errno != ENOENT) {
- ERR("GetVolumeByPath: realpath on '%s' failed: %d", utf8Path.get(), errno);
- return NSRESULT_FOR_ERRNO();
- }
- // The pathname we were passed doesn't exist, so we try stripping off trailing
- // components until we get a successful call to realpath, or until we run out
- // of components (if we finally get to /something then we also stop).
- int32_t slashIndex = utf8Path.RFindChar('/');
- if ((slashIndex == kNotFound) || (slashIndex == 0)) {
- errno = ENOENT;
- ERR("GetVolumeByPath: realpath on '%s' failed.", utf8Path.get());
- return NSRESULT_FOR_ERRNO();
- }
- utf8Path.Assign(Substring(utf8Path, 0, slashIndex));
- }
-
- // The volume mount point is always a directory. Something like /mnt/sdcard
- // Once we have a full qualified pathname with symlinks removed (which is
- // what realpath does), we basically check if aPath starts with the mount
- // point, but we don't want to have /mnt/sdcard match /mnt/sdcardfoo but we
- // do want it to match /mnt/sdcard/foo
- // So we add a trailing slash to the mount point and the pathname passed in
- // prior to doing the comparison.
-
- strlcat(realPathBuf, "/", sizeof(realPathBuf));
-
- MonitorAutoLock autoLock(mArrayMonitor);
-
- nsVolume::Array::size_type numVolumes = mVolumeArray.Length();
- nsVolume::Array::index_type volIndex;
- for (volIndex = 0; volIndex < numVolumes; volIndex++) {
- RefPtr<nsVolume> vol = mVolumeArray[volIndex];
- NS_ConvertUTF16toUTF8 volMountPointSlash(vol->MountPoint());
- volMountPointSlash.Append('/');
- nsDependentCSubstring testStr(realPathBuf, volMountPointSlash.Length());
- if (volMountPointSlash.Equals(testStr)) {
- vol.forget(aResult);
- return NS_OK;
- }
- }
- return NS_ERROR_FILE_NOT_FOUND;
-}
-
-NS_IMETHODIMP
-nsVolumeService::CreateOrGetVolumeByPath(const nsAString& aPath, nsIVolume** aResult)
-{
- nsresult rv = GetVolumeByPath(aPath, aResult);
- if (rv == NS_OK) {
- return NS_OK;
- }
-
- // In order to support queries by the updater, we will fabricate a volume
- // from the pathname, so that the caller can determine the volume size.
- nsCOMPtr<nsIVolume> vol = new nsVolume(NS_LITERAL_STRING("fake"),
- aPath, nsIVolume::STATE_MOUNTED,
- -1 /* generation */,
- true /* isMediaPresent*/,
- false /* isSharing */,
- false /* isFormatting */,
- true /* isFake */,
- false /* isUnmounting */,
- false /* isRemovable */,
- false /* isHotSwappable*/);
- vol.forget(aResult);
- return NS_OK;
-}
-
-NS_IMETHODIMP
-nsVolumeService::GetVolumeNames(nsIArray** aVolNames)
-{
- NS_ENSURE_ARG_POINTER(aVolNames);
- MonitorAutoLock autoLock(mArrayMonitor);
-
- *aVolNames = nullptr;
-
- nsresult rv;
- nsCOMPtr<nsIMutableArray> volNames =
- do_CreateInstance(NS_ARRAY_CONTRACTID, &rv);
- NS_ENSURE_SUCCESS(rv, rv);
-
- nsVolume::Array::size_type numVolumes = mVolumeArray.Length();
- nsVolume::Array::index_type volIndex;
- for (volIndex = 0; volIndex < numVolumes; volIndex++) {
- RefPtr<nsVolume> vol = mVolumeArray[volIndex];
- nsCOMPtr<nsISupportsString> isupportsString =
- do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID, &rv);
- NS_ENSURE_SUCCESS(rv, rv);
-
- rv = isupportsString->SetData(vol->Name());
- NS_ENSURE_SUCCESS(rv, rv);
-
- rv = volNames->AppendElement(isupportsString, false);
- NS_ENSURE_SUCCESS(rv, rv);
- }
-
- volNames.forget(aVolNames);
- return NS_OK;
-}
-
-void
-nsVolumeService::GetVolumesForIPC(nsTArray<VolumeInfo>* aResult)
-{
- MOZ_ASSERT(XRE_IsParentProcess());
- MOZ_ASSERT(NS_IsMainThread());
-
- MonitorAutoLock autoLock(mArrayMonitor);
-
- nsVolume::Array::size_type numVolumes = mVolumeArray.Length();
- nsVolume::Array::index_type volIndex;
- for (volIndex = 0; volIndex < numVolumes; volIndex++) {
- RefPtr<nsVolume> vol = mVolumeArray[volIndex];
- VolumeInfo* volInfo = aResult->AppendElement();
-
- volInfo->name() = vol->mName;
- volInfo->mountPoint() = vol->mMountPoint;
- volInfo->volState() = vol->mState;
- volInfo->mountGeneration() = vol->mMountGeneration;
- volInfo->isMediaPresent() = vol->mIsMediaPresent;
- volInfo->isSharing() = vol->mIsSharing;
- volInfo->isFormatting() = vol->mIsFormatting;
- volInfo->isFake() = vol->mIsFake;
- volInfo->isUnmounting() = vol->mIsUnmounting;
- volInfo->isRemovable() = vol->mIsRemovable;
- volInfo->isHotSwappable() = vol->mIsHotSwappable;
- }
-}
-
-void
-nsVolumeService::RecvVolumesFromParent(const nsTArray<VolumeInfo>& aVolumes)
-{
- if (XRE_IsParentProcess()) {
- // We are the parent. Therefore our volumes are already correct.
- return;
- }
- if (mGotVolumesFromParent) {
- // We've already done this, no need to do it again.
- return;
- }
-
- for (uint32_t i = 0; i < aVolumes.Length(); i++) {
- const VolumeInfo& volInfo(aVolumes[i]);
- RefPtr<nsVolume> vol = new nsVolume(volInfo.name(),
- volInfo.mountPoint(),
- volInfo.volState(),
- volInfo.mountGeneration(),
- volInfo.isMediaPresent(),
- volInfo.isSharing(),
- volInfo.isFormatting(),
- volInfo.isFake(),
- volInfo.isUnmounting(),
- volInfo.isRemovable(),
- volInfo.isHotSwappable());
- UpdateVolume(vol, false);
- }
-}
-
-NS_IMETHODIMP
-nsVolumeService::CreateMountLock(const nsAString& aVolumeName, nsIVolumeMountLock **aResult)
-{
- nsCOMPtr<nsIVolumeMountLock> mountLock = nsVolumeMountLock::Create(aVolumeName);
- if (!mountLock) {
- return NS_ERROR_NOT_AVAILABLE;
- }
- mountLock.forget(aResult);
- return NS_OK;
-}
-
-void
-nsVolumeService::CheckMountLock(const nsAString& aMountLockName,
- const nsAString& aMountLockState)
-{
- MOZ_ASSERT(XRE_IsParentProcess());
- MOZ_ASSERT(NS_IsMainThread());
-
- RefPtr<nsVolume> vol = FindVolumeByMountLockName(aMountLockName);
- if (vol) {
- vol->UpdateMountLock(aMountLockState);
- }
-}
-
-already_AddRefed<nsVolume>
-nsVolumeService::FindVolumeByMountLockName(const nsAString& aMountLockName)
-{
- MonitorAutoLock autoLock(mArrayMonitor);
-
- nsVolume::Array::size_type numVolumes = mVolumeArray.Length();
- nsVolume::Array::index_type volIndex;
- for (volIndex = 0; volIndex < numVolumes; volIndex++) {
- RefPtr<nsVolume> vol = mVolumeArray[volIndex];
- nsString mountLockName;
- vol->GetMountLockName(mountLockName);
- if (mountLockName.Equals(aMountLockName)) {
- return vol.forget();
- }
- }
- return nullptr;
-}
-
-already_AddRefed<nsVolume>
-nsVolumeService::FindVolumeByName(const nsAString& aName, nsVolume::Array::index_type* aIndex)
-{
- mArrayMonitor.AssertCurrentThreadOwns();
-
- nsVolume::Array::size_type numVolumes = mVolumeArray.Length();
- nsVolume::Array::index_type volIndex;
- for (volIndex = 0; volIndex < numVolumes; volIndex++) {
- RefPtr<nsVolume> vol = mVolumeArray[volIndex];
- if (vol->Name().Equals(aName)) {
- if (aIndex) {
- *aIndex = volIndex;
- }
- return vol.forget();
- }
- }
- return nullptr;
-}
-
-void
-nsVolumeService::UpdateVolume(nsVolume* aVolume, bool aNotifyObservers)
-{
- MOZ_ASSERT(NS_IsMainThread());
-
- {
- MonitorAutoLock autoLock(mArrayMonitor);
- nsVolume::Array::index_type volIndex;
- RefPtr<nsVolume> vol = FindVolumeByName(aVolume->Name(), &volIndex);
- if (!vol) {
- mVolumeArray.AppendElement(aVolume);
- } else if (vol->Equals(aVolume) || (!vol->IsFake() && aVolume->IsFake())) {
- // Ignore if nothing changed or if a fake tries to override a real volume.
- return;
- } else {
- mVolumeArray.ReplaceElementAt(volIndex, aVolume);
- }
- aVolume->UpdateMountLock(vol);
- }
-
- if (!aNotifyObservers) {
- return;
- }
-
- nsCOMPtr<nsIObserverService> obs = GetObserverService();
- if (!obs) {
- return;
- }
- NS_ConvertUTF8toUTF16 stateStr(aVolume->StateStr());
- obs->NotifyObservers(aVolume, NS_VOLUME_STATE_CHANGED, stateStr.get());
-}
-
-NS_IMETHODIMP
-nsVolumeService::CreateFakeVolume(const nsAString& name, const nsAString& path)
-{
- if (XRE_IsParentProcess()) {
- RefPtr<nsVolume> vol = new nsVolume(name, path, nsIVolume::STATE_INIT,
- -1 /* mountGeneration */,
- true /* isMediaPresent */,
- false /* isSharing */,
- false /* isFormatting */,
- true /* isFake */,
- false /* isUnmounting */,
- false /* isRemovable */,
- false /* isHotSwappable */);
- vol->SetState(nsIVolume::STATE_MOUNTED);
- vol->LogState();
- UpdateVolume(vol.get());
- return NS_OK;
- }
-
- ContentChild::GetSingleton()->SendCreateFakeVolume(nsString(name), nsString(path));
- return NS_OK;
-}
-
-NS_IMETHODIMP
-nsVolumeService::SetFakeVolumeState(const nsAString& name, int32_t state)
-{
- if (XRE_IsParentProcess()) {
- RefPtr<nsVolume> vol;
- {
- MonitorAutoLock autoLock(mArrayMonitor);
- vol = FindVolumeByName(name);
- }
- if (!vol || !vol->IsFake()) {
- return NS_ERROR_NOT_AVAILABLE;
- }
-
- // Clone the existing volume so we can replace it
- RefPtr<nsVolume> volume = new nsVolume(vol);
- volume->SetState(state);
- volume->LogState();
- UpdateVolume(volume.get());
- return NS_OK;
- }
-
- ContentChild::GetSingleton()->SendSetFakeVolumeState(nsString(name), state);
- return NS_OK;
-}
-
-NS_IMETHODIMP
-nsVolumeService::RemoveFakeVolume(const nsAString& name)
-{
- if (XRE_IsParentProcess()) {
- SetFakeVolumeState(name, nsIVolume::STATE_NOMEDIA);
- RemoveVolumeByName(name);
- return NS_OK;
- }
-
- ContentChild::GetSingleton()->SendRemoveFakeVolume(nsString(name));
- return NS_OK;
-}
-
-void
-nsVolumeService::RemoveVolumeByName(const nsAString& aName)
-{
- {
- MonitorAutoLock autoLock(mArrayMonitor);
- nsVolume::Array::index_type volIndex;
- RefPtr<nsVolume> vol = FindVolumeByName(aName, &volIndex);
- if (!vol) {
- return;
- }
- mVolumeArray.RemoveElementAt(volIndex);
- }
-
- if (XRE_IsParentProcess()) {
- nsCOMPtr<nsIObserverService> obs = GetObserverService();
- if (!obs) {
- return;
- }
- obs->NotifyObservers(nullptr, NS_VOLUME_REMOVED, nsString(aName).get());
- }
-}
-
-/***************************************************************************
-* The UpdateVolumeRunnable creates an nsVolume and updates the main thread
-* data structure while running on the main thread.
-*/
-class UpdateVolumeRunnable : public Runnable
-{
-public:
- UpdateVolumeRunnable(nsVolumeService* aVolumeService, const Volume* aVolume)
- : mVolumeService(aVolumeService),
- mVolume(new nsVolume(aVolume))
- {
- MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
- }
-
- NS_IMETHOD Run() override
- {
- MOZ_ASSERT(NS_IsMainThread());
- DBG("UpdateVolumeRunnable::Run '%s' state %s gen %d locked %d "
- "media %d sharing %d formatting %d unmounting %d removable %d hotswappable %d",
- mVolume->NameStr().get(), mVolume->StateStr(),
- mVolume->MountGeneration(), (int)mVolume->IsMountLocked(),
- (int)mVolume->IsMediaPresent(), mVolume->IsSharing(),
- mVolume->IsFormatting(), mVolume->IsUnmounting(),
- (int)mVolume->IsRemovable(), (int)mVolume->IsHotSwappable());
-
- mVolumeService->UpdateVolume(mVolume);
- mVolumeService = nullptr;
- mVolume = nullptr;
- return NS_OK;
- }
-
-private:
- RefPtr<nsVolumeService> mVolumeService;
- RefPtr<nsVolume> mVolume;
-};
-
-void
-nsVolumeService::UpdateVolumeIOThread(const Volume* aVolume)
-{
- DBG("UpdateVolumeIOThread: Volume '%s' state %s mount '%s' gen %d locked %d "
- "media %d sharing %d formatting %d unmounting %d removable %d hotswappable %d",
- aVolume->NameStr(), aVolume->StateStr(), aVolume->MountPoint().get(),
- aVolume->MountGeneration(), (int)aVolume->IsMountLocked(),
- (int)aVolume->MediaPresent(), (int)aVolume->IsSharing(),
- (int)aVolume->IsFormatting(), (int)aVolume->IsUnmounting(),
- (int)aVolume->IsRemovable(), (int)aVolume->IsHotSwappable());
- MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
- NS_DispatchToMainThread(new UpdateVolumeRunnable(this, aVolume));
-}
-
-} // namespace system
-} // namespace mozilla
diff --git a/dom/system/gonk/nsVolumeService.h b/dom/system/gonk/nsVolumeService.h
deleted file mode 100644
index 9bddc0b8fe..0000000000
--- a/dom/system/gonk/nsVolumeService.h
+++ /dev/null
@@ -1,78 +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/. */
-
-#ifndef mozilla_system_nsvolumeservice_h__
-#define mozilla_system_nsvolumeservice_h__
-
-#include "mozilla/Monitor.h"
-#include "mozilla/RefPtr.h"
-#include "mozilla/StaticPtr.h"
-#include "nsCOMPtr.h"
-#include "nsIDOMWakeLockListener.h"
-#include "nsIVolume.h"
-#include "nsIVolumeService.h"
-#include "nsVolume.h"
-
-namespace mozilla {
-
-namespace dom {
-class VolumeInfo;
-} // dom
-
-namespace system {
-
-class Volume;
-
-/***************************************************************************
-* The nsVolumeData class encapsulates the data that is updated/maintained
-* on the main thread in order to support the nsIVolume and nsIVolumeService
-* classes.
-*/
-
-class nsVolumeService final : public nsIVolumeService,
- public nsIDOMMozWakeLockListener
-{
-public:
- NS_DECL_THREADSAFE_ISUPPORTS
- NS_DECL_NSIVOLUMESERVICE
- NS_DECL_NSIDOMMOZWAKELOCKLISTENER
-
- nsVolumeService();
-
- static already_AddRefed<nsVolumeService> GetSingleton();
- //static nsVolumeService* GetSingleton();
- static void Shutdown();
-
- void DumpNoLock(const char* aLabel);
-
- // To use this function, you have to create a new volume and pass it in.
- void UpdateVolume(nsVolume* aVolume, bool aNotifyObservers = true);
- void UpdateVolumeIOThread(const Volume* aVolume);
-
- void RecvVolumesFromParent(const nsTArray<dom::VolumeInfo>& aVolumes);
- void GetVolumesForIPC(nsTArray<dom::VolumeInfo>* aResult);
-
- void RemoveVolumeByName(const nsAString& aName);
-
-private:
- ~nsVolumeService();
-
- void CheckMountLock(const nsAString& aMountLockName,
- const nsAString& aMountLockState);
- already_AddRefed<nsVolume> FindVolumeByMountLockName(const nsAString& aMountLockName);
-
- already_AddRefed<nsVolume> FindVolumeByName(const nsAString& aName,
- nsVolume::Array::index_type* aIndex = nullptr);
-
- Monitor mArrayMonitor;
- nsVolume::Array mVolumeArray;
-
- static StaticRefPtr<nsVolumeService> sSingleton;
- bool mGotVolumesFromParent;
-};
-
-} // system
-} // mozilla
-
-#endif // mozilla_system_nsvolumeservice_h__
diff --git a/dom/system/gonk/nsVolumeStat.cpp b/dom/system/gonk/nsVolumeStat.cpp
deleted file mode 100644
index 11976237f7..0000000000
--- a/dom/system/gonk/nsVolumeStat.cpp
+++ /dev/null
@@ -1,33 +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 "nsVolumeStat.h"
-#include "nsString.h"
-
-namespace mozilla {
-namespace system {
-
-NS_IMPL_ISUPPORTS(nsVolumeStat, nsIVolumeStat)
-
-nsVolumeStat::nsVolumeStat(const nsAString& aPath)
-{
- if (statfs(NS_ConvertUTF16toUTF8(aPath).get(), &mStat) != 0) {
- memset(&mStat, 0, sizeof(mStat));
- }
-}
-
-NS_IMETHODIMP nsVolumeStat::GetTotalBytes(int64_t* aTotalBytes)
-{
- *aTotalBytes = mStat.f_blocks * mStat.f_bsize;
- return NS_OK;
-}
-
-NS_IMETHODIMP nsVolumeStat::GetFreeBytes(int64_t* aFreeBytes)
-{
- *aFreeBytes = mStat.f_bfree * mStat.f_bsize;
- return NS_OK;
-}
-
-} // system
-} // mozilla
diff --git a/dom/system/gonk/nsVolumeStat.h b/dom/system/gonk/nsVolumeStat.h
deleted file mode 100644
index 2ca03ed464..0000000000
--- a/dom/system/gonk/nsVolumeStat.h
+++ /dev/null
@@ -1,33 +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/. */
-
-#ifndef mozilla_system_nsvolumestat_h__
-#define mozilla_system_nsvolumestat_h__
-
-#include "nsIVolumeStat.h"
-#include "nsString.h"
-#include <sys/statfs.h>
-
-namespace mozilla {
-namespace system {
-
-class nsVolumeStat final : public nsIVolumeStat
-{
-public:
- NS_DECL_ISUPPORTS
- NS_DECL_NSIVOLUMESTAT
-
- nsVolumeStat(const nsAString& aPath);
-
-protected:
- ~nsVolumeStat() {}
-
-private:
- struct statfs mStat;
-};
-
-} // system
-} // mozilla
-
-#endif // mozilla_system_nsvolumestat_h__
diff --git a/dom/system/gonk/ril_consts.js b/dom/system/gonk/ril_consts.js
deleted file mode 100644
index af5b9d8e10..0000000000
--- a/dom/system/gonk/ril_consts.js
+++ /dev/null
@@ -1,3338 +0,0 @@
-/* Copyright 2012 Mozilla Foundation and Mozilla contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-// Set to true to debug all RIL layers
-this.DEBUG_ALL = false;
-
-// Set individually to debug specific layers
-this.DEBUG_WORKER = false || DEBUG_ALL;
-this.DEBUG_CONTENT_HELPER = false || DEBUG_ALL;
-this.DEBUG_RIL = false || DEBUG_ALL;
-
-this.REQUEST_GET_SIM_STATUS = 1;
-this.REQUEST_ENTER_SIM_PIN = 2;
-this.REQUEST_ENTER_SIM_PUK = 3;
-this.REQUEST_ENTER_SIM_PIN2 = 4;
-this.REQUEST_ENTER_SIM_PUK2 = 5;
-this.REQUEST_CHANGE_SIM_PIN = 6;
-this.REQUEST_CHANGE_SIM_PIN2 = 7;
-this.REQUEST_ENTER_NETWORK_DEPERSONALIZATION_CODE = 8;
-this.REQUEST_GET_CURRENT_CALLS = 9;
-this.REQUEST_DIAL = 10;
-this.REQUEST_GET_IMSI = 11;
-this.REQUEST_HANGUP = 12;
-this.REQUEST_HANGUP_WAITING_OR_BACKGROUND = 13;
-this.REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND = 14;
-this.REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE = 15;
-this.REQUEST_CONFERENCE = 16;
-this.REQUEST_UDUB = 17;
-this.REQUEST_LAST_CALL_FAIL_CAUSE = 18;
-this.REQUEST_SIGNAL_STRENGTH = 19;
-this.REQUEST_VOICE_REGISTRATION_STATE = 20;
-this.REQUEST_DATA_REGISTRATION_STATE = 21;
-this.REQUEST_OPERATOR = 22;
-this.REQUEST_RADIO_POWER = 23;
-this.REQUEST_DTMF = 24;
-this.REQUEST_SEND_SMS = 25;
-this.REQUEST_SEND_SMS_EXPECT_MORE = 26;
-this.REQUEST_SETUP_DATA_CALL = 27;
-this.REQUEST_SIM_IO = 28;
-this.REQUEST_SEND_USSD = 29;
-this.REQUEST_CANCEL_USSD = 30;
-this.REQUEST_GET_CLIR = 31;
-this.REQUEST_SET_CLIR = 32;
-this.REQUEST_QUERY_CALL_FORWARD_STATUS = 33;
-this.REQUEST_SET_CALL_FORWARD = 34;
-this.REQUEST_QUERY_CALL_WAITING = 35;
-this.REQUEST_SET_CALL_WAITING = 36;
-this.REQUEST_SMS_ACKNOWLEDGE = 37;
-this.REQUEST_GET_IMEI = 38;
-this.REQUEST_GET_IMEISV = 39;
-this.REQUEST_ANSWER = 40;
-this.REQUEST_DEACTIVATE_DATA_CALL = 41;
-this.REQUEST_QUERY_FACILITY_LOCK = 42;
-this.REQUEST_SET_FACILITY_LOCK = 43;
-this.REQUEST_CHANGE_BARRING_PASSWORD = 44;
-this.REQUEST_QUERY_NETWORK_SELECTION_MODE = 45;
-this.REQUEST_SET_NETWORK_SELECTION_AUTOMATIC = 46;
-this.REQUEST_SET_NETWORK_SELECTION_MANUAL = 47;
-this.REQUEST_QUERY_AVAILABLE_NETWORKS = 48;
-this.REQUEST_DTMF_START = 49;
-this.REQUEST_DTMF_STOP = 50;
-this.REQUEST_BASEBAND_VERSION = 51;
-this.REQUEST_SEPARATE_CONNECTION = 52;
-this.REQUEST_SET_MUTE = 53;
-this.REQUEST_GET_MUTE = 54;
-this.REQUEST_QUERY_CLIP = 55;
-this.REQUEST_LAST_DATA_CALL_FAIL_CAUSE = 56;
-this.REQUEST_DATA_CALL_LIST = 57;
-this.REQUEST_RESET_RADIO = 58;
-this.REQUEST_OEM_HOOK_RAW = 59;
-this.REQUEST_OEM_HOOK_STRINGS = 60;
-this.REQUEST_SCREEN_STATE = 61;
-this.REQUEST_SET_SUPP_SVC_NOTIFICATION = 62;
-this.REQUEST_WRITE_SMS_TO_SIM = 63;
-this.REQUEST_DELETE_SMS_ON_SIM = 64;
-this.REQUEST_SET_BAND_MODE = 65;
-this.REQUEST_QUERY_AVAILABLE_BAND_MODE = 66;
-this.REQUEST_STK_GET_PROFILE = 67;
-this.REQUEST_STK_SET_PROFILE = 68;
-this.REQUEST_STK_SEND_ENVELOPE_COMMAND = 69;
-this.REQUEST_STK_SEND_TERMINAL_RESPONSE = 70;
-this.REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM = 71;
-this.REQUEST_EXPLICIT_CALL_TRANSFER = 72;
-this.REQUEST_SET_PREFERRED_NETWORK_TYPE = 73;
-this.REQUEST_GET_PREFERRED_NETWORK_TYPE = 74;
-this.REQUEST_GET_NEIGHBORING_CELL_IDS = 75;
-this.REQUEST_SET_LOCATION_UPDATES = 76;
-this.REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE = 77;
-this.REQUEST_CDMA_SET_ROAMING_PREFERENCE = 78;
-this.REQUEST_CDMA_QUERY_ROAMING_PREFERENCE = 79;
-this.REQUEST_SET_TTY_MODE = 80;
-this.REQUEST_QUERY_TTY_MODE = 81;
-this.REQUEST_CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE = 82;
-this.REQUEST_CDMA_QUERY_PREFERRED_VOICE_PRIVACY_MODE = 83;
-this.REQUEST_CDMA_FLASH = 84;
-this.REQUEST_CDMA_BURST_DTMF = 85;
-this.REQUEST_CDMA_VALIDATE_AND_WRITE_AKEY = 86;
-this.REQUEST_CDMA_SEND_SMS = 87;
-this.REQUEST_CDMA_SMS_ACKNOWLEDGE = 88;
-this.REQUEST_GSM_GET_BROADCAST_SMS_CONFIG = 89;
-this.REQUEST_GSM_SET_BROADCAST_SMS_CONFIG = 90;
-this.REQUEST_GSM_SMS_BROADCAST_ACTIVATION = 91;
-this.REQUEST_CDMA_GET_BROADCAST_SMS_CONFIG = 92;
-this.REQUEST_CDMA_SET_BROADCAST_SMS_CONFIG = 93;
-this.REQUEST_CDMA_SMS_BROADCAST_ACTIVATION = 94;
-this.REQUEST_CDMA_SUBSCRIPTION = 95;
-this.REQUEST_CDMA_WRITE_SMS_TO_RUIM = 96;
-this.REQUEST_CDMA_DELETE_SMS_ON_RUIM = 97;
-this.REQUEST_DEVICE_IDENTITY = 98;
-this.REQUEST_EXIT_EMERGENCY_CALLBACK_MODE = 99;
-this.REQUEST_GET_SMSC_ADDRESS = 100;
-this.REQUEST_SET_SMSC_ADDRESS = 101;
-this.REQUEST_REPORT_SMS_MEMORY_STATUS = 102;
-this.REQUEST_REPORT_STK_SERVICE_IS_RUNNING = 103;
-this.REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE = 104;
-this.REQUEST_ISIM_AUTHENTICATION = 105;
-this.REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU = 106;
-this.REQUEST_STK_SEND_ENVELOPE_WITH_STATUS = 107;
-this.REQUEST_VOICE_RADIO_TECH = 108;
-this.REQUEST_GET_CELL_INFO_LIST = 109;
-this.REQUEST_SET_UNSOL_CELL_INFO_LIST_RATE = 110;
-this.REQUEST_SET_INITIAL_ATTACH_APN = 111;
-this.REQUEST_IMS_REGISTRATION_STATE = 112;
-this.REQUEST_IMS_SEND_SMS = 113;
-this.REQUEST_SIM_TRANSMIT_APDU_BASIC = 114;
-this.REQUEST_SIM_OPEN_CHANNEL = 115;
-this.REQUEST_SIM_CLOSE_CHANNEL = 116;
-this.REQUEST_SIM_TRANSMIT_APDU_CHANNEL = 117;
-this.REQUEST_NV_READ_ITEM = 118;
-this.REQUEST_NV_WRITE_ITEM = 119;
-this.REQUEST_NV_WRITE_CDMA_PRL = 120;
-this.REQUEST_NV_RESET_CONFIG = 121;
-this.REQUEST_SET_UICC_SUBSCRIPTION = 122;
-this.REQUEST_ALLOW_DATA = 123;
-this.REQUEST_GET_HARDWARE_CONFIG = 124;
-this.REQUEST_SIM_AUTHENTICATION = 125;
-this.REQUEST_GET_DC_RT_INFO = 126;
-this.REQUEST_SET_DC_RT_INFO_RATE = 127;
-this.REQUEST_SET_DATA_PROFILE = 128;
-this.REQUEST_SHUTDOWN = 129;
-
-// CAF specific parcel type. It should be synced with latest version. But CAF
-// doesn't have l version for b2g yet, so we set REQUEST_SET_DATA_SUBSCRIPTION
-// to a value that won't get conflict with known AOSP parcel.
-this.REQUEST_SET_DATA_SUBSCRIPTION = 130;
-
-// Mozilla specific parcel type.
-this.REQUEST_GET_UNLOCK_RETRY_COUNT = 150;
-
-// Fugu specific parcel types.
-this.RIL_REQUEST_GPRS_ATTACH = 5018;
-this.RIL_REQUEST_GPRS_DETACH = 5019;
-
-// Galaxy S2 specific parcel type.
-this.REQUEST_DIAL_EMERGENCY_CALL = 10016;
-
-this.RESPONSE_TYPE_SOLICITED = 0;
-this.RESPONSE_TYPE_UNSOLICITED = 1;
-
-this.UNSOLICITED_RESPONSE_BASE = 1000;
-this.UNSOLICITED_RESPONSE_RADIO_STATE_CHANGED = 1000;
-this.UNSOLICITED_RESPONSE_CALL_STATE_CHANGED = 1001;
-this.UNSOLICITED_RESPONSE_VOICE_NETWORK_STATE_CHANGED = 1002;
-this.UNSOLICITED_RESPONSE_NEW_SMS = 1003;
-this.UNSOLICITED_RESPONSE_NEW_SMS_STATUS_REPORT = 1004;
-this.UNSOLICITED_RESPONSE_NEW_SMS_ON_SIM = 1005;
-this.UNSOLICITED_ON_USSD = 1006;
-this.UNSOLICITED_ON_USSD_REQUEST = 1007;
-this.UNSOLICITED_NITZ_TIME_RECEIVED = 1008;
-this.UNSOLICITED_SIGNAL_STRENGTH = 1009;
-this.UNSOLICITED_DATA_CALL_LIST_CHANGED = 1010;
-this.UNSOLICITED_SUPP_SVC_NOTIFICATION = 1011;
-this.UNSOLICITED_STK_SESSION_END = 1012;
-this.UNSOLICITED_STK_PROACTIVE_COMMAND = 1013;
-this.UNSOLICITED_STK_EVENT_NOTIFY = 1014;
-this.UNSOLICITED_STK_CALL_SETUP = 1015;
-this.UNSOLICITED_SIM_SMS_STORAGE_FULL = 1016;
-this.UNSOLICITED_SIM_REFRESH = 1017;
-this.UNSOLICITED_CALL_RING = 1018;
-this.UNSOLICITED_RESPONSE_SIM_STATUS_CHANGED = 1019;
-this.UNSOLICITED_RESPONSE_CDMA_NEW_SMS = 1020;
-this.UNSOLICITED_RESPONSE_NEW_BROADCAST_SMS = 1021;
-this.UNSOLICITED_CDMA_RUIM_SMS_STORAGE_FULL = 1022;
-this.UNSOLICITED_RESTRICTED_STATE_CHANGED = 1023;
-this.UNSOLICITED_ENTER_EMERGENCY_CALLBACK_MODE = 1024;
-this.UNSOLICITED_CDMA_CALL_WAITING = 1025;
-this.UNSOLICITED_CDMA_OTA_PROVISION_STATUS = 1026;
-this.UNSOLICITED_CDMA_INFO_REC = 1027;
-this.UNSOLICITED_OEM_HOOK_RAW = 1028;
-this.UNSOLICITED_RINGBACK_TONE = 1029;
-this.UNSOLICITED_RESEND_INCALL_MUTE = 1030;
-this.UNSOLICITED_CDMA_SUBSCRIPTION_SOURCE_CHANGED = 1031;
-this.UNSOLICITED_CDMA_PRL_CHANGED = 1032;
-this.UNSOLICITED_EXIT_EMERGENCY_CALLBACK_MODE = 1033;
-this.UNSOLICITED_RIL_CONNECTED = 1034;
-this.UNSOLICITED_VOICE_RADIO_TECH_CHANGED = 1035;
-this.UNSOLICITED_CELL_INFO_LIST = 1036;
-this.UNSOLICITED_RESPONSE_IMS_NETWORK_STATE_CHANGED = 1037;
-this.UNSOLICITED_UICC_SUBSCRIPTION_STATUS_CHANGED = 1038;
-this.UNSOLICITED_SRVCC_STATE_NOTIFY = 1039;
-this.UNSOLICITED_HARDWARE_CONFIG_CHANGED = 1040;
-this.UNSOLICITED_DC_RT_INFO_CHANGED = 1041;
-
-this.ERROR_SUCCESS = 0;
-this.ERROR_RADIO_NOT_AVAILABLE = 1;
-this.ERROR_GENERIC_FAILURE = 2;
-this.ERROR_PASSWORD_INCORRECT = 3;
-this.ERROR_SIM_PIN2 = 4;
-this.ERROR_SIM_PUK2 = 5;
-this.ERROR_REQUEST_NOT_SUPPORTED = 6;
-this.ERROR_CANCELLED = 7;
-this.ERROR_OP_NOT_ALLOWED_DURING_VOICE_CALL = 8;
-this.ERROR_OP_NOT_ALLOWED_BEFORE_REG_TO_NW = 9;
-this.ERROR_SMS_SEND_FAIL_RETRY = 10;
-this.ERROR_SIM_ABSENT = 11;
-this.ERROR_SUBSCRIPTION_NOT_AVAILABLE = 12;
-this.ERROR_MODE_NOT_SUPPORTED = 13;
-this.ERROR_FDN_CHECK_FAILURE = 14;
-this.ERROR_ILLEGAL_SIM_OR_ME = 15;
-this.ERROR_MISSING_RESOURCE = 16;
-this.ERROR_NO_SUCH_ELEMENT = 17;
-
-this.GECKO_ERROR_RADIO_NOT_AVAILABLE = "RadioNotAvailable";
-this.GECKO_ERROR_GENERIC_FAILURE = "GenericFailure";
-this.GECKO_ERROR_PASSWORD_INCORRECT = "IncorrectPassword";
-this.GECKO_ERROR_SIM_PIN2 = "SimPin2";
-this.GECKO_ERROR_SIM_PUK2 = "SimPuk2";
-this.GECKO_ERROR_REQUEST_NOT_SUPPORTED = "RequestNotSupported";
-this.GECKO_ERROR_CANCELLED = "Cancelled";
-this.GECKO_ERROR_OP_NOT_ALLOWED_DURING_VOICE_CALL = "OpNotAllowedDuringVoiceCall";
-this.GECKO_ERROR_OP_NOT_ALLOWED_BEFORE_REG_TO_NW = "OpNotAllowedBeforeRegToNw";
-this.GECKO_ERROR_SMS_SEND_FAIL_RETRY = "SmsSendFailRetry";
-this.GECKO_ERROR_SIM_ABSENT = "SimAbsent";
-this.GECKO_ERROR_SUBSCRIPTION_NOT_AVAILABLE = "SubscriptionNotAvailable";
-this.GECKO_ERROR_MODE_NOT_SUPPORTED = "ModeNotSupported";
-this.GECKO_ERROR_FDN_CHECK_FAILURE = "FdnCheckFailure";
-this.GECKO_ERROR_ILLEGAL_SIM_OR_ME = "IllegalSIMorME";
-this.GECKO_ERROR_MISSING_RESOURCE = "MissingResource";
-this.GECKO_ERROR_NO_SUCH_ELEMENT = "NoSuchElement";
-this.GECKO_ERROR_INVALID_PARAMETER = "InvalidParameter";
-this.GECKO_ERROR_UNSPECIFIED_ERROR = "UnspecifiedError";
-
-this.RIL_ERROR_TO_GECKO_ERROR = {};
-RIL_ERROR_TO_GECKO_ERROR[ERROR_RADIO_NOT_AVAILABLE] = GECKO_ERROR_RADIO_NOT_AVAILABLE;
-RIL_ERROR_TO_GECKO_ERROR[ERROR_GENERIC_FAILURE] = GECKO_ERROR_GENERIC_FAILURE;
-RIL_ERROR_TO_GECKO_ERROR[ERROR_PASSWORD_INCORRECT] = GECKO_ERROR_PASSWORD_INCORRECT;
-RIL_ERROR_TO_GECKO_ERROR[ERROR_SIM_PIN2] = GECKO_ERROR_SIM_PIN2;
-RIL_ERROR_TO_GECKO_ERROR[ERROR_SIM_PUK2] = GECKO_ERROR_SIM_PUK2;
-RIL_ERROR_TO_GECKO_ERROR[ERROR_REQUEST_NOT_SUPPORTED] = GECKO_ERROR_REQUEST_NOT_SUPPORTED;
-RIL_ERROR_TO_GECKO_ERROR[ERROR_CANCELLED] = GECKO_ERROR_CANCELLED;
-RIL_ERROR_TO_GECKO_ERROR[ERROR_OP_NOT_ALLOWED_DURING_VOICE_CALL] = GECKO_ERROR_OP_NOT_ALLOWED_DURING_VOICE_CALL;
-RIL_ERROR_TO_GECKO_ERROR[ERROR_OP_NOT_ALLOWED_BEFORE_REG_TO_NW] = GECKO_ERROR_OP_NOT_ALLOWED_BEFORE_REG_TO_NW;
-RIL_ERROR_TO_GECKO_ERROR[ERROR_SMS_SEND_FAIL_RETRY] = GECKO_ERROR_SMS_SEND_FAIL_RETRY;
-RIL_ERROR_TO_GECKO_ERROR[ERROR_SIM_ABSENT] = GECKO_ERROR_SIM_ABSENT;
-RIL_ERROR_TO_GECKO_ERROR[ERROR_SUBSCRIPTION_NOT_AVAILABLE] = GECKO_ERROR_SUBSCRIPTION_NOT_AVAILABLE;
-RIL_ERROR_TO_GECKO_ERROR[ERROR_MODE_NOT_SUPPORTED] = GECKO_ERROR_MODE_NOT_SUPPORTED;
-RIL_ERROR_TO_GECKO_ERROR[ERROR_FDN_CHECK_FAILURE] = GECKO_ERROR_FDN_CHECK_FAILURE;
-RIL_ERROR_TO_GECKO_ERROR[ERROR_ILLEGAL_SIM_OR_ME] = GECKO_ERROR_ILLEGAL_SIM_OR_ME;
-RIL_ERROR_TO_GECKO_ERROR[ERROR_MISSING_RESOURCE] = GECKO_ERROR_MISSING_RESOURCE;
-RIL_ERROR_TO_GECKO_ERROR[ERROR_NO_SUCH_ELEMENT] = GECKO_ERROR_NO_SUCH_ELEMENT;
-
-// 3GPP 23.040 clause 9.2.3.6 TP-Message-Reference(TP-MR):
-// The number of times the MS automatically repeats the SMS-SUBMIT shall be in
-// the range 1 to 3 but the precise number is an implementation matter.
-this.SMS_RETRY_MAX = 3;
-
-this.RADIO_STATE_OFF = 0;
-this.RADIO_STATE_UNAVAILABLE = 1;
-this.RADIO_STATE_ON = 10; // since RIL v7
-
-this.CARD_STATE_ABSENT = 0;
-this.CARD_STATE_PRESENT = 1;
-this.CARD_STATE_ERROR = 2;
-
-this.CARD_PERSOSUBSTATE_UNKNOWN = 0;
-this.CARD_PERSOSUBSTATE_IN_PROGRESS = 1;
-this.CARD_PERSOSUBSTATE_READY = 2;
-this.CARD_PERSOSUBSTATE_SIM_NETWORK = 3;
-this.CARD_PERSOSUBSTATE_SIM_NETWORK_SUBSET = 4;
-this.CARD_PERSOSUBSTATE_SIM_CORPORATE = 5;
-this.CARD_PERSOSUBSTATE_SIM_SERVICE_PROVIDER = 6;
-this.CARD_PERSOSUBSTATE_SIM_SIM = 7;
-this.CARD_PERSOSUBSTATE_SIM_NETWORK_PUK = 8;
-this.CARD_PERSOSUBSTATE_SIM_NETWORK_SUBSET_PUK = 9;
-this.CARD_PERSOSUBSTATE_SIM_CORPORATE_PUK = 10;
-this.CARD_PERSOSUBSTATE_SIM_SERVICE_PROVIDER_PUK = 11;
-this.CARD_PERSOSUBSTATE_SIM_SIM_PUK = 12;
-this.CARD_PERSOSUBSTATE_RUIM_NETWORK1 = 13;
-this.CARD_PERSOSUBSTATE_RUIM_NETWORK2 = 14;
-this.CARD_PERSOSUBSTATE_RUIM_HRPD = 15;
-this.CARD_PERSOSUBSTATE_RUIM_CORPORATE = 16;
-this.CARD_PERSOSUBSTATE_RUIM_SERVICE_PROVIDER = 17;
-this.CARD_PERSOSUBSTATE_RUIM_RUIM = 18;
-this.CARD_PERSOSUBSTATE_RUIM_NETWORK1_PUK = 19;
-this.CARD_PERSOSUBSTATE_RUIM_NETWORK2_PUK = 20;
-this.CARD_PERSOSUBSTATE_RUIM_HRPD_PUK = 21;
-this.CARD_PERSOSUBSTATE_RUIM_CORPORATE_PUK = 22;
-this.CARD_PERSOSUBSTATE_RUIM_SERVICE_PROVIDER_PUK = 23;
-this.CARD_PERSOSUBSTATE_RUIM_RUIM_PUK = 24;
-
-this.CARD_APPSTATE_ILLEGAL = -1;
-this.CARD_APPSTATE_UNKNOWN = 0;
-this.CARD_APPSTATE_DETECTED = 1;
-this.CARD_APPSTATE_PIN = 2; // If PIN1 or UPin is required.
-this.CARD_APPSTATE_PUK = 3; // If PUK1 or Puk for UPin is required.
-this.CARD_APPSTATE_SUBSCRIPTION_PERSO = 4; // perso_substate should be looked
- // at when app_state is assigned
- // to this value.
-this.CARD_APPSTATE_READY = 5;
-
-this.CARD_PINSTATE_UNKNOWN = 0;
-this.CARD_PINSTATE_ENABLED_NOT_VERIFIED = 1;
-this.CARD_PINSTATE_ENABLED_VERIFIED = 2;
-this.CARD_PINSTATE_DISABLED = 3;
-this.CARD_PINSTATE_ENABLED_BLOCKED = 4;
-this.CARD_PINSTATE_ENABLED_PERM_BLOCKED = 5;
-
-this.CARD_APPTYPE_UNKNOWN = 0;
-this.CARD_APPTYPE_SIM = 1;
-this.CARD_APPTYPE_USIM = 2;
-this.CARD_APPTYPE_RUIM = 3;
-this.CARD_APPTYPE_CSIM = 4;
-this.CARD_APPTYPE_ISIM = 5;
-
-this.CARD_MAX_APPS = 8;
-
-this.GECKO_CARD_TYPE = [
- null,
- "sim",
- "usim",
- "ruim",
- "csim",
- "isim"
-];
-
-
-// Used for QUERY_AVAILABLE_NETWORKS status.
-this.QAN_STATE_UNKNOWN = "unknown";
-this.QAN_STATE_AVAILABLE = "available";
-this.QAN_STATE_CURRENT = "current";
-this.QAN_STATE_FORBIDDEN = "forbidden";
-
-// Must be in sync with MobileNetworkState of MozMobileNetworkInfo.webidl
-this.GECKO_QAN_STATE_UNKNOWN = null;
-this.GECKO_QAN_STATE_AVAILABLE = "available";
-this.GECKO_QAN_STATE_CONNECTED = "connected";
-this.GECKO_QAN_STATE_FORBIDDEN = "forbidden";
-
-this.RIL_QAN_STATE_TO_GECKO_STATE = {};
-this.RIL_QAN_STATE_TO_GECKO_STATE[this.QAN_STATE_UNKNOWN] = this.GECKO_QAN_STATE_UNKNOWN;
-this.RIL_QAN_STATE_TO_GECKO_STATE[this.QAN_STATE_AVAILABLE] = this.GECKO_QAN_STATE_AVAILABLE;
-this.RIL_QAN_STATE_TO_GECKO_STATE[this.QAN_STATE_CURRENT] = this.GECKO_QAN_STATE_CONNECTED;
-this.RIL_QAN_STATE_TO_GECKO_STATE[this.QAN_STATE_FORBIDDEN] = this.GECKO_QAN_STATE_FORBIDDEN;
-
-this.NETWORK_SELECTION_MODE_AUTOMATIC = 0;
-this.NETWORK_SELECTION_MODE_MANUAL = 1;
-
-this.NETWORK_INFO_VOICE_REGISTRATION_STATE = "voiceRegistrationState";
-this.NETWORK_INFO_DATA_REGISTRATION_STATE = "dataRegistrationState";
-this.NETWORK_INFO_OPERATOR = "operator";
-this.NETWORK_INFO_NETWORK_SELECTION_MODE = "networkSelectionMode";
-this.NETWORK_INFO_SIGNAL = "signal";
-this.NETWORK_INFO_MESSAGE_TYPES = [
- NETWORK_INFO_VOICE_REGISTRATION_STATE,
- NETWORK_INFO_DATA_REGISTRATION_STATE,
- NETWORK_INFO_OPERATOR,
- NETWORK_INFO_NETWORK_SELECTION_MODE,
- NETWORK_INFO_SIGNAL
-];
-
-this.GECKO_PREFERRED_NETWORK_TYPE_WCDMA_GSM = "wcdma/gsm";
-this.GECKO_PREFERRED_NETWORK_TYPE_GSM_ONLY = "gsm";
-this.GECKO_PREFERRED_NETWORK_TYPE_WCDMA_ONLY = "wcdma";
-this.GECKO_PREFERRED_NETWORK_TYPE_WCDMA_GSM_AUTO = "wcdma/gsm-auto";
-this.GECKO_PREFERRED_NETWORK_TYPE_CDMA_EVDO = "cdma/evdo";
-this.GECKO_PREFERRED_NETWORK_TYPE_CDMA_ONLY = "cdma";
-this.GECKO_PREFERRED_NETWORK_TYPE_EVDO_ONLY = "evdo";
-this.GECKO_PREFERRED_NETWORK_TYPE_WCDMA_GSM_CDMA_EVDO = "wcdma/gsm/cdma/evdo";
-this.GECKO_PREFERRED_NETWORK_TYPE_LTE_CDMA_EVDO = "lte/cdma/evdo";
-this.GECKO_PREFERRED_NETWORK_TYPE_LTE_WCDMA_GSM = "lte/wcdma/gsm";
-this.GECKO_PREFERRED_NETWORK_TYPE_LTE_WCDMA = "lte/wcdma";
-this.GECKO_PREFERRED_NETWORK_TYPE_LTE_WCDMA_GSM_CDMA_EVDO = "lte/wcdma/gsm/cdma/evdo";
-this.GECKO_PREFERRED_NETWORK_TYPE_LTE_ONLY = "lte";
-this.RIL_PREFERRED_NETWORK_TYPE_TO_GECKO = [
- GECKO_PREFERRED_NETWORK_TYPE_WCDMA_GSM,
- GECKO_PREFERRED_NETWORK_TYPE_GSM_ONLY,
- GECKO_PREFERRED_NETWORK_TYPE_WCDMA_ONLY,
- GECKO_PREFERRED_NETWORK_TYPE_WCDMA_GSM_AUTO,
- GECKO_PREFERRED_NETWORK_TYPE_CDMA_EVDO,
- GECKO_PREFERRED_NETWORK_TYPE_CDMA_ONLY,
- GECKO_PREFERRED_NETWORK_TYPE_EVDO_ONLY,
- GECKO_PREFERRED_NETWORK_TYPE_WCDMA_GSM_CDMA_EVDO,
- GECKO_PREFERRED_NETWORK_TYPE_LTE_CDMA_EVDO,
- GECKO_PREFERRED_NETWORK_TYPE_LTE_WCDMA_GSM,
- GECKO_PREFERRED_NETWORK_TYPE_LTE_WCDMA_GSM_CDMA_EVDO,
- GECKO_PREFERRED_NETWORK_TYPE_LTE_ONLY,
- GECKO_PREFERRED_NETWORK_TYPE_LTE_WCDMA
-];
-
-this.GECKO_SUPPORTED_NETWORK_TYPES_DEFAULT = "gsm,wcdma";
-// Index-item pair must be in sync with nsIMobileConnection.MOBILE_NETWORK_TYPE_*
-this.GECKO_SUPPORTED_NETWORK_TYPES = [
- "gsm",
- "wcdma",
- "cdma",
- "evdo",
- "lte"
-];
-
-// Network registration states. See TS 27.007 7.2
-this.NETWORK_CREG_STATE_NOT_SEARCHING = 0;
-this.NETWORK_CREG_STATE_REGISTERED_HOME = 1;
-this.NETWORK_CREG_STATE_SEARCHING = 2;
-this.NETWORK_CREG_STATE_DENIED = 3;
-this.NETWORK_CREG_STATE_UNKNOWN = 4;
-this.NETWORK_CREG_STATE_REGISTERED_ROAMING = 5;
-this.NETWORK_CREG_STATE_NOT_SEARCHING_EMERGENCY_CALLS = 10;
-this.NETWORK_CREG_STATE_SEARCHING_EMERGENCY_CALLS = 12;
-this.NETWORK_CREG_STATE_DENIED_EMERGENCY_CALLS = 13;
-this.NETWORK_CREG_STATE_UNKNOWN_EMERGENCY_CALLS = 14;
-
-this.NETWORK_CREG_TECH_UNKNOWN = 0;
-this.NETWORK_CREG_TECH_GPRS = 1;
-this.NETWORK_CREG_TECH_EDGE = 2;
-this.NETWORK_CREG_TECH_UMTS = 3;
-this.NETWORK_CREG_TECH_IS95A = 4;
-this.NETWORK_CREG_TECH_IS95B = 5;
-this.NETWORK_CREG_TECH_1XRTT = 6;
-this.NETWORK_CREG_TECH_EVDO0 = 7;
-this.NETWORK_CREG_TECH_EVDOA = 8;
-this.NETWORK_CREG_TECH_HSDPA = 9;
-this.NETWORK_CREG_TECH_HSUPA = 10;
-this.NETWORK_CREG_TECH_HSPA = 11;
-this.NETWORK_CREG_TECH_EVDOB = 12;
-this.NETWORK_CREG_TECH_EHRPD = 13;
-this.NETWORK_CREG_TECH_LTE = 14;
-this.NETWORK_CREG_TECH_HSPAP = 15;
-this.NETWORK_CREG_TECH_GSM = 16;
-this.NETWORK_CREG_TECH_DCHSPAP_1 = 18; // Some devices reports as 18
-this.NETWORK_CREG_TECH_DCHSPAP_2 = 19; // Some others report it as 19
-
-this.CELL_INFO_TYPE_GSM = 1;
-this.CELL_INFO_TYPE_CDMA = 2;
-this.CELL_INFO_TYPE_LTE = 3;
-this.CELL_INFO_TYPE_WCDMA = 4;
-
-this.CALL_STATE_UNKNOWN = -1;
-this.CALL_STATE_ACTIVE = 0;
-this.CALL_STATE_HOLDING = 1;
-this.CALL_STATE_DIALING = 2;
-this.CALL_STATE_ALERTING = 3;
-this.CALL_STATE_INCOMING = 4;
-this.CALL_STATE_WAITING = 5;
-
-this.TOA_INTERNATIONAL = 0x91;
-this.TOA_UNKNOWN = 0x81;
-
-this.CALL_PRESENTATION_ALLOWED = 0;
-this.CALL_PRESENTATION_RESTRICTED = 1;
-this.CALL_PRESENTATION_UNKNOWN = 2;
-this.CALL_PRESENTATION_PAYPHONE = 3;
-
-// Call forwarding actions, see TS 27.007 7.11 "mode"
-this.CALL_FORWARD_ACTION_QUERY_STATUS = 2;
-
-// ICC commands, see TS 27.007 +CRSM commands
-this.ICC_COMMAND_SEEK = 0xa2;
-this.ICC_COMMAND_READ_BINARY = 0xb0;
-this.ICC_COMMAND_READ_RECORD = 0xb2;
-this.ICC_COMMAND_GET_RESPONSE = 0xc0;
-this.ICC_COMMAND_UPDATE_BINARY = 0xd6;
-this.ICC_COMMAND_UPDATE_RECORD = 0xdc;
-
-// ICC constants, GSM SIM file ids from TS 51.011
-this.ICC_EF_ICCID = 0x2fe2;
-this.ICC_EF_IMG = 0x4f20;
-this.ICC_EF_PBR = 0x4f30;
-this.ICC_EF_PLMNsel = 0x6f30; // PLMN for SIM
-this.ICC_EF_SST = 0x6f38;
-this.ICC_EF_UST = 0x6f38; // For USIM
-this.ICC_EF_ADN = 0x6f3a;
-this.ICC_EF_FDN = 0x6f3b;
-this.ICC_EF_SMS = 0x6f3c;
-this.ICC_EF_GID1 = 0x6f3e;
-this.ICC_EF_MSISDN = 0x6f40;
-this.ICC_EF_CBMI = 0x6f45;
-this.ICC_EF_SPN = 0x6f46;
-this.ICC_EF_CBMID = 0x6f48;
-this.ICC_EF_SDN = 0x6f49;
-this.ICC_EF_EXT1 = 0x6f4a;
-this.ICC_EF_EXT2 = 0x6f4b;
-this.ICC_EF_EXT3 = 0x6f4c;
-this.ICC_EF_CBMIR = 0x6f50;
-this.ICC_EF_AD = 0x6fad;
-this.ICC_EF_PHASE = 0x6fae;
-this.ICC_EF_PNN = 0x6fc5;
-this.ICC_EF_OPL = 0x6fc6;
-this.ICC_EF_MBDN = 0x6fc7;
-this.ICC_EF_EXT6 = 0x6fc8; // Ext record for EF[MBDN]
-this.ICC_EF_MBI = 0x6fc9;
-this.ICC_EF_MWIS = 0x6fca;
-this.ICC_EF_CFIS = 0x6fcb;
-this.ICC_EF_SPDI = 0x6fcd;
-
-// CPHS files to be supported
-this.ICC_EF_CPHS_INFO = 0x6f16; // CPHS Information
-this.ICC_EF_CPHS_MBN = 0x6f17; // Mailbox Numbers
-
-// CSIM files
-this.ICC_EF_CSIM_IMSI_M = 0x6f22;
-this.ICC_EF_CSIM_CDMAHOME = 0x6f28;
-this.ICC_EF_CSIM_CST = 0x6f32; // CDMA Service table
-this.ICC_EF_CSIM_SPN = 0x6f41;
-
-this.ICC_PHASE_1 = 0x00;
-this.ICC_PHASE_2 = 0x02;
-this.ICC_PHASE_2_PROFILE_DOWNLOAD_REQUIRED = 0x03;
-
-// Types of files TS 11.11 9.3
-this.TYPE_RFU = 0;
-this.TYPE_MF = 1;
-this.TYPE_DF = 2;
-this.TYPE_EF = 4;
-
-this.RESPONSE_DATA_FILE_SIZE = 2;
-this.RESPONSE_DATA_FILE_ID_1 = 4;
-this.RESPONSE_DATA_FILE_ID_2 = 5;
-this.RESPONSE_DATA_FILE_TYPE = 6;
-this.RESPONSE_DATA_RFU_3 = 7;
-this.RESPONSE_DATA_ACCESS_CONDITION_1 = 8;
-this.RESPONSE_DATA_ACCESS_CONDITION_2 = 9;
-this.RESPONSE_DATA_ACCESS_CONDITION_3 = 10;
-this.RESPONSE_DATA_FILE_STATUS = 11;
-this.RESPONSE_DATA_LENGTH = 12;
-this.RESPONSE_DATA_STRUCTURE = 13;
-this.RESPONSE_DATA_RECORD_LENGTH = 14;
-
-// Structure of files TS 11.11 9.3
-this.EF_STRUCTURE_TRANSPARENT = 0;
-this.EF_STRUCTURE_LINEAR_FIXED = 1;
-this.EF_STRUCTURE_CYCLIC = 3;
-
-// TS 102.221 11.1.1.4.3 Table 11.5: File descriptor byte.
-this.UICC_EF_STRUCTURE = {};
-this.UICC_EF_STRUCTURE[this.EF_STRUCTURE_TRANSPARENT]= 1;
-this.UICC_EF_STRUCTURE[this.EF_STRUCTURE_LINEAR_FIXED]= 2;
-this.UICC_EF_STRUCTURE[this.EF_STRUCTURE_CYCLIC]= 6;
-
-// Status code of EFsms
-// see 3GPP TS 51.011 clause 10.5.3
-this.EFSMS_STATUS_FREE = 0x00;
-this.EFSMS_STATUS_READ = 0x01;
-this.EFSMS_STATUS_TO_BE_READ = 0x03;
-this.EFSMS_STATUS_TO_BE_SENT = 0x07;
-
-// Total size of ADN footer(the size of Alpha identifier excluded).
-// See TS 151.011 clause 10.5.1 EF_ADN.
-this.ADN_FOOTER_SIZE_BYTES = 14;
-// Maximum size of BCD numbers in ADN.
-// See TS 151.011 clause 10.5.1 EF_ADN, 'Length of BCD number/SSC contents'.
-this.ADN_MAX_BCD_NUMBER_BYTES = 11;
-// Maximum digits of the Dialling Number in ADN.
-// See TS 151.011 clause 10.5.1 EF_ADN, 'Dialling Number'.
-this.ADN_MAX_NUMBER_DIGITS = 20;
-// Maximum size of BCD numbers in EXT.
-// See TS 151.011 clause 10.5.10 EF_EXT1, 'Extension data'.
-this.EXT_MAX_BCD_NUMBER_BYTES = 10;
-// Maximum digits of the Dialling Number in EXT.
-// See TS 151.011 clause 10.5.10 EF_EXT1, 'Extension data'.
-this.EXT_MAX_NUMBER_DIGITS = 20;
-
-// READ_RECORD mode, TS 102.221
-this.READ_RECORD_ABSOLUTE_MODE = 4;
-
-// TS 102.221 Table 11.2, return FCP template
-this.GET_RESPONSE_FCP_TEMPLATE = 4;
-
-// GET_RESPONSE mandatory response size for EF, see TS 51.011 clause 9,
-// 'Response data in case of an EF.'
-this.GET_RESPONSE_EF_SIZE_BYTES = 15;
-
-// EF path
-this.EF_PATH_MF_SIM = "3f00";
-this.EF_PATH_DF_PHONEBOOK = "5f3a";
-this.EF_PATH_GRAPHICS = "5f50";
-this.EF_PATH_DF_TELECOM = "7f10";
-this.EF_PATH_DF_GSM = "7f20";
-this.EF_PATH_DF_CDMA = "7f25";
-this.EF_PATH_ADF_USIM = "7fff";
-
-// Status code of sw1 for ICC I/O,
-// see GSM11.11 and TS 51.011 clause 9.4, and ISO 7816-4
-this.ICC_STATUS_NORMAL_ENDING = 0x90;
-this.ICC_STATUS_NORMAL_ENDING_WITH_EXTRA = 0x91;
-this.ICC_STATUS_SAT_BUSY = 0x93;
-this.ICC_STATUS_WITH_SIM_DATA = 0x9e;
-this.ICC_STATUS_WITH_RESPONSE_DATA = 0x9f;
-this.ICC_STATUS_ERROR_WRONG_LENGTH = 0x67;
-this.ICC_STATUS_ERROR_COMMAND_NOT_ALLOWED = 0x69;
-this.ICC_STATUS_ERROR_WRONG_PARAMETERS = 0x6a;
-
-// ICC call barring facility.
-// TS 27.007, clause 7.4, +CLCK
-this.ICC_CB_FACILITY_SIM = "SC";
-this.ICC_CB_FACILITY_FDN = "FD";
-this.ICC_CB_FACILITY_BAOC = "AO";
-this.ICC_CB_FACILITY_BAOIC = "OI";
-this.ICC_CB_FACILITY_BAOICxH = "OX";
-this.ICC_CB_FACILITY_BAIC = "AI";
-this.ICC_CB_FACILITY_BAICr = "IR";
-this.ICC_CB_FACILITY_BA_ALL = "AB";
-this.ICC_CB_FACILITY_BA_MO = "AG";
-this.ICC_CB_FACILITY_BA_MT = "AC";
-
-// ICC service class
-// TS 27.007, clause 7.4, +CLCK
-this.ICC_SERVICE_CLASS_NONE = 0; // no user input
-this.ICC_SERVICE_CLASS_VOICE = (1 << 0);
-this.ICC_SERVICE_CLASS_DATA = (1 << 1);
-this.ICC_SERVICE_CLASS_FAX = (1 << 2);
-this.ICC_SERVICE_CLASS_SMS = (1 << 3);
-this.ICC_SERVICE_CLASS_DATA_SYNC = (1 << 4);
-this.ICC_SERVICE_CLASS_DATA_ASYNC = (1 << 5);
-this.ICC_SERVICE_CLASS_PACKET = (1 << 6);
-this.ICC_SERVICE_CLASS_PAD = (1 << 7);
-this.ICC_SERVICE_CLASS_MAX = (1 << 7); // Max ICC_SERVICE_CLASS value
-
-// ICC lock-selection codes
-// TS 27.007, clause 8.65, +CPINR
-this.ICC_SEL_CODE_SIM_PIN = "SIM PIN";
-this.ICC_SEL_CODE_SIM_PUK = "SIM PUK";
-this.ICC_SEL_CODE_PH_SIM_PIN = "PH-SIM PIN";
-this.ICC_SEL_CODE_PH_FSIM_PIN = "PH-FSIM PIN";
-this.ICC_SEL_CODE_PH_FSIM_PUK = "PH-FSIM PUK";
-this.ICC_SEL_CODE_SIM_PIN2 = "SIM PIN2";
-this.ICC_SEL_CODE_SIM_PUK2 = "SIM PUK2";
-this.ICC_SEL_CODE_PH_NET_PIN = "PH-NET PIN";
-this.ICC_SEL_CODE_PH_NET_PUK = "PH-NET PUK";
-this.ICC_SEL_CODE_PH_NETSUB_PIN = "PH-NETSUB PIN";
-this.ICC_SEL_CODE_PH_NETSUB_PUK = "PH-NETSUB PUK";
-this.ICC_SEL_CODE_PH_SP_PIN = "PH-SP PIN";
-this.ICC_SEL_CODE_PH_SP_PUK = "PH-SP PUK";
-this.ICC_SEL_CODE_PH_CORP_PIN = "PH-CORP PIN";
-this.ICC_SEL_CODE_PH_CORP_PUK = "PH-CORP PUK";
-// TODO: Bug 1116072: identify the mapping between RIL_PERSOSUBSTATE_SIM_SIM @
-// ril.h and TS 27.007, clause 8.65 for GECKO_CARDLOCK_PCK.
-
-this.ICC_USIM_TYPE1_TAG = 0xa8;
-this.ICC_USIM_TYPE2_TAG = 0xa9;
-this.ICC_USIM_TYPE3_TAG = 0xaa;
-this.ICC_USIM_EFADN_TAG = 0xc0;
-this.ICC_USIM_EFIAP_TAG = 0xc1;
-this.ICC_USIM_EFEXT1_TAG = 0xc2;
-this.ICC_USIM_EFSNE_TAG = 0xc3;
-this.ICC_USIM_EFANR_TAG = 0xc4;
-this.ICC_USIM_EFPBC_TAG = 0xc5;
-this.ICC_USIM_EFGRP_TAG = 0xc6;
-this.ICC_USIM_EFAAS_TAG = 0xc7;
-this.ICC_USIM_EFGSD_TAG = 0xc8;
-this.ICC_USIM_EFUID_TAG = 0xc9;
-this.ICC_USIM_EFEMAIL_TAG = 0xca;
-this.ICC_USIM_EFCCP1_TAG = 0xcb;
-
-// ICC image coding scheme
-// TS 31.102, sub-clause 4.6.1.1
-this.ICC_IMG_CODING_SCHEME_BASIC = 0x11;
-this.ICC_IMG_CODING_SCHEME_COLOR = 0x21;
-this.ICC_IMG_CODING_SCHEME_COLOR_TRANSPARENCY = 0x22;
-
-// Must be in sync with enum IccImageCodingScheme in MozStkCommandEvent.webidl.
-this.GECKO_IMG_CODING_SCHEME_BASIC = "basic";
-this.GECKO_IMG_CODING_SCHEME_COLOR = "color";
-this.GECKO_IMG_CODING_SCHEME_COLOR_TRANSPARENCY = "color-transparency";
-
-this.ICC_IMG_CODING_SCHEME_TO_GECKO = {};
-ICC_IMG_CODING_SCHEME_TO_GECKO[ICC_IMG_CODING_SCHEME_BASIC] = GECKO_IMG_CODING_SCHEME_BASIC;
-ICC_IMG_CODING_SCHEME_TO_GECKO[ICC_IMG_CODING_SCHEME_COLOR] = GECKO_IMG_CODING_SCHEME_COLOR;
-ICC_IMG_CODING_SCHEME_TO_GECKO[ICC_IMG_CODING_SCHEME_COLOR_TRANSPARENCY] = GECKO_IMG_CODING_SCHEME_COLOR_TRANSPARENCY;
-
-// ICC image header size per coding scheme
-// TS 31.102, Annex B
-this.ICC_IMG_HEADER_SIZE_BASIC = 2;
-this.ICC_IMG_HEADER_SIZE_COLOR = 6;
-
-this.ICC_CLUT_ENTRY_SIZE = 3;
-
-this.USIM_PBR_ANR = "anr";
-this.USIM_PBR_ANR0 = "anr0";
-this.USIM_PBR_EMAIL = "email";
-
-// Current supported fields. Adding more fields to read will increasing I/O
-// time dramatically, do check the performance is acceptable when you add
-// more fields.
-this.USIM_PBR_FIELDS = [USIM_PBR_EMAIL, USIM_PBR_ANR0];
-
-this.USIM_TAG_NAME = {};
-this.USIM_TAG_NAME[ICC_USIM_EFADN_TAG] = "adn";
-this.USIM_TAG_NAME[ICC_USIM_EFIAP_TAG] ="iap";
-this.USIM_TAG_NAME[ICC_USIM_EFEXT1_TAG] = "ext1";
-this.USIM_TAG_NAME[ICC_USIM_EFSNE_TAG] = "sne";
-this.USIM_TAG_NAME[ICC_USIM_EFANR_TAG] = "anr";
-this.USIM_TAG_NAME[ICC_USIM_EFPBC_TAG] = "pbc";
-this.USIM_TAG_NAME[ICC_USIM_EFGRP_TAG] = "grp";
-this.USIM_TAG_NAME[ICC_USIM_EFAAS_TAG] = "aas";
-this.USIM_TAG_NAME[ICC_USIM_EFGSD_TAG] = "gsd";
-this.USIM_TAG_NAME[ICC_USIM_EFUID_TAG] = "uid";
-this.USIM_TAG_NAME[ICC_USIM_EFEMAIL_TAG] = "email";
-this.USIM_TAG_NAME[ICC_USIM_EFCCP1_TAG] = "ccp1";
-
-// Error message for ICC contact.
-this.CONTACT_ERR_REQUEST_NOT_SUPPORTED = GECKO_ERROR_REQUEST_NOT_SUPPORTED;
-this.CONTACT_ERR_CONTACT_TYPE_NOT_SUPPORTED = "ContactTypeNotSupported";
-this.CONTACT_ERR_FIELD_NOT_SUPPORTED = "FieldNotSupported";
-this.CONTACT_ERR_NO_FREE_RECORD_FOUND = "NoFreeRecordFound";
-this.CONTACT_ERR_CANNOT_ACCESS_PHONEBOOK = "CannotAccessPhoneBook";
-
-// CDMA IMSI_M's byte const.
-// 3GPP2 C.S0065 Sec. 5.2.2
-this.CSIM_IMSI_M_MIN2_BYTE = 1;
-this.CSIM_IMSI_M_MIN1_BYTE = 3;
-this.CSIM_IMSI_M_MNC_BYTE = 6;
-this.CSIM_IMSI_M_PROGRAMMED_BYTE = 7;
-this.CSIM_IMSI_M_MCC_BYTE = 8;
-
-/**
- * Tags for Ber Tlv.
- * See 3GPP TS 101 220 clause 7.2 - Assigned TLV tag values.
- */
-this.BER_UNKNOWN_TAG = 0x00;
-this.BER_FCP_TEMPLATE_TAG = 0x62;
-this.BER_FCP_FILE_SIZE_DATA_TAG = 0x80;
-this.BER_FCP_FILE_SIZE_TOTAL_TAG = 0x81;
-this.BER_FCP_FILE_DESCRIPTOR_TAG = 0x82;
-this.BER_FCP_FILE_IDENTIFIER_TAG = 0x83;
-this.BER_FCP_DF_NAME_TAG = 0x84; // AID.
-this.BER_FCP_PROPRIETARY_PRIMITIVE_TAG = 0x85;
-this.BER_FCP_SFI_SUPPORT_TAG = 0x88;
-this.BER_FCP_LIFE_CYCLE_STATUS_TAG = 0x8a;
-this.BER_FCP_SA_REFERENCE_FORMAT_TAG = 0x8b; // Security Attribute - Reference Format.
-this.BER_FCP_SA_COMPACT_FORMAT_TAG = 0x8c; // Security Attribute - Compact Format.
-this.BER_FCP_SAT_EXPANDED_FORMAT_TAG = 0xab; // Security Attribute Template - Expanded Format.
-this.BER_FCP_PROPRIETARY_TEMPLATE_TAG = 0xa5;
-this.BER_FCP_PIN_STATUS_DATA_OBJECTS_TAG = 0xc6;
-this.BER_PROACTIVE_COMMAND_TAG = 0xd0;
-this.BER_SMS_PP_DOWNLOAD_TAG = 0xd1;
-this.BER_MENU_SELECTION_TAG = 0xd3;
-this.BER_EVENT_DOWNLOAD_TAG = 0xd6;
-this.BER_TIMER_EXPIRATION_TAG = 0xd7;
-
-// Flags in Comprehension TLV.
-this.COMPREHENSIONTLV_FLAG_CR = 0x80; // Comprehension required.
-
-// Tags for Comprehension TLV.
-this.COMPREHENSIONTLV_TAG_COMMAND_DETAILS = 0x01;
-this.COMPREHENSIONTLV_TAG_DEVICE_ID = 0x02;
-this.COMPREHENSIONTLV_TAG_RESULT = 0x03;
-this.COMPREHENSIONTLV_TAG_DURATION = 0x04;
-this.COMPREHENSIONTLV_TAG_ALPHA_ID = 0x05;
-this.COMPREHENSIONTLV_TAG_ADDRESS = 0x06;
-this.COMPREHENSIONTLV_TAG_SUBADDRESS = 0x08;
-this.COMPREHENSIONTLV_TAG_SMS_TPDU = 0x0b;
-this.COMPREHENSIONTLV_TAG_TEXT_STRING = 0x0d;
-this.COMPREHENSIONTLV_TAG_TONE = 0x0e;
-this.COMPREHENSIONTLV_TAG_ITEM = 0x0f;
-this.COMPREHENSIONTLV_TAG_ITEM_ID = 0x10;
-this.COMPREHENSIONTLV_TAG_RESPONSE_LENGTH = 0x11;
-this.COMPREHENSIONTLV_TAG_FILE_LIST = 0x12;
-this.COMPREHENSIONTLV_TAG_LOCATION_INFO = 0x13;
-this.COMPREHENSIONTLV_TAG_IMEI = 0x14;
-this.COMPREHENSIONTLV_TAG_HELP_REQUEST = 0x15;
-this.COMPREHENSIONTLV_TAG_NMR = 0x16;
-this.COMPREHENSIONTLV_TAG_DEFAULT_TEXT = 0x17;
-this.COMPREHENSIONTLV_TAG_NEXT_ACTION_IND = 0x18;
-this.COMPREHENSIONTLV_TAG_CAUSE = 0x1a;
-this.COMPREHENSIONTLV_TAG_LOCATION_STATUS = 0x1b;
-this.COMPREHENSIONTLV_TAG_TRANSACTION_ID = 0x1c;
-this.COMPREHENSIONTLV_TAG_EVENT_LIST = 0x19;
-this.COMPREHENSIONTLV_TAG_ICON_ID = 0x1e;
-this.COMPREHENSIONTLV_TAG_ICON_ID_LIST = 0x1f;
-this.COMPREHENSIONTLV_TAG_TIMER_IDENTIFIER = 0x24;
-this.COMPREHENSIONTLV_TAG_TIMER_VALUE = 0x25;
-this.COMPREHENSIONTLV_TAG_DATE_TIME_ZONE = 0x26;
-this.COMPREHENSIONTLV_TAG_IMMEDIATE_RESPONSE = 0x2b;
-this.COMPREHENSIONTLV_TAG_LANGUAGE = 0x2d;
-this.COMPREHENSIONTLV_TAG_URL = 0x31;
-this.COMPREHENSIONTLV_TAG_BROWSER_TERMINATION_CAUSE = 0x34;
-this.COMPREHENSIONTLV_TAG_ACCESS_TECH = 0x3f;
-this.COMPREHENSIONTLV_TAG_SERVICE_RECORD = 0x41;
-this.COMPREHENSIONTLV_TAG_IMEISV = 0x62;
-this.COMPREHENSIONTLV_TAG_BATTERY_STATE = 0x63;
-this.COMPREHENSIONTLV_TAG_NETWORK_SEARCH_MODE = 0x65;
-this.COMPREHENSIONTLV_TAG_MEID = 0x6d;
-this.COMPREHENSIONTLV_TAG_BROADCAST_NETWORK_INFO = 0x7a;
-
-// Tags for Service Provider Display Information TLV
-this.SPDI_TAG_SPDI = 0xa3;
-this.SPDI_TAG_PLMN_LIST = 0x80;
-
-// MM INFORMATION message content IEIs
-// See 3GPP TS 24.008 table 9.2.18
-this.PNN_IEI_FULL_NETWORK_NAME = 0x43;
-this.PNN_IEI_SHORT_NETWORK_NAME = 0x45;
-
-// Device identifiers, see TS 11.14, clause 12.7
-this.STK_DEVICE_ID_KEYPAD = 0x01;
-this.STK_DEVICE_ID_DISPLAY = 0x02;
-this.STK_DEVICE_ID_EARPIECE = 0x03;
-this.STK_DEVICE_ID_SIM = 0x81;
-this.STK_DEVICE_ID_ME = 0x82;
-this.STK_DEVICE_ID_NETWORK = 0x83;
-
-// STK Proactive commands.
-this.STK_CMD_REFRESH = 0x01;
-this.STK_CMD_MORE_TIME = 0x02;
-this.STK_CMD_POLL_INTERVAL = 0x03;
-this.STK_CMD_POLL_OFF = 0x04;
-this.STK_CMD_SET_UP_EVENT_LIST = 0x05;
-this.STK_CMD_SET_UP_CALL = 0x10;
-this.STK_CMD_SEND_SS = 0x11;
-this.STK_CMD_SEND_USSD = 0x12;
-this.STK_CMD_SEND_SMS = 0x13;
-this.STK_CMD_SEND_DTMF = 0x14;
-this.STK_CMD_LAUNCH_BROWSER = 0x15;
-this.STK_CMD_PLAY_TONE = 0x20;
-this.STK_CMD_DISPLAY_TEXT = 0x21;
-this.STK_CMD_GET_INKEY = 0x22;
-this.STK_CMD_GET_INPUT = 0x23;
-this.STK_CMD_SELECT_ITEM = 0x24;
-this.STK_CMD_SET_UP_MENU = 0x25;
-this.STK_CMD_PROVIDE_LOCAL_INFO = 0x26;
-this.STK_CMD_TIMER_MANAGEMENT = 0x27;
-this.STK_CMD_SET_UP_IDLE_MODE_TEXT = 0x28;
-this.STK_CMD_OPEN_CHANNEL = 0x40;
-this.STK_CMD_CLOSE_CHANNEL = 0x41;
-this.STK_CMD_RECEIVE_DATA = 0x42;
-this.STK_CMD_SEND_DATA = 0x43;
-
-// STK Result code.
-// TS 11.14, clause 12.12
-
-// Results '0X' and '1X' indicate that the command has been performed.
-
-// Command performed successfully.
-this.STK_RESULT_OK = 0x00;
-
-// Command performed with partial comprehension.
-this.STK_RESULT_PRFRMD_WITH_PARTIAL_COMPREHENSION = 0x01;
-
-// Command performed, with missing information.
-this.STK_RESULT_PRFRMD_WITH_MISSING_INFO = 0x02;
-
-// REFRESH performed with additional EFs read.
-this.STK_RESULT_PRFRMD_WITH_ADDITIONAL_EFS_READ = 0x03;
-
-// Command performed successfully, but requested icon could not be
-// displayed.
-this.STK_RESULT_PRFRMD_ICON_NOT_DISPLAYED = 0x04;
-
-// Command performed, but modified by call control by NAA.
-this.STK_RESULT_PRFRMD_MODIFIED_BY_NAA = 0x05;
-
-// Command performed successfully, limited service.
-this.STK_RESULT_PRFRMD_LIMITED_SERVICE = 0x06;
-
-// Command performed with modification.
-this.STK_RESULT_PRFRMD_WITH_MODIFICATION = 0x07;
-
-// REFRESH performed but indicated NAA was not active.
-this.STK_RESULT_PRFRMD_NAA_NOT_ACTIVE = 0x08;
-
-// Command performed successfully; tone not played.
-this.STK_RESULT_PRFRMD_TONE_NOT_PLAYED = 0x09;
-
-// Proactive UICC session terminated by the user.
-this.STK_RESULT_UICC_SESSION_TERM_BY_USER = 0x10;
-
-// Backward move in the proactive UICC session requested by the user.
-this.STK_RESULT_BACKWARD_MOVE_BY_USER = 0x11;
-
-// No response from user.
-this.STK_RESULT_NO_RESPONSE_FROM_USER = 0x12;
-
-// Help information required by the user.
-this.STK_RESULT_HELP_INFO_REQUIRED = 0x13;
-
-// USSD or SS transaction terminated by the user.
-this.STK_RESULT_USSD_SS_SESSION_TERM_BY_USER = 0x14;
-
-// Results '2X' indicate to the UICC that it may be worth re-trying the
-// command at a later opportunity.
-
-// Terminal currently unable to process command.
-this.STK_RESULT_TERMINAL_CRNTLY_UNABLE_TO_PROCESS = 0x20;
-
-// Network currently unable to process command.
-this.STK_RESULT_NETWORK_CRNTLY_UNABLE_TO_PROCESS = 0x21;
-
-// User did not accept the proactive command.
-this.STK_RESULT_USER_NOT_ACCEPT = 0x22;
-
-// User cleared down call before connection or network release.
-this.STK_RESULT_USER_CLEAR_DOWN_CALL = 0x23;
-
-// Action in contradiction with the current timer state.
-this.STK_RESULT_CONTRADICTION_WITH_TIMER = 0x24;
-
-// Interaction with call control by NAA; temporary problem.
-this.STK_RESULT_NAA_CALL_CONTROL_TEMPORARY = 0x25;
-
-// Launch browser generic error code.
-this.STK_RESULT_LAUNCH_BROWSER_ERROR = 0x26;
-
-// MMS temporary problem.
-this.STK_RESULT_MMS_TEMPORARY = 0x27;
-
-// Results '3X' indicate that it is not worth the UICC re-trying with an
-// identical command; as it will only get the same response. However, the
-// decision to retry lies with the application.
-
-// Command beyond terminal's capabilities.
-this.STK_RESULT_BEYOND_TERMINAL_CAPABILITY = 0x30;
-
-// Command type not understood by terminal.
-this.STK_RESULT_CMD_TYPE_NOT_UNDERSTOOD = 0x31;
-
-// Command data not understood by terminal.
-this.STK_RESULT_CMD_DATA_NOT_UNDERSTOOD = 0x32;
-
-// Command number not known by terminal.
-this.STK_RESULT_CMD_NUM_NOT_KNOWN = 0x33;
-
-// SS Return Error.
-this.STK_RESULT_SS_RETURN_ERROR = 0x34;
-
-// SMS RP-ERROR.
-this.STK_RESULT_SMS_RP_ERROR = 0x35;
-
-// Error, required values are missing.
-this.STK_RESULT_REQUIRED_VALUES_MISSING = 0x36;
-
-// USSD Return Error.
-this.STK_RESULT_USSD_RETURN_ERROR = 0x37;
-
-// MultipleCard commands error.
-this.STK_RESULT_MULTI_CARDS_CMD_ERROR = 0x38;
-
-// Interaction with call control by USIM or MO short message control by
-// USIM; permanent problem.
-this.STK_RESULT_USIM_CALL_CONTROL_PERMANENT = 0x39;
-
-// Bearer Independent Protocol error.
-this.STK_RESULT_BIP_ERROR = 0x3a;
-
-// Access Technology unable to process command.
-this.STK_RESULT_ACCESS_TECH_UNABLE_TO_PROCESS = 0x3b;
-
-// Frames error.
-this.STK_RESULT_FRAMES_ERROR = 0x3c;
-
-// MMS Error.
-this.STK_RESULT_MMS_ERROR = 0x3d;
-
-// STK presentation types, TS 11.14, clause 12.6, Command Qualifier: Select Item
-this.STK_PRESENTATION_TYPE_NOT_SPECIFIED = 0x00; // Bit 1 is 0.
-this.STK_PRESENTATION_TYPE_DATA_VALUES = 0x01; // Bit 1 is 1, bit 2 is 0.
-this.STK_PRESENTATION_TYPE_NAVIGATION_OPTIONS = 0x03; // Bit 1 is 1, bit 2 is 1.
-
-// STK Coding Scheme.
-this.STK_TEXT_CODING_GSM_7BIT_PACKED = 0x00;
-this.STK_TEXT_CODING_GSM_8BIT = 0x04;
-this.STK_TEXT_CODING_UCS2 = 0x08;
-
-// STK Event List.
-this.STK_EVENT_TYPE_MT_CALL = 0x00;
-this.STK_EVENT_TYPE_CALL_CONNECTED = 0x01;
-this.STK_EVENT_TYPE_CALL_DISCONNECTED = 0x02;
-this.STK_EVENT_TYPE_LOCATION_STATUS = 0x03;
-this.STK_EVENT_TYPE_USER_ACTIVITY = 0x04;
-this.STK_EVENT_TYPE_IDLE_SCREEN_AVAILABLE = 0x05;
-this.STK_EVENT_TYPE_CARD_READER_STATUS = 0x06;
-this.STK_EVENT_TYPE_LANGUAGE_SELECTION = 0x07;
-this.STK_EVENT_TYPE_BROWSER_TERMINATION = 0x08;
-this.STK_EVENT_TYPE_DATA_AVAILABLE = 0x09;
-this.STK_EVENT_TYPE_CHANNEL_STATUS = 0x0a;
-this.STK_EVENT_TYPE_SINGLE_ACCESS_TECHNOLOGY_CHANGED = 0x0b;
-this.STK_EVENT_TYPE_DISPLAY_PARAMETER_CHANGED = 0x0c;
-this.STK_EVENT_TYPE_LOCAL_CONNECTION = 0x0d;
-this.STK_EVENT_TYPE_NETWORK_SEARCH_MODE_CHANGED = 0x0e;
-this.STK_EVENT_TYPE_BROWSING_STATUS = 0x0f;
-
-// STK Service state of Location Status.
-this.STK_SERVICE_STATE_NORMAL = 0x00;
-this.STK_SERVICE_STATE_LIMITED = 0x01;
-this.STK_SERVICE_STATE_UNAVAILABLE = 0x02;
-
-// Refresh mode.
-this.STK_REFRESH_NAA_INIT_AND_FULL_FILE_CHANGE = 0x00;
-this.STK_REFRESH_FILE_CHANGE = 0x01;
-this.STK_REFRESH_NAA_INIT_AND_FILE_CHANGE = 0x02;
-this.STK_REFRESH_NAA_INIT = 0x03;
-this.STK_REFRESH_UICC_RESET = 0x04;
-
-// Tone type.
-this.STK_TONE_TYPE_DIAL_TONE = 0x01;
-this.STK_TONE_TYPE_CALLED_SUBSCRIBER_BUSY = 0x02;
-this.STK_TONE_TYPE_CONGESTION = 0x03;
-this.STK_TONE_TYPE_RADIO_PATH_ACK = 0x04;
-this.STK_TONE_TYPE_RADIO_PATH_NOT_AVAILABLE = 0x05;
-this.STK_TONE_TYPE_ERROR = 0x06;
-this.STK_TONE_TYPE_CALL_WAITING_TONE = 0x07;
-this.STK_TONE_TYPE_RINGING_TONE = 0x08;
-this.STK_TONE_TYPE_GENERAL_BEEP = 0x10;
-this.STK_TONE_TYPE_POSITIVE_ACK_TONE = 0x11;
-this.STK_TONE_TYPE_NEGATIVE_ACK_TONE = 0x12;
-
-// Time unit.
-this.STK_TIME_UNIT_MINUTE = 0x00;
-this.STK_TIME_UNIT_SECOND = 0x01;
-this.STK_TIME_UNIT_TENTH_SECOND = 0x02;
-
-// Local Information type.
-this.STK_LOCAL_INFO_NNA = 0x00;
-this.STK_LOCAL_INFO_IMEI = 0x01;
-this.STK_LOCAL_INFO_NMR_FOR_NNA = 0x02;
-this.STK_LOCAL_INFO_DATE_TIME_ZONE = 0x03;
-this.STK_LOCAL_INFO_LANGUAGE = 0x04;
-this.STK_LOCAL_INFO_ACCESS_TECH = 0x06;
-this.STK_LOCAL_INFO_ESN = 0x07;
-this.STK_LOCAL_INFO_IMEISV = 0x08;
-this.STK_LOCAL_INFO_SEARCH_MODE = 0x09;
-this.STK_LOCAL_INFO_CHARGE_STATE = 0x0A;
-this.STK_LOCAL_INFO_MEID = 0x0B;
-this.STK_LOCAL_INFO_BROADCAST_NETWORK_INFO = 0x0D;
-this.STK_LOCAL_INFO_MULTIPLE_ACCESS_TECH = 0x0E;
-this.STK_LOCAL_INFO_INFO_FOR_MULTIPLE_ACCESS_TECH = 0x0F;
-this.STK_LOCAL_INFO_NMR_FOR_MULTIPLE_ACCESS_TECH = 0x10;
-
-// Timer Management.
-this.STK_TIMER_START = 0x00;
-this.STK_TIMER_DEACTIVATE = 0x01;
-this.STK_TMIER_GET_CURRENT_VALUE = 0x02;
-
-// Browser Launch Mode.
-this.STK_BROWSER_MODE_LAUNCH_IF_NOT_ALREADY_LAUNCHED = 0x00;
-this.STK_BROWSER_MODE_USING_EXISTING_BROWSER = 0x02;
-this.STK_BROWSER_MODE_USING_NEW_BROWSER = 0x03;
-
-// Browser Termination Cause.
-this.STK_BROWSER_TERMINATION_CAUSE_USER = 0x00;
-this.STK_BROWSER_TERMINATION_CAUSE_ERROR = 0x01;
-
-// Next Action Indicator.
-this.STK_NEXT_ACTION_NULL = 0x00;
-this.STK_NEXT_ACTION_END_PROACTIVE_SESSION = 0x81;
-
-/**
- * Supported Terminal Facilities.
- *
- * value = 1, supported.
- * 0, not supported.
- */
-this.STK_TERMINAL_SUPPORT_PROFILE_DOWNLOAD = 1;
-this.STK_TERMINAL_SUPPORT_SMS_PP_DOWNLOAD = 1;
-this.STK_TERMINAL_SUPPORT_CELL_BROADCAST_DATA_DOWNLOAD = 0;
-this.STK_TERMINAL_SUPPORT_MENU_SELECTION = 1;
-this.STK_TERMINAL_SUPPORT_SIM_DATA_DOWNLOAD_ERROR = 0;
-this.STK_TERMINAL_SUPPORT_TIMER_EXPIRATION = 1;
-this.STK_TERMINAL_SUPPORT_USSD_IN_CALL_CONTROL = 0;
-this.STK_TERMINAL_SUPPORT_CALL_CONTROL_IN_REDIAL = 0;
-
-this.STK_TERMINAL_SUPPORT_COMMAND_RESULT = 1;
-this.STK_TERMINAL_SUPPORT_CALL_CONTROL = 1;
-this.STK_TERMINAL_SUPPORT_CALL_ID_INCLUDED = 0;
-this.STK_TERMINAL_SUPPORT_MO_SMS_CONTROL = 0;
-this.STK_TERMINAL_SUPPORT_ALPHA_ID_INDICATION = 0;
-this.STK_TERMINAL_SUPPORT_UCS2_ENTRY = 1;
-this.STK_TERMINAL_SUPPORT_UCS2_DISPLAY = 1;
-this.STK_TERMINAL_SUPPORT_EXTENSION_TEXT = 1;
-
-this.STK_TERMINAL_SUPPORT_PROACTIVE_DISPLAY_TEXT = 1;
-this.STK_TERMINAL_SUPPORT_PROACTIVE_GET_INKEY = 1;
-this.STK_TERMINAL_SUPPORT_PROACTIVE_GET_INPUT = 1;
-this.STK_TERMINAL_SUPPORT_PROACTIVE_MORE_TIME = 1;
-this.STK_TERMINAL_SUPPORT_PROACTIVE_PLAY_TONE = 1;
-this.STK_TERMINAL_SUPPORT_PROACTIVE_POLL_INTERVAL = 1;
-this.STK_TERMINAL_SUPPORT_PROACTIVE_POLL_OFF = 1;
-this.STK_TERMINAL_SUPPORT_PROACTIVE_REFRESH = 1;
-
-this.STK_TERMINAL_SUPPORT_PROACTIVE_SELECT_ITEM = 1;
-this.STK_TERMINAL_SUPPORT_PROACTIVE_SEND_SMS = 1;
-this.STK_TERMINAL_SUPPORT_PROACTIVE_SEND_SS = 1;
-this.STK_TERMINAL_SUPPORT_PROACTIVE_SEND_USSD = 1;
-this.STK_TERMINAL_SUPPORT_PROACTIVE_SET_UP_CALL = 1;
-this.STK_TERMINAL_SUPPORT_PROACTIVE_SET_UP_MENU = 1;
-this.STK_TERMINAL_SUPPORT_PROACTIVE_LOCAL_INFO = 1;
-this.STK_TERMINAL_SUPPORT_PROACTIVE_LOCAL_INFO_NMR = 0;
-
-this.STK_TERMINAL_SUPPORT_PROACTIVE_SET_UP_EVENT_LIST = 1;
-this.STK_TERMINAL_SUPPORT_EVENT_MT_CALL = 1;
-this.STK_TERMINAL_SUPPORT_EVENT_CALL_CONNECTED = 1;
-this.STK_TERMINAL_SUPPORT_EVENT_CALL_DISCONNECTED = 1;
-this.STK_TERMINAL_SUPPORT_EVENT_LOCATION_STATUS = 1;
-this.STK_TERMINAL_SUPPORT_EVENT_USER_ACTIVITY = 1;
-this.STK_TERMINAL_SUPPORT_EVENT_IDLE_SCREEN_AVAILABLE = 1;
-this.STK_TERMINAL_SUPPORT_EVENT_CARD_READER_STATUS = 0;
-
-this.STK_TERMINAL_SUPPORT_EVENT_LANGUAGE_SELECTION = 1;
-this.STK_TERMINAL_SUPPORT_EVENT_BROWSER_TERMINATION = 1;
-this.STK_TERMINAL_SUPPORT_EVENT_DATA_AVAILABLE = 0;
-this.STK_TERMINAL_SUPPORT_EVENT_CHANNEL_STATUS = 0;
-
-this.STK_TERMINAL_SUPPORT_PROACTIVE_TIMER_START_STOP = 1;
-this.STK_TERMINAL_SUPPORT_PROACTIVE_TIMER_GET_CURRENT = 1;
-this.STK_TERMINAL_SUPPORT_PROACTIVE_LOCAL_INFO_DATE = 1;
-this.STK_TERMINAL_SUPPORT_GET_INKEY = 1;
-this.STK_TERMINAL_SUPPORT_SET_UP_IDLE_MODE_TEXT = 1;
-this.STK_TERMINAL_SUPPORT_RUN_AT_COMMAND = 0;
-this.STK_TERMINAL_SUPPORT_SET_UP_CALL = 1;
-this.STK_TERMINAL_SUPPORT_CALL_CONTROL_BY_NNA = 0;
-
-this.STK_TERMINAL_SUPPORT_DISPLAY_TEXT = 1;
-this.STK_TERMINAL_SUPPORT_SEND_DTMF_COMMAND = 1;
-this.STK_TERMINAL_SUPPORT_PROACTIVE_LOCAL_INFO_NMR = 0;
-this.STK_TERMINAL_SUPPORT_PROACTIVE_LOCAL_INFO_LANGUAGE = 1;
-this.STK_TERMINAL_SUPPORT_PROACTIVE_LOCAL_INFO_TIME_ADVANCE = 0;
-this.STK_TERMINAL_SUPPORT_PROACTIVE_LANGUAGE_NOTIFICATION = 0;
-this.STK_TERMINAL_SUPPORT_PROACTIVE_LAUNCH_BROWSER = 1;
-this.STK_TERMINAL_SUPPORT_PROACTIVE_LOCAL_INFO_ACCESS_TECH = 0;
-
-this.STK_TERMINAL_SUPPORT_BIP_COMMAND_OPEN_CHANNEL = 1;
-this.STK_TERMINAL_SUPPORT_BIP_COMMAND_CLOSE_CHANNEL = 1;
-this.STK_TERMINAL_SUPPORT_BIP_COMMAND_RECEIVE_DATA = 1;
-this.STK_TERMINAL_SUPPORT_BIP_COMMAND_SEND_DATA = 1;
-this.STK_TERMINAL_SUPPORT_BIP_COMMAND_GET_CHANNEL_STATUS = 0;
-
-/**
- * SAT profile
- *
- * @see ETSI TS 101.267, section 5.2.
- */
-this.STK_TERMINAL_PROFILE_DOWNLOAD =
- (STK_TERMINAL_SUPPORT_PROFILE_DOWNLOAD << 0) |
- (STK_TERMINAL_SUPPORT_SMS_PP_DOWNLOAD << 1) |
- (STK_TERMINAL_SUPPORT_CELL_BROADCAST_DATA_DOWNLOAD << 2) |
- (STK_TERMINAL_SUPPORT_MENU_SELECTION << 3) |
- (STK_TERMINAL_SUPPORT_SIM_DATA_DOWNLOAD_ERROR << 4) |
- (STK_TERMINAL_SUPPORT_TIMER_EXPIRATION << 5) |
- (STK_TERMINAL_SUPPORT_USSD_IN_CALL_CONTROL << 6) |
- (STK_TERMINAL_SUPPORT_CALL_CONTROL_IN_REDIAL << 7);
-
-this.STK_TERMINAL_PROFILE_OTHER =
- (STK_TERMINAL_SUPPORT_COMMAND_RESULT << 0) |
- (STK_TERMINAL_SUPPORT_CALL_CONTROL << 1) |
- (STK_TERMINAL_SUPPORT_CALL_ID_INCLUDED << 2) |
- (STK_TERMINAL_SUPPORT_MO_SMS_CONTROL << 3) |
- (STK_TERMINAL_SUPPORT_ALPHA_ID_INDICATION << 4) |
- (STK_TERMINAL_SUPPORT_UCS2_ENTRY << 5) |
- (STK_TERMINAL_SUPPORT_UCS2_DISPLAY << 6) |
- (STK_TERMINAL_SUPPORT_EXTENSION_TEXT << 7);
-
-this.STK_TERMINAL_PROFILE_PROACTIVE_1 =
- (STK_TERMINAL_SUPPORT_PROACTIVE_DISPLAY_TEXT << 0) |
- (STK_TERMINAL_SUPPORT_PROACTIVE_GET_INKEY << 1) |
- (STK_TERMINAL_SUPPORT_PROACTIVE_GET_INPUT << 2) |
- (STK_TERMINAL_SUPPORT_PROACTIVE_MORE_TIME << 3) |
- (STK_TERMINAL_SUPPORT_PROACTIVE_PLAY_TONE << 4) |
- (STK_TERMINAL_SUPPORT_PROACTIVE_POLL_INTERVAL << 5) |
- (STK_TERMINAL_SUPPORT_PROACTIVE_POLL_OFF << 6) |
- (STK_TERMINAL_SUPPORT_PROACTIVE_REFRESH << 7);
-
-this.STK_TERMINAL_PROFILE_PROACTIVE_2 =
- (STK_TERMINAL_SUPPORT_PROACTIVE_SELECT_ITEM << 0) |
- (STK_TERMINAL_SUPPORT_PROACTIVE_SEND_SMS << 1) |
- (STK_TERMINAL_SUPPORT_PROACTIVE_SEND_SS << 2) |
- (STK_TERMINAL_SUPPORT_PROACTIVE_SEND_USSD << 3) |
- (STK_TERMINAL_SUPPORT_PROACTIVE_SET_UP_CALL << 4) |
- (STK_TERMINAL_SUPPORT_PROACTIVE_SET_UP_MENU << 5) |
- (STK_TERMINAL_SUPPORT_PROACTIVE_LOCAL_INFO << 6) |
- (STK_TERMINAL_SUPPORT_PROACTIVE_LOCAL_INFO_NMR << 7);
-
-this.STK_TERMINAL_PROFILE_EVENT =
- (STK_TERMINAL_SUPPORT_PROACTIVE_SET_UP_EVENT_LIST << 0) |
- (STK_TERMINAL_SUPPORT_EVENT_MT_CALL << 1) |
- (STK_TERMINAL_SUPPORT_EVENT_CALL_CONNECTED << 2) |
- (STK_TERMINAL_SUPPORT_EVENT_CALL_DISCONNECTED << 3) |
- (STK_TERMINAL_SUPPORT_EVENT_LOCATION_STATUS << 4) |
- (STK_TERMINAL_SUPPORT_EVENT_USER_ACTIVITY << 5) |
- (STK_TERMINAL_SUPPORT_EVENT_IDLE_SCREEN_AVAILABLE << 6) |
- (STK_TERMINAL_SUPPORT_EVENT_CARD_READER_STATUS << 7);
-
-this.STK_TERMINAL_PROFILE_EVENT_EXT =
- (STK_TERMINAL_SUPPORT_EVENT_LANGUAGE_SELECTION << 0) |
- (STK_TERMINAL_SUPPORT_EVENT_BROWSER_TERMINATION << 1) |
- (STK_TERMINAL_SUPPORT_EVENT_DATA_AVAILABLE << 2) |
- (STK_TERMINAL_SUPPORT_EVENT_CHANNEL_STATUS << 3);
-
-this.STK_TERMINAL_PROFILE_PROACTIVE_3 =
- (STK_TERMINAL_SUPPORT_PROACTIVE_TIMER_START_STOP << 0) |
- (STK_TERMINAL_SUPPORT_PROACTIVE_TIMER_GET_CURRENT << 1) |
- (STK_TERMINAL_SUPPORT_PROACTIVE_LOCAL_INFO_DATE << 2) |
- (STK_TERMINAL_SUPPORT_GET_INKEY << 3) |
- (STK_TERMINAL_SUPPORT_SET_UP_IDLE_MODE_TEXT << 4) |
- (STK_TERMINAL_SUPPORT_RUN_AT_COMMAND << 5) |
- (STK_TERMINAL_SUPPORT_SET_UP_CALL << 6) |
- (STK_TERMINAL_SUPPORT_CALL_CONTROL_BY_NNA << 7);
-
-this.STK_TERMINAL_PROFILE_PROACTIVE_4 =
- (STK_TERMINAL_SUPPORT_DISPLAY_TEXT << 0) |
- (STK_TERMINAL_SUPPORT_SEND_DTMF_COMMAND << 1) |
- (STK_TERMINAL_SUPPORT_PROACTIVE_LOCAL_INFO_NMR << 2) |
- (STK_TERMINAL_SUPPORT_PROACTIVE_LOCAL_INFO_LANGUAGE << 3) |
- (STK_TERMINAL_SUPPORT_PROACTIVE_LOCAL_INFO_TIME_ADVANCE << 4) |
- (STK_TERMINAL_SUPPORT_PROACTIVE_LANGUAGE_NOTIFICATION << 5) |
- (STK_TERMINAL_SUPPORT_PROACTIVE_LAUNCH_BROWSER << 6) |
- (STK_TERMINAL_SUPPORT_PROACTIVE_LOCAL_INFO_ACCESS_TECH << 7);
-
-this.STK_TERMINAL_PROFILE_BIP_COMMAND =
- (STK_TERMINAL_SUPPORT_BIP_COMMAND_OPEN_CHANNEL << 0) |
- (STK_TERMINAL_SUPPORT_BIP_COMMAND_CLOSE_CHANNEL << 1) |
- (STK_TERMINAL_SUPPORT_BIP_COMMAND_RECEIVE_DATA << 2) |
- (STK_TERMINAL_SUPPORT_BIP_COMMAND_SEND_DATA << 3) |
- (STK_TERMINAL_SUPPORT_BIP_COMMAND_GET_CHANNEL_STATUS << 4);
-
-this.STK_SUPPORTED_TERMINAL_PROFILE = [
- STK_TERMINAL_PROFILE_DOWNLOAD,
- STK_TERMINAL_PROFILE_OTHER,
- STK_TERMINAL_PROFILE_PROACTIVE_1,
- STK_TERMINAL_PROFILE_PROACTIVE_2,
- STK_TERMINAL_PROFILE_EVENT,
- STK_TERMINAL_PROFILE_EVENT_EXT, // Event extension
- 0x00, // Multiple card proactive commands
- STK_TERMINAL_PROFILE_PROACTIVE_3,
- STK_TERMINAL_PROFILE_PROACTIVE_4,
- 0x00, // Softkey support
- 0x00, // Softkey information
- STK_TERMINAL_PROFILE_BIP_COMMAND,
- 0x00, // BIP supported bearers
- 0x00, // Screen height
- 0x00, // Screen width
- 0x00, // 16, Screen effects
- 0x00, // 17, BIP supported transport interface
- 0x00, // 18, RFU
- 0x00, // 19, RFU
- 0x00, // 20, RFU
-];
-
-/**
- * ICC Services Table.
- *
- * @see 3GPP TS 51.011 10.3.7 (SIM) and 3GPP TS 31.102 4.2.8 (USIM).
- */
-this.GECKO_ICC_SERVICES = {
- // @see 3GPP TS 51.011 10.3.7 (SIM).
- sim: {
- ADN: 2,
- FDN: 3,
- PLMNSEL: 7,
- MSISDN: 9,
- EXT1: 10,
- EXT2: 11,
- CBMI: 14,
- GID1: 15,
- SPN: 17,
- SDN: 18,
- EXT3: 19,
- DATA_DOWNLOAD_SMS_CB: 25,
- DATA_DOWNLOAD_SMS_PP: 26,
- CBMIR: 30,
- BDN: 31,
- IMG: 39,
- PNN: 51,
- OPL: 52,
- MDN: 53,
- MWIS: 54,
- SPDI: 56
- },
- // @see 3GPP TS 31.102 4.2.8 (USIM).
- usim: {
- FDN: 2,
- EXT2: 3,
- SDN: 4,
- EXT3: 5,
- BDN: 6,
- CBMI: 15,
- CBMIR: 16,
- GID1: 17,
- SPN: 19,
- MSISDN: 21,
- IMG: 22,
- DATA_DOWNLOAD_SMS_PP: 28,
- DATA_DOWNLOAD_SMS_CB: 29,
- PNN: 45,
- OPL: 46,
- MDN: 47,
- MWIS: 48,
- SPDI: 51
- },
- // @see 3GPP2 C.S0023-D 3.4.18 (RUIM).
- ruim: {
- FDN: 3,
- ENHANCED_PHONEBOOK: 6,
- EXT1: 10,
- EXT2: 11,
- SPN: 17,
- SDN: 18,
- EXT3: 19,
- },
- // @see B.3.1.1 CPHS Information in CPHS Phase 2:
- // Indicates which of the CPHS 'optional' data-fields are present in the SIM card:
- // EF_CPHS_CSP, EF_CPHS_SST, EF_CPHS_MBN, EF_CPHS_ONSF, EF_CPHS_INFO_NUM
- // Note: Mandatory EFs are: (B.3.1 Enhanced SIM Requirements)
- // EF_CPHS_CFF, EF_CPHS_VMI, EF_CPHS_ONS, EF_CPHS_INFO
- cphs: {
- CSP: 1,
- SST: 2,
- MBN: 3,
- ONSF: 4,
- INFO_NUM: 5
- }
-};
-
-/**
- * Cell Broadcast constants
- */
-
-this.CB_FORMAT_GSM = 0;
-this.CB_FORMAT_ETWS = 1;
-this.CB_FORMAT_CMAS = 2;
-this.CB_FORMAT_UMTS = 3;
-
-// CBS Data Coding Scheme: Language groups
-// see 3GPP TS 23.038 section 5
-this.CB_DCS_LANG_GROUP_1 = [
- "de", "en", "it", "fr", "es", "nl", "sv", "da", "pt", "fi",
- "no", "el", "tr", "hu", "pl", null
-];
-this.CB_DCS_LANG_GROUP_2 = [
- "cs", "he", "ar", "ru", "is", null, null, null, null, null,
- null, null, null, null, null, null
-];
-
-// See 3GPP TS 23.041 v11.2.0 section 9.4.1.2.2
-this.CB_NON_MMI_SETTABLE_RANGES = [
- /*0x1000 - 0x107F*/4096, 4224, /*0x1080 - 0x10FF*/4224, 4352,
- /*0x1112 - 0x1112*/4370, 4371, /*0x111F - 0x111F*/4383, 4384,
- /*0xF000 - 0xFFFE*/61440, 65535, /*0xFFFF - 0xFFFF*/65535, 65536
-];
-
-// User Data max length in septets
-this.CB_MAX_CONTENT_7BIT = 93;
-// User Data max length in octets
-this.CB_MAX_CONTENT_8BIT = 82;
-// User Data max length in chars
-this.CB_MAX_CONTENT_UCS2 = 41;
-
-// See 3GPP TS 23.041 v11.6.0 senction 9.3.19
-this.CB_MSG_PAGE_INFO_SIZE = 82;
-
-this.CB_MESSAGE_SIZE_ETWS = 56;
-this.CB_MESSAGE_SIZE_GSM = 88;
-this.CB_MESSAGE_SIZE_UMTS_MIN = 90;
-this.CB_MESSAGE_SIZE_UMTS_MAX = 1252;
-
-
-
-// GSM Cell Broadcast Geographical Scope
-// See 3GPP TS 23.041 clause 9.4.1.2.1
-this.CB_GSM_GEOGRAPHICAL_SCOPE_CELL_WIDE_IMMEDIATE = 0;
-this.CB_GSM_GEOGRAPHICAL_SCOPE_PLMN_WIDE = 1;
-this.CB_GSM_GEOGRAPHICAL_SCOPE_LOCATION_AREA_WIDE = 2;
-this.CB_GSM_GEOGRAPHICAL_SCOPE_CELL_WIDE = 3;
-
-// GSM Cell Broadcast Geographical Scope
-// See 3GPP TS 23.041 clause 9.4.1.2.1
-this.CB_GSM_GEOGRAPHICAL_SCOPE_NAMES = [
- "cell-immediate",
- "plmn",
- "location-area",
- "cell"
-];
-
-// GSM Cell Broadcast Message Identifiers
-// see 3GPP TS 23.041 clause 9.4.1.2.2
-this.CB_GSM_MESSAGEID_ETWS_BEGIN = 0x1100;
-this.CB_GSM_MESSAGEID_ETWS_END = 0x1107;
-
-// ETWS Warning-Type
-// see 3GPP TS 23.041 clause 9.3.24
-this.CB_ETWS_WARNING_TYPE_NAMES = [
- "earthquake",
- "tsunami",
- "earthquake-tsunami",
- "test",
- "other"
-];
-
-// UMTS Message Type
-// see 3GPP TS 25.324 section 11.1
-this.CB_UMTS_MESSAGE_TYPE_CBS = 1;
-this.CB_UMTS_MESSAGE_TYPE_SCHEDULE = 2;
-this.CB_UMTS_MESSAGE_TYPE_CBS41 = 3;
-
-/**
- * Number plan identification defined in
- * |Table 10.5.118: Called party BCD number| of 3GPP TS 24.008.
- */
-this.CALLED_PARTY_BCD_NPI_UNKNOWN = 0;
-this.CALLED_PARTY_BCD_NPI_ISDN = 1;
-this.CALLED_PARTY_BCD_NPI_DATA = 3;
-this.CALLED_PARTY_BCD_NPI_TELEX = 4;
-this.CALLED_PARTY_BCD_NPI_NATIONAL = 8;
-this.CALLED_PARTY_BCD_NPI_PRIVATE = 9;
-
-/**
- * Array of number plan identification values which can be used to map an
- * enumeration to the corresponding value. The indices should be consistent
- * with nsISmsService::NUMBER_PLAN_IDENTIFICATION_* constants.
- */
-this.CALLED_PARTY_BCD_NPI = [
- CALLED_PARTY_BCD_NPI_UNKNOWN,
- CALLED_PARTY_BCD_NPI_ISDN,
- CALLED_PARTY_BCD_NPI_DATA,
- CALLED_PARTY_BCD_NPI_TELEX,
- CALLED_PARTY_BCD_NPI_NATIONAL,
- CALLED_PARTY_BCD_NPI_PRIVATE
-];
-
-/**
- * GSM PDU constants
- */
-
-// PDU TYPE-OF-ADDRESS
-this.PDU_TOA_UNKNOWN = 0x80; // Unknown. This is used when the user or
- // network has no a priori information
- // about the numbering plan.
-this.PDU_TOA_ISDN = 0x81; // ISDN/Telephone numbering
-this.PDU_TOA_DATA_NUM = 0x83; // Data numbering plan
-this.PDU_TOA_TELEX_NUM = 0x84; // Telex numbering plan
-this.PDU_TOA_NATIONAL_NUM = 0x88; // National numbering plan
-this.PDU_TOA_PRIVATE_NUM = 0x89; // Private numbering plan
-this.PDU_TOA_ERMES_NUM = 0x8A; // Ermes numbering plan
-this.PDU_TOA_INTERNATIONAL = 0x90; // International number
-this.PDU_TOA_NATIONAL = 0xA0; // National number. Prefix or escape digits
- // shall not be included
-this.PDU_TOA_NETWORK_SPEC = 0xB0; // Network specific number This is used to
- // indicate administration/service number
- // specific to the serving network
-this.PDU_TOA_SUBSCRIBER = 0xC0; // Subscriber number. This is used when a
- // specific short number representation is
- // stored in one or more SCs as part of a
- // higher layer application
-this.PDU_TOA_ALPHANUMERIC = 0xD0; // Alphanumeric, (coded according to GSM TS
- // 03.38 7-bit default alphabet)
-this.PDU_TOA_ABBREVIATED = 0xE0; // Abbreviated number
-
-/**
- * First octet of the SMS-DELIVER PDU
- *
- * RP: 0 Reply Path parameter is not set in this PDU
- * 1 Reply Path parameter is set in this PDU
- *
- * UDHI: 0 The UD field contains only the short message
- * 1 The beginning of the UD field contains a header in addition of
- * the short message
- *
- * SRI: (is only set by the SMSC)
- * 0 A status report will not be returned to the SME
- * 1 A status report will be returned to the SME
- *
- * MMS: (is only set by the SMSC)
- * 0 More messages are waiting for the MS in the SMSC
- * 1 No more messages are waiting for the MS in the SMSC
- *
- * MTI: bit1 bit0 Message type
- * 0 0 SMS-DELIVER (SMSC ==> MS)
- * 0 0 SMS-DELIVER REPORT (MS ==> SMSC, is generated
- * automatically by the M20, after receiving a
- * SMS-DELIVER)
- * 0 1 SMS-SUBMIT (MS ==> SMSC)
- * 0 1 SMS-SUBMIT REPORT (SMSC ==> MS)
- * 1 0 SMS-STATUS REPORT (SMSC ==> MS)
- * 1 0 SMS-COMMAND (MS ==> SMSC)
- * 1 1 Reserved
- */
-this.PDU_RP = 0x80; // Reply path. Parameter indicating that
- // reply path exists.
-this.PDU_UDHI = 0x40; // User data header indicator. This bit is
- // set to 1 if the User Data field starts
- // with a header
-this.PDU_SRI_SRR = 0x20; // Status report indication (SMS-DELIVER)
- // or request (SMS-SUBMIT)
-this.PDU_VPF_ABSOLUTE = 0x18;// Validity period aboslute format
- // (SMS-SUBMIT only)
-this.PDU_VPF_RELATIVE = 0x10;// Validity period relative format
- // (SMS-SUBMIT only)
-this.PDU_VPF_ENHANCED = 0x8; // Validity period enhance format
- // (SMS-SUBMIT only)
-this.PDU_MMS_RD = 0x04;// More messages to send. (SMS-DELIVER only) or
- // Reject duplicates (SMS-SUBMIT only)
-
-// MTI - Message Type Indicator
-this.PDU_MTI_SMS_RESERVED = 0x03;
-this.PDU_MTI_SMS_STATUS_REPORT = 0x02;
-this.PDU_MTI_SMS_COMMAND = 0x02;
-this.PDU_MTI_SMS_SUBMIT = 0x01;
-this.PDU_MTI_SMS_DELIVER = 0x00;
-
-// PI - Parameter Indicator
-this.PDU_PI_EXTENSION = 0x80;
-this.PDU_PI_USER_DATA_LENGTH = 0x04;
-this.PDU_PI_DATA_CODING_SCHEME = 0x02;
-this.PDU_PI_PROTOCOL_IDENTIFIER = 0x01;
-this.PDU_PI_RESERVED = 0x78;
-
-// FCS - Failure Cause
-// 0...127 see 3GPP TS 24.011 clause E.2
-// 128...255 see 3GPP TS 23.040 clause 9.2.3.22
-// others see 3GPP TS 27.005 clause 3.2.5
-this.PDU_FCS_OK = 0x00;
-this.PDU_FCS_PROTOCOL_ERROR = 0x6F;
-this.PDU_FCS_MEMORY_CAPACITY_EXCEEDED = 0XD3;
-this.PDU_FCS_USAT_BUSY = 0XD4;
-this.PDU_FCS_USIM_DATA_DOWNLOAD_ERROR = 0xD5;
-this.PDU_FCS_RESERVED = 0xE0;
-this.PDU_FCS_UNSPECIFIED = 0xFF;
-// Special internal value that means we should not acknowledge an
-// incoming text right away, but need to wait for other components
-// (e.g. storage) to complete. This can be any value, so long it
-// doesn't conflict with the PDU_FCS_* constants above.
-this.MOZ_FCS_WAIT_FOR_EXPLICIT_ACK = 0x0F;
-
-// ST - Status
-// Bit 7..0 = 000xxxxx, short message transaction completed
-this.PDU_ST_0_RECEIVED = 0x00;
-this.PDU_ST_0_FORWARDED_NO_CONFIRM = 0x01;
-this.PDU_ST_0_REPLACED_BY_SC = 0x02;
-this.PDU_ST_0_RESERVED_BEGIN = 0x03;
-this.PDU_ST_0_SC_SPECIFIC_BEGIN = 0x10;
-this.PDU_ST_0_SC_SPECIFIC_END = 0x1F;
-// Bit 7..0 = 001xxxxx, temporary error, SC still trying to transfer SM
-this.PDU_ST_1_CONGESTION = 0x20;
-this.PDU_ST_1_SME_BUSY = 0x21;
-this.PDU_ST_1_SME_NO_RESPONSE = 0x22;
-this.PDU_ST_1_SERVICE_REJECTED = 0x23;
-this.PDU_ST_1_QOS_UNAVAILABLE = 0x24;
-this.PDU_ST_1_SME_ERROR = 0x25;
-this.PDU_ST_1_RESERVED_BEGIN = 0x26;
-this.PDU_ST_1_SC_SPECIFIC_BEGIN = 0x30;
-this.PDU_ST_1_SC_SPECIFIC_END = 0x3F;
-// Bit 7..0 = 010xxxxx, permanent error, SC is not making any more transfer
-// attempts
-this.PDU_ST_2_RPC_ERROR = 0x40;
-this.PDU_ST_2_DEST_INCOMPATIBLE = 0x41;
-this.PDU_ST_2_CONNECTION_REJECTED = 0x42;
-this.PDU_ST_2_NOT_OBTAINABLE = 0x43;
-this.PDU_ST_2_QOS_UNAVAILABLE = 0x44;
-this.PDU_ST_2_INTERWORKING_UNAVALIABLE = 0x45;
-this.PDU_ST_2_VALIDITY_EXPIRED = 0x46;
-this.PDU_ST_2_DELETED_BY_SME = 0x47;
-this.PDU_ST_2_DELETED_BY_SC = 0x48;
-this.PDU_ST_2_SM_MISSING = 0x49;
-this.PDU_ST_2_RESERVED_BEGIN = 0x4A;
-this.PDU_ST_2_SC_SPECIFIC_BEGIN = 0x50;
-this.PDU_ST_2_SC_SPECIFIC_END = 0x5F;
-// Bit 7..0 = 011xxxxx, temporary error, SC is not making any more transfer
-// attempts
-this.PDU_ST_3_CONGESTION = 0x60;
-this.PDU_ST_3_SME_BUSY = 0x61;
-this.PDU_ST_3_SME_NO_RESPONSE = 0x62;
-this.PDU_ST_3_SERVICE_REJECTED = 0x63;
-this.PDU_ST_3_QOS_UNAVAILABLE = 0x64;
-this.PDU_ST_3_SME_ERROR = 0x65;
-this.PDU_ST_3_RESERVED_BEGIN = 0x66;
-this.PDU_ST_3_SC_SPECIFIC_BEGIN = 0x70;
-this.PDU_ST_3_SC_SPECIFIC_END = 0x7F;
-
-this.GECKO_SMS_DELIVERY_STATUS_NOT_APPLICABLE = "not-applicable";
-this.GECKO_SMS_DELIVERY_STATUS_SUCCESS = "success";
-this.GECKO_SMS_DELIVERY_STATUS_PENDING = "pending";
-this.GECKO_SMS_DELIVERY_STATUS_ERROR = "error";
-
-// User Data max length in septets
-this.PDU_MAX_USER_DATA_7BIT = 160;
-// User Data max length in octets
-this.PDU_MAX_USER_DATA_8BIT = 140;
-// User Data max length in chars
-this.PDU_MAX_USER_DATA_UCS2 = 70;
-
-// PID - Protocol Indicator
-this.PDU_PID_DEFAULT = 0x00;
-this.PDU_PID_TELEMATIC_INTERWORKING = 0x20;
-this.PDU_PID_SHORT_MESSAGE_TYPE_0 = 0x40;
-this.PDU_PID_REPLACE_SHORT_MESSAGE_TYPE_1 = 0x41;
-this.PDU_PID_REPLACE_SHORT_MESSAGE_TYPE_2 = 0x42;
-this.PDU_PID_REPLACE_SHORT_MESSAGE_TYPE_3 = 0x43;
-this.PDU_PID_REPLACE_SHORT_MESSAGE_TYPE_4 = 0x44;
-this.PDU_PID_REPLACE_SHORT_MESSAGE_TYPE_5 = 0x45;
-this.PDU_PID_REPLACE_SHORT_MESSAGE_TYPE_6 = 0x46;
-this.PDU_PID_REPLACE_SHORT_MESSAGE_TYPE_7 = 0x47;
-this.PDU_PID_ENHANDED_MESSAGE_SERVICE = 0x5E;
-this.PDU_PID_RETURN_CALL_MESSAGE = 0x5F;
-this.PDU_PID_ANSI_136_R_DATA = 0x7C;
-this.PDU_PID_ME_DATA_DOWNLOAD = 0x7D;
-this.PDU_PID_ME_DEPERSONALIZATION = 0x7E;
-this.PDU_PID_USIM_DATA_DOWNLOAD = 0x7F;
-
-// DCS - Data Coding Scheme
-this.PDU_DCS_MSG_CODING_7BITS_ALPHABET = 0x00;
-this.PDU_DCS_MSG_CODING_8BITS_ALPHABET = 0x04;
-this.PDU_DCS_MSG_CODING_16BITS_ALPHABET = 0x08;
-this.PDU_DCS_MSG_CLASS_0 = 0x00;
-this.PDU_DCS_MSG_CLASS_1 = 0x01;
-this.PDU_DCS_MSG_CLASS_2 = 0x02;
-this.PDU_DCS_MSG_CLASS_3 = 0x03;
-this.PDU_DCS_MSG_CLASS_USER_1 = 0x04;
-this.PDU_DCS_MSG_CLASS_USER_2 = 0x05;
-this.PDU_DCS_MSG_CLASS_NORMAL = 0x06;
-this.PDU_DCS_CODING_GROUP_BITS = 0xF0;
-this.PDU_DCS_MSG_CLASS_BITS = 0x03;
-this.PDU_DCS_MWI_ACTIVE_BITS = 0x08;
-this.PDU_DCS_MWI_ACTIVE_VALUE = 0x08;
-this.PDU_DCS_MWI_TYPE_BITS = 0x03;
-this.PDU_DCS_MWI_TYPE_VOICEMAIL = 0x00;
-this.PDU_DCS_MWI_TYPE_FAX = 0x01;
-this.PDU_DCS_MWI_TYPE_EMAIL = 0x02;
-this.PDU_DCS_MWI_TYPE_OTHER = 0x03;
-
-// Set as Array instead of Object for reversed-mapping with Array.indexOf().
-this.GECKO_SMS_MESSAGE_CLASSES = [];
-GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_0] = "class-0";
-GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_1] = "class-1";
-GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_2] = "class-2";
-GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_3] = "class-3";
-GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_USER_1] = "user-1";
-GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_USER_2] = "user-2";
-GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_NORMAL] = "normal";
-
-// Because service center timestamp omit the century. Yay.
-this.PDU_TIMESTAMP_YEAR_OFFSET = 2000;
-
-// See 9.2.3.24 TP‑User Data (TP‑UD)
-this.PDU_IEI_CONCATENATED_SHORT_MESSAGES_8BIT = 0x00;
-this.PDU_IEI_SPECIAL_SMS_MESSAGE_INDICATION = 0x01;
-this.PDU_IEI_APPLICATION_PORT_ADDRESSING_SCHEME_8BIT = 0x04;
-this.PDU_IEI_APPLICATION_PORT_ADDRESSING_SCHEME_16BIT = 0x05;
-this.PDU_IEI_SMSC_CONTROL_PARAMS = 0x06;
-this.PDU_IEI_UDH_SOURCE_INDICATOR = 0x07;
-this.PDU_IEI_CONCATENATED_SHORT_MESSAGES_16BIT = 0x08;
-this.PDU_IEI_WIRELESS_CONTROL_MESSAGE_PROTOCOL = 0x09;
-this.PDU_IEI_TEXT_FORMATING = 0x0A;
-this.PDU_IEI_PREDEFINED_SOUND = 0x0B;
-this.PDU_IEI_USER_DATA_SOUND = 0x0C;
-this.PDU_IEI_PREDEFINED_ANIMATION = 0x0D;
-this.PDU_IEI_LARGE_ANIMATION = 0x0E;
-this.PDU_IEI_SMALL_ANIMATION = 0x0F;
-this.PDU_IEI_LARGE_PICTURE = 0x10;
-this.PDU_IEI_SMALL_PICTURE = 0x11;
-this.PDU_IEI_VARIABLE_PICTURE = 0x12;
-this.PDU_IEI_USER_PROMPT_INDICATOR = 0x13;
-this.PDU_IEI_EXTENDED_OBJECT = 0x14;
-this.PDU_IEI_REUSED_EXTENDED_OBJECT = 0x15;
-this.PDU_IEI_COMPRESS_CONTROL = 0x16;
-this.PDU_IEI_OBJECT_DISTRIBUTION_INDICATOR = 0x17;
-this.PDU_IEI_STANDARD_WVG_OBJECT = 0x18;
-this.PDU_IEI_CHARACTER_SIZE_WVG_OBJECT = 0x19;
-this.PDU_IEI_EXTENDED_OBJECT_DATA_REQUEST_COMMAND = 0x1A;
-this.PDU_IEI_RFC822_EMAIL_HEADER = 0x20;
-this.PDU_IEI_HYPERLINK_FORMAT_ELEMENT = 0x21;
-this.PDU_IEI_REPLY_ADDRESS_ELEMENT = 0x22;
-this.PDU_IEI_ENHANCED_VOICE_MAIL_INFORMATION = 0x23;
-this.PDU_IEI_NATIONAL_LANGUAGE_SINGLE_SHIFT = 0x24;
-this.PDU_IEI_NATIONAL_LANGUAGE_LOCKING_SHIFT = 0x25;
-
-// Application Port Addressing, see 3GPP TS 23.040 9.2.3.24.3
-this.PDU_APA_RESERVED_8BIT_PORTS = 240;
-this.PDU_APA_VALID_16BIT_PORTS = 49152;
-
-// 7bit alphabet escape character. The encoded value of this code point is left
-// undefined in official spec. Its code value is internally assigned to \uffff,
-// <noncharacter-FFFF> in Unicode basic multilingual plane.
-this.PDU_NL_EXTENDED_ESCAPE = 0x1B;
-
-// <SP>, <LF>, <CR> are only defined in locking shift tables.
-this.PDU_NL_SPACE = 0x20;
-this.PDU_NL_LINE_FEED = 0x0A;
-this.PDU_NL_CARRIAGE_RETURN = 0x0D;
-
-// 7bit alphabet page break character, only defined in single shift tables.
-// The encoded value of this code point is left undefined in official spec, but
-// the code point itself maybe be used for example in compressed CBS messages.
-// Its code value is internally assigned to \u000c, ASCII form feed, or new page.
-this.PDU_NL_PAGE_BREAK = 0x0A;
-// 7bit alphabet reserved control character, only defined in single shift
-// tables. The encoded value of this code point is left undefined in official
-// spec. Its code value is internally assigned to \ufffe, <noncharacter-FFFE>
-// in Unicode basic multilingual plane.
-this.PDU_NL_RESERVED_CONTROL = 0x0D;
-
-this.PDU_NL_IDENTIFIER_DEFAULT = 0;
-this.PDU_NL_IDENTIFIER_TURKISH = 1;
-this.PDU_NL_IDENTIFIER_SPANISH = 2;
-this.PDU_NL_IDENTIFIER_PORTUGUESE = 3;
-this.PDU_NL_IDENTIFIER_BENGALI = 4;
-this.PDU_NL_IDENTIFIER_GUJARATI = 5;
-this.PDU_NL_IDENTIFIER_HINDI = 6;
-this.PDU_NL_IDENTIFIER_KANNADA = 7;
-this.PDU_NL_IDENTIFIER_MALAYALAM = 8;
-this.PDU_NL_IDENTIFIER_ORIYA = 9;
-this.PDU_NL_IDENTIFIER_PUNJABI = 10;
-this.PDU_NL_IDENTIFIER_TAMIL = 11;
-this.PDU_NL_IDENTIFIER_TELUGU = 12;
-this.PDU_NL_IDENTIFIER_URDU = 13;
-
-// The mapping of mcc and their extra GSM national language locking / single
-// shift table tuples to enable. The default GSM alphabet and extension table
-// are always enabled and need not to be list here.
-//
-// The content should be updated when a relevant national regulatory body
-// requests. See 'NOTE 2' of 6.2.1.2.5 in 3GPP TS 23.038:
-// "
-// Encoding of a message using the national locking shift mechanism is not
-// intended to be implemented until a formal request is issued by the
-// relevant national regulatory body. This is because a receiving entity
-// not supporting the relevant locking-shift decoding will present different
-// characters from the ones intended by the sending entity.
-// "
-this.PDU_MCC_NL_TABLE_TUPLES_MAPPING = {
- // Configuration for Turkey.
- //
- // The Turkish single shift table contains 7 extra characters
- // (Ğ, İ, Ş, ç, ğ, ı, ş) than the GSM default alphabet extension table. Since
- // all the 7 characters are also included in Turkish locking shift table, it's
- // not necessary to enable Turkish single shift table. Using GSM default
- // alphabet extension table instead saves 3 octets when these extension table
- // characters present in a message.
- 286: [[PDU_NL_IDENTIFIER_TURKISH, PDU_NL_IDENTIFIER_DEFAULT]]
-};
-
-/*
- * 3GPP TS 23.038 - 6.2.1 GSM 7 bit Default Alphabet
- */
-this.PDU_NL_GSM_DEFAULT_ALPHABET =
- // 01.....23.....4.....5.....6.....7.....8.....9.....A.B.....C.....D.E.....F.....
- "@\u00a3$\u00a5\u00e8\u00e9\u00f9\u00ec\u00f2\u00c7\n\u00d8\u00f8\r\u00c5\u00e5"
- // 0.....12.....3.....4.....5.....6.....7.....8.....9.....A.....B.....C.....D.....E.....F.....
- + "\u0394_\u03a6\u0393\u039b\u03a9\u03a0\u03a8\u03a3\u0398\u039e\uffff\u00c6\u00e6\u00df\u00c9"
- // 012.34.....56789ABCDEF
- + " !\"#\u00a4%&'()*+,-./"
- // 0123456789ABCDEF
- + "0123456789:;<=>?"
- // 0.....123456789ABCDEF
- + "\u00a1ABCDEFGHIJKLMNO"
- // 0123456789AB.....C.....D.....E.....F.....
- + "PQRSTUVWXYZ\u00c4\u00d6\u00d1\u00dc\u00a7"
- // 0.....123456789ABCDEF
- + "\u00bfabcdefghijklmno"
- // 0123456789AB.....C.....D.....E.....F.....
- + "pqrstuvwxyz\u00e4\u00f6\u00f1\u00fc\u00e0";
-
-// National Language Locking Shift Tables, see 3GPP TS 23.038
-this.PDU_NL_LOCKING_SHIFT_TABLES = [
- /**
- * National Language Identifier: 0x00
- * 6.2.1 GSM 7 bit Default Alphabet
- */
- PDU_NL_GSM_DEFAULT_ALPHABET,
-
- /**
- * National Language Identifier: 0x01
- * A.3.1 Turkish National Language Locking Shift Table
- */
- // 01.....23.....4.....5.....6.....7.....8.....9.....A.B.....C.....D.E.....F.....
- "@\u00a3$\u00a5\u20ac\u00e9\u00f9\u0131\u00f2\u00c7\n\u011e\u011f\r\u00c5\u00e5"
- // 0.....12.....3.....4.....5.....6.....7.....8.....9.....A.....B.....C.....D.....E.....F.....
- + "\u0394_\u03a6\u0393\u039b\u03a9\u03a0\u03a8\u03a3\u0398\u039e\uffff\u015e\u015f\u00df\u00c9"
- // 012.34.....56789ABCDEF
- + " !\"#\u00a4%&'()*+,-./"
- // 0123456789ABCDEF
- + "0123456789:;<=>?"
- // 0.....123456789ABCDEF
- + "\u0130ABCDEFGHIJKLMNO"
- // 0123456789AB.....C.....D.....E.....F.....
- + "PQRSTUVWXYZ\u00c4\u00d6\u00d1\u00dc\u00a7"
- // 0.....123456789ABCDEF
- + "\u00e7abcdefghijklmno"
- // 0123456789AB.....C.....D.....E.....F.....
- + "pqrstuvwxyz\u00e4\u00f6\u00f1\u00fc\u00e0",
-
- /**
- * National Language Identifier: 0x02
- * A.3.2 Void
- * Fallback to GSM Default Alphabet
- */
- PDU_NL_GSM_DEFAULT_ALPHABET,
-
- /**
- * National Language Identifier: 0x03
- * A.3.3 Portuguese National Language Locking Shift Table
- */
- // 01.....23.....4.....5.....6.....7.....8.....9.....A.B.....C.....D.E.....F.....
- "@\u00a3$\u00a5\u00ea\u00e9\u00fa\u00ed\u00f3\u00e7\n\u00d4\u00f4\r\u00c1\u00e1"
- // 0.....12.....3.....4.....5.....67.8.....9.....AB.....C.....D.....E.....F.....
- + "\u0394_\u00aa\u00c7\u00c0\u221e^\\\u20ac\u00d3|\uffff\u00c2\u00e2\u00ca\u00c9"
- // 012.34.....56789ABCDEF
- + " !\"#\u00ba%&'()*+,-./"
- // 0123456789ABCDEF
- + "0123456789:;<=>?"
- // 0.....123456789ABCDEF
- + "\u00cdABCDEFGHIJKLMNO"
- // 0123456789AB.....C.....D.....E.....F.....
- + "PQRSTUVWXYZ\u00c3\u00d5\u00da\u00dc\u00a7"
- // 0123456789ABCDEF
- + "~abcdefghijklmno"
- // 0123456789AB.....C.....DE.....F.....
- + "pqrstuvwxyz\u00e3\u00f5`\u00fc\u00e0",
-
- /**
- * National Language Identifier: 0x04
- * A.3.4 Bengali National Language Locking Shift Table
- */
- // 0.....1.....2.....3.....4.....5.....6.....7.....8.....9.....A.B.....CD.EF.....
- "\u0981\u0982\u0983\u0985\u0986\u0987\u0988\u0989\u098a\u098b\n\u098c \r \u098f"
- // 0.....123.....4.....5.....6.....7.....8.....9.....A.....B.....C.....D.....E.....F.....
- + "\u0990 \u0993\u0994\u0995\u0996\u0997\u0998\u0999\u099a\uffff\u099b\u099c\u099d\u099e"
- // 012.....3.....4.....5.....6.....7.....89A.....B.....CD.....EF.....
- + " !\u099f\u09a0\u09a1\u09a2\u09a3\u09a4)(\u09a5\u09a6,\u09a7.\u09a8"
- // 0123456789ABCD.....E.....F
- + "0123456789:; \u09aa\u09ab?"
- // 0.....1.....2.....3.....4.....56.....789A.....B.....C.....D.....E.....F.....
- + "\u09ac\u09ad\u09ae\u09af\u09b0 \u09b2 \u09b6\u09b7\u09b8\u09b9\u09bc\u09bd"
- // 0.....1.....2.....3.....4.....5.....6.....789.....A.....BCD.....E.....F.....
- + "\u09be\u09bf\u09c0\u09c1\u09c2\u09c3\u09c4 \u09c7\u09c8 \u09cb\u09cc\u09cd"
- // 0.....123456789ABCDEF
- + "\u09ceabcdefghijklmno"
- // 0123456789AB.....C.....D.....E.....F.....
- + "pqrstuvwxyz\u09d7\u09dc\u09dd\u09f0\u09f1",
-
- /**
- * National Language Identifier: 0x05
- * A.3.5 Gujarati National Language Locking Shift Table
- */
- // 0.....1.....2.....3.....4.....5.....6.....7.....8.....9.....A.B.....C.....D.EF.....
- "\u0a81\u0a82\u0a83\u0a85\u0a86\u0a87\u0a88\u0a89\u0a8a\u0a8b\n\u0a8c\u0a8d\r \u0a8f"
- // 0.....1.....23.....4.....5.....6.....7.....8.....9.....A.....B.....C.....D.....E.....F.....
- + "\u0a90\u0a91 \u0a93\u0a94\u0a95\u0a96\u0a97\u0a98\u0a99\u0a9a\uffff\u0a9b\u0a9c\u0a9d\u0a9e"
- // 012.....3.....4.....5.....6.....7.....89A.....B.....CD.....EF.....
- + " !\u0a9f\u0aa0\u0aa1\u0aa2\u0aa3\u0aa4)(\u0aa5\u0aa6,\u0aa7.\u0aa8"
- // 0123456789ABCD.....E.....F
- + "0123456789:; \u0aaa\u0aab?"
- // 0.....1.....2.....3.....4.....56.....7.....89.....A.....B.....C.....D.....E.....F.....
- + "\u0aac\u0aad\u0aae\u0aaf\u0ab0 \u0ab2\u0ab3 \u0ab5\u0ab6\u0ab7\u0ab8\u0ab9\u0abc\u0abd"
- // 0.....1.....2.....3.....4.....5.....6.....7.....89.....A.....B.....CD.....E.....F.....
- + "\u0abe\u0abf\u0ac0\u0ac1\u0ac2\u0ac3\u0ac4\u0ac5 \u0ac7\u0ac8\u0ac9 \u0acb\u0acc\u0acd"
- // 0.....123456789ABCDEF
- + "\u0ad0abcdefghijklmno"
- // 0123456789AB.....C.....D.....E.....F.....
- + "pqrstuvwxyz\u0ae0\u0ae1\u0ae2\u0ae3\u0af1",
-
- /**
- * National Language Identifier: 0x06
- * A.3.6 Hindi National Language Locking Shift Table
- */
- // 0.....1.....2.....3.....4.....5.....6.....7.....8.....9.....A.B.....C.....D.E.....F.....
- "\u0901\u0902\u0903\u0905\u0906\u0907\u0908\u0909\u090a\u090b\n\u090c\u090d\r\u090e\u090f"
- // 0.....1.....2.....3.....4.....5.....6.....7.....8.....9.....A.....B.....C.....D.....E.....F.....
- + "\u0910\u0911\u0912\u0913\u0914\u0915\u0916\u0917\u0918\u0919\u091a\uffff\u091b\u091c\u091d\u091e"
- // 012.....3.....4.....5.....6.....7.....89A.....B.....CD.....EF.....
- + " !\u091f\u0920\u0921\u0922\u0923\u0924)(\u0925\u0926,\u0927.\u0928"
- // 0123456789ABC.....D.....E.....F
- + "0123456789:;\u0929\u092a\u092b?"
- // 0.....1.....2.....3.....4.....5.....6.....7.....8.....9.....A.....B.....C.....D.....E.....F.....
- + "\u092c\u092d\u092e\u092f\u0930\u0931\u0932\u0933\u0934\u0935\u0936\u0937\u0938\u0939\u093c\u093d"
- // 0.....1.....2.....3.....4.....5.....6.....7.....8.....9.....A.....B.....C.....D.....E.....F.....
- + "\u093e\u093f\u0940\u0941\u0942\u0943\u0944\u0945\u0946\u0947\u0948\u0949\u094a\u094b\u094c\u094d"
- // 0.....123456789ABCDEF
- + "\u0950abcdefghijklmno"
- // 0123456789AB.....C.....D.....E.....F.....
- + "pqrstuvwxyz\u0972\u097b\u097c\u097e\u097f",
-
- /**
- * National Language Identifier: 0x07
- * A.3.7 Kannada National Language Locking Shift Table
- */
- // 01.....2.....3.....4.....5.....6.....7.....8.....9.....A.B.....CD.E.....F.....
- " \u0c82\u0c83\u0c85\u0c86\u0c87\u0c88\u0c89\u0c8a\u0c8b\n\u0c8c \r\u0c8e\u0c8f"
- // 0.....12.....3.....4.....5.....6.....7.....8.....9.....A.....B.....C.....D.....E.....F.....
- + "\u0c90 \u0c92\u0c93\u0c94\u0c95\u0c96\u0c97\u0c98\u0c99\u0c9a\uffff\u0c9b\u0c9c\u0c9d\u0c9e"
- // 012.....3.....4.....5.....6.....7.....89A.....B.....CD.....EF.....
- + " !\u0c9f\u0ca0\u0ca1\u0ca2\u0ca3\u0ca4)(\u0ca5\u0ca6,\u0ca7.\u0ca8"
- // 0123456789ABCD.....E.....F
- + "0123456789:; \u0caa\u0cab?"
- // 0.....1.....2.....3.....4.....5.....6.....7.....89.....A.....B.....C.....D.....E.....F.....
- + "\u0cac\u0cad\u0cae\u0caf\u0cb0\u0cb1\u0cb2\u0cb3 \u0cb5\u0cb6\u0cb7\u0cb8\u0cb9\u0cbc\u0cbd"
- // 0.....1.....2.....3.....4.....5.....6.....78.....9.....A.....BC.....D.....E.....F.....
- + "\u0cbe\u0cbf\u0cc0\u0cc1\u0cc2\u0cc3\u0cc4 \u0cc6\u0cc7\u0cc8 \u0cca\u0ccb\u0ccc\u0ccd"
- // 0.....123456789ABCDEF
- + "\u0cd5abcdefghijklmno"
- // 0123456789AB.....C.....D.....E.....F.....
- + "pqrstuvwxyz\u0cd6\u0ce0\u0ce1\u0ce2\u0ce3",
-
- /**
- * National Language Identifier: 0x08
- * A.3.8 Malayalam National Language Locking Shift Table
- */
- // 01.....2.....3.....4.....5.....6.....7.....8.....9.....A.B.....CD.E.....F.....
- " \u0d02\u0d03\u0d05\u0d06\u0d07\u0d08\u0d09\u0d0a\u0d0b\n\u0d0c \r\u0d0e\u0d0f"
- // 0.....12.....3.....4.....5.....6.....7.....8.....9.....A.....B.....C.....D.....E.....F.....
- + "\u0d10 \u0d12\u0d13\u0d14\u0d15\u0d16\u0d17\u0d18\u0d19\u0d1a\uffff\u0d1b\u0d1c\u0d1d\u0d1e"
- // 012.....3.....4.....5.....6.....7.....89A.....B.....CD.....EF.....
- + " !\u0d1f\u0d20\u0d21\u0d22\u0d23\u0d24)(\u0d25\u0d26,\u0d27.\u0d28"
- // 0123456789ABCD.....E.....F
- + "0123456789:; \u0d2a\u0d2b?"
- // 0.....1.....2.....3.....4.....5.....6.....7.....8.....9.....A.....B.....C.....D.....EF.....
- + "\u0d2c\u0d2d\u0d2e\u0d2f\u0d30\u0d31\u0d32\u0d33\u0d34\u0d35\u0d36\u0d37\u0d38\u0d39 \u0d3d"
- // 0.....1.....2.....3.....4.....5.....6.....78.....9.....A.....BC.....D.....E.....F.....
- + "\u0d3e\u0d3f\u0d40\u0d41\u0d42\u0d43\u0d44 \u0d46\u0d47\u0d48 \u0d4a\u0d4b\u0d4c\u0d4d"
- // 0.....123456789ABCDEF
- + "\u0d57abcdefghijklmno"
- // 0123456789AB.....C.....D.....E.....F.....
- + "pqrstuvwxyz\u0d60\u0d61\u0d62\u0d63\u0d79",
-
- /**
- * National Language Identifier: 0x09
- * A.3.9 Oriya National Language Locking Shift Table
- */
- // 0.....1.....2.....3.....4.....5.....6.....7.....8.....9.....A.B.....CD.EF.....
- "\u0b01\u0b02\u0b03\u0b05\u0b06\u0b07\u0b08\u0b09\u0b0a\u0b0b\n\u0b0c \r \u0b0f"
- // 0.....123.....4.....5.....6.....7.....8.....9.....A.....B.....C.....D.....E.....F.....
- + "\u0b10 \u0b13\u0b14\u0b15\u0b16\u0b17\u0b18\u0b19\u0b1a\uffff\u0b1b\u0b1c\u0b1d\u0b1e"
- // 012.....3.....4.....5.....6.....7.....89A.....B.....CD.....EF.....
- + " !\u0b1f\u0b20\u0b21\u0b22\u0b23\u0b24)(\u0b25\u0b26,\u0b27.\u0b28"
- // 0123456789ABCD.....E.....F
- + "0123456789:; \u0b2a\u0b2b?"
- // 0.....1.....2.....3.....4.....56.....7.....89.....A.....B.....C.....D.....E.....F.....
- + "\u0b2c\u0b2d\u0b2e\u0b2f\u0b30 \u0b32\u0b33 \u0b35\u0b36\u0b37\u0b38\u0b39\u0b3c\u0b3d"
- // 0.....1.....2.....3.....4.....5.....6.....789.....A.....BCD.....E.....F.....
- + "\u0b3e\u0b3f\u0b40\u0b41\u0b42\u0b43\u0b44 \u0b47\u0b48 \u0b4b\u0b4c\u0b4d"
- // 0.....123456789ABCDEF
- + "\u0b56abcdefghijklmno"
- // 0123456789AB.....C.....D.....E.....F.....
- + "pqrstuvwxyz\u0b57\u0b60\u0b61\u0b62\u0b63",
-
- /**
- * National Language Identifier: 0x0A
- * A.3.10 Punjabi National Language Locking Shift Table
- */
- // 0.....1.....2.....3.....4.....5.....6.....7.....8.....9A.BCD.EF.....
- "\u0a01\u0a02\u0a03\u0a05\u0a06\u0a07\u0a08\u0a09\u0a0a \n \r \u0a0f"
- // 0.....123.....4.....5.....6.....7.....8.....9.....A.....B.....C.....D.....E.....F.....
- + "\u0a10 \u0a13\u0a14\u0a15\u0a16\u0a17\u0a18\u0a19\u0a1a\uffff\u0a1b\u0a1c\u0a1d\u0a1e"
- // 012.....3.....4.....5.....6.....7.....89A.....B.....CD.....EF.....
- + " !\u0a1f\u0a20\u0a21\u0a22\u0a23\u0a24)(\u0a25\u0a26,\u0a27.\u0a28"
- // 0123456789ABCD.....E.....F
- + "0123456789:; \u0a2a\u0a2b?"
- // 0.....1.....2.....3.....4.....56.....7.....89.....A.....BC.....D.....E.....F
- + "\u0a2c\u0a2d\u0a2e\u0a2f\u0a30 \u0a32\u0a33 \u0a35\u0a36 \u0a38\u0a39\u0a3c "
- // 0.....1.....2.....3.....4.....56789.....A.....BCD.....E.....F.....
- + "\u0a3e\u0a3f\u0a40\u0a41\u0a42 \u0a47\u0a48 \u0a4b\u0a4c\u0a4d"
- // 0.....123456789ABCDEF
- + "\u0a51abcdefghijklmno"
- // 0123456789AB.....C.....D.....E.....F.....
- + "pqrstuvwxyz\u0a70\u0a71\u0a72\u0a73\u0a74",
-
- /**
- * National Language Identifier: 0x0B
- * A.3.11 Tamil National Language Locking Shift Table
- */
- // 01.....2.....3.....4.....5.....6.....7.....8.....9A.BCD.E.....F.....
- " \u0b82\u0b83\u0b85\u0b86\u0b87\u0b88\u0b89\u0b8a \n \r\u0b8e\u0b8f"
- // 0.....12.....3.....4.....5.....6789.....A.....B.....CD.....EF.....
- + "\u0b90 \u0b92\u0b93\u0b94\u0b95 \u0b99\u0b9a\uffff \u0b9c \u0b9e"
- // 012.....3456.....7.....89ABCDEF.....
- + " !\u0b9f \u0ba3\u0ba4)( , .\u0ba8"
- // 0123456789ABC.....D.....EF
- + "0123456789:;\u0ba9\u0baa ?"
- // 012.....3.....4.....5.....6.....7.....8.....9.....A.....B.....C.....D.....EF
- + " \u0bae\u0baf\u0bb0\u0bb1\u0bb2\u0bb3\u0bb4\u0bb5\u0bb6\u0bb7\u0bb8\u0bb9 "
- // 0.....1.....2.....3.....4.....5678.....9.....A.....BC.....D.....E.....F.....
- + "\u0bbe\u0bbf\u0bc0\u0bc1\u0bc2 \u0bc6\u0bc7\u0bc8 \u0bca\u0bcb\u0bcc\u0bcd"
- // 0.....123456789ABCDEF
- + "\u0bd0abcdefghijklmno"
- // 0123456789AB.....C.....D.....E.....F.....
- + "pqrstuvwxyz\u0bd7\u0bf0\u0bf1\u0bf2\u0bf9",
-
- /**
- * National Language Identifier: 0x0C
- * A.3.12 Telugu National Language Locking Shift Table
- */
- // 0.....1.....2.....3.....4.....5.....6.....7.....8.....9.....A.B.....CD.E.....F.....
- "\u0c01\u0c02\u0c03\u0c05\u0c06\u0c07\u0c08\u0c09\u0c0a\u0c0b\n\u0c0c \r\u0c0e\u0c0f"
- // 0.....12.....3.....4.....5.....6.....7.....8.....9.....A.....B.....C.....D.....E.....F.....
- + "\u0c10 \u0c12\u0c13\u0c14\u0c15\u0c16\u0c17\u0c18\u0c19\u0c1a\uffff\u0c1b\u0c1c\u0c1d\u0c1e"
- // 012.....3.....4.....5.....6.....7.....89A.....B.....CD.....EF.....
- + " !\u0c1f\u0c20\u0c21\u0c22\u0c23\u0c24)(\u0c25\u0c26,\u0c27.\u0c28"
- // 0123456789ABCD.....E.....F
- + "0123456789:; \u0c2a\u0c2b?"
- // 0.....1.....2.....3.....4.....5.....6.....7.....89.....A.....B.....C.....D.....EF.....
- + "\u0c2c\u0c2d\u0c2e\u0c2f\u0c30\u0c31\u0c32\u0c33 \u0c35\u0c36\u0c37\u0c38\u0c39 \u0c3d"
- // 0.....1.....2.....3.....4.....5.....6.....78.....9.....A.....BC.....D.....E.....F.....
- + "\u0c3e\u0c3f\u0c40\u0c41\u0c42\u0c43\u0c44 \u0c46\u0c47\u0c48 \u0c4a\u0c4b\u0c4c\u0c4d"
- // 0.....123456789ABCDEF
- + "\u0c55abcdefghijklmno"
- // 0123456789AB.....C.....D.....E.....F.....
- + "pqrstuvwxyz\u0c56\u0c60\u0c61\u0c62\u0c63",
-
- /**
- * National Language Identifier: 0x0D
- * A.3.13 Urdu National Language Locking Shift Table
- */
- // 0.....1.....2.....3.....4.....5.....6.....7.....8.....9.....A.B.....C.....D.E.....F.....
- "\u0627\u0622\u0628\u067b\u0680\u067e\u06a6\u062a\u06c2\u067f\n\u0679\u067d\r\u067a\u067c"
- // 0.....1.....2.....3.....4.....5.....6.....7.....8.....9.....A.....B.....C.....D.....E.....F.....
- + "\u062b\u062c\u0681\u0684\u0683\u0685\u0686\u0687\u062d\u062e\u062f\uffff\u068c\u0688\u0689\u068a"
- // 012.....3.....4.....5.....6.....7.....89A.....B.....CD.....EF.....
- + " !\u068f\u068d\u0630\u0631\u0691\u0693)(\u0699\u0632,\u0696.\u0698"
- // 0123456789ABC.....D.....E.....F
- + "0123456789:;\u069a\u0633\u0634?"
- // 0.....1.....2.....3.....4.....5.....6.....7.....8.....9.....A.....B.....C.....D.....E.....F.....
- + "\u0635\u0636\u0637\u0638\u0639\u0641\u0642\u06a9\u06aa\u06ab\u06af\u06b3\u06b1\u0644\u0645\u0646"
- // 0.....1.....2.....3.....4.....5.....6.....7.....8.....9.....A.....B.....C.....D.....E.....F.....
- + "\u06ba\u06bb\u06bc\u0648\u06c4\u06d5\u06c1\u06be\u0621\u06cc\u06d0\u06d2\u064d\u0650\u064f\u0657"
- // 0.....123456789ABCDEF
- + "\u0654abcdefghijklmno"
- // 0123456789AB.....C.....D.....E.....F.....
- + "pqrstuvwxyz\u0655\u0651\u0653\u0656\u0670"
-];
-
-// National Language Single Shift Tables, see 3GPP TS 23.038
-this.PDU_NL_SINGLE_SHIFT_TABLES = [
- /**
- * National Language Identifier: 0x00
- * 6.2.1.1 GSM 7 bit default alphabet extension table
- */
- // 0123456789A.....BCD.....EF
- " \u000c \ufffe "
- // 0123456789AB.....CDEF
- + " ^ \uffff "
- // 0123456789ABCDEF.
- + " {} \\"
- // 0123456789ABCDEF
- + " [~] "
- // 0123456789ABCDEF
- + "| "
- // 0123456789ABCDEF
- + " "
- // 012345.....6789ABCDEF
- + " \u20ac "
- // 0123456789ABCDEF
- + " ",
-
- /**
- * National Language Identifier: 0x01
- * A.2.1 Turkish National Language Single Shift Table
- */
- // 0123456789A.....BCD.....EF
- " \u000c \ufffe "
- // 0123456789AB.....CDEF
- + " ^ \uffff "
- // 0123456789ABCDEF.
- + " {} \\"
- // 0123456789ABCDEF
- + " [~] "
- // 01234567.....89.....ABCDEF
- + "| \u011e \u0130 "
- // 0123.....456789ABCDEF
- + " \u015e "
- // 0123.....45.....67.....89.....ABCDEF
- + " \u00e7 \u20ac \u011f \u0131 "
- // 0123.....456789ABCDEF
- + " \u015f ",
-
- /**
- * National Language Identifier: 0x02
- * A.2.2 Spanish National Language Single Shift Table
- */
- // 0123456789.....A.....BCD.....EF
- " \u00e7\u000c \ufffe "
- // 0123456789AB.....CDEF
- + " ^ \uffff "
- // 0123456789ABCDEF.
- + " {} \\"
- // 0123456789ABCDEF
- + " [~] "
- // 01.....23456789.....ABCDEF.....
- + "|\u00c1 \u00cd \u00d3"
- // 012345.....6789ABCDEF
- + " \u00da "
- // 01.....2345.....6789.....ABCDEF.....
- + " \u00e1 \u20ac \u00ed \u00f3"
- // 012345.....6789ABCDEF
- + " \u00fa ",
-
- /**
- * National Language Identifier: 0x03
- * A.2.3 Portuguese National Language Single Shift Table
- */
- // 012345.....6789.....A.....B.....C.....D.....E.....F.....
- " \u00ea \u00e7\u000c\u00d4\u00f4\ufffe\u00c1\u00e1"
- // 012.....3.....45.....6.....7.....8.....9.....AB.....CDEF.....
- + " \u03a6\u0393^\u03a9\u03a0\u03a8\u03a3\u0398 \uffff \u00ca"
- // 0123456789ABCDEF.
- + " {} \\"
- // 0123456789ABCDEF
- + " [~] "
- // 01.....23456789.....ABCDEF.....
- + "|\u00c0 \u00cd \u00d3"
- // 012345.....6789AB.....C.....DEF
- + " \u00da \u00c3\u00d5 "
- // 01.....2345.....6789.....ABCDEF.....
- + " \u00c2 \u20ac \u00ed \u00f3"
- // 012345.....6789AB.....C.....DEF.....
- + " \u00fa \u00e3\u00f5 \u00e2",
-
- /**
- * National Language Identifier: 0x04
- * A.2.4 Bengali National Language Single Shift Table
- */
- // 01.....23.....4.....5.6.....789A.....BCD.....EF
- "@\u00a3$\u00a5\u00bf\"\u00a4%&'\u000c*+\ufffe-/"
- // 0123.....45.....6789.....A.....B.....C.....D.....E.....F.....
- + "<=>\u00a1^\u00a1_#*\u09e6\u09e7\uffff\u09e8\u09e9\u09ea\u09eb"
- // 0.....1.....2.....3.....4.....5.....6.....7.....89A.....B.....C.....D.....E.....F.
- + "\u09ec\u09ed\u09ee\u09ef\u09df\u09e0\u09e1\u09e2{}\u09e3\u09f2\u09f3\u09f4\u09f5\\"
- // 0.....1.....2.....3.....4.....56789ABCDEF
- + "\u09f6\u09f7\u09f8\u09f9\u09fa [~] "
- // 0123456789ABCDEF
- + "|ABCDEFGHIJKLMNO"
- // 0123456789ABCDEF
- + "PQRSTUVWXYZ "
- // 012345.....6789ABCDEF
- + " \u20ac "
- // 0123456789ABCDEF
- + " ",
-
- /**
- * National Language Identifier: 0x05
- * A.2.5 Gujarati National Language Single Shift Table
- */
- // 01.....23.....4.....5.6.....789A.....BCD.....EF
- "@\u00a3$\u00a5\u00bf\"\u00a4%&'\u000c*+\ufffe-/"
- // 0123.....45.....6789.....A.....B.....C.....D.....E.....F.....
- + "<=>\u00a1^\u00a1_#*\u0964\u0965\uffff\u0ae6\u0ae7\u0ae8\u0ae9"
- // 0.....1.....2.....3.....4.....5.....6789ABCDEF.
- + "\u0aea\u0aeb\u0aec\u0aed\u0aee\u0aef {} \\"
- // 0123456789ABCDEF
- + " [~] "
- // 0123456789ABCDEF
- + "|ABCDEFGHIJKLMNO"
- // 0123456789ABCDEF
- + "PQRSTUVWXYZ "
- // 012345.....6789ABCDEF
- + " \u20ac "
- // 0123456789ABCDEF
- + " ",
-
- /**
- * National Language Identifier: 0x06
- * A.2.6 Hindi National Language Single Shift Table
- */
- // 01.....23.....4.....5.6.....789A.....BCD.....EF
- "@\u00a3$\u00a5\u00bf\"\u00a4%&'\u000c*+\ufffe-/"
- // 0123.....45.....6789.....A.....B.....C.....D.....E.....F.....
- + "<=>\u00a1^\u00a1_#*\u0964\u0965\uffff\u0966\u0967\u0968\u0969"
- // 0.....1.....2.....3.....4.....5.....6.....7.....89A.....B.....C.....D.....E.....F.
- + "\u096a\u096b\u096c\u096d\u096e\u096f\u0951\u0952{}\u0953\u0954\u0958\u0959\u095a\\"
- // 0.....1.....2.....3.....4.....5.....6.....7.....8.....9.....A.....BCDEF
- + "\u095b\u095c\u095d\u095e\u095f\u0960\u0961\u0962\u0963\u0970\u0971 [~] "
- // 0123456789ABCDEF
- + "|ABCDEFGHIJKLMNO"
- // 0123456789ABCDEF
- + "PQRSTUVWXYZ "
- // 012345.....6789ABCDEF
- + " \u20ac "
- // 0123456789ABCDEF
- + " ",
-
- /**
- * National Language Identifier: 0x07
- * A.2.7 Kannada National Language Single Shift Table
- */
- // 01.....23.....4.....5.6.....789A.....BCD.....EF
- "@\u00a3$\u00a5\u00bf\"\u00a4%&'\u000c*+\ufffe-/"
- // 0123.....45.....6789.....A.....B.....C.....D.....E.....F.....
- + "<=>\u00a1^\u00a1_#*\u0964\u0965\uffff\u0ce6\u0ce7\u0ce8\u0ce9"
- // 0.....1.....2.....3.....4.....5.....6.....7.....89A.....BCDEF.
- + "\u0cea\u0ceb\u0cec\u0ced\u0cee\u0cef\u0cde\u0cf1{}\u0cf2 \\"
- // 0123456789ABCDEF
- + " [~] "
- // 0123456789ABCDEF
- + "|ABCDEFGHIJKLMNO"
- // 0123456789ABCDEF
- + "PQRSTUVWXYZ "
- // 012345.....6789ABCDEF
- + " \u20ac "
- // 0123456789ABCDEF
- + " ",
-
- /**
- * National Language Identifier: 0x08
- * A.2.8 Malayalam National Language Single Shift Table
- */
- // 01.....23.....4.....5.6.....789A.....BCD.....EF
- "@\u00a3$\u00a5\u00bf\"\u00a4%&'\u000c*+\ufffe-/"
- // 0123.....45.....6789.....A.....B.....C.....D.....E.....F.....
- + "<=>\u00a1^\u00a1_#*\u0964\u0965\uffff\u0d66\u0d67\u0d68\u0d69"
- // 0.....1.....2.....3.....4.....5.....6.....7.....89A.....B.....C.....D.....E.....F.
- + "\u0d6a\u0d6b\u0d6c\u0d6d\u0d6e\u0d6f\u0d70\u0d71{}\u0d72\u0d73\u0d74\u0d75\u0d7a\\"
- // 0.....1.....2.....3.....4.....56789ABCDEF
- + "\u0d7b\u0d7c\u0d7d\u0d7e\u0d7f [~] "
- // 0123456789ABCDEF
- + "|ABCDEFGHIJKLMNO"
- // 0123456789ABCDEF
- + "PQRSTUVWXYZ "
- // 012345.....6789ABCDEF
- + " \u20ac "
- // 0123456789ABCDEF
- + " ",
-
- /**
- * National Language Identifier: 0x09
- * A.2.9 Oriya National Language Single Shift Table
- */
- // 01.....23.....4.....5.6.....789A.....BCD.....EF
- "@\u00a3$\u00a5\u00bf\"\u00a4%&'\u000c*+\ufffe-/"
- // 0123.....45.....6789.....A.....B.....C.....D.....E.....F.....
- + "<=>\u00a1^\u00a1_#*\u0964\u0965\uffff\u0b66\u0b67\u0b68\u0b69"
- // 0.....1.....2.....3.....4.....5.....6.....7.....89A.....B.....C.....DEF.
- + "\u0b6a\u0b6b\u0b6c\u0b6d\u0b6e\u0b6f\u0b5c\u0b5d{}\u0b5f\u0b70\u0b71 \\"
- // 0123456789ABCDEF
- + " [~] "
- // 0123456789ABCDEF
- + "|ABCDEFGHIJKLMNO"
- // 0123456789ABCDEF
- + "PQRSTUVWXYZ "
- // 012345.....6789ABCDEF
- + " \u20ac "
- // 0123456789ABCDEF
- + " ",
-
- /**
- * National Language Identifier: 0x0A
- * A.2.10 Punjabi National Language Single Shift Table
- */
- // 01.....23.....4.....5.6.....789A.....BCD.....EF
- "@\u00a3$\u00a5\u00bf\"\u00a4%&'\u000c*+\ufffe-/"
- // 0123.....45.....6789.....A.....B.....C.....D.....E.....F.....
- + "<=>\u00a1^\u00a1_#*\u0964\u0965\uffff\u0a66\u0a67\u0a68\u0a69"
- // 0.....1.....2.....3.....4.....5.....6.....7.....89A.....B.....C.....D.....EF.
- + "\u0a6a\u0a6b\u0a6c\u0a6d\u0a6e\u0a6f\u0a59\u0a5a{}\u0a5b\u0a5c\u0a5e\u0a75 \\"
- // 0123456789ABCDEF
- + " [~] "
- // 0123456789ABCDEF
- + "|ABCDEFGHIJKLMNO"
- // 0123456789ABCDEF
- + "PQRSTUVWXYZ "
- // 012345.....6789ABCDEF
- + " \u20ac "
- // 0123456789ABCDEF
- + " ",
-
- /**
- * National Language Identifier: 0x0B
- * A.2.11 Tamil National Language Single Shift Table
- */
- // 01.....23.....4.....5.6.....789A.....BCD.....EF
- "@\u00a3$\u00a5\u00bf\"\u00a4%&'\u000c*+\ufffe-/"
- // 0123.....45.....6789.....A.....B.....C.....D.....E.....F.....
- + "<=>\u00a1^\u00a1_#*\u0964\u0965\uffff\u0be6\u0be7\u0be8\u0be9"
- // 0.....1.....2.....3.....4.....5.....6.....7.....89A.....B.....C.....D.....E.....F.
- + "\u0bea\u0beb\u0bec\u0bed\u0bee\u0bef\u0bf3\u0bf4{}\u0bf5\u0bf6\u0bf7\u0bf8\u0bfa\\"
- // 0123456789ABCDEF
- + " [~] "
- // 0123456789ABCDEF
- + "|ABCDEFGHIJKLMNO"
- // 0123456789ABCDEF
- + "PQRSTUVWXYZ "
- // 012345.....6789ABCDEF
- + " \u20ac "
- // 0123456789ABCDEF
- + " ",
-
- /**
- * National Language Identifier: 0x0C
- * A.2.12 Telugu National Language Single Shift Table
- */
- // 01.....23.....4.....5.6.....789A.....BCD.....EF
- "@\u00a3$\u00a5\u00bf\"\u00a4%&'\u000c*+\ufffe-/"
- // 0123.....45.....6789AB.....C.....D.....E.....F.....
- + "<=>\u00a1^\u00a1_#* \uffff\u0c66\u0c67\u0c68\u0c69"
- // 0.....1.....2.....3.....4.....5.....6.....7.....89A.....B.....C.....D.....E.....F.
- + "\u0c6a\u0c6b\u0c6c\u0c6d\u0c6e\u0c6f\u0c58\u0c59{}\u0c78\u0c79\u0c7a\u0c7b\u0c7c\\"
- // 0.....1.....2.....3456789ABCDEF
- + "\u0c7d\u0c7e\u0c7f [~] "
- // 0123456789ABCDEF
- + "|ABCDEFGHIJKLMNO"
- // 0123456789ABCDEF
- + "PQRSTUVWXYZ "
- // 012345.....6789ABCDEF
- + " \u20ac "
- // 0123456789ABCDEF
- + " ",
-
- /**
- * National Language Identifier: 0x0D
- * A.2.13 Urdu National Language Single Shift Table
- */
- // 01.....23.....4.....5.6.....789A.....BCD.....EF
- "@\u00a3$\u00a5\u00bf\"\u00a4%&'\u000c*+\ufffe-/"
- // 0123.....45.....6789.....A.....B.....C.....D.....E.....F.....
- + "<=>\u00a1^\u00a1_#*\u0600\u0601\uffff\u06f0\u06f1\u06f2\u06f3"
- // 0.....1.....2.....3.....4.....5.....6.....7.....89A.....B.....C.....D.....E.....F.
- + "\u06f4\u06f5\u06f6\u06f7\u06f8\u06f9\u060c\u060d{}\u060e\u060f\u0610\u0611\u0612\\"
- // 0.....1.....2.....3.....4.....5.....6.....7.....8.....9.....A.....B.....CDEF.....
- + "\u0613\u0614\u061b\u061f\u0640\u0652\u0658\u066b\u066c\u0672\u0673\u06cd[~]\u06d4"
- // 0123456789ABCDEF
- + "|ABCDEFGHIJKLMNO"
- // 0123456789ABCDEF
- + "PQRSTUVWXYZ "
- // 012345.....6789ABCDEF
- + " \u20ac "
- // 0123456789ABCDEF
- + " "
-];
-
-// Special SMS Message Indication constants
-this.PDU_MWI_STORE_TYPE_BIT = 0x80;
-this.PDU_MWI_STORE_TYPE_DISCARD = 0x00;
-this.PDU_MWI_STORE_TYPE_STORE = 0x80;
-
-this.GSM_SMS_STRICT_7BIT_CHARMAP = {
-//"\u0024": "\u0024", // "$" => "$", already in default alphabet
-//"\u00a5": "\u00a5", // "¥" => "¥", already in default alphabet
- "\u00c0": "\u0041", // "À" => "A"
- "\u00c1": "\u0041", // "Á" => "A"
- "\u00c2": "\u0041", // "Â" => "A"
- "\u00c3": "\u0041", // "Ã" => "A"
-//"\u00c4": "\u00c4", // "Ä" => "Ä", already in default alphabet
-//"\u00c5": "\u00c5", // "Å" => "Å", already in default alphabet
-//"\u00c6": "\u00c6", // "Æ" => "Æ", already in default alphabet
-//"\u00c7": "\u00c7", // "Ç" => "Ç", already in default alphabet
- "\u00c8": "\u0045", // "È" => "E"
-//"\u00c9": "\u00c9", // "É" => "É", already in default alphabet
- "\u00ca": "\u0045", // "Ê" => "E"
- "\u00cb": "\u0045", // "Ë" => "E"
- "\u00cc": "\u0049", // "Ì" => "I"
- "\u00cd": "\u0049", // "Í" => "I"
- "\u00ce": "\u0049", // "Î" => "I"
- "\u00cf": "\u0049", // "Ï" => "I"
-//"\u00d1": "\u00d1", // "Ñ" => "Ñ", already in default alphabet
- "\u00d2": "\u004f", // "Ò" => "O"
- "\u00d3": "\u004f", // "Ó" => "O"
- "\u00d4": "\u004f", // "Ô" => "O"
- "\u00d5": "\u004f", // "Õ" => "O"
-//"\u00d6": "\u00d6", // "Ö" => "Ö", already in default alphabet
- "\u00d9": "\u0055", // "Ù" => "U"
- "\u00da": "\u0055", // "Ú" => "U"
- "\u00db": "\u0055", // "Û" => "U"
-//"\u00dc": "\u00dc", // "Ü" => "Ü", already in default alphabet
-//"\u00df": "\u00df", // "ß" => "ß", already in default alphabet
-//"\u00e0": "\u00e0", // "à" => "à", already in default alphabet
- "\u00e1": "\u0061", // "á" => "a"
- "\u00e2": "\u0061", // "â" => "a"
- "\u00e3": "\u0061", // "ã" => "a"
-//"\u00e4": "\u00e4", // "ä" => "ä", already in default alphabet
-//"\u00e5": "\u00e5", // "å" => "å", already in default alphabet
-//"\u00e6": "\u00e6", // "æ" => "æ", already in default alphabet
- "\u00e7": "\u00c7", // "ç" => "Ç"
-//"\u00e8": "\u00e8", // "è" => "è", already in default alphabet
-//"\u00e9": "\u00e9", // "é" => "é", already in default alphabet
- "\u00ea": "\u0065", // "ê" => "e"
- "\u00eb": "\u0065", // "ë" => "e"
-//"\u00ec": "\u00ec", // "ì" => "ì", already in default alphabet
- "\u00ed": "\u0069", // "í" => "i"
- "\u00ee": "\u0069", // "î" => "i"
- "\u00ef": "\u0069", // "ï" => "i"
-//"\u00f1": "\u00f1", // "ñ" => "ñ", already in default alphabet
-//"\u00f2": "\u00f2", // "ò" => "ò", already in default alphabet
- "\u00f3": "\u006f", // "ó" => "o"
- "\u00f4": "\u006f", // "ô" => "o"
- "\u00f5": "\u006f", // "õ" => "o"
-//"\u00f6": "\u00f6", // "ö" => "ö", already in default alphabet
-//"\u00f8": "\u00f8", // "ø" => "ø", already in default alphabet
-//"\u00f9": "\u00f9", // "ù" => "ù", already in default alphabet
- "\u00fa": "\u0075", // "ú" => "u"
- "\u00fb": "\u0075", // "û" => "u"
-//"\u00fc": "\u00fc", // "ü" => "ü", already in default alphabet
- "\u00fe": "\u0074", // "þ" => "t"
- "\u0100": "\u0041", // "Ā" => "A"
- "\u0101": "\u0061", // "ā" => "a"
- "\u0106": "\u0043", // "Ć" => "C"
- "\u0107": "\u0063", // "ć" => "c"
- "\u010c": "\u0043", // "Č" => "C"
- "\u010d": "\u0063", // "č" => "c"
- "\u010f": "\u0064", // "ď" => "d"
- "\u0110": "\u0044", // "Đ" => "D"
- "\u0111": "\u0064", // "đ" => "d"
- "\u0112": "\u0045", // "Ē" => "E"
- "\u0113": "\u0065", // "ē" => "e"
- "\u0118": "\u0045", // "Ę" => "E"
- "\u0119": "\u0065", // "ę" => "e"
- "\u0128": "\u0049", // "Ĩ" => "I"
- "\u0129": "\u0069", // "ĩ" => "i"
- "\u012a": "\u0049", // "Ī" => "I"
- "\u012b": "\u0069", // "ī" => "i"
- "\u012e": "\u0049", // "Į" => "I"
- "\u012f": "\u0069", // "į" => "i"
- "\u0141": "\u004c", // "Ł" => "L"
- "\u0142": "\u006c", // "ł" => "l"
- "\u0143": "\u004e", // "Ń" => "N"
- "\u0144": "\u006e", // "ń" => "n"
- "\u0147": "\u004e", // "Ň" => "N"
- "\u0148": "\u006e", // "ň" => "n"
- "\u014c": "\u004f", // "Ō" => "O"
- "\u014d": "\u006f", // "ō" => "o"
- "\u0152": "\u004f", // "Œ" => "O"
- "\u0153": "\u006f", // "œ" => "o"
- "\u0158": "\u0052", // "Ř" => "R"
- "\u0159": "\u0072", // "ř" => "r"
- "\u0160": "\u0053", // "Š" => "S"
- "\u0161": "\u0073", // "š" => "s"
- "\u0165": "\u0074", // "ť" => "t"
- "\u0168": "\u0055", // "Ū" => "U"
- "\u0169": "\u0075", // "ū" => "u"
- "\u016a": "\u0055", // "Ū" => "U"
- "\u016b": "\u0075", // "ū" => "u"
- "\u0178": "\u0059", // "Ÿ" => "Y"
- "\u0179": "\u005a", // "Ź" => "Z"
- "\u017a": "\u007a", // "ź" => "z"
- "\u017b": "\u005a", // "Ż" => "Z"
- "\u017c": "\u007a", // "ż" => "z"
- "\u017d": "\u005a", // "Ž" => "Z"
- "\u017e": "\u007a", // "ž" => "z"
- "\u025b": "\u0045", // "ɛ" => "E"
-//"\u0398": "\u0398", // "Θ" => "Θ", already in default alphabet
- "\u1e7c": "\u0056", // "Ṽ" => "V"
- "\u1e7d": "\u0076", // "ṽ" => "v"
- "\u1ebc": "\u0045", // "Ẽ" => "E"
- "\u1ebd": "\u0065", // "ẽ" => "e"
- "\u1ef8": "\u0059", // "Ỹ" => "Y"
- "\u1ef9": "\u0079", // "ỹ" => "y"
- "\u20a4": "\u00a3", // "₤" => "£"
-//"\u20ac": "\u20ac", // "€" => "€", already in default alphabet
-};
-
-this.RADIOTECH_FAMILY_3GPP = 1; // GSM, WCDMA, LTE
-this.RADIOTECH_FAMILY_3GPP2 = 2; // CDMA, EVDO
-
-this.DATACALL_RADIOTECHNOLOGY_CDMA = 0;
-this.DATACALL_RADIOTECHNOLOGY_GSM = 1;
-
-this.DATACALL_AUTH_NONE = 0;
-this.DATACALL_AUTH_PAP = 1;
-this.DATACALL_AUTH_CHAP = 2;
-this.DATACALL_AUTH_PAP_OR_CHAP = 3;
-
-this.GECKO_DATACALL_AUTH_NONE = "none";
-this.GECKO_DATACALL_AUTH_PAP = "pap";
-this.GECKO_DATACALL_AUTH_CHAP = "chap";
-this.GECKO_DATACALL_AUTH_PAP_OR_CHAP = "papOrChap";
-this.GECKO_DATACALL_AUTH_DEFAULT = GECKO_DATACALL_AUTH_PAP_OR_CHAP;
-this.RIL_DATACALL_AUTH_TO_GECKO = [
- GECKO_DATACALL_AUTH_NONE, // DATACALL_AUTH_NONE
- GECKO_DATACALL_AUTH_PAP, // DATACALL_AUTH_PAP
- GECKO_DATACALL_AUTH_CHAP, // DATACALL_AUTH_CHAP
- GECKO_DATACALL_AUTH_PAP_OR_CHAP // DATACALL_AUTH_PAP_OR_CHAP
-];
-
-this.GECKO_DATACALL_PDP_TYPE_IP = "IP";
-this.GECKO_DATACALL_PDP_TYPE_IPV4V6 = "IPV4V6";
-this.GECKO_DATACALL_PDP_TYPE_IPV6 = "IPV6";
-this.GECKO_DATACALL_PDP_TYPE_DEFAULT = GECKO_DATACALL_PDP_TYPE_IP;
-this.RIL_DATACALL_PDP_TYPES = [
- GECKO_DATACALL_PDP_TYPE_IP,
- GECKO_DATACALL_PDP_TYPE_IPV4V6,
- GECKO_DATACALL_PDP_TYPE_IPV6,
-];
-
-this.DATACALL_PROFILE_DEFAULT = 0;
-this.DATACALL_PROFILE_TETHERED = 1;
-this.DATACALL_PROFILE_OEM_BASE = 1000;
-
-this.DATACALL_DEACTIVATE_NO_REASON = 0;
-this.DATACALL_DEACTIVATE_RADIO_SHUTDOWN = 1;
-
-this.DATACALL_ACTIVE_UNKNOWN = -1;
-this.DATACALL_INACTIVE = 0;
-this.DATACALL_ACTIVE_DOWN = 1;
-this.DATACALL_ACTIVE_UP = 2;
-
-this.DATACALL_FAIL_NONE = 0;
-this.DATACALL_FAIL_OPERATOR_BARRED = 0x08;
-this.DATACALL_FAIL_INSUFFICIENT_RESOURCES = 0x1A;
-this.DATACALL_FAIL_MISSING_UKNOWN_APN = 0x1B;
-this.DATACALL_FAIL_UNKNOWN_PDP_ADDRESS_TYPE = 0x1C;
-this.DATACALL_FAIL_USER_AUTHENTICATION = 0x1D;
-this.DATACALL_FAIL_ACTIVATION_REJECT_GGSN = 0x1E;
-this.DATACALL_FAIL_ACTIVATION_REJECT_UNSPECIFIED = 0x1F;
-this.DATACALL_FAIL_SERVICE_OPTION_NOT_SUPPORTED = 0x20;
-this.DATACALL_FAIL_SERVICE_OPTION_NOT_SUBSCRIBED = 0x21;
-this.DATACALL_FAIL_SERVICE_OPTION_OUT_OF_ORDER = 0x22;
-this.DATACALL_FAIL_NSAPI_IN_USE = 0x23;
-this.DATACALL_FAIL_ONLY_IPV4_ALLOWED = 0x32;
-this.DATACALL_FAIL_ONLY_IPV6_ALLOWED = 0x33;
-this.DATACALL_FAIL_ONLY_SINGLE_BEARER_ALLOWED = 0x34;
-this.DATACALL_FAIL_PROTOCOL_ERRORS = 0x6F;
-this.DATACALL_FAIL_VOICE_REGISTRATION_FAIL = -1;
-this.DATACALL_FAIL_DATA_REGISTRATION_FAIL = -2;
-this.DATACALL_FAIL_SIGNAL_LOST = -3;
-this.DATACALL_FAIL_PREF_RADIO_TECH_CHANGED = -4;
-this.DATACALL_FAIL_RADIO_POWER_OFF = -5;
-this.DATACALL_FAIL_TETHERED_CALL_ACTIVE = -6;
-this.DATACALL_FAIL_ERROR_UNSPECIFIED = 0xffff;
-
-// Keep consistent with nsINetworkManager.NETWORK_STATE_*.
-this.GECKO_NETWORK_STATE_UNKNOWN = -1;
-this.GECKO_NETWORK_STATE_CONNECTING = 0;
-this.GECKO_NETWORK_STATE_CONNECTED = 1;
-this.GECKO_NETWORK_STATE_DISCONNECTING = 2;
-this.GECKO_NETWORK_STATE_DISCONNECTED = 3;
-
-// 3GPP 24.008 Annex H.
-this.CALL_FAIL_UNOBTAINABLE_NUMBER = 1;
-this.CALL_FAIL_NO_ROUTE_TO_DESTINATION = 3;
-this.CALL_FAIL_CHANNEL_UNACCEPTABLE = 6;
-this.CALL_FAIL_OPERATOR_DETERMINED_BARRING = 8;
-this.CALL_FAIL_NORMAL = 16;
-this.CALL_FAIL_BUSY = 17;
-this.CALL_FAIL_NO_USER_RESPONDING = 18;
-this.CALL_FAIL_USER_ALERTING = 19;
-this.CALL_FAIL_CALL_REJECTED = 21;
-this.CALL_FAIL_NUMBER_CHANGED = 22;
-this.CALL_FAIL_CALL_REJECTED_DESTINATION_FEATURE = 24;
-this.CALL_FAIL_CALL_PRE_EMPTION = 25;
-this.CALL_FAIL_DEST_OUT_OF_ORDER = 27;
-this.CALL_FAIL_INVALID_FORMAT = 28;
-this.CALL_FAIL_FACILITY_REJECTED = 29;
-this.CALL_FAIL_RESPONSE_TO_STATUS_ENQUIRY = 30;
-this.CALL_FAIL_NORMAL_UNSPECIFIED = 31;
-this.CALL_FAIL_CONGESTION = 34;
-this.CALL_FAIL_NETWORK_OUT_OF_ORDER = 38;
-this.CALL_FAIL_NETWORK_TEMP_FAILURE = 41;
-this.CALL_FAIL_SWITCHING_EQUIP_CONGESTION = 42;
-this.CALL_FAIL_ACCESS_INFO_DISCARDED = 43;
-this.CALL_FAIL_REQUESTED_CHANNEL_NOT_AVAILABLE = 44;
-this.CALL_FAIL_RESOURCE_UNAVAILABLE = 47;
-this.CALL_FAIL_QOS_UNAVAILABLE = 49;
-this.CALL_FAIL_REQUESTED_FACILITY_NOT_SUBSCRIBED = 50;
-this.CALL_FAIL_INCOMING_CALLS_BARRED_WITHIN_CUG = 55;
-this.CALL_FAIL_BEARER_CAPABILITY_NOT_AUTHORIZED = 57;
-this.CALL_FAIL_BEARER_CAPABILITY_NOT_AVAILABLE = 58;
-this.CALL_FAIL_SERVICE_NOT_AVAILABLE = 63;
-this.CALL_FAIL_BEARER_NOT_IMPLEMENTED = 65;
-this.CALL_FAIL_ACM_LIMIT_EXCEEDED = 68;
-this.CALL_FAIL_REQUESTED_FACILITY_NOT_IMPLEMENTED = 69;
-this.CALL_FAIL_UNRESTRICTED_BEARER_NOT_AVAILABLE = 70;
-this.CALL_FAIL_SERVICE_NOT_IMPLEMENTED = 79;
-this.CALL_FAIL_INVALID_TRANSACTION_ID = 81;
-this.CALL_FAIL_USER_NOT_CUG_MEMBER = 87;
-this.CALL_FAIL_INCOMPATIBLE_DESTINATION = 88;
-this.CALL_FAIL_INVALID_TRANSIT_NETWORK_SELECTION = 91;
-this.CALL_FAIL_SEMANTICALLY_INCORRECT_MESSAGE = 95;
-this.CALL_FAIL_INVALID_MANDATORY_INFO = 96;
-this.CALL_FAIL_MESSAGE_TYPE_NOT_IMPLEMENTED = 97;
-this.CALL_FAIL_MESSAGE_TYPE_INCOMPATIBLE_PROTOCOL_STATE = 98;
-this.CALL_FAIL_INFO_ELEMENT_NOT_IMPLEMENTED = 99;
-this.CALL_FAIL_CONDITIONAL_IE_ERROR = 100;
-this.CALL_FAIL_MESSAGE_INCOMPABITLE_PROTOCOL_STATE = 101;
-this.CALL_FAIL_RECOVERY_ON_TIMER_EXPIRY = 102;
-this.CALL_FAIL_PROTOCOL_ERROR = 111;
-this.CALL_FAIL_INTERWORKING = 127;
-// AOSP ril.h
-this.CALL_FAIL_CALL_BARRED = 240;
-this.CALL_FAIL_FDN_BLOCKED = 241;
-this.CALL_FAIL_IMSI_UNKNOWN_IN_VLR = 242;
-this.CALL_FAIL_IMEI_NOT_ACCEPTED = 243;
-this.CALL_FAIL_DIAL_MODIFIED_TO_USSD = 244; // STK Call Control
-this.CALL_FAIL_DIAL_MODIFIED_TO_SS = 245;
-this.CALL_FAIL_DIAL_MODIFIED_TO_DIAL = 246;
-this.CALL_FAIL_CDMA_LOCKED_UNTIL_POWER_CYCLE = 1000;
-this.CALL_FAIL_CDMA_DROP = 1001;
-this.CALL_FAIL_CDMA_INTERCEPT = 1002;
-this.CALL_FAIL_CDMA_REORDER = 1003;
-this.CALL_FAIL_CDMA_SO_REJECT = 1004;
-this.CALL_FAIL_CDMA_RETRY_ORDER = 1005;
-this.CALL_FAIL_CDMA_ACCESS_FAILURE = 1006;
-this.CALL_FAIL_CDMA_PREEMPTED = 1007;
-this.CALL_FAIL_CDMA_NOT_EMERGENCY = 1008; // For non-emergency number dialed
- // during emergency callback mode
-this.CALL_FAIL_CDMA_ACCESS_BLOCKED = 1009;
-this.CALL_FAIL_ERROR_UNSPECIFIED = 0xffff;
-
-// See nsIMobileConnection::MOBILE_RADIO_STATE_*
-this.GECKO_RADIOSTATE_UNKNOWN = -1;
-this.GECKO_RADIOSTATE_ENABLED = 0;
-this.GECKO_RADIOSTATE_DISABLED = 1;
-
-// Only used in ril_worker.js
-this.GECKO_CARDSTATE_UNINITIALIZED = 4294967294; // UINT32_MAX - 1
-// See nsIIcc::CARD_STATE_*
-this.GECKO_CARDSTATE_UNDETECTED = 4294967295; // UINT32_MAX
-this.GECKO_CARDSTATE_UNKNOWN = 0;
-this.GECKO_CARDSTATE_READY = 1;
-this.GECKO_CARDSTATE_PIN_REQUIRED = 2;
-this.GECKO_CARDSTATE_PUK_REQUIRED = 3;
-this.GECKO_CARDSTATE_PERMANENT_BLOCKED = 4;
-this.GECKO_CARDSTATE_PERSONALIZATION_IN_PROGRESS = 5;
-this.GECKO_CARDSTATE_PERSONALIZATION_READY = 6;
-this.GECKO_CARDSTATE_NETWORK_LOCKED = 7;
-this.GECKO_CARDSTATE_NETWORK_SUBSET_LOCKED = 8;
-this.GECKO_CARDSTATE_CORPORATE_LOCKED = 9;
-this.GECKO_CARDSTATE_SERVICE_PROVIDER_LOCKED = 10;
-this.GECKO_CARDSTATE_SIM_LOCKED = 11;
-this.GECKO_CARDSTATE_NETWORK_PUK_REQUIRED = 12;
-this.GECKO_CARDSTATE_NETWORK_SUBSET_PUK_REQUIRED = 13;
-this.GECKO_CARDSTATE_CORPORATE_PUK_REQUIRED = 14;
-this.GECKO_CARDSTATE_SERVICE_PROVIDER_PUK_REQUIRED = 15;
-this.GECKO_CARDSTATE_SIM_PUK_REQUIRED = 16;
-this.GECKO_CARDSTATE_NETWORK1_LOCKED = 17;
-this.GECKO_CARDSTATE_NETWORK2_LOCKED = 18;
-this.GECKO_CARDSTATE_HRPD_NETWORK_LOCKED = 19;
-this.GECKO_CARDSTATE_RUIM_CORPORATE_LOCKED = 20;
-this.GECKO_CARDSTATE_RUIM_SERVICE_PROVIDER_LOCKED = 21;
-this.GECKO_CARDSTATE_RUIM_LOCKED = 22;
-this.GECKO_CARDSTATE_NETWORK1_PUK_REQUIRED = 23;
-this.GECKO_CARDSTATE_NETWORK2_PUK_REQUIRED = 24;
-this.GECKO_CARDSTATE_HRPD_NETWORK_PUK_REQUIRED = 25;
-this.GECKO_CARDSTATE_RUIM_CORPORATE_PUK_REQUIRED = 26;
-this.GECKO_CARDSTATE_RUIM_SERVICE_PROVIDER_PUK_REQUIRED = 27;
-this.GECKO_CARDSTATE_RUIM_PUK_REQUIRED = 28;
-this.GECKO_CARDSTATE_ILLEGAL = 29;
-
-// See nsIIcc::CARD_LOCK_TYPE_*
-this.GECKO_CARDLOCK_PIN = 0;
-this.GECKO_CARDLOCK_PIN2 = 1;
-this.GECKO_CARDLOCK_PUK = 2;
-this.GECKO_CARDLOCK_PUK2 = 3;
-this.GECKO_CARDLOCK_NCK = 4;
-this.GECKO_CARDLOCK_NSCK = 5;
-this.GECKO_CARDLOCK_NCK1 = 6;
-this.GECKO_CARDLOCK_NCK2 = 7;
-this.GECKO_CARDLOCK_HNCK = 8;
-this.GECKO_CARDLOCK_CCK = 9;
-this.GECKO_CARDLOCK_SPCK = 10;
-this.GECKO_CARDLOCK_PCK = 11;
-this.GECKO_CARDLOCK_RCCK = 12;
-this.GECKO_CARDLOCK_RSPCK = 13;
-this.GECKO_CARDLOCK_NCK_PUK = 14;
-this.GECKO_CARDLOCK_NSCK_PUK = 15;
-this.GECKO_CARDLOCK_NCK1_PUK = 16;
-this.GECKO_CARDLOCK_NCK2_PUK = 17;
-this.GECKO_CARDLOCK_HNCK_PUK = 18;
-this.GECKO_CARDLOCK_CCK_PUK = 19;
-this.GECKO_CARDLOCK_SPCK_PUK = 20;
-this.GECKO_CARDLOCK_PCK_PUK = 21;
-this.GECKO_CARDLOCK_RCCK_PUK = 22;
-this.GECKO_CARDLOCK_RSPCK_PUK = 23;
-this.GECKO_CARDLOCK_FDN = 24;
-
-this.GECKO_CARDLOCK_TO_FACILITY = {};
-GECKO_CARDLOCK_TO_FACILITY[GECKO_CARDLOCK_PIN] = ICC_CB_FACILITY_SIM;
-GECKO_CARDLOCK_TO_FACILITY[GECKO_CARDLOCK_FDN] = ICC_CB_FACILITY_FDN;
-
-this.GECKO_CARDLOCK_TO_SEL_CODE = {};
-GECKO_CARDLOCK_TO_SEL_CODE[GECKO_CARDLOCK_PIN] = ICC_SEL_CODE_SIM_PIN;
-GECKO_CARDLOCK_TO_SEL_CODE[GECKO_CARDLOCK_PIN2] = ICC_SEL_CODE_SIM_PIN2;
-GECKO_CARDLOCK_TO_SEL_CODE[GECKO_CARDLOCK_PUK] = ICC_SEL_CODE_SIM_PUK;
-GECKO_CARDLOCK_TO_SEL_CODE[GECKO_CARDLOCK_PUK2] = ICC_SEL_CODE_SIM_PUK2;
-GECKO_CARDLOCK_TO_SEL_CODE[GECKO_CARDLOCK_NCK] = ICC_SEL_CODE_PH_NET_PIN;
-GECKO_CARDLOCK_TO_SEL_CODE[GECKO_CARDLOCK_NSCK] = ICC_SEL_CODE_PH_NETSUB_PIN;
-GECKO_CARDLOCK_TO_SEL_CODE[GECKO_CARDLOCK_CCK] = ICC_SEL_CODE_PH_CORP_PIN;
-GECKO_CARDLOCK_TO_SEL_CODE[GECKO_CARDLOCK_SPCK] = ICC_SEL_CODE_PH_SP_PIN;
-// TODO: Bug 1116072: identify the mapping between RIL_PERSOSUBSTATE_SIM_SIM @
-// ril.h and TS 27.007, clause 8.65 for GECKO_CARDLOCK_PCK.
-
-// See nsIIcc::CARD_CONTACT_TYPE_*
-this.GECKO_CARDCONTACT_TYPE_ADN = 0;
-this.GECKO_CARDCONTACT_TYPE_FDN = 1;
-this.GECKO_CARDCONTACT_TYPE_SDN = 2;
-
-// See nsIIcc::CARD_MVNO_TYPE_*
-this.GECKO_CARDMVNO_TYPE_IMSI = 0;
-this.GECKO_CARDMVNO_TYPE_SPN = 1;
-this.GECKO_CARDMVNO_TYPE_GID = 2;
-
-// See nsIIcc::CARD_SERVICE_*
-this.GECKO_CARDSERVICE_FDN = 0;
-
-// See ril.h RIL_PersoSubstate
-this.PERSONSUBSTATE = {};
-PERSONSUBSTATE[CARD_PERSOSUBSTATE_UNKNOWN] = GECKO_CARDSTATE_UNKNOWN;
-PERSONSUBSTATE[CARD_PERSOSUBSTATE_IN_PROGRESS] = GECKO_CARDSTATE_PERSONALIZATION_IN_PROGRESS;
-PERSONSUBSTATE[CARD_PERSOSUBSTATE_READY] = GECKO_CARDSTATE_PERSONALIZATION_READY;
-PERSONSUBSTATE[CARD_PERSOSUBSTATE_SIM_NETWORK] = GECKO_CARDSTATE_NETWORK_LOCKED;
-PERSONSUBSTATE[CARD_PERSOSUBSTATE_SIM_NETWORK_SUBSET] = GECKO_CARDSTATE_NETWORK_SUBSET_LOCKED;
-PERSONSUBSTATE[CARD_PERSOSUBSTATE_SIM_CORPORATE] = GECKO_CARDSTATE_CORPORATE_LOCKED;
-PERSONSUBSTATE[CARD_PERSOSUBSTATE_SIM_SERVICE_PROVIDER] = GECKO_CARDSTATE_SERVICE_PROVIDER_LOCKED;
-PERSONSUBSTATE[CARD_PERSOSUBSTATE_SIM_SIM] = GECKO_CARDSTATE_SIM_LOCKED;
-PERSONSUBSTATE[CARD_PERSOSUBSTATE_SIM_NETWORK_PUK] = GECKO_CARDSTATE_NETWORK_PUK_REQUIRED;
-PERSONSUBSTATE[CARD_PERSOSUBSTATE_SIM_NETWORK_SUBSET_PUK] = GECKO_CARDSTATE_NETWORK_SUBSET_PUK_REQUIRED;
-PERSONSUBSTATE[CARD_PERSOSUBSTATE_SIM_CORPORATE_PUK] = GECKO_CARDSTATE_CORPORATE_PUK_REQUIRED;
-PERSONSUBSTATE[CARD_PERSOSUBSTATE_SIM_SERVICE_PROVIDER_PUK] = GECKO_CARDSTATE_SERVICE_PROVIDER_PUK_REQUIRED;
-PERSONSUBSTATE[CARD_PERSOSUBSTATE_SIM_SIM_PUK] = GECKO_CARDSTATE_SIM_PUK_REQUIRED;
-PERSONSUBSTATE[CARD_PERSOSUBSTATE_RUIM_NETWORK1] = GECKO_CARDSTATE_NETWORK1_LOCKED;
-PERSONSUBSTATE[CARD_PERSOSUBSTATE_RUIM_NETWORK2] = GECKO_CARDSTATE_NETWORK2_LOCKED;
-PERSONSUBSTATE[CARD_PERSOSUBSTATE_RUIM_HRPD] = GECKO_CARDSTATE_HRPD_NETWORK_LOCKED;
-PERSONSUBSTATE[CARD_PERSOSUBSTATE_RUIM_CORPORATE] = GECKO_CARDSTATE_RUIM_CORPORATE_LOCKED;
-PERSONSUBSTATE[CARD_PERSOSUBSTATE_RUIM_SERVICE_PROVIDER] = GECKO_CARDSTATE_RUIM_SERVICE_PROVIDER_LOCKED;
-PERSONSUBSTATE[CARD_PERSOSUBSTATE_RUIM_RUIM] = GECKO_CARDSTATE_RUIM_LOCKED;
-PERSONSUBSTATE[CARD_PERSOSUBSTATE_RUIM_NETWORK1_PUK] = GECKO_CARDSTATE_NETWORK1_PUK_REQUIRED;
-PERSONSUBSTATE[CARD_PERSOSUBSTATE_RUIM_NETWORK2_PUK] = GECKO_CARDSTATE_NETWORK2_PUK_REQUIRED;
-PERSONSUBSTATE[CARD_PERSOSUBSTATE_RUIM_HRPD_PUK] = GECKO_CARDSTATE_HRPD_NETWORK_PUK_REQUIRED;
-PERSONSUBSTATE[CARD_PERSOSUBSTATE_RUIM_CORPORATE_PUK] = GECKO_CARDSTATE_RUIM_CORPORATE_PUK_REQUIRED;
-PERSONSUBSTATE[CARD_PERSOSUBSTATE_RUIM_SERVICE_PROVIDER_PUK] = GECKO_CARDSTATE_RUIM_SERVICE_PROVIDER_PUK_REQUIRED;
-PERSONSUBSTATE[CARD_PERSOSUBSTATE_RUIM_RUIM_PUK] = GECKO_CARDSTATE_RUIM_PUK_REQUIRED;
-
-// See nsIMobileConnection::NETWORK_SELECTION_MODE_*
-this.GECKO_NETWORK_SELECTION_UNKNOWN = -1;
-this.GECKO_NETWORK_SELECTION_AUTOMATIC = 0;
-this.GECKO_NETWORK_SELECTION_MANUAL = 1;
-
-this.GECKO_MOBILE_CONNECTION_STATE_UNKNOWN = null;
-this.GECKO_MOBILE_CONNECTION_STATE_NOTSEARCHING = "notSearching";
-this.GECKO_MOBILE_CONNECTION_STATE_SEARCHING = "searching";
-this.GECKO_MOBILE_CONNECTION_STATE_REGISTERED = "registered";
-this.GECKO_MOBILE_CONNECTION_STATE_DENIED = "denied";
-
-this.NETWORK_CREG_TO_GECKO_MOBILE_CONNECTION_STATE = {};
-NETWORK_CREG_TO_GECKO_MOBILE_CONNECTION_STATE[NETWORK_CREG_STATE_NOT_SEARCHING] = GECKO_MOBILE_CONNECTION_STATE_NOTSEARCHING;
-NETWORK_CREG_TO_GECKO_MOBILE_CONNECTION_STATE[NETWORK_CREG_STATE_REGISTERED_HOME] = GECKO_MOBILE_CONNECTION_STATE_REGISTERED;
-NETWORK_CREG_TO_GECKO_MOBILE_CONNECTION_STATE[NETWORK_CREG_STATE_SEARCHING] = GECKO_MOBILE_CONNECTION_STATE_SEARCHING;
-NETWORK_CREG_TO_GECKO_MOBILE_CONNECTION_STATE[NETWORK_CREG_STATE_DENIED] = GECKO_MOBILE_CONNECTION_STATE_DENIED;
-NETWORK_CREG_TO_GECKO_MOBILE_CONNECTION_STATE[NETWORK_CREG_STATE_UNKNOWN] = GECKO_MOBILE_CONNECTION_STATE_UNKNOWN;
-NETWORK_CREG_TO_GECKO_MOBILE_CONNECTION_STATE[NETWORK_CREG_STATE_REGISTERED_ROAMING] = GECKO_MOBILE_CONNECTION_STATE_REGISTERED;
-NETWORK_CREG_TO_GECKO_MOBILE_CONNECTION_STATE[NETWORK_CREG_STATE_NOT_SEARCHING_EMERGENCY_CALLS] = GECKO_MOBILE_CONNECTION_STATE_NOTSEARCHING;
-NETWORK_CREG_TO_GECKO_MOBILE_CONNECTION_STATE[NETWORK_CREG_STATE_SEARCHING_EMERGENCY_CALLS] = GECKO_MOBILE_CONNECTION_STATE_SEARCHING;
-NETWORK_CREG_TO_GECKO_MOBILE_CONNECTION_STATE[NETWORK_CREG_STATE_DENIED_EMERGENCY_CALLS] = GECKO_MOBILE_CONNECTION_STATE_DENIED;
-NETWORK_CREG_TO_GECKO_MOBILE_CONNECTION_STATE[NETWORK_CREG_STATE_UNKNOWN_EMERGENCY_CALLS] = GECKO_MOBILE_CONNECTION_STATE_UNKNOWN;
-
-
-// Should match enum TelephonyCallDisconnectedReason defined in TelephonyCall.webidl
-this.GECKO_CALL_ERROR_BAD_NUMBER = "BadNumberError";
-this.GECKO_CALL_ERROR_NO_ROUTE_TO_DESTINATION = "NoRouteToDestinationError";
-this.GECKO_CALL_ERROR_CHANNEL_UNACCEPTABLE = "ChannelUnacceptableError";
-this.GECKO_CALL_ERROR_OPERATOR_DETERMINED_BARRING = "OperatorDeterminedBarringError";
-this.GECKO_CALL_ERROR_NORMAL_CALL_CLEARING = "NormalCallClearingError";
-this.GECKO_CALL_ERROR_BUSY = "BusyError";
-this.GECKO_CALL_ERROR_NO_USER_RESPONDING = "NoUserRespondingError";
-this.GECKO_CALL_ERROR_USER_ALERTING = "UserAlertingNoAnswerError";
-this.GECKO_CALL_ERROR_REJECTED = "CallRejectedError";
-this.GECKO_CALL_ERROR_NUMBER_CHANGED = "NumberChangedError";
-this.GECKO_CALL_ERROR_REJECTED_DETINATION_FEATURE = "CallRejectedDestinationFeatureError";
-this.GECKO_CALL_ERROR_PRE_EMPTION = "PreEmptionError";
-this.GECKO_CALL_ERROR_DEST_OUT_OF_ORDER = "DestinationOutOfOrderError";
-this.GECKO_CALL_ERROR_INVALID_NUMBER_FORMAT = "InvalidNumberFormatError";
-this.GECKO_CALL_ERROR_FACILITY_REJECTED = "FacilityRejectedError";
-this.GECKO_CALL_ERROR_RESPONSE_TO_STATUS_ENQUIRY = "ResponseToStatusEnquiryError";
-this.GECKO_CALL_ERROR_CONGESTION = "CongestionError";
-this.GECKO_CALL_ERROR_NETWORK_OUT_OF_ORDER = "NetworkOutOfOrderError";
-this.GECKO_CALL_ERROR_NETWORK_TEMP_FAILURE = "NetworkTempFailureError";
-this.GECKO_CALL_ERROR_SWITCHING_EQUIP_CONGESTION = "SwitchingEquipCongestionError";
-this.GECKO_CALL_ERROR_ACCESS_INFO_DISCARDED = "AccessInfoDiscardedError";
-this.GECKO_CALL_ERROR_REQUESTED_CHANNEL_NOT_AVAILABLE = "RequestedChannelNotAvailableError";
-this.GECKO_CALL_ERROR_RESOURCE_UNAVAILABLE = "ResourceUnavailableError";
-this.GECKO_CALL_ERROR_QOS_UNAVAILABLE = "QosUnavailableError";
-this.GECKO_CALL_ERROR_REQUESTED_FACILITY_NOT_SUBSCRIBED = "RequestedFacilityNotSubscribedError";
-this.GECKO_CALL_ERROR_INCOMING_CALLS_BARRED_WITHIN_CUG = "IncomingCallsBarredWithinCugError";
-this.GECKO_CALL_ERROR_BEARER_CAPABILITY_NOT_AUTHORIZED = "BearerCapabilityNotAuthorizedError";
-this.GECKO_CALL_ERROR_BEARER_CAPABILITY_NOT_AVAILABLE = "BearerCapabilityNotAvailableError";
-this.GECKO_CALL_ERROR_BEARER_NOT_IMPLEMENTED = "BearerNotImplementedError";
-this.GECKO_CALL_ERROR_SERVICE_NOT_AVAILABLE = "ServiceNotAvailableError";
-this.GECKO_CALL_ERROR_INCOMING_CALL_EXCEEDED = "IncomingCallExceededError";
-this.GECKO_CALL_ERROR_REQUESTED_FACILITY_NOT_IMPLEMENTED = "RequestedFacilityNotImplementedError";
-this.GECKO_CALL_ERROR_UNRESTRICTED_BEARER_NOT_AVAILABLE = "UnrestrictedBearerNotAvailableError";
-this.GECKO_CALL_ERROR_SERVICE_NOT_IMPLEMENTED = "ServiceNotImplementedError";
-this.GECKO_CALL_ERROR_INVALID_TRANSACTION_ID = "InvalidTransactionIdError";
-this.GECKO_CALL_ERROR_USER_NOT_CUG_MEMBER = "NotCugMemberError";
-this.GECKO_CALL_ERROR_INCOMPATIBLE_DESTINATION = "IncompatibleDestinationError";
-this.GECKO_CALL_ERROR_INVALID_TRANSIT_NETWORK_SELECTION = "InvalidTransitNetworkSelectionError";
-this.GECKO_CALL_ERROR_SEMANTICALLY_INCORRECT_MESSAGE = "SemanticallyIncorrectMessageError";
-this.GECKO_CALL_ERROR_INVALID_MANDATORY_INFO = "InvalidMandatoryInfoError";
-this.GECKO_CALL_ERROR_MESSAGE_TYPE_NOT_IMPLEMENTED = "MessageTypeNotImplementedError";
-this.GECKO_CALL_ERROR_MESSAGE_TYPE_INCOMPATIBLE_PROTOCOL_STATE = "MessageTypeIncompatibleProtocolStateError";
-this.GECKO_CALL_ERROR_INFO_ELEMENT_NOT_IMPLEMENTED = "InfoElementNotImplementedError";
-this.GECKO_CALL_ERROR_CONDITIONAL_IE = "ConditionalIeError";
-this.GECKO_CALL_ERROR_MESSAGE_INCOMPATIBLE_PROTOCOL_STATE = "MessageIncompatibleProtocolStateError";
-this.GECKO_CALL_ERROR_RECOVERY_ON_TIMER_EXPIRY = "RecoveryOnTimerExpiryError";
-this.GECKO_CALL_ERROR_PROTOCOL = "ProtocolError";
-this.GECKO_CALL_ERROR_INTERWORKING = "InterworkingError";
-this.GECKO_CALL_ERROR_BARRED = "BarredError";
-this.GECKO_CALL_ERROR_FDN_BLOCKED = "FDNBlockedError";
-this.GECKO_CALL_ERROR_SUBSCRIBER_UNKNOWN = "SubscriberUnknownError";
-this.GECKO_CALL_ERROR_DEVICE_NOT_ACCEPTED = "DeviceNotAcceptedError";
-this.GECKO_CALL_ERROR_MODIFIED_TO_DIAL_FAILED = "ModifiedDialError";
-this.GECKO_CALL_ERROR_CDMA_LOCKED_UNTIL_POWER_CYCLE = "CdmaLockedUntilPowerCycleError";
-this.GECKO_CALL_ERROR_CDMA_DROP = "CdmaDropError";
-this.GECKO_CALL_ERROR_CDMA_INTERCEPT = "CdmaInterceptError";
-this.GECKO_CALL_ERROR_CDMA_REORDER = "CdmaReorderError";
-this.GECKO_CALL_ERROR_CDMA_SO_REJECT = "CdmaSoRejectError";
-this.GECKO_CALL_ERROR_CDMA_RETRY_ORDER = "CdmaRetryOrderError";
-this.GECKO_CALL_ERROR_CDMA_ACCESS_FAILURE = "CdmaAcessError";
-this.GECKO_CALL_ERROR_CDMA_PREEMPTED = "CdmaPreemptedError";
-this.GECKO_CALL_ERROR_CDMA_NOT_EMERGENCY = "CdmaNotEmergencyError";
-this.GECKO_CALL_ERROR_CDMA_ACCESS_BLOCKED = "CdmaAccessBlockedError";
-this.GECKO_CALL_ERROR_UNSPECIFIED = "UnspecifiedError";
-
-this.RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR = {};
-RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_UNOBTAINABLE_NUMBER] = GECKO_CALL_ERROR_BAD_NUMBER;
-RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_NO_ROUTE_TO_DESTINATION] = GECKO_CALL_ERROR_NO_ROUTE_TO_DESTINATION;
-RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_CHANNEL_UNACCEPTABLE] = GECKO_CALL_ERROR_CHANNEL_UNACCEPTABLE;
-RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_OPERATOR_DETERMINED_BARRING] = GECKO_CALL_ERROR_OPERATOR_DETERMINED_BARRING;
-RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_NORMAL] = GECKO_CALL_ERROR_NORMAL_CALL_CLEARING;
-RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_BUSY] = GECKO_CALL_ERROR_BUSY;
-RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_NO_USER_RESPONDING] = GECKO_CALL_ERROR_NO_USER_RESPONDING;
-RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_USER_ALERTING] = GECKO_CALL_ERROR_USER_ALERTING;
-RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_CALL_REJECTED] = GECKO_CALL_ERROR_REJECTED;
-RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_NUMBER_CHANGED] = GECKO_CALL_ERROR_NUMBER_CHANGED;
-RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_CALL_REJECTED_DESTINATION_FEATURE] = GECKO_CALL_ERROR_REJECTED_DETINATION_FEATURE;
-RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_CALL_PRE_EMPTION] = GECKO_CALL_ERROR_PRE_EMPTION;
-RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_DEST_OUT_OF_ORDER] = GECKO_CALL_ERROR_DEST_OUT_OF_ORDER;
-RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_INVALID_FORMAT] = GECKO_CALL_ERROR_INVALID_NUMBER_FORMAT;
-RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_FACILITY_REJECTED] = GECKO_CALL_ERROR_FACILITY_REJECTED;
-RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_RESPONSE_TO_STATUS_ENQUIRY] = GECKO_CALL_ERROR_RESPONSE_TO_STATUS_ENQUIRY;
-RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_NORMAL_UNSPECIFIED] = GECKO_CALL_ERROR_NORMAL_CALL_CLEARING;
-RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_CONGESTION] = GECKO_CALL_ERROR_CONGESTION;
-RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_NETWORK_OUT_OF_ORDER] = GECKO_CALL_ERROR_NETWORK_OUT_OF_ORDER;
-RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_NETWORK_TEMP_FAILURE] = GECKO_CALL_ERROR_NETWORK_TEMP_FAILURE;
-RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_SWITCHING_EQUIP_CONGESTION] = GECKO_CALL_ERROR_SWITCHING_EQUIP_CONGESTION;
-RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_ACCESS_INFO_DISCARDED] = GECKO_CALL_ERROR_ACCESS_INFO_DISCARDED;
-RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_REQUESTED_CHANNEL_NOT_AVAILABLE] = GECKO_CALL_ERROR_REQUESTED_CHANNEL_NOT_AVAILABLE;
-RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_RESOURCE_UNAVAILABLE] = GECKO_CALL_ERROR_RESOURCE_UNAVAILABLE;
-RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_QOS_UNAVAILABLE] = GECKO_CALL_ERROR_QOS_UNAVAILABLE;
-RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_REQUESTED_FACILITY_NOT_SUBSCRIBED] = GECKO_CALL_ERROR_REQUESTED_FACILITY_NOT_SUBSCRIBED;
-RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_INCOMING_CALLS_BARRED_WITHIN_CUG] = GECKO_CALL_ERROR_INCOMING_CALLS_BARRED_WITHIN_CUG;
-RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_BEARER_CAPABILITY_NOT_AUTHORIZED] = GECKO_CALL_ERROR_BEARER_CAPABILITY_NOT_AUTHORIZED;
-RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_BEARER_CAPABILITY_NOT_AVAILABLE] = GECKO_CALL_ERROR_BEARER_CAPABILITY_NOT_AVAILABLE;
-RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_SERVICE_NOT_AVAILABLE] = GECKO_CALL_ERROR_SERVICE_NOT_AVAILABLE;
-RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_BEARER_NOT_IMPLEMENTED] = GECKO_CALL_ERROR_BEARER_NOT_IMPLEMENTED;
-RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_ACM_LIMIT_EXCEEDED] = GECKO_CALL_ERROR_INCOMING_CALL_EXCEEDED;
-RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_REQUESTED_FACILITY_NOT_IMPLEMENTED] = GECKO_CALL_ERROR_REQUESTED_FACILITY_NOT_IMPLEMENTED;
-RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_UNRESTRICTED_BEARER_NOT_AVAILABLE] = GECKO_CALL_ERROR_UNRESTRICTED_BEARER_NOT_AVAILABLE;
-RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_SERVICE_NOT_IMPLEMENTED] = GECKO_CALL_ERROR_SERVICE_NOT_IMPLEMENTED;
-RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_INVALID_TRANSACTION_ID] = GECKO_CALL_ERROR_INVALID_TRANSACTION_ID;
-RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_USER_NOT_CUG_MEMBER] = GECKO_CALL_ERROR_USER_NOT_CUG_MEMBER;
-RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_INCOMPATIBLE_DESTINATION] = GECKO_CALL_ERROR_INCOMPATIBLE_DESTINATION;
-RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_INVALID_TRANSIT_NETWORK_SELECTION] = GECKO_CALL_ERROR_INVALID_TRANSIT_NETWORK_SELECTION;
-RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_SEMANTICALLY_INCORRECT_MESSAGE] = GECKO_CALL_ERROR_SEMANTICALLY_INCORRECT_MESSAGE;
-RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_INVALID_MANDATORY_INFO] = GECKO_CALL_ERROR_INVALID_MANDATORY_INFO;
-RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_MESSAGE_TYPE_NOT_IMPLEMENTED] = GECKO_CALL_ERROR_MESSAGE_TYPE_NOT_IMPLEMENTED;
-RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_MESSAGE_TYPE_INCOMPATIBLE_PROTOCOL_STATE] = GECKO_CALL_ERROR_MESSAGE_TYPE_INCOMPATIBLE_PROTOCOL_STATE;
-RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_INFO_ELEMENT_NOT_IMPLEMENTED] = GECKO_CALL_ERROR_INFO_ELEMENT_NOT_IMPLEMENTED;
-RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_CONDITIONAL_IE_ERROR] = GECKO_CALL_ERROR_CONDITIONAL_IE;
-RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_MESSAGE_INCOMPABITLE_PROTOCOL_STATE] = GECKO_CALL_ERROR_MESSAGE_INCOMPATIBLE_PROTOCOL_STATE;
-RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_RECOVERY_ON_TIMER_EXPIRY] = GECKO_CALL_ERROR_RECOVERY_ON_TIMER_EXPIRY;
-RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_PROTOCOL_ERROR] = GECKO_CALL_ERROR_PROTOCOL;
-RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_INTERWORKING] = GECKO_CALL_ERROR_INTERWORKING;
-RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_CALL_BARRED] = GECKO_CALL_ERROR_BARRED;
-RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_FDN_BLOCKED] = GECKO_CALL_ERROR_FDN_BLOCKED;
-RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_IMSI_UNKNOWN_IN_VLR] = GECKO_CALL_ERROR_SUBSCRIBER_UNKNOWN;
-RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_IMEI_NOT_ACCEPTED] = GECKO_CALL_ERROR_DEVICE_NOT_ACCEPTED;
-RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_DIAL_MODIFIED_TO_USSD] = GECKO_CALL_ERROR_MODIFIED_TO_DIAL_FAILED;
-RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_DIAL_MODIFIED_TO_SS] = GECKO_CALL_ERROR_MODIFIED_TO_DIAL_FAILED;
-RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_DIAL_MODIFIED_TO_DIAL] = GECKO_CALL_ERROR_MODIFIED_TO_DIAL_FAILED;
-RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_CDMA_LOCKED_UNTIL_POWER_CYCLE] = GECKO_CALL_ERROR_CDMA_LOCKED_UNTIL_POWER_CYCLE;
-RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_CDMA_DROP] = GECKO_CALL_ERROR_CDMA_DROP;
-RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_CDMA_INTERCEPT] = GECKO_CALL_ERROR_CDMA_INTERCEPT;
-RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_CDMA_REORDER] = GECKO_CALL_ERROR_CDMA_REORDER;
-RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_CDMA_SO_REJECT] = GECKO_CALL_ERROR_CDMA_SO_REJECT;
-RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_CDMA_RETRY_ORDER] = GECKO_CALL_ERROR_CDMA_RETRY_ORDER;
-RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_CDMA_ACCESS_FAILURE] = GECKO_CALL_ERROR_CDMA_ACCESS_FAILURE;
-RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_CDMA_PREEMPTED] = GECKO_CALL_ERROR_CDMA_PREEMPTED;
-RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_CDMA_NOT_EMERGENCY] = GECKO_CALL_ERROR_CDMA_NOT_EMERGENCY;
-RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_CDMA_ACCESS_BLOCKED] = GECKO_CALL_ERROR_CDMA_ACCESS_BLOCKED;
-RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_ERROR_UNSPECIFIED] = GECKO_CALL_ERROR_UNSPECIFIED;
-
-this.GECKO_DATACALL_ERROR_OPERATOR_BARRED = "OperatorBarredError";
-this.GECKO_DATACALL_ERROR_INSUFFICIENT_RESOURCES = "InsufficientResourcesError";
-this.GECKO_DATACALL_ERROR_MISSING_UKNOWN_APN = "MissingUnknownAPNError";
-this.GECKO_DATACALL_ERROR_UNKNOWN_PDP_ADDRESS_TYPE = "UnknownPDPAddressTypeError";
-this.GECKO_DATACALL_ERROR_USER_AUTHENTICATION = "UserAuthenticationError";
-this.GECKO_DATACALL_ERROR_ACTIVATION_REJECT_GGSN = "ActivationRejectGGSNError";
-this.GECKO_DATACALL_ERROR_ACTIVATION_REJECT_UNSPECIFIED = "ActivationRejectUnspecifiedError";
-this.GECKO_DATACALL_ERROR_SERVICE_OPTION_NOT_SUPPORTED = "ServiceOptionNotSupportedError";
-this.GECKO_DATACALL_ERROR_SERVICE_OPTION_NOT_SUBSCRIBED = "ServiceOptionNotSubscribedError";
-this.GECKO_DATACALL_ERROR_SERVICE_OPTION_OUT_OF_ORDER = "ServiceOptionOutOfOrderError";
-this.GECKO_DATACALL_ERROR_NSAPI_IN_USE = "NSAPIInUseError";
-this.GECKO_DATACALL_ERROR_ONLY_IPV4_ALLOWED = "OnlyIPv4Error";
-this.GECKO_DATACALL_ERROR_ONLY_IPV6_ALLOWED = "OnlyIPv6Error";
-this.GECKO_DATACALL_ERROR_ONLY_SINGLE_BEARER_ALLOWED = "OnlySingleBearerAllowedError";
-this.GECKO_DATACALL_ERROR_PROTOCOL_ERRORS = "ProtocolErrorsError";
-this.GECKO_DATACALL_ERROR_VOICE_REGISTRATION_FAIL = "VoiceRegistrationFailError";
-this.GECKO_DATACALL_ERROR_DATA_REGISTRATION_FAIL = "DataRegistrationFailError";
-this.GECKO_DATACALL_ERROR_SIGNAL_LOST = "SignalLostError";
-this.GECKO_DATACALL_ERROR_PREF_RADIO_TECH_CHANGED = "PrefRadioTechChangedError";
-this.GECKO_DATACALL_ERROR_RADIO_POWER_OFF = "RadioPowerOffError";
-this.GECKO_DATACALL_ERROR_TETHERED_CALL_ACTIVE = "TetheredCallActiveError";
-this.GECKO_DATACALL_ERROR_UNSPECIFIED = "UnspecifiedError";
-
-this.RIL_DATACALL_FAILCAUSE_TO_GECKO_DATACALL_ERROR = {};
-RIL_DATACALL_FAILCAUSE_TO_GECKO_DATACALL_ERROR[DATACALL_FAIL_OPERATOR_BARRED] = GECKO_DATACALL_ERROR_OPERATOR_BARRED;
-RIL_DATACALL_FAILCAUSE_TO_GECKO_DATACALL_ERROR[DATACALL_FAIL_INSUFFICIENT_RESOURCES] = GECKO_DATACALL_ERROR_INSUFFICIENT_RESOURCES;
-RIL_DATACALL_FAILCAUSE_TO_GECKO_DATACALL_ERROR[DATACALL_FAIL_MISSING_UKNOWN_APN] = GECKO_DATACALL_ERROR_MISSING_UKNOWN_APN;
-RIL_DATACALL_FAILCAUSE_TO_GECKO_DATACALL_ERROR[DATACALL_FAIL_UNKNOWN_PDP_ADDRESS_TYPE] = GECKO_DATACALL_ERROR_UNKNOWN_PDP_ADDRESS_TYPE;
-RIL_DATACALL_FAILCAUSE_TO_GECKO_DATACALL_ERROR[DATACALL_FAIL_USER_AUTHENTICATION] = GECKO_DATACALL_ERROR_USER_AUTHENTICATION;
-RIL_DATACALL_FAILCAUSE_TO_GECKO_DATACALL_ERROR[DATACALL_FAIL_ACTIVATION_REJECT_GGSN] = GECKO_DATACALL_ERROR_ACTIVATION_REJECT_GGSN;
-RIL_DATACALL_FAILCAUSE_TO_GECKO_DATACALL_ERROR[DATACALL_FAIL_ACTIVATION_REJECT_UNSPECIFIED] = GECKO_DATACALL_ERROR_ACTIVATION_REJECT_UNSPECIFIED;
-RIL_DATACALL_FAILCAUSE_TO_GECKO_DATACALL_ERROR[DATACALL_FAIL_SERVICE_OPTION_NOT_SUPPORTED] = GECKO_DATACALL_ERROR_SERVICE_OPTION_NOT_SUPPORTED;
-RIL_DATACALL_FAILCAUSE_TO_GECKO_DATACALL_ERROR[DATACALL_FAIL_SERVICE_OPTION_NOT_SUBSCRIBED] = GECKO_DATACALL_ERROR_SERVICE_OPTION_NOT_SUBSCRIBED;
-RIL_DATACALL_FAILCAUSE_TO_GECKO_DATACALL_ERROR[DATACALL_FAIL_SERVICE_OPTION_OUT_OF_ORDER] = GECKO_DATACALL_ERROR_SERVICE_OPTION_OUT_OF_ORDER;
-RIL_DATACALL_FAILCAUSE_TO_GECKO_DATACALL_ERROR[DATACALL_FAIL_NSAPI_IN_USE] = GECKO_DATACALL_ERROR_NSAPI_IN_USE;
-RIL_DATACALL_FAILCAUSE_TO_GECKO_DATACALL_ERROR[DATACALL_FAIL_ONLY_IPV4_ALLOWED] = GECKO_DATACALL_ERROR_ONLY_IPV4_ALLOWED;
-RIL_DATACALL_FAILCAUSE_TO_GECKO_DATACALL_ERROR[DATACALL_FAIL_ONLY_IPV6_ALLOWED] = GECKO_DATACALL_ERROR_ONLY_IPV6_ALLOWED;
-RIL_DATACALL_FAILCAUSE_TO_GECKO_DATACALL_ERROR[DATACALL_FAIL_ONLY_SINGLE_BEARER_ALLOWED] = GECKO_DATACALL_ERROR_ONLY_SINGLE_BEARER_ALLOWED;
-RIL_DATACALL_FAILCAUSE_TO_GECKO_DATACALL_ERROR[DATACALL_FAIL_PROTOCOL_ERRORS] = GECKO_DATACALL_ERROR_PROTOCOL_ERRORS;
-RIL_DATACALL_FAILCAUSE_TO_GECKO_DATACALL_ERROR[DATACALL_FAIL_VOICE_REGISTRATION_FAIL] = GECKO_DATACALL_ERROR_VOICE_REGISTRATION_FAIL;
-RIL_DATACALL_FAILCAUSE_TO_GECKO_DATACALL_ERROR[DATACALL_FAIL_DATA_REGISTRATION_FAIL] = GECKO_DATACALL_ERROR_DATA_REGISTRATION_FAIL;
-RIL_DATACALL_FAILCAUSE_TO_GECKO_DATACALL_ERROR[DATACALL_FAIL_SIGNAL_LOST] = GECKO_DATACALL_ERROR_SIGNAL_LOST;
-RIL_DATACALL_FAILCAUSE_TO_GECKO_DATACALL_ERROR[DATACALL_FAIL_PREF_RADIO_TECH_CHANGED] = GECKO_DATACALL_ERROR_PREF_RADIO_TECH_CHANGED;
-RIL_DATACALL_FAILCAUSE_TO_GECKO_DATACALL_ERROR[DATACALL_FAIL_RADIO_POWER_OFF] = GECKO_DATACALL_ERROR_RADIO_POWER_OFF;
-RIL_DATACALL_FAILCAUSE_TO_GECKO_DATACALL_ERROR[DATACALL_FAIL_TETHERED_CALL_ACTIVE] = GECKO_DATACALL_ERROR_TETHERED_CALL_ACTIVE;
-RIL_DATACALL_FAILCAUSE_TO_GECKO_DATACALL_ERROR[DATACALL_FAIL_ERROR_UNSPECIFIED] = GECKO_DATACALL_ERROR_UNSPECIFIED;
-
-this.GECKO_RADIO_TECH = [
- null,
- "gprs",
- "edge",
- "umts",
- "is95a",
- "is95b",
- "1xrtt",
- "evdo0",
- "evdoa",
- "hsdpa",
- "hsupa",
- "hspa",
- "evdob",
- "ehrpd",
- "lte",
- "hspa+",
- "gsm",
- null,
- "hspa+", // DC-HSPA+
- "hspa+"
-];
-
-this.GECKO_VOICEMAIL_MESSAGE_COUNT_UNKNOWN = -1;
-
-// Call forwarding action. Must be in sync with nsIMobileConnectionService interface
-this.CALL_FORWARD_ACTION_DISABLE = 0;
-this.CALL_FORWARD_ACTION_ENABLE = 1;
-this.CALL_FORWARD_ACTION_QUERY_STATUS = 2;
-this.CALL_FORWARD_ACTION_REGISTRATION = 3;
-this.CALL_FORWARD_ACTION_ERASURE = 4;
-
-// Call forwarding reason. Must be in sync with nsIMobileConnectionService interface
-this.CALL_FORWARD_REASON_UNCONDITIONAL = 0;
-this.CALL_FORWARD_REASON_MOBILE_BUSY = 1;
-this.CALL_FORWARD_REASON_NO_REPLY = 2;
-this.CALL_FORWARD_REASON_NOT_REACHABLE = 3;
-this.CALL_FORWARD_REASON_ALL_CALL_FORWARDING = 4;
-this.CALL_FORWARD_REASON_ALL_CONDITIONAL_CALL_FORWARDING = 5;
-
-// Call barring program. Must be in sync with nsIMobileConnectionService interface
-this.CALL_BARRING_PROGRAM_ALL_OUTGOING = 0;
-this.CALL_BARRING_PROGRAM_OUTGOING_INTERNATIONAL = 1;
-this.CALL_BARRING_PROGRAM_OUTGOING_INTERNATIONAL_EXCEPT_HOME = 2;
-this.CALL_BARRING_PROGRAM_ALL_INCOMING = 3;
-this.CALL_BARRING_PROGRAM_INCOMING_ROAMING = 4;
-this.CALL_BARRING_PROGRAM_ALL_SERVICE = 5;
-this.CALL_BARRING_PROGRAM_OUTGOING_SERVICE = 6;
-this.CALL_BARRING_PROGRAM_INCOMING_SERVICE = 7;
-
-this.CALL_BARRING_PROGRAM_TO_FACILITY = {};
-CALL_BARRING_PROGRAM_TO_FACILITY[CALL_BARRING_PROGRAM_ALL_OUTGOING] = ICC_CB_FACILITY_BAOC;
-CALL_BARRING_PROGRAM_TO_FACILITY[CALL_BARRING_PROGRAM_OUTGOING_INTERNATIONAL] = ICC_CB_FACILITY_BAOIC;
-CALL_BARRING_PROGRAM_TO_FACILITY[CALL_BARRING_PROGRAM_OUTGOING_INTERNATIONAL_EXCEPT_HOME] = ICC_CB_FACILITY_BAOICxH;
-CALL_BARRING_PROGRAM_TO_FACILITY[CALL_BARRING_PROGRAM_ALL_INCOMING] = ICC_CB_FACILITY_BAIC;
-CALL_BARRING_PROGRAM_TO_FACILITY[CALL_BARRING_PROGRAM_INCOMING_ROAMING] = ICC_CB_FACILITY_BAICr;
-CALL_BARRING_PROGRAM_TO_FACILITY[CALL_BARRING_PROGRAM_ALL_SERVICE] = ICC_CB_FACILITY_BA_ALL;
-CALL_BARRING_PROGRAM_TO_FACILITY[CALL_BARRING_PROGRAM_OUTGOING_SERVICE] = ICC_CB_FACILITY_BA_MO;
-CALL_BARRING_PROGRAM_TO_FACILITY[CALL_BARRING_PROGRAM_INCOMING_SERVICE] = ICC_CB_FACILITY_BA_MT;
-
-/**
- * CDMA PDU constants
- */
-
-// SMS Message Type, as defined in 3GPP2 C.S0015-A v2.0, Table 3.4-1
-this.PDU_CDMA_MSG_TYPE_P2P = 0x00; // Point-to-Point
-this.PDU_CDMA_MSG_TYPE_BROADCAST = 0x01; // Broadcast
-this.PDU_CDMA_MSG_TYPE_ACK = 0x02; // Acknowledge
-
-// SMS Teleservice Identitifier, as defined in 3GPP2 N.S0005, Table 175
-this.PDU_CDMA_MSG_TELESERIVCIE_ID_SMS = 0x1002; // SMS
-this.PDU_CDMA_MSG_TELESERIVCIE_ID_WAP = 0x1004; // WAP
-this.PDU_CDMA_MSG_TELESERIVCIE_ID_WEMT = 0x1005; // Wireless Enhanced Messaging Teleservice
- // required for fragmented SMS
-
-// SMS Service Category, as defined in 3GPP2 C.R1001-D, Table 9.3.1-1
-this.PDU_CDMA_MSG_CATEGORY_UNSPEC = 0x00; // Unknown/Unspecified
-
-// Address Information, Digit Mode, as defined in 3GPP2 C.S0015-A v2.0, sec 3.4.3.3
-this.PDU_CDMA_MSG_ADDR_DIGIT_MODE_DTMF = 0x00; // Digit Mode : DTMF
-this.PDU_CDMA_MSG_ADDR_DIGIT_MODE_ASCII = 0x01; // Digit Mode : 8-bit ASCII with MSB = 0
-
-// Address Information, Number Mode, as defined in 3GPP2 C.S0015-A v2.0, sec 3.4.3.3
-this.PDU_CDMA_MSG_ADDR_NUMBER_MODE_ANSI = 0x00; // Number Mode : ANSI T1.607-2000(R2004)
-this.PDU_CDMA_MSG_ADDR_NUMBER_MODE_ASCII = 0x01; // Number Mode : Data network address format
-
-// Address Information, Number Type, as defined in 3GPP2 C.S0015-A v2.0, Table 3.4.3.3-1
-this.PDU_CDMA_MSG_ADDR_NUMBER_TYPE_UNKNOWN = 0x00; // Number Type : Unknown
-this.PDU_CDMA_MSG_ADDR_NUMBER_TYPE_INTERNATIONAL = 0x01; // Number Type : Internaltional number(+XXXXX)
-this.PDU_CDMA_MSG_ADDR_NUMBER_TYPE_NATIONAL = 0x02; // Number Type : National number
-
-// Address Information, Number Plan, as defined in 3GPP2 C.S0005-D v2.0, Table 2.7.1.3.2.4-3
-this.PDU_CDMA_MSG_ADDR_NUMBER_PLAN_UNKNOWN = 0x00; // Number Plan : Unknown
-this.PDU_CDMA_MSG_ADDR_NUMBER_PLAN_ISDN = 0x01; // Number Plan : ISDN/Telephony numbering plan
-
-// SMS Encoding, as defined in 3GPP2 C.R1001-D, Table 9.1-1
-this.PDU_CDMA_MSG_CODING_OCTET = 0x00; // octet(8-bit), Not tested
-this.PDU_CDMA_MSG_CODING_IS_91 = 0x01; // IS-91 Extended Protocol Message(variable), Not tested
-this.PDU_CDMA_MSG_CODING_7BITS_ASCII = 0x02; // 7-bit ASCII(7-bit)
-this.PDU_CDMA_MSG_CODING_IA5 = 0x03; // IA5(7-bit), Not tested
-this.PDU_CDMA_MSG_CODING_UNICODE = 0x04; // Unicode(16-bit)
-this.PDU_CDMA_MSG_CODING_SHIFT_JIS = 0x05; // Shift-6 JIS(8/16-bit variable), Not supported
-this.PDU_CDMA_MSG_CODING_KOREAN = 0x06; // Korean(8/16-bit variable), Not supported
-this.PDU_CDMA_MSG_CODING_LATIN_HEBREW = 0x07; // Latin/ Hebrew(8-bit), ISO/IEC 8859-8, Not supported
-this.PDU_CDMA_MSG_CODING_LATIN = 0x08; // Latin(8-bit), ISO/IEC 8859-1, Not tested
-this.PDU_CDMA_MSG_CODING_7BITS_GSM = 0x09; // GSM 7-bit default alphabet(7-bit), Not tested
-this.PDU_CDMA_MSG_CODING_GSM_DCS = 0x0A; // GSM Data-Coding-Scheme, Not supported
-
-// SMS Message Type, as defined in 3GPP2 C.S0015-A v2.0, Table 4.5.1-1
-this.PDU_CDMA_MSG_TYPE_DELIVER = 0x01; // Deliver
-this.PDU_CDMA_MSG_TYPE_SUBMIT = 0x02; // Submit
-this.PDU_CDMA_MSG_TYPE_DELIVER_ACK = 0x04; // Delivery Acknowledgment
-
-// SMS User Data Subparameters, as defined in 3GPP2 C.S0015-A v2.0, Table 4.5-1
-this.PDU_CDMA_MSG_USERDATA_MSG_ID = 0x00; // Message Identifier
-this.PDU_CDMA_MSG_USERDATA_BODY = 0x01; // User Data Body
-this.PDU_CDMA_MSG_USERDATA_TIMESTAMP = 0x03; // Message Center Time Stamp
-this.PDU_CDMA_MSG_USERDATA_REPLY_OPTION = 0x0A; // Reply Option
-this.PDU_CDMA_LANGUAGE_INDICATOR = 0x0D; // Language Indicator
-this.PDU_CDMA_MSG_USERDATA_CALLBACK_NUMBER = 0x0E; // Callback Number
-this.PDU_CDMA_MSG_USER_DATA_MSG_STATUS = 0x14; // Message Status
-
-// CDMA Language Indicator: Language groups
-// see 3GPP2 C.R1001-F table 9.2-1
-this.CB_CDMA_LANG_GROUP = [
- null, "en", "fr", "es", "ja", "ko", "zh", "he"
-];
-
-// IS-91 Message Type, as defined in TIA/EIA/IS-91-A, Table 9
-this.PDU_CDMA_MSG_CODING_IS_91_TYPE_VOICEMAIL_STATUS = 0x82;
-this.PDU_CDMA_MSG_CODING_IS_91_TYPE_SMS_FULL = 0x83;
-this.PDU_CDMA_MSG_CODING_IS_91_TYPE_CLI = 0x84;
-this.PDU_CDMA_MSG_CODING_IS_91_TYPE_SMS = 0x85;
-
-// Information Record Type, reference from ril.h
-this.PDU_CDMA_INFO_REC_TYPE_DISPLAY = 0;
-this.PDU_CDMA_INFO_REC_TYPE_CALLED_PARTY_NUMBER = 1;
-this.PDU_CDMA_INFO_REC_TYPE_CALLING_PARTY_NUMBER = 2;
-this.PDU_CDMA_INFO_REC_TYPE_CONNECTED_NUMBER =3;
-this.PDU_CDMA_INFO_REC_TYPE_SIGNAL = 4;
-this.PDU_CDMA_INFO_REC_TYPE_REDIRECTING_NUMBER = 5;
-this.PDU_CDMA_INFO_REC_TYPE_LINE_CONTROL = 6;
-this.PDU_CDMA_INFO_REC_TYPE_EXTENDED_DISPLAY = 7;
-this.PDU_CDMA_INFO_REC_TYPE_T53_CLIR = 8;
-this.PDU_CDMA_INFO_REC_TYPE_T53_RELEASE = 9;
-this.PDU_CDMA_INFO_REC_TYPE_T53_AUDIO_CONTROL = 10;
-
-// Display type of extended display of information record,
-// as defined in C.S0005-F v1.0, Table 3.7.5.16-2
-this.INFO_REC_EXTENDED_DISPLAY_BLANK = 0x80;
-this.INFO_REC_EXTENDED_DISPLAY_SKIP = 0x81;
-this.INFO_REC_EXTENDED_DISPLAY_CONTINATION = 0x82;
-this.INFO_REC_EXTENDED_DISPLAY_CALLED_ADDRESS = 0x83;
-this.INFO_REC_EXTENDED_DISPLAY_CAUSE = 0x84;
-this.INFO_REC_EXTENDED_DISPLAY_PROGRESS_INDICATOR = 0x85;
-this.INFO_REC_EXTENDED_DISPLAY_NOTIFICATION_INDICATOR = 0x86;
-this.INFO_REC_EXTENDED_DISPLAY_PROMPT = 0x87;
-this.INFO_REC_EXTENDED_DISPLAY_ACCUMULATED_DIGITS = 0x88;
-this.INFO_REC_EXTENDED_DISPLAY_STATUS = 0x89;
-this.INFO_REC_EXTENDED_DISPLAY_INBAND = 0x8A;
-this.INFO_REC_EXTENDED_DISPLAY_CALLING_ADDRESS = 0x8B;
-this.INFO_REC_EXTENDED_DISPLAY_REASON = 0x8C;
-this.INFO_REC_EXTENDED_DISPLAY_CALLING_PARTY_NAME = 0x8D;
-this.INFO_REC_EXTENDED_DISPLAY_CALLED_PARTY_NAME = 0x8E;
-this.INFO_REC_EXTENDED_DISPLAY_ORIGINAL_CALLED_NAME = 0x8F;
-this.INFO_REC_EXTENDED_DISPLAY_REDIRECT_NAME = 0x90;
-this.INFO_REC_EXTENDED_DISPLAY_CONNECTED_NAME = 0x91;
-this.INFO_REC_EXTENDED_DISPLAY_ORIGINATING_RESTRICTIONS = 0x92;
-this.INFO_REC_EXTENDED_DISPLAY_DATE_TIME_OF_DAY = 0x93;
-this.INFO_REC_EXTENDED_DISPLAY_CALL_APPEARANCE_ID = 0x94;
-this.INFO_REC_EXTENDED_DISPLAY_FEATURE_ADDRESS = 0x95;
-this.INFO_REC_EXTENDED_DISPLAY_REDIRECTION_NAME = 0x96;
-this.INFO_REC_EXTENDED_DISPLAY_REDIRECTION_NUMBER = 0x97;
-this.INFO_REC_EXTENDED_DISPLAY_REDIRECTING_NUMBER = 0x98;
-this.INFO_REC_EXTENDED_DISPLAY_ORIGINAL_CALLED_NUMBER = 0x99;
-this.INFO_REC_EXTENDED_DISPLAY_CONNECTED_NUMBER = 0x9A;
-this.INFO_REC_EXTENDED_DISPLAY_TEXT = 0x9B;
-
-/**
- * The table for MCC/MNC which the length of MNC is 3.
- *
- * This table is built from below links.
- * - http://www.itu.int/pub/T-SP-E.212B-2013
- * - http://en.wikipedia.org/wiki/Mobile_Network_Code
- */
-this.PLMN_HAVING_3DIGITS_MNC = {
- // Puerto Rico.
- "330":
- ["110", // América Móvil
- "120" // PR Wireless
- ],
- // Trinidad and Tobago.
- "374":
- ["130", // Digicel Trinidad and Tobago Ltd.
- "140" // LaqTel Ltd.
- ],
- // India.
- "405":
- ["000", // Shyam Telelink Ltd.
- "005", // Reliance, Delhi
- "006", // Reliance, Gujarat
- "007", // Reliance, Haryana
- "009", // Reliance, J&K
- "010", // Reliance, Karnataka
- "011", // Reliance, Kerala
- "012", // Reliance, Andhra Pradesh
- "013", // Reliance, Maharashtr
- "014", // Reliance, Madhya Pradesh
- "018", // Reliance, Punjab
- "020", // Reliance, Tamilnadu
- "021", // Reliance, UP (East)
- "022", // Reliance, UP (West)
- "025", // TATA DOCOMO, Andhra Pradesh
- "026", // TATA DOCOMO, Assam
- "027", // TATA DOCOMO, Bihar
- "028", // TATA DOCOMO, Chennai
- "029", // TATA DOCOMO, Delhi
- "030", // TATA DOCOMO, Gujarat
- "031", // TATA DOCOMO, Haryana
- "032", // TATA DOCOMO, Himachal Pradesh
- "033", // Reliance, Bihar
- "034", // TATA DOCOMO, Kamataka
- "035", // TATA DOCOMO, Kerala
- "036", // TATA DOCOMO, Kolkata
- "037", // TATA DOCOMO, Maharashtra
- "038", // TATA DOCOMO, Madhya Pradesh
- "039", // TATA DOCOMO, Mumbai
- "040", // Reliance, Chennai
- "041", // TATA DOCOMO, Orissa
- "042", // TATA DOCOMO, Punjab
- "043", // TATA DOCOMO, Rajasthan
- "044", // TATA DOCOMO, Tamilnadu
- "045", // TATA DOCOMO, UP (East)
- "046", // TATA DOCOMO, UP (West)
- "047", // TATA DOCOMO, West Bengal
- "750", // Vodafone IN, J&K
- "751", // Vodafone IN, Assam
- "752", // Vodafone IN, Bihar
- "753", // Vodafone IN, Orissa
- "754", // Vodafone IN, Himachal Pradesh
- "755", // Vodafone IN, North East
- "756", // Vodafone IN, Madhya Pradesh & Chhattisgarh
- "799", // Idea, MUMBAI
- "800", // Aircell, Delhi
- "801", // Aircell, Andhra Pradesh
- "802", // Aircell, Gujarat
- "803", // Aircell, Kamataka
- "804", // Aircell, Maharashtra
- "805", // Aircell, Mumbai
- "806", // Aircell, Rajasthan
- "807", // Aircell, Haryana
- "808", // Aircell, Madhya Pradesh
- "809", // Aircell, Kerala
- "810", // Aircell, Uttar Pradesh (East)
- "811", // Aircell, Uttar Pradesh (West)
- "812", // Aircell, Punjab
- "818", // Uninor, Uttar Pradesh (West)
- "819", // Uninor, Andhra Pradesh
- "820", // Uninor, Karnataka
- "821", // Uninor, Kerala
- "822", // Uninor, Kolkata
- "824", // Videocon, Assam
- "827", // Videocon, Gujarat
- "834", // Videocon, Madhya Pradesh
- "840", // Jio, West Bengal
- "844", // Uninor, Delhi & NCR
- "845", // IDEA, Assam
- "846", // IDEA, Jammu & Kashmir
- "847", // IDEA, Karnataka
- "848", // IDEA, Kolkata
- "849", // IDEA, North East
- "850", // IDEA, Orissa
- "851", // IDEA, Punjab
- "852", // IDEA, Tamil Nadu
- "853", // IDEA, West Bengal
- "854", // Jio, Andra Pradesh
- "855", // Jio, Assam
- "856", // Jio, Bihar
- "857", // Jio, Gujarat
- "858", // Jio, Haryana
- "859", // Jio, Himachal Pradesh
- "860", // Jio, Jammu Kashmir
- "861", // Jio, Karnataka
- "862", // Jio, Kerala
- "863", // Jio, Madhyya Pradesh
- "864", // Jio, Maharashtra
- "865", // Jio, North East
- "866", // Jio, Orissa
- "867", // Jio, Punjab
- "868", // Jio, Rajasthan
- "869", // Jio, Tamil Nadu Chennai
- "870", // Jio, Uttar Pradesh West
- "871", // Jio, Uttar Pradesh East
- "872", // Jio, Delhi
- "873", // Jio, Kolkatta
- "874", // Jio, Mumbai
- "875", // Uninor, Assam
- "880", // Uninor, West Bengal
- "881", // S Tel, Assam
- "908", // IDEA, Andhra Pradesh
- "909", // IDEA, Delhi
- "910", // IDEA, Haryana
- "911", // Etisalat, Maharashtra
- "912", // Etisalat, Andhra Pradesh
- "913", // Etisalat, Delhi & NCR
- "914", // Etisalat, Gujarat
- "917", // Etisalat, Kerala
- "927", // Uninor, Gujarat
- "929" // Uninor, Maharashtra
- ],
- // Malaysia.
- "502":
- ["150", // Tune Talk Sdn Bhd
- "151", // Baraka Telecom Sdn Bhd (MVNE)
- "152", // YTL Communications Sdn Bhd
- "156" // Altel Communications Sdn Bhd
- ],
- // Brazil.
- "724":
- ["055" // Sercomtel
- ]
-};
-
-/**
- * The table for MCC which the length of MNC is 3
- *
- * This table is built from below links.
- * - http://www.itu.int/pub/T-SP-E.212B-2013
- * - http://en.wikipedia.org/wiki/Mobile_Network_Code
- */
-this.MCC_TABLE_FOR_MNC_LENGTH_IS_3 = [
- "302", // Canada
- "310", // United States of America
- "311", // United States of America
- "312", // United States of America
- "313", // United States of America
- "316", // United States of America
- "330", // Puerto Rico
- "334", // Mexico
- "338", // Jamaica
- "342", // Barbados
- "344", // Antigua and Barbuda
- "346", // Cayman Islands
- "348", // British Virgin Islands
- "350", // Bermuda
- "352", // Grenada
- "354", // Montserrat
- "356", // Saint Kitts and Nevis
- "358", // Saint Lucia
- "360", // Saint Vincent and the Grenadines
- "365", // Anguilla
- "366", // Dominica
- "376", // Turks and Caicos Islands
- "708", // Honduras
- "722", // Argentina
- "732", // Colombia
- "750" // Falkland Islands (Malvinas)
-];
-
-// Supplementary service notifications, code2, as defined in 3GPP 27.007 7.17
-this.SUPP_SVC_NOTIFICATION_CODE2_PUT_ON_HOLD = 2;
-this.SUPP_SVC_NOTIFICATION_CODE2_RETRIEVED = 3;
-
-this.GECKO_SUPP_SVC_NOTIFICATION_REMOTE_HELD = "RemoteHeld";
-this.GECKO_SUPP_SVC_NOTIFICATION_REMOTE_RESUMED = "RemoteResumed";
-
-this.GECKO_SUPP_SVC_NOTIFICATION_FROM_CODE2 = {};
-GECKO_SUPP_SVC_NOTIFICATION_FROM_CODE2[SUPP_SVC_NOTIFICATION_CODE2_PUT_ON_HOLD] = GECKO_SUPP_SVC_NOTIFICATION_REMOTE_HELD;
-GECKO_SUPP_SVC_NOTIFICATION_FROM_CODE2[SUPP_SVC_NOTIFICATION_CODE2_RETRIEVED] = GECKO_SUPP_SVC_NOTIFICATION_REMOTE_RESUMED;
-
-/**
- * The status for an Over-the-Air Service Provisioning / Over-the-Air
- * Parameter Administration (OTASP/OTAPA) session.
- *
- * @see 3GPP2 C.S0016
- */
-this.GECKO_OTA_STATUS_SPL_UNLOCKED = "spl_unlocked";
-this.GECKO_OTA_STATUS_SPC_RETRIES_EXCEEDED = "spc_retries_exceeded";
-this.GECKO_OTA_STATUS_A_KEY_EXCHANGED = "a_key_exchanged";
-this.GECKO_OTA_STATUS_SSD_UPDATED = "ssd_updated";
-this.GECKO_OTA_STATUS_NAM_DOWNLOADED = "nam_downloaded";
-this.GECKO_OTA_STATUS_MDN_DOWNLOADED = "mdn_downloaded";
-this.GECKO_OTA_STATUS_IMSI_DOWNLOADED = "imsi_downloaded";
-this.GECKO_OTA_STATUS_PRL_DOWNLOADED = "prl_downloaded";
-this.GECKO_OTA_STATUS_COMMITTED = "committed";
-this.GECKO_OTA_STATUS_OTAPA_STARTED = "otapa_started";
-this.GECKO_OTA_STATUS_OTAPA_STOPPED = "otapa_stopped";
-this.GECKO_OTA_STATUS_OTAPA_ABORTED = "otapa_aborted";
-this.CDMA_OTA_PROVISION_STATUS_TO_GECKO = [
- GECKO_OTA_STATUS_SPL_UNLOCKED,
- GECKO_OTA_STATUS_SPC_RETRIES_EXCEEDED,
- GECKO_OTA_STATUS_A_KEY_EXCHANGED,
- GECKO_OTA_STATUS_SSD_UPDATED,
- GECKO_OTA_STATUS_NAM_DOWNLOADED,
- GECKO_OTA_STATUS_MDN_DOWNLOADED,
- GECKO_OTA_STATUS_IMSI_DOWNLOADED,
- GECKO_OTA_STATUS_PRL_DOWNLOADED,
- GECKO_OTA_STATUS_COMMITTED,
- GECKO_OTA_STATUS_OTAPA_STARTED,
- GECKO_OTA_STATUS_OTAPA_STOPPED,
- GECKO_OTA_STATUS_OTAPA_ABORTED
-];
-
-// Allow this file to be imported via Components.utils.import().
-this.EXPORTED_SYMBOLS = Object.keys(this);
diff --git a/dom/system/gonk/ril_worker.js b/dom/system/gonk/ril_worker.js
deleted file mode 100644
index 0608a5be39..0000000000
--- a/dom/system/gonk/ril_worker.js
+++ /dev/null
@@ -1,15206 +0,0 @@
-/* Copyright 2012 Mozilla Foundation and Mozilla contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * This file implements the RIL worker thread. It communicates with
- * the main thread to provide a high-level API to the phone's RIL
- * stack, and with the RIL IPC thread to communicate with the RIL
- * device itself. These communication channels use message events as
- * known from Web Workers:
- *
- * - postMessage()/"message" events for main thread communication
- *
- * - postRILMessage()/"RILMessageEvent" events for RIL IPC thread
- * communication.
- *
- * The two main objects in this file represent individual parts of this
- * communication chain:
- *
- * - RILMessageEvent -> Buf -> RIL -> postMessage() -> nsIRadioInterfaceLayer
- * - nsIRadioInterfaceLayer -> postMessage() -> RIL -> Buf -> postRILMessage()
- *
- * Note: The code below is purposely lean on abstractions to be as lean in
- * terms of object allocations. As a result, it may look more like C than
- * JavaScript, and that's intended.
- */
-
-/* global BufObject */
-/* global TelephonyRequestQueue */
-
-"use strict";
-
-importScripts("ril_consts.js");
-importScripts("resource://gre/modules/workers/require.js");
-importScripts("ril_worker_buf_object.js");
-importScripts("ril_worker_telephony_request_queue.js");
-
-// set to true in ril_consts.js to see debug messages
-var DEBUG = DEBUG_WORKER;
-var GLOBAL = this;
-
-if (!this.debug) {
- // Debugging stub that goes nowhere.
- this.debug = function debug(message) {
- dump("RIL Worker: " + message + "\n");
- };
-}
-
-// Timeout value for emergency callback mode.
-const EMERGENCY_CB_MODE_TIMEOUT_MS = 300000; // 5 mins = 300000 ms.
-
-const ICC_MAX_LINEAR_FIXED_RECORDS = 0xfe;
-
-const GET_CURRENT_CALLS_RETRY_MAX = 3;
-
-var RILQUIRKS_CALLSTATE_EXTRA_UINT32;
-var RILQUIRKS_REQUEST_USE_DIAL_EMERGENCY_CALL;
-var RILQUIRKS_SIM_APP_STATE_EXTRA_FIELDS;
-var RILQUIRKS_SIGNAL_EXTRA_INT32;
-var RILQUIRKS_AVAILABLE_NETWORKS_EXTRA_STRING;
-// Needed for call-waiting on Peak device
-var RILQUIRKS_EXTRA_UINT32_2ND_CALL;
-// On the emulator we support querying the number of lock retries
-var RILQUIRKS_HAVE_QUERY_ICC_LOCK_RETRY_COUNT;
-// Ril quirk to Send STK Profile Download
-var RILQUIRKS_SEND_STK_PROFILE_DOWNLOAD;
-// Ril quirk to attach data registration on demand.
-var RILQUIRKS_DATA_REGISTRATION_ON_DEMAND;
-// Ril quirk to control the uicc/data subscription.
-var RILQUIRKS_SUBSCRIPTION_CONTROL;
-// Ril quirk to describe the SMSC address format.
-var RILQUIRKS_SMSC_ADDRESS_FORMAT;
-
-/**
- * The RIL state machine.
- *
- * This object communicates with rild via parcels and with the main thread
- * via post messages. It maintains state about the radio, ICC, calls, etc.
- * and acts upon state changes accordingly.
- */
-function RilObject(aContext) {
- this.context = aContext;
-
- this.telephonyRequestQueue = new TelephonyRequestQueue(this);
- this.currentConferenceState = CALL_STATE_UNKNOWN;
- this._pendingSentSmsMap = {};
- this.pendingNetworkType = {};
- this._receivedSmsCbPagesMap = {};
- this._getCurrentCallsRetryCount = 0;
-}
-RilObject.prototype = {
- context: null,
-
- /**
- * RIL version.
- */
- version: null,
-
- /**
- * Call state of current conference group.
- */
- currentConferenceState: null,
-
- /**
- * Outgoing messages waiting for SMS-STATUS-REPORT.
- */
- _pendingSentSmsMap: null,
-
- /**
- * Marker object.
- */
- pendingNetworkType: null,
-
- /**
- * Global Cell Broadcast switch.
- */
- cellBroadcastDisabled: false,
-
- /**
- * Parsed Cell Broadcast search lists.
- * cellBroadcastConfigs.MMI should be preserved over rild reset.
- */
- cellBroadcastConfigs: null,
- mergedCellBroadcastConfig: null,
-
- _receivedSmsCbPagesMap: null,
-
- initRILState: function() {
- /**
- * One of the RADIO_STATE_* constants.
- */
- this.radioState = GECKO_RADIOSTATE_UNKNOWN;
-
- /**
- * True if we are on a CDMA phone.
- */
- this._isCdma = false;
-
- /**
- * True if we are in emergency callback mode.
- */
- this._isInEmergencyCbMode = false;
-
- /**
- * Set when radio is ready but radio tech is unknown. That is, we are
- * waiting for REQUEST_VOICE_RADIO_TECH
- */
- this._waitingRadioTech = false;
-
- /**
- * Card state
- */
- this.cardState = GECKO_CARDSTATE_UNINITIALIZED;
-
- /**
- * Device Identities including IMEI, IMEISV, ESN and MEID.
- */
- this.deviceIdentities = null;
-
- /**
- * ICC information that is not exposed to Gaia.
- */
- this.iccInfoPrivate = {};
-
- /**
- * ICC information, such as MSISDN, MCC, MNC, SPN...etc.
- */
- this.iccInfo = {};
-
- /**
- * CDMA specific information. ex. CDMA Network ID, CDMA System ID... etc.
- */
- this.cdmaHome = null;
-
- /**
- * Application identification for apps in ICC.
- */
- this.aid = null;
-
- /**
- * Application type for apps in ICC.
- */
- this.appType = null;
-
- this.networkSelectionMode = GECKO_NETWORK_SELECTION_UNKNOWN;
-
- this.voiceRegistrationState = {};
- this.dataRegistrationState = {};
-
- /**
- * List of strings identifying the network operator.
- */
- this.operator = null;
-
- /**
- * String containing the baseband version.
- */
- this.basebandVersion = null;
-
- // Clean up currentCalls: rild might have restarted.
- this.sendChromeMessage({
- rilMessageType: "currentCalls",
- calls: {}
- });
-
- // Don't clean up this._pendingSentSmsMap
- // because on rild restart: we may continue with the pending segments.
-
- /**
- * Whether or not the multiple requests in requestNetworkInfo() are currently
- * being processed
- */
- this._processingNetworkInfo = false;
-
- /**
- * Multiple requestNetworkInfo() in a row before finishing the first
- * request, hence we need to fire requestNetworkInfo() again after
- * gathering all necessary stuffs. This is to make sure that ril_worker
- * gets precise network information.
- */
- this._needRepollNetworkInfo = false;
-
- /**
- * Pending messages to be send in batch from requestNetworkInfo()
- */
- this._pendingNetworkInfo = {rilMessageType: "networkinfochanged"};
-
- /**
- * Cell Broadcast Search Lists.
- */
- let cbmmi = this.cellBroadcastConfigs && this.cellBroadcastConfigs.MMI;
- this.cellBroadcastConfigs = {
- MMI: cbmmi || null
- };
- this.mergedCellBroadcastConfig = null;
-
- /**
- * True when the request to report SMS Memory Status is pending.
- */
- this.pendingToReportSmsMemoryStatus = false;
- this.smsStorageAvailable = true;
- },
-
- /**
- * Parse an integer from a string, falling back to a default value
- * if the the provided value is not a string or does not contain a valid
- * number.
- *
- * @param string
- * String to be parsed.
- * @param defaultValue [optional]
- * Default value to be used.
- * @param radix [optional]
- * A number that represents the numeral system to be used. Default 10.
- */
- parseInt: function(string, defaultValue, radix) {
- let number = parseInt(string, radix || 10);
- if (!isNaN(number)) {
- return number;
- }
- if (defaultValue === undefined) {
- defaultValue = null;
- }
- return defaultValue;
- },
-
-
- /**
- * Outgoing requests to the RIL. These can be triggered from the
- * main thread via messages that look like this:
- *
- * {rilMessageType: "methodName",
- * extra: "parameters",
- * go: "here"}
- *
- * So if one of the following methods takes arguments, it takes only one,
- * an object, which then contains all of the parameters as attributes.
- * The "@param" documentation is to be interpreted accordingly.
- */
-
- /**
- * Retrieve the ICC's status.
- */
- getICCStatus: function() {
- this.context.Buf.simpleRequest(REQUEST_GET_SIM_STATUS);
- },
-
- /**
- * Helper function for unlocking ICC locks.
- */
- iccUnlockCardLock: function(options) {
- switch (options.lockType) {
- case GECKO_CARDLOCK_PIN:
- this.enterICCPIN(options);
- break;
- case GECKO_CARDLOCK_PIN2:
- this.enterICCPIN2(options);
- break;
- case GECKO_CARDLOCK_PUK:
- this.enterICCPUK(options);
- break;
- case GECKO_CARDLOCK_PUK2:
- this.enterICCPUK2(options);
- break;
- case GECKO_CARDLOCK_NCK:
- case GECKO_CARDLOCK_NSCK:
- case GECKO_CARDLOCK_NCK1:
- case GECKO_CARDLOCK_NCK2:
- case GECKO_CARDLOCK_HNCK:
- case GECKO_CARDLOCK_CCK:
- case GECKO_CARDLOCK_SPCK:
- case GECKO_CARDLOCK_PCK:
- case GECKO_CARDLOCK_RCCK:
- case GECKO_CARDLOCK_RSPCK:
- case GECKO_CARDLOCK_NCK_PUK:
- case GECKO_CARDLOCK_NSCK_PUK:
- case GECKO_CARDLOCK_NCK1_PUK:
- case GECKO_CARDLOCK_NCK2_PUK:
- case GECKO_CARDLOCK_HNCK_PUK:
- case GECKO_CARDLOCK_CCK_PUK:
- case GECKO_CARDLOCK_SPCK_PUK:
- case GECKO_CARDLOCK_PCK_PUK:
- case GECKO_CARDLOCK_RCCK_PUK: // Fall through.
- case GECKO_CARDLOCK_RSPCK_PUK:
- this.enterDepersonalization(options);
- break;
- default:
- options.errorMsg = GECKO_ERROR_REQUEST_NOT_SUPPORTED;
- this.sendChromeMessage(options);
- }
- },
-
- /**
- * Enter a PIN to unlock the ICC.
- *
- * @param password
- * String containing the PIN.
- * @param [optional] aid
- * AID value.
- */
- enterICCPIN: function(options) {
- let Buf = this.context.Buf;
- Buf.newParcel(REQUEST_ENTER_SIM_PIN, options);
- Buf.writeInt32(2);
- Buf.writeString(options.password);
- Buf.writeString(options.aid || this.aid);
- Buf.sendParcel();
- },
-
- /**
- * Enter a PIN2 to unlock the ICC.
- *
- * @param password
- * String containing the PIN2.
- * @param [optional] aid
- * AID value.
- */
- enterICCPIN2: function(options) {
- let Buf = this.context.Buf;
- Buf.newParcel(REQUEST_ENTER_SIM_PIN2, options);
- Buf.writeInt32(2);
- Buf.writeString(options.password);
- Buf.writeString(options.aid || this.aid);
- Buf.sendParcel();
- },
-
- /**
- * Requests a network personalization be deactivated.
- *
- * @param personlization
- * One of CARD_PERSOSUBSTATE_*
- * @param password
- * String containing the password.
- */
- enterDepersonalization: function(options) {
- let Buf = this.context.Buf;
- Buf.newParcel(REQUEST_ENTER_NETWORK_DEPERSONALIZATION_CODE, options);
- Buf.writeInt32(1);
- Buf.writeString(options.password);
- Buf.sendParcel();
- },
-
- /**
- * Change the current ICC PIN number.
- *
- * @param password
- * String containing the old PIN value
- * @param newPassword
- * String containing the new PIN value
- * @param [optional] aid
- * AID value.
- */
- changeICCPIN: function(options) {
- let Buf = this.context.Buf;
- Buf.newParcel(REQUEST_CHANGE_SIM_PIN, options);
- Buf.writeInt32(3);
- Buf.writeString(options.password);
- Buf.writeString(options.newPassword);
- Buf.writeString(options.aid || this.aid);
- Buf.sendParcel();
- },
-
- /**
- * Change the current ICC PIN2 number.
- *
- * @param password
- * String containing the old PIN2 value
- * @param newPassword
- * String containing the new PIN2 value
- * @param [optional] aid
- * AID value.
- */
- changeICCPIN2: function(options) {
- let Buf = this.context.Buf;
- Buf.newParcel(REQUEST_CHANGE_SIM_PIN2, options);
- Buf.writeInt32(3);
- Buf.writeString(options.password);
- Buf.writeString(options.newPassword);
- Buf.writeString(options.aid || this.aid);
- Buf.sendParcel();
- },
-
- /**
- * Supplies ICC PUK and a new PIN to unlock the ICC.
- *
- * @param password
- * String containing the PUK value.
- * @param newPassword
- * String containing the new PIN value.
- * @param [optional] aid
- * AID value.
- */
- enterICCPUK: function(options) {
- let Buf = this.context.Buf;
- Buf.newParcel(REQUEST_ENTER_SIM_PUK, options);
- Buf.writeInt32(3);
- Buf.writeString(options.password);
- Buf.writeString(options.newPin);
- Buf.writeString(options.aid || this.aid);
- Buf.sendParcel();
- },
-
- /**
- * Supplies ICC PUK2 and a new PIN2 to unlock the ICC.
- *
- * @param password
- * String containing the PUK2 value.
- * @param newPassword
- * String containing the new PIN2 value.
- * @param [optional] aid
- * AID value.
- */
- enterICCPUK2: function(options) {
- let Buf = this.context.Buf;
- Buf.newParcel(REQUEST_ENTER_SIM_PUK2, options);
- Buf.writeInt32(3);
- Buf.writeString(options.password);
- Buf.writeString(options.newPin);
- Buf.writeString(options.aid || this.aid);
- Buf.sendParcel();
- },
-
- /**
- * Helper function for changing ICC locks.
- */
- iccChangeCardLockPassword: function(options) {
- switch (options.lockType) {
- case GECKO_CARDLOCK_PIN:
- this.changeICCPIN(options);
- break;
- case GECKO_CARDLOCK_PIN2:
- this.changeICCPIN2(options);
- break;
- default:
- options.errorMsg = GECKO_ERROR_REQUEST_NOT_SUPPORTED;
- this.sendChromeMessage(options);
- }
- },
-
- /**
- * Helper function for setting the state of ICC locks.
- */
- iccSetCardLockEnabled: function(options) {
- switch (options.lockType) {
- case GECKO_CARDLOCK_PIN: // Fall through.
- case GECKO_CARDLOCK_FDN:
- options.facility = GECKO_CARDLOCK_TO_FACILITY[options.lockType];
- break;
- default:
- options.errorMsg = GECKO_ERROR_REQUEST_NOT_SUPPORTED;
- this.sendChromeMessage(options);
- return;
- }
-
- options.serviceClass = ICC_SERVICE_CLASS_VOICE |
- ICC_SERVICE_CLASS_DATA |
- ICC_SERVICE_CLASS_FAX;
- this.setICCFacilityLock(options);
- },
-
- /**
- * Helper function for fetching the state of ICC locks.
- */
- iccGetCardLockEnabled: function(options) {
- switch (options.lockType) {
- case GECKO_CARDLOCK_PIN: // Fall through.
- case GECKO_CARDLOCK_FDN:
- options.facility = GECKO_CARDLOCK_TO_FACILITY[options.lockType];
- break;
- default:
- options.errorMsg = GECKO_ERROR_REQUEST_NOT_SUPPORTED;
- this.sendChromeMessage(options);
- return;
- }
-
- options.password = ""; // For query no need to provide pin.
- options.serviceClass = ICC_SERVICE_CLASS_VOICE |
- ICC_SERVICE_CLASS_DATA |
- ICC_SERVICE_CLASS_FAX;
- this.queryICCFacilityLock(options);
- },
-
- /**
- * Helper function for fetching the number of unlock retries of ICC locks.
- *
- * We only query the retry count when we're on the emulator. The phones do
- * not support the request id and their rild doesn't return an error.
- */
- iccGetCardLockRetryCount: function(options) {
- if (!RILQUIRKS_HAVE_QUERY_ICC_LOCK_RETRY_COUNT) {
- // Only the emulator supports this request.
- options.errorMsg = GECKO_ERROR_REQUEST_NOT_SUPPORTED;
- this.sendChromeMessage(options);
- return;
- }
-
- switch (options.lockType) {
- case GECKO_CARDLOCK_PIN:
- case GECKO_CARDLOCK_PIN2:
- case GECKO_CARDLOCK_PUK:
- case GECKO_CARDLOCK_PUK2:
- case GECKO_CARDLOCK_NCK:
- case GECKO_CARDLOCK_NSCK:
- case GECKO_CARDLOCK_CCK: // Fall through.
- case GECKO_CARDLOCK_SPCK:
- // TODO: Bug 1116072: identify the mapping between RIL_PERSOSUBSTATE_SIM_SIM
- // @ ril.h and TS 27.007, clause 8.65 for GECKO_CARDLOCK_SPCK.
- options.selCode = GECKO_CARDLOCK_TO_SEL_CODE[options.lockType];
- break;
- default:
- options.errorMsg = GECKO_ERROR_REQUEST_NOT_SUPPORTED;
- this.sendChromeMessage(options);
- return;
- }
-
- this.queryICCLockRetryCount(options);
- },
-
- /**
- * Query ICC lock retry count.
- *
- * @param selCode
- * One of ICC_SEL_CODE_*.
- * @param serviceClass
- * One of ICC_SERVICE_CLASS_*.
- */
- queryICCLockRetryCount: function(options) {
- let Buf = this.context.Buf;
- Buf.newParcel(REQUEST_GET_UNLOCK_RETRY_COUNT, options);
- Buf.writeInt32(1);
- Buf.writeString(options.selCode);
- Buf.sendParcel();
- },
-
- /**
- * Query ICC facility lock.
- *
- * @param facility
- * One of ICC_CB_FACILITY_*.
- * @param password
- * Password for the facility, or "" if not required.
- * @param serviceClass
- * One of ICC_SERVICE_CLASS_*.
- * @param [optional] aid
- * AID value.
- */
- queryICCFacilityLock: function(options) {
- let Buf = this.context.Buf;
- Buf.newParcel(REQUEST_QUERY_FACILITY_LOCK, options);
- Buf.writeInt32(4);
- Buf.writeString(options.facility);
- Buf.writeString(options.password);
- Buf.writeString(options.serviceClass.toString());
- Buf.writeString(options.aid || this.aid);
- Buf.sendParcel();
- },
-
- /**
- * Set ICC facility lock.
- *
- * @param facility
- * One of ICC_CB_FACILITY_*.
- * @param enabled
- * true to enable, false to disable.
- * @param password
- * Password for the facility, or "" if not required.
- * @param serviceClass
- * One of ICC_SERVICE_CLASS_*.
- * @param [optional] aid
- * AID value.
- */
- setICCFacilityLock: function(options) {
- let Buf = this.context.Buf;
- Buf.newParcel(REQUEST_SET_FACILITY_LOCK, options);
- Buf.writeInt32(5);
- Buf.writeString(options.facility);
- Buf.writeString(options.enabled ? "1" : "0");
- Buf.writeString(options.password);
- Buf.writeString(options.serviceClass.toString());
- Buf.writeString(options.aid || this.aid);
- Buf.sendParcel();
- },
-
- /**
- * Request an ICC I/O operation.
- *
- * See TS 27.007 "restricted SIM" operation, "AT Command +CRSM".
- * The sequence is in the same order as how libril reads this parcel,
- * see the struct RIL_SIM_IO_v5 or RIL_SIM_IO_v6 defined in ril.h
- *
- * @param command
- * The I/O command, one of the ICC_COMMAND_* constants.
- * @param fileId
- * The file to operate on, one of the ICC_EF_* constants.
- * @param pathId
- * String type, check the 'pathid' parameter from TS 27.007 +CRSM.
- * @param p1, p2, p3
- * Arbitrary integer parameters for the command.
- * @param [optional] dataWriter
- * The function for writing string parameter for the ICC_COMMAND_UPDATE_RECORD.
- * @param [optional] pin2
- * String containing the PIN2.
- * @param [optional] aid
- * AID value.
- */
- iccIO: function(options) {
- let Buf = this.context.Buf;
- Buf.newParcel(REQUEST_SIM_IO, options);
- Buf.writeInt32(options.command);
- Buf.writeInt32(options.fileId);
- Buf.writeString(options.pathId);
- Buf.writeInt32(options.p1);
- Buf.writeInt32(options.p2);
- Buf.writeInt32(options.p3);
-
- // Write data.
- if (options.command == ICC_COMMAND_UPDATE_RECORD &&
- options.dataWriter) {
- options.dataWriter(options.p3);
- } else {
- Buf.writeString(null);
- }
-
- // Write pin2.
- if (options.command == ICC_COMMAND_UPDATE_RECORD &&
- options.pin2) {
- Buf.writeString(options.pin2);
- } else {
- Buf.writeString(null);
- }
-
- Buf.writeString(options.aid || this.aid);
- Buf.sendParcel();
- },
-
- /**
- * Get IMSI.
- *
- * @param [optional] aid
- * AID value.
- */
- getIMSI: function(aid) {
- let Buf = this.context.Buf;
- Buf.newParcel(REQUEST_GET_IMSI);
- Buf.writeInt32(1);
- Buf.writeString(aid || this.aid);
- Buf.sendParcel();
- },
-
- /**
- * Retrieve ICC's GID1 field.
- */
- getGID1: function(options) {
- options.gid1 = this.iccInfoPrivate.gid1;
- this.sendChromeMessage(options);
- },
-
- /**
- * Read UICC Phonebook contacts.
- *
- * @param contactType
- * One of GECKO_CARDCONTACT_TYPE_*.
- * @param requestId
- * Request id from RadioInterfaceLayer.
- */
- readICCContacts: function(options) {
- if (!this.appType) {
- options.errorMsg = CONTACT_ERR_REQUEST_NOT_SUPPORTED;
- this.sendChromeMessage(options);
- return;
- }
-
- this.context.ICCContactHelper.readICCContacts(
- this.appType,
- options.contactType,
- function onsuccess(contacts) {
- for (let i = 0; i < contacts.length; i++) {
- let contact = contacts[i];
- let pbrIndex = contact.pbrIndex || 0;
- let recordIndex = pbrIndex * ICC_MAX_LINEAR_FIXED_RECORDS + contact.recordId;
- contact.contactId = this.iccInfo.iccid + recordIndex;
- }
- // Reuse 'options' to get 'requestId' and 'contactType'.
- options.contacts = contacts;
- this.sendChromeMessage(options);
- }.bind(this),
- function onerror(errorMsg) {
- options.errorMsg = errorMsg;
- this.sendChromeMessage(options);
- }.bind(this));
- },
-
- /**
- * Update UICC Phonebook.
- *
- * @param contactType One of GECKO_CARDCONTACT_TYPE_*.
- * @param contact The contact will be updated.
- * @param pin2 PIN2 is required for updating FDN.
- * @param requestId Request id from RadioInterfaceLayer.
- */
- updateICCContact: function(options) {
- let onsuccess = function onsuccess(updatedContact) {
- let recordIndex =
- updatedContact.pbrIndex * ICC_MAX_LINEAR_FIXED_RECORDS + updatedContact.recordId;
- updatedContact.contactId = this.iccInfo.iccid + recordIndex;
- options.contact = updatedContact;
- // Reuse 'options' to get 'requestId' and 'contactType'.
- this.sendChromeMessage(options);
- }.bind(this);
-
- let onerror = function onerror(errorMsg) {
- options.errorMsg = errorMsg;
- this.sendChromeMessage(options);
- }.bind(this);
-
- if (!this.appType || !options.contact) {
- onerror(CONTACT_ERR_REQUEST_NOT_SUPPORTED );
- return;
- }
-
- let contact = options.contact;
- let iccid = this.iccInfo.iccid;
- let isValidRecordId = false;
- if (typeof contact.contactId === "string" &&
- contact.contactId.startsWith(iccid)) {
- let recordIndex = contact.contactId.substring(iccid.length);
- contact.pbrIndex = Math.floor(recordIndex / ICC_MAX_LINEAR_FIXED_RECORDS);
- contact.recordId = recordIndex % ICC_MAX_LINEAR_FIXED_RECORDS;
- isValidRecordId = contact.recordId > 0 && contact.recordId < 0xff;
- }
-
- if (DEBUG) {
- this.context.debug("Update ICC Contact " + JSON.stringify(contact));
- }
-
- let ICCContactHelper = this.context.ICCContactHelper;
- // If contact has 'recordId' property, updates corresponding record.
- // If not, inserts the contact into a free record.
- if (isValidRecordId) {
- ICCContactHelper.updateICCContact(
- this.appType, options.contactType, contact, options.pin2, onsuccess, onerror);
- } else {
- ICCContactHelper.addICCContact(
- this.appType, options.contactType, contact, options.pin2, onsuccess, onerror);
- }
- },
-
- /**
- * Check if operator name needs to be overriden by current voiceRegistrationState
- * , EFOPL and EFPNN. See 3GPP TS 31.102 clause 4.2.58 EFPNN and 4.2.59 EFOPL
- * for detail.
- *
- * @return true if operator name is overridden, false otherwise.
- */
- overrideICCNetworkName: function() {
- if (!this.operator) {
- return false;
- }
-
- // We won't get network name using PNN and OPL if voice registration isn't
- // ready.
- if (!this.voiceRegistrationState.cell ||
- this.voiceRegistrationState.cell.gsmLocationAreaCode == -1) {
- return false;
- }
-
- let ICCUtilsHelper = this.context.ICCUtilsHelper;
- let networkName = ICCUtilsHelper.getNetworkNameFromICC(
- this.operator.mcc,
- this.operator.mnc,
- this.voiceRegistrationState.cell.gsmLocationAreaCode);
-
- if (!networkName) {
- return false;
- }
-
- if (DEBUG) {
- this.context.debug("Operator names will be overriden: " +
- "longName = " + networkName.fullName + ", " +
- "shortName = " + networkName.shortName);
- }
-
- this.operator.longName = networkName.fullName;
- this.operator.shortName = networkName.shortName;
-
- this._sendNetworkInfoMessage(NETWORK_INFO_OPERATOR, this.operator);
- return true;
- },
-
- /**
- * Request the phone's radio to be enabled or disabled.
- *
- * @param enabled
- * Boolean indicating the desired state.
- */
- setRadioEnabled: function(options) {
- let Buf = this.context.Buf;
- Buf.newParcel(REQUEST_RADIO_POWER, options);
- Buf.writeInt32(1);
- Buf.writeInt32(options.enabled ? 1 : 0);
- Buf.sendParcel();
- },
-
- /**
- * Query call waiting status.
- *
- */
- queryCallWaiting: function(options) {
- let Buf = this.context.Buf;
- Buf.newParcel(REQUEST_QUERY_CALL_WAITING, options);
- Buf.writeInt32(1);
- // As per 3GPP TS 24.083, section 1.6 UE doesn't need to send service
- // class parameter in call waiting interrogation to network.
- Buf.writeInt32(ICC_SERVICE_CLASS_NONE);
- Buf.sendParcel();
- },
-
- /**
- * Set call waiting status.
- *
- * @param enabled
- * Boolean indicating the desired waiting status.
- * @param serviceClass
- * One of ICC_SERVICE_CLASS_* constants.
- */
- setCallWaiting: function(options) {
- let Buf = this.context.Buf;
- Buf.newParcel(REQUEST_SET_CALL_WAITING, options);
- Buf.writeInt32(2);
- Buf.writeInt32(options.enabled ? 1 : 0);
- Buf.writeInt32(options.serviceClass);
- Buf.sendParcel();
- },
-
- /**
- * Queries current CLIP status.
- */
- queryCLIP: function(options) {
- this.context.Buf.simpleRequest(REQUEST_QUERY_CLIP, options);
- },
-
- /**
- * Queries current CLIR status.
- *
- */
- getCLIR: function(options) {
- this.context.Buf.simpleRequest(REQUEST_GET_CLIR, options);
- },
-
- /**
- * Enables or disables the presentation of the calling line identity (CLI) to
- * the called party when originating a call.
- *
- * @param options.clirMode
- * One of the CLIR_* constants.
- */
- setCLIR: function(options) {
- let Buf = this.context.Buf;
- Buf.newParcel(REQUEST_SET_CLIR, options);
- Buf.writeInt32(1);
- Buf.writeInt32(options.clirMode);
- Buf.sendParcel();
- },
-
- /**
- * Set screen state.
- *
- * @param on
- * Boolean indicating whether the screen should be on or off.
- */
- setScreenState: function(options) {
- let Buf = this.context.Buf;
- Buf.newParcel(REQUEST_SCREEN_STATE);
- Buf.writeInt32(1);
- Buf.writeInt32(options.on ? 1 : 0);
- Buf.sendParcel();
- },
-
- getVoiceRegistrationState: function() {
- this.context.Buf.simpleRequest(REQUEST_VOICE_REGISTRATION_STATE);
- },
-
- getVoiceRadioTechnology: function() {
- this.context.Buf.simpleRequest(REQUEST_VOICE_RADIO_TECH);
- },
-
- getDataRegistrationState: function() {
- this.context.Buf.simpleRequest(REQUEST_DATA_REGISTRATION_STATE);
- },
-
- getOperator: function() {
- this.context.Buf.simpleRequest(REQUEST_OPERATOR);
- },
-
- /**
- * Set the preferred network type.
- *
- * @param options An object contains a valid value of
- * RIL_PREFERRED_NETWORK_TYPE_TO_GECKO as its `type` attribute.
- */
- setPreferredNetworkType: function(options) {
- let networkType = options.type;
- if (networkType < 0 || networkType >= RIL_PREFERRED_NETWORK_TYPE_TO_GECKO.length) {
- options.errorMsg = GECKO_ERROR_INVALID_PARAMETER;
- this.sendChromeMessage(options);
- return;
- }
-
- let Buf = this.context.Buf;
- Buf.newParcel(REQUEST_SET_PREFERRED_NETWORK_TYPE, options);
- Buf.writeInt32(1);
- Buf.writeInt32(networkType);
- Buf.sendParcel();
- },
-
- /**
- * Get the preferred network type.
- */
- getPreferredNetworkType: function(options) {
- this.context.Buf.simpleRequest(REQUEST_GET_PREFERRED_NETWORK_TYPE, options);
- },
-
- /**
- * Request neighboring cell ids in GSM network.
- */
- getNeighboringCellIds: function(options) {
- this.context.Buf.simpleRequest(REQUEST_GET_NEIGHBORING_CELL_IDS, options);
- },
-
- /**
- * Request all of the current cell information known to the radio.
- */
- getCellInfoList: function(options) {
- this.context.Buf.simpleRequest(REQUEST_GET_CELL_INFO_LIST, options);
- },
-
- /**
- * Request various states about the network.
- */
- requestNetworkInfo: function() {
- if (this._processingNetworkInfo) {
- if (DEBUG) {
- this.context.debug("Network info requested, but we're already " +
- "requesting network info.");
- }
- this._needRepollNetworkInfo = true;
- return;
- }
-
- if (DEBUG) this.context.debug("Requesting network info");
-
- this._processingNetworkInfo = true;
- this.getVoiceRegistrationState();
- this.getDataRegistrationState(); //TODO only GSM
- this.getOperator();
- this.getNetworkSelectionMode();
- this.getSignalStrength();
- },
-
- /**
- * Get the available networks
- */
- getAvailableNetworks: function(options) {
- if (DEBUG) this.context.debug("Getting available networks");
- let Buf = this.context.Buf;
- Buf.newParcel(REQUEST_QUERY_AVAILABLE_NETWORKS, options);
- Buf.sendParcel();
- },
-
- /**
- * Request the radio's network selection mode
- */
- getNetworkSelectionMode: function() {
- if (DEBUG) this.context.debug("Getting network selection mode");
- this.context.Buf.simpleRequest(REQUEST_QUERY_NETWORK_SELECTION_MODE);
- },
-
- /**
- * Tell the radio to automatically choose a voice/data network
- */
- selectNetworkAuto: function(options) {
- if (DEBUG) this.context.debug("Setting automatic network selection");
- this.context.Buf.simpleRequest(REQUEST_SET_NETWORK_SELECTION_AUTOMATIC, options);
- },
-
- /**
- * Set the roaming preference mode
- */
- setRoamingPreference: function(options) {
- let Buf = this.context.Buf;
- Buf.newParcel(REQUEST_CDMA_SET_ROAMING_PREFERENCE, options);
- Buf.writeInt32(1);
- Buf.writeInt32(options.mode);
- Buf.sendParcel();
- },
-
- /**
- * Get the roaming preference mode
- */
- queryRoamingPreference: function(options) {
- this.context.Buf.simpleRequest(REQUEST_CDMA_QUERY_ROAMING_PREFERENCE, options);
- },
-
- /**
- * Set the voice privacy mode
- */
- setVoicePrivacyMode: function(options) {
- let Buf = this.context.Buf;
- Buf.newParcel(REQUEST_CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE, options);
- Buf.writeInt32(1);
- Buf.writeInt32(options.enabled ? 1 : 0);
- Buf.sendParcel();
- },
-
- /**
- * Get the voice privacy mode
- */
- queryVoicePrivacyMode: function(options) {
- this.context.Buf.simpleRequest(REQUEST_CDMA_QUERY_PREFERRED_VOICE_PRIVACY_MODE, options);
- },
-
- /**
- * Open Logical UICC channel (aid) for Secure Element access
- */
- iccOpenChannel: function(options) {
- let Buf = this.context.Buf;
- Buf.newParcel(REQUEST_SIM_OPEN_CHANNEL, options);
- Buf.writeString(options.aid);
- Buf.sendParcel();
- },
-
- /**
- * Exchange APDU data on an open Logical UICC channel
- */
- iccExchangeAPDU: function(options) {
- let Buf = this.context.Buf;
- Buf.newParcel(REQUEST_SIM_TRANSMIT_APDU_CHANNEL, options);
- Buf.writeInt32(options.channel);
- Buf.writeInt32(options.apdu.cla);
- Buf.writeInt32(options.apdu.command);
- Buf.writeInt32(options.apdu.p1);
- Buf.writeInt32(options.apdu.p2);
- Buf.writeInt32(options.apdu.p3);
- Buf.writeString(options.apdu.data);
- Buf.sendParcel();
- },
-
- /**
- * Close Logical UICC channel
- */
- iccCloseChannel: function(options) {
- let Buf = this.context.Buf;
- Buf.newParcel(REQUEST_SIM_CLOSE_CHANNEL, options);
- Buf.writeInt32(1);
- Buf.writeInt32(options.channel);
- Buf.sendParcel();
- },
-
- /**
- * Get UICC service state
- */
- getIccServiceState: function(options) {
- switch (options.service) {
- case GECKO_CARDSERVICE_FDN:
- let ICCUtilsHelper = this.context.ICCUtilsHelper;
- options.result = ICCUtilsHelper.isICCServiceAvailable("FDN");
- break;
- default:
- options.errorMsg = GECKO_ERROR_REQUEST_NOT_SUPPORTED;
- break;
- }
- this.sendChromeMessage(options);
- },
-
- /**
- * Enable/Disable UICC subscription
- */
- setUiccSubscription: function(options) {
- if (DEBUG) {
- this.context.debug("setUiccSubscription: " + JSON.stringify(options));
- }
-
- let Buf = this.context.Buf;
- Buf.newParcel(REQUEST_SET_UICC_SUBSCRIPTION, options);
- Buf.writeInt32(this.context.clientId);
- Buf.writeInt32(options.appIndex);
- Buf.writeInt32(this.context.clientId);
- Buf.writeInt32(options.enabled ? 1 : 0);
- Buf.sendParcel();
- },
-
- /**
- * Tell the radio to choose a specific voice/data network
- */
- selectNetwork: function(options) {
- if (DEBUG) {
- this.context.debug("Setting manual network selection: " +
- options.mcc + ", " + options.mnc);
- }
-
- let numeric = (options.mcc && options.mnc) ? options.mcc + options.mnc : null;
- let Buf = this.context.Buf;
- Buf.newParcel(REQUEST_SET_NETWORK_SELECTION_MANUAL, options);
- Buf.writeString(numeric);
- Buf.sendParcel();
- },
-
- /**
- * Get the signal strength.
- */
- getSignalStrength: function() {
- this.context.Buf.simpleRequest(REQUEST_SIGNAL_STRENGTH);
- },
-
- getDeviceIdentity: function() {
- this.deviceIdentities || this.context.Buf.simpleRequest(REQUEST_DEVICE_IDENTITY);
- },
-
- getBasebandVersion: function() {
- this.context.Buf.simpleRequest(REQUEST_BASEBAND_VERSION);
- },
-
- sendExitEmergencyCbModeRequest: function(options) {
- this.context.Buf.simpleRequest(REQUEST_EXIT_EMERGENCY_CALLBACK_MODE, options);
- },
-
- getCdmaSubscription: function() {
- this.context.Buf.simpleRequest(REQUEST_CDMA_SUBSCRIPTION);
- },
-
- exitEmergencyCbMode: function(options) {
- // The function could be called by an API from RadioInterfaceLayer or by
- // ril_worker itself. From ril_worker, we won't pass the parameter
- // 'options'. In this case, it is marked as internal.
- if (!options) {
- options = {internal: true};
- }
- this._cancelEmergencyCbModeTimeout();
- this.sendExitEmergencyCbModeRequest(options);
- },
-
- /**
- * Dial a non-emergency number.
- *
- * @param isEmergency
- * Whether the number is an emergency number.
- * @param number
- * String containing the number to dial.
- * @param clirMode
- * Integer for showing/hidding the caller Id to the called party.
- * @param uusInfo
- * Integer doing something XXX TODO
- */
- dial: function(options) {
- if (options.isEmergency) {
- options.request = RILQUIRKS_REQUEST_USE_DIAL_EMERGENCY_CALL ?
- REQUEST_DIAL_EMERGENCY_CALL : REQUEST_DIAL;
-
- } else {
- options.request = REQUEST_DIAL;
-
- // Exit emergency callback mode when user dial a non-emergency call.
- if (this._isInEmergencyCbMode) {
- this.exitEmergencyCbMode();
- }
- }
-
- this.telephonyRequestQueue.push(options.request, () => {
- let Buf = this.context.Buf;
- Buf.newParcel(options.request, options);
- Buf.writeString(options.number);
- Buf.writeInt32(options.clirMode || 0);
- Buf.writeInt32(options.uusInfo || 0);
- // TODO Why do we need this extra 0? It was put it in to make this
- // match the format of the binary message.
- Buf.writeInt32(0);
- Buf.sendParcel();
- });
- },
-
- /**
- * CDMA flash.
- *
- * @param featureStr (optional)
- * Dialing number when the command is used for three-way-calling
- */
- cdmaFlash: function(options) {
- let Buf = this.context.Buf;
- options.request = REQUEST_CDMA_FLASH;
- Buf.newParcel(options.request, options);
- Buf.writeString(options.featureStr || "");
- Buf.sendParcel();
- },
-
- /**
- * Hang up the phone.
- *
- * @param callIndex
- * Call index (1-based) as reported by REQUEST_GET_CURRENT_CALLS.
- */
- hangUpCall: function(options) {
- this.telephonyRequestQueue.push(REQUEST_HANGUP, () => {
- let Buf = this.context.Buf;
- Buf.newParcel(REQUEST_HANGUP, options);
- Buf.writeInt32(1);
- Buf.writeInt32(options.callIndex);
- Buf.sendParcel();
- });
- },
-
- hangUpForeground: function(options) {
- this.telephonyRequestQueue.push(REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND, () => {
- this.context.Buf.simpleRequest(REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND,
- options);
- });
- },
-
- hangUpBackground: function(options) {
- this.telephonyRequestQueue.push(REQUEST_HANGUP_WAITING_OR_BACKGROUND, () => {
- this.context.Buf.simpleRequest(REQUEST_HANGUP_WAITING_OR_BACKGROUND,
- options);
- });
- },
-
- switchActiveCall: function(options) {
- this.telephonyRequestQueue.push(REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE, () => {
- this.context.Buf.simpleRequest(REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE,
- options);
- });
- },
-
- udub: function(options) {
- this.telephonyRequestQueue.push(REQUEST_UDUB, () => {
- this.context.Buf.simpleRequest(REQUEST_UDUB, options);
- });
- },
-
- answerCall: function(options) {
- this.telephonyRequestQueue.push(REQUEST_ANSWER, () => {
- this.context.Buf.simpleRequest(REQUEST_ANSWER, options);
- });
- },
-
- conferenceCall: function(options) {
- this.telephonyRequestQueue.push(REQUEST_CONFERENCE, () => {
- this.context.Buf.simpleRequest(REQUEST_CONFERENCE, options);
- });
- },
-
- separateCall: function(options) {
- this.telephonyRequestQueue.push(REQUEST_SEPARATE_CONNECTION, () => {
- let Buf = this.context.Buf;
- Buf.newParcel(REQUEST_SEPARATE_CONNECTION, options);
- Buf.writeInt32(1);
- Buf.writeInt32(options.callIndex);
- Buf.sendParcel();
- });
- },
-
- /**
- * Get current calls.
- */
- getCurrentCalls: function(options) {
- this.telephonyRequestQueue.push(REQUEST_GET_CURRENT_CALLS, () => {
- this.context.Buf.simpleRequest(REQUEST_GET_CURRENT_CALLS, options);
- });
- },
-
- /**
- * Mute or unmute the radio.
- *
- * @param mute
- * Boolean to indicate whether to mute or unmute the radio.
- */
- setMute: function(options) {
- let Buf = this.context.Buf;
- Buf.newParcel(REQUEST_SET_MUTE);
- Buf.writeInt32(1);
- Buf.writeInt32(options.muted ? 1 : 0);
- Buf.sendParcel();
- },
-
- /**
- * Send an SMS.
- *
- * The `options` parameter object should contain the following attributes:
- *
- * @param number
- * String containing the recipient number.
- * @param body
- * String containing the message text.
- * @param envelopeId
- * Numeric value identifying the sms request.
- */
- sendSMS: function(options) {
- options.langIndex = options.langIndex || PDU_NL_IDENTIFIER_DEFAULT;
- options.langShiftIndex = options.langShiftIndex || PDU_NL_IDENTIFIER_DEFAULT;
-
- if (!options.segmentSeq) {
- // Fist segment to send
- options.segmentSeq = 1;
- options.body = options.segments[0].body;
- options.encodedBodyLength = options.segments[0].encodedBodyLength;
- }
-
- let Buf = this.context.Buf;
- if (this._isCdma) {
- Buf.newParcel(REQUEST_CDMA_SEND_SMS, options);
- this.context.CdmaPDUHelper.writeMessage(options);
- } else {
- Buf.newParcel(REQUEST_SEND_SMS, options);
- Buf.writeInt32(2);
- Buf.writeString(options.SMSC);
- this.context.GsmPDUHelper.writeMessage(options);
- }
- Buf.sendParcel();
- },
-
- /**
- * Acknowledge the receipt and handling of an SMS.
- *
- * @param success
- * Boolean indicating whether the message was successfuly handled.
- * @param cause
- * SMS_* constant indicating the reason for unsuccessful handling.
- */
- acknowledgeGsmSms: function(success, cause) {
- let Buf = this.context.Buf;
- Buf.newParcel(REQUEST_SMS_ACKNOWLEDGE);
- Buf.writeInt32(2);
- Buf.writeInt32(success ? 1 : 0);
- Buf.writeInt32(cause);
- Buf.sendParcel();
- },
-
- /**
- * Acknowledge the receipt and handling of an SMS.
- *
- * @param success
- * Boolean indicating whether the message was successfuly handled.
- */
- ackSMS: function(options) {
- if (options.result == PDU_FCS_RESERVED) {
- return;
- }
- if (this._isCdma) {
- this.acknowledgeCdmaSms(options.result == PDU_FCS_OK, options.result);
- } else {
- this.acknowledgeGsmSms(options.result == PDU_FCS_OK, options.result);
- }
- },
-
- /**
- * Acknowledge the receipt and handling of a CDMA SMS.
- *
- * @param success
- * Boolean indicating whether the message was successfuly handled.
- * @param cause
- * SMS_* constant indicating the reason for unsuccessful handling.
- */
- acknowledgeCdmaSms: function(success, cause) {
- let Buf = this.context.Buf;
- Buf.newParcel(REQUEST_CDMA_SMS_ACKNOWLEDGE);
- Buf.writeInt32(success ? 0 : 1);
- Buf.writeInt32(cause);
- Buf.sendParcel();
- },
-
- /**
- * Update received MWI into EF_MWIS.
- */
- updateMwis: function(options) {
- if (this.context.ICCUtilsHelper.isICCServiceAvailable("MWIS")) {
- this.context.SimRecordHelper.updateMWIS(options.mwi);
- }
- },
-
- /**
- * Report SMS storage status to modem.
- */
- _updateSmsMemoryStatus: function() {
- let Buf = this.context.Buf;
- Buf.newParcel(REQUEST_REPORT_SMS_MEMORY_STATUS);
- Buf.writeInt32(1);
- Buf.writeInt32(this.smsStorageAvailable ? 1 : 0);
- Buf.sendParcel();
- },
-
- reportSmsMemoryStatus: function(options) {
- this.pendingToReportSmsMemoryStatus = true;
- this.smsStorageAvailable = options.isAvailable;
- this._updateSmsMemoryStatus();
- },
-
- setCellBroadcastDisabled: function(options) {
- this.cellBroadcastDisabled = options.disabled;
-
- // If |this.mergedCellBroadcastConfig| is null, either we haven't finished
- // reading required SIM files, or no any channel is ever configured. In
- // the former case, we'll call |this.updateCellBroadcastConfig()| later
- // with correct configs; in the latter case, we don't bother resetting CB
- // to disabled again.
- if (this.mergedCellBroadcastConfig) {
- this.updateCellBroadcastConfig();
- }
- },
-
- setCellBroadcastSearchList: function(options) {
- let getSearchListStr = function(aSearchList) {
- if (typeof aSearchList === "string" || aSearchList instanceof String) {
- return aSearchList;
- }
-
- // TODO: Set search list for CDMA/GSM individually. Bug 990926
- let prop = this._isCdma ? "cdma" : "gsm";
-
- return aSearchList && aSearchList[prop];
- }.bind(this);
-
- try {
- let str = getSearchListStr(options.searchList);
- this.cellBroadcastConfigs.MMI = this._convertCellBroadcastSearchList(str);
- } catch (e) {
- if (DEBUG) {
- this.context.debug("Invalid Cell Broadcast search list: " + e);
- }
- options.errorMsg = GECKO_ERROR_UNSPECIFIED_ERROR;
- }
-
- this.sendChromeMessage(options);
- if (options.errorMsg) {
- return;
- }
-
- this._mergeAllCellBroadcastConfigs();
- },
-
- updateCellBroadcastConfig: function() {
- let activate = !this.cellBroadcastDisabled &&
- (this.mergedCellBroadcastConfig != null) &&
- (this.mergedCellBroadcastConfig.length > 0);
- if (activate) {
- this.setSmsBroadcastConfig(this.mergedCellBroadcastConfig);
- } else {
- // It's unnecessary to set config first if we're deactivating.
- this.setSmsBroadcastActivation(false);
- }
- },
-
- setGsmSmsBroadcastConfig: function(config) {
- let Buf = this.context.Buf;
- Buf.newParcel(REQUEST_GSM_SET_BROADCAST_SMS_CONFIG);
-
- let numConfigs = config ? config.length / 2 : 0;
- Buf.writeInt32(numConfigs);
- for (let i = 0; i < config.length;) {
- // convert [from, to) to [from, to - 1]
- Buf.writeInt32(config[i++]);
- Buf.writeInt32(config[i++] - 1);
- Buf.writeInt32(0x00);
- Buf.writeInt32(0xFF);
- Buf.writeInt32(1);
- }
-
- Buf.sendParcel();
- },
-
- /**
- * Send CDMA SMS broadcast config.
- *
- * @see 3GPP2 C.R1001 Sec. 9.2 and 9.3
- */
- setCdmaSmsBroadcastConfig: function(config) {
- let Buf = this.context.Buf;
- // |config| is an array of half-closed range: [[from, to), [from, to), ...].
- // It will be further decomposed, ex: [1, 4) => 1, 2, 3.
- Buf.newParcel(REQUEST_CDMA_SET_BROADCAST_SMS_CONFIG);
-
- let numConfigs = 0;
- for (let i = 0; i < config.length; i += 2) {
- numConfigs += (config[i+1] - config[i]);
- }
-
- Buf.writeInt32(numConfigs);
- for (let i = 0; i < config.length;) {
- let begin = config[i++];
- let end = config[i++];
-
- for (let j = begin; j < end; ++j) {
- Buf.writeInt32(j);
- Buf.writeInt32(0); // Language Indicator: Unknown or unspecified.
- Buf.writeInt32(1);
- }
- }
-
- Buf.sendParcel();
- },
-
- setSmsBroadcastConfig: function(config) {
- if (this._isCdma) {
- this.setCdmaSmsBroadcastConfig(config);
- } else {
- this.setGsmSmsBroadcastConfig(config);
- }
- },
-
- setSmsBroadcastActivation: function(activate) {
- let parcelType = this._isCdma ? REQUEST_CDMA_SMS_BROADCAST_ACTIVATION :
- REQUEST_GSM_SMS_BROADCAST_ACTIVATION;
- let Buf = this.context.Buf;
- Buf.newParcel(parcelType);
- Buf.writeInt32(1);
- // See hardware/ril/include/telephony/ril.h, 0 - Activate, 1 - Turn off.
- Buf.writeInt32(activate ? 0 : 1);
- Buf.sendParcel();
- },
-
- /**
- * Start a DTMF Tone.
- *
- * @param dtmfChar
- * DTMF signal to send, 0-9, *, +
- */
- startTone: function(options) {
- let Buf = this.context.Buf;
- Buf.newParcel(REQUEST_DTMF_START, options);
- Buf.writeString(options.dtmfChar);
- Buf.sendParcel();
- },
-
- stopTone: function() {
- this.context.Buf.simpleRequest(REQUEST_DTMF_STOP);
- },
-
- /**
- * Send a DTMF tone.
- *
- * @param dtmfChar
- * DTMF signal to send, 0-9, *, +
- */
- sendTone: function(options) {
- let Buf = this.context.Buf;
- Buf.newParcel(REQUEST_DTMF);
- Buf.writeString(options.dtmfChar);
- Buf.sendParcel();
- },
-
- /**
- * Get the Short Message Service Center address.
- */
- getSmscAddress: function(options) {
- this.context.Buf.simpleRequest(REQUEST_GET_SMSC_ADDRESS, options);
- },
-
- /**
- * Set the Short Message Service Center address.
- *
- * @param smscAddress
- * Number part of the SMSC address.
- * @param typeOfNumber
- * Type of number in integer, as defined in
- * |Table 10.5.118: Called party BCD number| of 3GPP TS 24.008.
- * @param numberPlanIdentification
- * The index of number plan identification value in
- * CALLED_PARTY_BCD_NPI array.
- */
- setSmscAddress: function(options) {
- let ton = options.typeOfNumber;
- let npi = CALLED_PARTY_BCD_NPI[options.numberPlanIdentification];
-
- // If any of the mandatory arguments is not available, return an error
- // immediately.
- if (ton === undefined || npi === undefined || !options.smscAddress) {
- options.errorMsg = GECKO_ERROR_INVALID_PARAMETER;
- this.sendChromeMessage(options);
- return;
- }
-
- // Remove all illegal characters in the number string for user-input fault
- // tolerance.
- let numStart = options.smscAddress[0] === "+" ? 1 : 0;
- let number = options.smscAddress.substring(0, numStart) +
- options.smscAddress.substring(numStart)
- .replace(/[^0-9*#abc]/ig, "");
-
- // If the filtered number is an empty string, return an error immediately.
- if (number.length === 0) {
- options.errorMsg = GECKO_ERROR_INVALID_PARAMETER;
- this.sendChromeMessage(options);
- return;
- }
-
- // Init parcel.
- let Buf = this.context.Buf;
- Buf.newParcel(REQUEST_SET_SMSC_ADDRESS, options);
-
- // +---+-----------+---------------+
- // | 1 | TON | NPI |
- // +---+-----------+---------------+
- let tosca = (0x1 << 7) + (ton << 4) + npi;
- if (RILQUIRKS_SMSC_ADDRESS_FORMAT === "pdu") {
- let pduHelper = this.context.GsmPDUHelper;
-
- // Remove the preceding '+', and covert the special BCD digits defined in
- // |Called party BCD number| of 3GPP TS 24.008 to corresponding
- // hexadecimal values (refer the following table).
- //
- // +=========+=======+=====+
- // | value | digit | hex |
- // +========================
- // | 1 0 1 0 | * | 0xA |
- // | 1 0 1 1 | # | 0xB |
- // | 1 1 0 0 | a | 0xC |
- // | 1 1 0 1 | b | 0xD |
- // | 1 1 1 0 | c | 0xE |
- // +=========+=======+=====+
- //
- // The replace order is reversed intentionally, because if the digits are
- // replaced in ascending order, "#" will be converted to "b" and then be
- // converted again to "d", which generates incorrect result.
- let pureNumber = number.substring(numStart)
- .replace(/c/ig, "e")
- .replace(/b/ig, "d")
- .replace(/a/ig, "c")
- .replace(/\#/g, "b")
- .replace(/\*/g, "a");
-
- // address length and string length
- let length = Math.ceil(pureNumber.length / 2) + 1; // +1 octet for TOA
- let strlen = length * 2 + 2; // +2 semi-octets for length octet
-
- Buf.writeInt32(strlen);
- pduHelper.writeHexOctet(length);
- pduHelper.writeHexOctet(tosca);
- pduHelper.writeSwappedNibbleBCD(pureNumber);
- Buf.writeStringDelimiter(strlen);
- } else /* RILQUIRKS_SMSC_ADDRESS_FORMAT === "text" */ {
- let sca;
- sca = '"' + number + '"' + ',' + tosca;
- Buf.writeString(sca);
- }
-
- Buf.sendParcel();
- },
-
- /**
- * Setup a data call.
- *
- * @param radioTech
- * Integer to indicate radio technology.
- * DATACALL_RADIOTECHNOLOGY_CDMA => CDMA.
- * DATACALL_RADIOTECHNOLOGY_GSM => GSM.
- * @param apn
- * String containing the name of the APN to connect to.
- * @param user
- * String containing the username for the APN.
- * @param passwd
- * String containing the password for the APN.
- * @param chappap
- * Integer containing CHAP/PAP auth type.
- * DATACALL_AUTH_NONE => PAP and CHAP is never performed.
- * DATACALL_AUTH_PAP => PAP may be performed.
- * DATACALL_AUTH_CHAP => CHAP may be performed.
- * DATACALL_AUTH_PAP_OR_CHAP => PAP / CHAP may be performed.
- * @param pdptype
- * String containing PDP type to request. ("IP", "IPV6", ...)
- */
- setupDataCall: function(options) {
- // From ./hardware/ril/include/telephony/ril.h:
- // ((const char **)data)[0] Radio technology to use: 0-CDMA, 1-GSM/UMTS, 2...
- // for values above 2 this is RIL_RadioTechnology + 2.
- //
- // From frameworks/base/telephony/java/com/android/internal/telephony/DataConnection.java:
- // if the mRilVersion < 6, radio technology must be GSM/UMTS or CDMA.
- // Otherwise, it must be + 2
- //
- // See also bug 901232 and 867873
- let radioTech = options.radioTech + 2;
- let Buf = this.context.Buf;
- let token = Buf.newParcel(REQUEST_SETUP_DATA_CALL, options);
- Buf.writeInt32(7);
- Buf.writeString(radioTech.toString());
- Buf.writeString(DATACALL_PROFILE_DEFAULT.toString());
- Buf.writeString(options.apn);
- Buf.writeString(options.user);
- Buf.writeString(options.passwd);
- Buf.writeString(options.chappap.toString());
- Buf.writeString(options.pdptype);
- Buf.sendParcel();
- return token;
- },
-
- /**
- * Deactivate a data call.
- *
- * @param cid
- * String containing CID.
- * @param reason
- * One of DATACALL_DEACTIVATE_* constants.
- */
- deactivateDataCall: function(options) {
- let Buf = this.context.Buf;
- Buf.newParcel(REQUEST_DEACTIVATE_DATA_CALL, options);
- Buf.writeInt32(2);
- Buf.writeString(options.cid.toString());
- Buf.writeString(options.reason !== undefined ?
- options.reason.toString() :
- DATACALL_DEACTIVATE_NO_REASON.toString());
- Buf.sendParcel();
- },
-
- /**
- * Get a list of data calls.
- */
- getDataCallList: function(options) {
- this.context.Buf.simpleRequest(REQUEST_DATA_CALL_LIST, options);
- },
-
- _attachDataRegistration: false,
- /**
- * Manually attach/detach data registration.
- *
- * @param attach
- * Boolean value indicating attach or detach.
- */
- setDataRegistration: function(options) {
- this._attachDataRegistration = options.attach;
-
- if (RILQUIRKS_DATA_REGISTRATION_ON_DEMAND) {
- let request = options.attach ? RIL_REQUEST_GPRS_ATTACH :
- RIL_REQUEST_GPRS_DETACH;
- this.context.Buf.simpleRequest(request, options);
- return;
- } else if (RILQUIRKS_SUBSCRIPTION_CONTROL && options.attach) {
- this.context.Buf.simpleRequest(REQUEST_SET_DATA_SUBSCRIPTION, options);
- return;
- }
-
- // We don't really send a request to rild, so instantly reply success to
- // RadioInterfaceLayer.
- this.sendChromeMessage(options);
- },
-
- /**
- * Get failure casue code for the most recently failed PDP context.
- */
- getFailCause: function(options) {
- this.context.Buf.simpleRequest(REQUEST_LAST_CALL_FAIL_CAUSE, options);
- },
-
- /**
- * Send USSD.
- *
- * @param ussd
- * String containing the USSD code.
- */
- sendUSSD: function(options) {
- let Buf = this.context.Buf;
- Buf.newParcel(REQUEST_SEND_USSD, options);
- Buf.writeString(options.ussd);
- Buf.sendParcel();
- },
-
- /**
- * Cancel pending USSD.
- */
- cancelUSSD: function(options) {
- this.context.Buf.simpleRequest(REQUEST_CANCEL_USSD, options);
- },
-
- /**
- * Queries current call forward rules.
- *
- * @param reason
- * One of CALL_FORWARD_REASON_* constants.
- * @param serviceClass
- * One of ICC_SERVICE_CLASS_* constants.
- * @param number
- * Phone number of forwarding address.
- */
- queryCallForwardStatus: function(options) {
- let Buf = this.context.Buf;
- let number = options.number || "";
- Buf.newParcel(REQUEST_QUERY_CALL_FORWARD_STATUS, options);
- Buf.writeInt32(CALL_FORWARD_ACTION_QUERY_STATUS);
- Buf.writeInt32(options.reason);
- Buf.writeInt32(options.serviceClass || ICC_SERVICE_CLASS_NONE);
- Buf.writeInt32(this._toaFromString(number));
- Buf.writeString(number);
- Buf.writeInt32(0);
- Buf.sendParcel();
- },
-
- /**
- * Configures call forward rule.
- *
- * @param action
- * One of CALL_FORWARD_ACTION_* constants.
- * @param reason
- * One of CALL_FORWARD_REASON_* constants.
- * @param serviceClass
- * One of ICC_SERVICE_CLASS_* constants.
- * @param number
- * Phone number of forwarding address.
- * @param timeSeconds
- * Time in seconds to wait beforec all is forwarded.
- */
- setCallForward: function(options) {
- let Buf = this.context.Buf;
- Buf.newParcel(REQUEST_SET_CALL_FORWARD, options);
- Buf.writeInt32(options.action);
- Buf.writeInt32(options.reason);
- Buf.writeInt32(options.serviceClass);
- Buf.writeInt32(this._toaFromString(options.number));
- Buf.writeString(options.number);
- Buf.writeInt32(options.timeSeconds);
- Buf.sendParcel();
- },
-
- /**
- * Queries current call barring rules.
- *
- * @param program
- * One of CALL_BARRING_PROGRAM_* constants.
- * @param serviceClass
- * One of ICC_SERVICE_CLASS_* constants.
- */
- queryCallBarringStatus: function(options) {
- options.facility = CALL_BARRING_PROGRAM_TO_FACILITY[options.program];
- options.password = ""; // For query no need to provide it.
-
- // For some operators, querying specific serviceClass doesn't work. We use
- // serviceClass 0 instead, and then process the response to extract the
- // answer for queryServiceClass.
- options.queryServiceClass = options.serviceClass;
- options.serviceClass = 0;
-
- this.queryICCFacilityLock(options);
- },
-
- /**
- * Configures call barring rule.
- *
- * @param program
- * One of CALL_BARRING_PROGRAM_* constants.
- * @param enabled
- * Enable or disable the call barring.
- * @param password
- * Barring password.
- * @param serviceClass
- * One of ICC_SERVICE_CLASS_* constants.
- */
- setCallBarring: function(options) {
- options.facility = CALL_BARRING_PROGRAM_TO_FACILITY[options.program];
- this.setICCFacilityLock(options);
- },
-
- /**
- * Change call barring facility password.
- *
- * @param pin
- * Old password.
- * @param newPin
- * New password.
- */
- changeCallBarringPassword: function(options) {
- let Buf = this.context.Buf;
- Buf.newParcel(REQUEST_CHANGE_BARRING_PASSWORD, options);
- Buf.writeInt32(3);
- // Set facility to ICC_CB_FACILITY_BA_ALL by following TS.22.030 clause
- // 6.5.4 and Table B.1.
- Buf.writeString(ICC_CB_FACILITY_BA_ALL);
- Buf.writeString(options.pin);
- Buf.writeString(options.newPin);
- Buf.sendParcel();
- },
-
- /**
- * Handle STK CALL_SET_UP request.
- *
- * @param hasConfirmed
- * Does use have confirmed the call requested from ICC?
- */
- stkHandleCallSetup: function(options) {
- let Buf = this.context.Buf;
- Buf.newParcel(REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM);
- Buf.writeInt32(1);
- Buf.writeInt32(options.hasConfirmed ? 1 : 0);
- Buf.sendParcel();
- },
-
- /**
- * Send STK Profile Download.
- *
- * @param profile Profile supported by ME.
- */
- sendStkTerminalProfile: function(profile) {
- let Buf = this.context.Buf;
- let GsmPDUHelper = this.context.GsmPDUHelper;
-
- Buf.newParcel(REQUEST_STK_SET_PROFILE);
- Buf.writeInt32(profile.length * 2);
- for (let i = 0; i < profile.length; i++) {
- GsmPDUHelper.writeHexOctet(profile[i]);
- }
- Buf.writeInt32(0);
- Buf.sendParcel();
- },
-
- /**
- * Send STK terminal response.
- *
- * @param command
- * @param deviceIdentities
- * @param resultCode
- * @param [optional] additionalInformation
- * @param [optional] itemIdentifier
- * @param [optional] input
- * @param [optional] isYesNo
- * @param [optional] hasConfirmed
- * @param [optional] localInfo
- * @param [optional] timer
- */
- sendStkTerminalResponse: function(response) {
- if (response.hasConfirmed !== undefined) {
- this.stkHandleCallSetup(response);
- return;
- }
-
- let Buf = this.context.Buf;
- let ComprehensionTlvHelper = this.context.ComprehensionTlvHelper;
- let GsmPDUHelper = this.context.GsmPDUHelper;
-
- let command = response.command;
- Buf.newParcel(REQUEST_STK_SEND_TERMINAL_RESPONSE);
-
- // 1st mark for Parcel size
- Buf.startCalOutgoingSize(function(size) {
- // Parcel size is in string length, which costs 2 uint8 per char.
- Buf.writeInt32(size / 2);
- });
-
- // Command Details
- GsmPDUHelper.writeHexOctet(COMPREHENSIONTLV_TAG_COMMAND_DETAILS |
- COMPREHENSIONTLV_FLAG_CR);
- GsmPDUHelper.writeHexOctet(3);
- if (command) {
- GsmPDUHelper.writeHexOctet(command.commandNumber);
- GsmPDUHelper.writeHexOctet(command.typeOfCommand);
- GsmPDUHelper.writeHexOctet(command.commandQualifier);
- } else {
- GsmPDUHelper.writeHexOctet(0x00);
- GsmPDUHelper.writeHexOctet(0x00);
- GsmPDUHelper.writeHexOctet(0x00);
- }
-
- // Device Identifier
- // According to TS102.223/TS31.111 section 6.8 Structure of
- // TERMINAL RESPONSE, "For all SIMPLE-TLV objects with Min=N,
- // the ME should set the CR(comprehension required) flag to
- // comprehension not required.(CR=0)"
- // Since DEVICE_IDENTITIES and DURATION TLVs have Min=N,
- // the CR flag is not set.
- GsmPDUHelper.writeHexOctet(COMPREHENSIONTLV_TAG_DEVICE_ID);
- GsmPDUHelper.writeHexOctet(2);
- GsmPDUHelper.writeHexOctet(STK_DEVICE_ID_ME);
- GsmPDUHelper.writeHexOctet(STK_DEVICE_ID_SIM);
-
- // Result
- GsmPDUHelper.writeHexOctet(COMPREHENSIONTLV_TAG_RESULT |
- COMPREHENSIONTLV_FLAG_CR);
- if ("additionalInformation" in response) {
- // In |12.12 Result| TS 11.14, the length of additional information is
- // varied and all possible values are addressed in 12.12.1-11 of TS 11.14
- // and 8.12.1-13 in TS 31.111.
- // However,
- // 1. Only SEND SS requires info with more than 1 octet.
- // 2. In rild design, SEND SS is expected to be handled by modem and
- // UNSOLICITED_STK_EVENT_NOTIFY will be sent to application layer to
- // indicate appropriate messages to users. TR is not required in this
- // case.
- // Hence, we simplify the structure of |additionalInformation| to a
- // numeric value instead of a octet array.
- GsmPDUHelper.writeHexOctet(2);
- GsmPDUHelper.writeHexOctet(response.resultCode);
- GsmPDUHelper.writeHexOctet(response.additionalInformation);
- } else {
- GsmPDUHelper.writeHexOctet(1);
- GsmPDUHelper.writeHexOctet(response.resultCode);
- }
-
- // Item Identifier
- if (response.itemIdentifier != null) {
- GsmPDUHelper.writeHexOctet(COMPREHENSIONTLV_TAG_ITEM_ID |
- COMPREHENSIONTLV_FLAG_CR);
- GsmPDUHelper.writeHexOctet(1);
- GsmPDUHelper.writeHexOctet(response.itemIdentifier);
- }
-
- // No need to process Text data if user requests help information.
- if (response.resultCode != STK_RESULT_HELP_INFO_REQUIRED) {
- let text;
- let coding = command.options.isUCS2 ?
- STK_TEXT_CODING_UCS2 :
- (command.options.isPacked ?
- STK_TEXT_CODING_GSM_7BIT_PACKED :
- STK_TEXT_CODING_GSM_8BIT);
- if (response.isYesNo !== undefined) {
- // Tag: GET_INKEY
- // When the ME issues a successful TERMINAL RESPONSE for a GET INKEY
- // ("Yes/No") command with command qualifier set to "Yes/No", it shall
- // supply the value '01' when the answer is "positive" and the value
- // '00' when the answer is "negative" in the Text string data object.
- GsmPDUHelper.writeHexOctet(COMPREHENSIONTLV_TAG_TEXT_STRING |
- COMPREHENSIONTLV_FLAG_CR);
- // Length: 2
- GsmPDUHelper.writeHexOctet(2);
- // Value: Coding, Yes/No.
- GsmPDUHelper.writeHexOctet(coding);
- GsmPDUHelper.writeHexOctet(response.isYesNo ? 0x01 : 0x00);
- } else {
- if (response.input !== undefined) {
- ComprehensionTlvHelper.writeTextStringTlv(response.input, coding);
- }
- }
- }
-
- // Duration
- if (response.resultCode === STK_RESULT_NO_RESPONSE_FROM_USER) {
- // In TS102 223, 6.4.2 GET INKEY, "if the UICC requests a variable timeout,
- // the terminal shall wait until either the user enters a single character
- // or the timeout expires. The timer starts when the text is displayed on
- // the screen and stops when the TERMINAL RESPONSE is sent. The terminal
- // shall pass the total display text duration (command execution duration)
- // to the UICC using the TERMINAL RESPONSE. The time unit of the response
- // is identical to the time unit of the requested variable timeout."
- let duration = command && command.options && command.options.duration;
- if (duration) {
- GsmPDUHelper.writeHexOctet(COMPREHENSIONTLV_TAG_DURATION);
- GsmPDUHelper.writeHexOctet(2);
- GsmPDUHelper.writeHexOctet(duration.timeUnit);
- GsmPDUHelper.writeHexOctet(duration.timeInterval);
- }
- }
-
- // Local Information
- if (response.localInfo) {
- let localInfo = response.localInfo;
-
- // Location Infomation
- if (localInfo.locationInfo) {
- ComprehensionTlvHelper.writeLocationInfoTlv(localInfo.locationInfo);
- }
-
- // IMEI
- if (localInfo.imei != null) {
- let imei = localInfo.imei;
- if (imei.length == 15) {
- imei = imei + "0";
- }
-
- GsmPDUHelper.writeHexOctet(COMPREHENSIONTLV_TAG_IMEI);
- GsmPDUHelper.writeHexOctet(8);
- for (let i = 0; i < imei.length / 2; i++) {
- GsmPDUHelper.writeHexOctet(parseInt(imei.substr(i * 2, 2), 16));
- }
- }
-
- // Date and Time Zone
- if (localInfo.date != null) {
- ComprehensionTlvHelper.writeDateTimeZoneTlv(localInfo.date);
- }
-
- // Language
- if (localInfo.language) {
- ComprehensionTlvHelper.writeLanguageTlv(localInfo.language);
- }
- }
-
- // Timer
- if (response.timer) {
- let timer = response.timer;
-
- if (timer.timerId) {
- GsmPDUHelper.writeHexOctet(COMPREHENSIONTLV_TAG_TIMER_IDENTIFIER);
- GsmPDUHelper.writeHexOctet(1);
- GsmPDUHelper.writeHexOctet(timer.timerId);
- }
-
- if (timer.timerValue) {
- ComprehensionTlvHelper.writeTimerValueTlv(timer.timerValue, false);
- }
- }
-
- // Calculate and write Parcel size to 1st mark
- Buf.stopCalOutgoingSize();
-
- Buf.writeInt32(0);
- Buf.sendParcel();
- },
-
- /**
- * Send STK Envelope(Menu Selection) command.
- *
- * @param itemIdentifier
- * @param helpRequested
- */
- sendStkMenuSelection: function(command) {
- command.tag = BER_MENU_SELECTION_TAG;
- command.deviceId = {
- sourceId :STK_DEVICE_ID_KEYPAD,
- destinationId: STK_DEVICE_ID_SIM
- };
- this.sendICCEnvelopeCommand(command);
- },
-
- /**
- * Send STK Envelope(Timer Expiration) command.
- *
- * @param timer
- */
- sendStkTimerExpiration: function(command) {
- command.tag = BER_TIMER_EXPIRATION_TAG;
- command.deviceId = {
- sourceId: STK_DEVICE_ID_ME,
- destinationId: STK_DEVICE_ID_SIM
- };
- command.timerId = command.timer.timerId;
- command.timerValue = command.timer.timerValue;
- this.sendICCEnvelopeCommand(command);
- },
-
- /**
- * Send STK Envelope(Event Download) command.
- * @param event
- */
- sendStkEventDownload: function(command) {
- command.tag = BER_EVENT_DOWNLOAD_TAG;
- command.eventList = command.event.eventType;
- switch (command.eventList) {
- case STK_EVENT_TYPE_LOCATION_STATUS:
- command.deviceId = {
- sourceId :STK_DEVICE_ID_ME,
- destinationId: STK_DEVICE_ID_SIM
- };
- command.locationStatus = command.event.locationStatus;
- // Location info should only be provided when locationStatus is normal.
- if (command.locationStatus == STK_SERVICE_STATE_NORMAL) {
- command.locationInfo = command.event.locationInfo;
- }
- break;
- case STK_EVENT_TYPE_MT_CALL:
- command.deviceId = {
- sourceId: STK_DEVICE_ID_NETWORK,
- destinationId: STK_DEVICE_ID_SIM
- };
- command.transactionId = 0;
- command.address = command.event.number;
- break;
- case STK_EVENT_TYPE_CALL_DISCONNECTED:
- command.cause = command.event.error;
- // Fall through.
- case STK_EVENT_TYPE_CALL_CONNECTED:
- command.deviceId = {
- sourceId: (command.event.isIssuedByRemote ?
- STK_DEVICE_ID_NETWORK : STK_DEVICE_ID_ME),
- destinationId: STK_DEVICE_ID_SIM
- };
- command.transactionId = 0;
- break;
- case STK_EVENT_TYPE_USER_ACTIVITY:
- command.deviceId = {
- sourceId: STK_DEVICE_ID_ME,
- destinationId: STK_DEVICE_ID_SIM
- };
- break;
- case STK_EVENT_TYPE_IDLE_SCREEN_AVAILABLE:
- command.deviceId = {
- sourceId: STK_DEVICE_ID_DISPLAY,
- destinationId: STK_DEVICE_ID_SIM
- };
- break;
- case STK_EVENT_TYPE_LANGUAGE_SELECTION:
- command.deviceId = {
- sourceId: STK_DEVICE_ID_ME,
- destinationId: STK_DEVICE_ID_SIM
- };
- command.language = command.event.language;
- break;
- case STK_EVENT_TYPE_BROWSER_TERMINATION:
- command.deviceId = {
- sourceId: STK_DEVICE_ID_ME,
- destinationId: STK_DEVICE_ID_SIM
- };
- command.terminationCause = command.event.terminationCause;
- break;
- }
- this.sendICCEnvelopeCommand(command);
- },
-
- /**
- * Send REQUEST_STK_SEND_ENVELOPE_COMMAND to ICC.
- *
- * @param tag
- * @patam deviceId
- * @param [optioanl] itemIdentifier
- * @param [optional] helpRequested
- * @param [optional] eventList
- * @param [optional] locationStatus
- * @param [optional] locationInfo
- * @param [optional] address
- * @param [optional] transactionId
- * @param [optional] cause
- * @param [optional] timerId
- * @param [optional] timerValue
- * @param [optional] terminationCause
- */
- sendICCEnvelopeCommand: function(options) {
- if (DEBUG) {
- this.context.debug("Stk Envelope " + JSON.stringify(options));
- }
-
- let Buf = this.context.Buf;
- let ComprehensionTlvHelper = this.context.ComprehensionTlvHelper;
- let GsmPDUHelper = this.context.GsmPDUHelper;
-
- Buf.newParcel(REQUEST_STK_SEND_ENVELOPE_COMMAND);
-
- // 1st mark for Parcel size
- Buf.startCalOutgoingSize(function(size) {
- // Parcel size is in string length, which costs 2 uint8 per char.
- Buf.writeInt32(size / 2);
- });
-
- // Write a BER-TLV
- GsmPDUHelper.writeHexOctet(options.tag);
- // 2nd mark for BER length
- Buf.startCalOutgoingSize(function(size) {
- // BER length is in number of hexOctets, which costs 4 uint8 per hexOctet.
- GsmPDUHelper.writeHexOctet(size / 4);
- });
-
- // Event List
- if (options.eventList != null) {
- GsmPDUHelper.writeHexOctet(COMPREHENSIONTLV_TAG_EVENT_LIST |
- COMPREHENSIONTLV_FLAG_CR);
- GsmPDUHelper.writeHexOctet(1);
- GsmPDUHelper.writeHexOctet(options.eventList);
- }
-
- // Device Identifies
- GsmPDUHelper.writeHexOctet(COMPREHENSIONTLV_TAG_DEVICE_ID |
- COMPREHENSIONTLV_FLAG_CR);
- GsmPDUHelper.writeHexOctet(2);
- GsmPDUHelper.writeHexOctet(options.deviceId.sourceId);
- GsmPDUHelper.writeHexOctet(options.deviceId.destinationId);
-
- // Item Identifier
- if (options.itemIdentifier != null) {
- GsmPDUHelper.writeHexOctet(COMPREHENSIONTLV_TAG_ITEM_ID |
- COMPREHENSIONTLV_FLAG_CR);
- GsmPDUHelper.writeHexOctet(1);
- GsmPDUHelper.writeHexOctet(options.itemIdentifier);
- }
-
- // Help Request
- if (options.helpRequested) {
- GsmPDUHelper.writeHexOctet(COMPREHENSIONTLV_TAG_HELP_REQUEST |
- COMPREHENSIONTLV_FLAG_CR);
- GsmPDUHelper.writeHexOctet(0);
- // Help Request doesn't have value
- }
-
- // Location Status
- if (options.locationStatus != null) {
- let len = options.locationStatus.length;
- GsmPDUHelper.writeHexOctet(COMPREHENSIONTLV_TAG_LOCATION_STATUS |
- COMPREHENSIONTLV_FLAG_CR);
- GsmPDUHelper.writeHexOctet(1);
- GsmPDUHelper.writeHexOctet(options.locationStatus);
- }
-
- // Location Info
- if (options.locationInfo) {
- ComprehensionTlvHelper.writeLocationInfoTlv(options.locationInfo);
- }
-
- // Transaction Id
- if (options.transactionId != null) {
- GsmPDUHelper.writeHexOctet(COMPREHENSIONTLV_TAG_TRANSACTION_ID |
- COMPREHENSIONTLV_FLAG_CR);
- GsmPDUHelper.writeHexOctet(1);
- GsmPDUHelper.writeHexOctet(options.transactionId);
- }
-
- // Address
- if (options.address) {
- GsmPDUHelper.writeHexOctet(COMPREHENSIONTLV_TAG_ADDRESS |
- COMPREHENSIONTLV_FLAG_CR);
- let addressLength = options.address[0] == '+' ? options.address.length - 1
- : options.address.length;
- ComprehensionTlvHelper.writeLength(
- Math.ceil(addressLength / 2) + 1 // address BCD + TON
- );
- this.context.ICCPDUHelper.writeDiallingNumber(options.address);
- }
-
- // Cause of disconnection.
- if (options.cause != null) {
- ComprehensionTlvHelper.writeCauseTlv(options.cause);
- }
-
- // Timer Identifier
- if (options.timerId != null) {
- GsmPDUHelper.writeHexOctet(COMPREHENSIONTLV_TAG_TIMER_IDENTIFIER |
- COMPREHENSIONTLV_FLAG_CR);
- GsmPDUHelper.writeHexOctet(1);
- GsmPDUHelper.writeHexOctet(options.timerId);
- }
-
- // Timer Value
- if (options.timerValue != null) {
- ComprehensionTlvHelper.writeTimerValueTlv(options.timerValue, true);
- }
-
- // Language
- if (options.language) {
- ComprehensionTlvHelper.writeLanguageTlv(options.language);
- }
-
- // Browser Termination
- if (options.terminationCause != null) {
- GsmPDUHelper.writeHexOctet(COMPREHENSIONTLV_TAG_BROWSER_TERMINATION_CAUSE |
- COMPREHENSIONTLV_FLAG_CR);
- GsmPDUHelper.writeHexOctet(1);
- GsmPDUHelper.writeHexOctet(options.terminationCause);
- }
-
- // Calculate and write BER length to 2nd mark
- Buf.stopCalOutgoingSize();
-
- // Calculate and write Parcel size to 1st mark
- Buf.stopCalOutgoingSize();
-
- Buf.writeInt32(0);
- Buf.sendParcel();
- },
-
- /**
- * Report STK Service is running.
- */
- reportStkServiceIsRunning: function() {
- this.context.Buf.simpleRequest(REQUEST_REPORT_STK_SERVICE_IS_RUNNING);
- },
-
- /**
- * Process ICC status.
- */
- _processICCStatus: function(iccStatus) {
- // If |_waitingRadioTech| is true, we should not get app information because
- // the |_isCdma| flag is not ready yet. Otherwise we may use wrong index to
- // get app information, especially for the case that icc card has both cdma
- // and gsm subscription.
- if (this._waitingRadioTech) {
- return;
- }
-
- // When |iccStatus.cardState| is not CARD_STATE_PRESENT, set cardState to
- // undetected.
- if (iccStatus.cardState !== CARD_STATE_PRESENT) {
- if (this.cardState !== GECKO_CARDSTATE_UNDETECTED) {
- this.operator = null;
- // We should send |cardstatechange| before |iccinfochange|, otherwise we
- // may lost cardstatechange event when icc card becomes undetected.
- this.cardState = GECKO_CARDSTATE_UNDETECTED;
- this.sendChromeMessage({rilMessageType: "cardstatechange",
- cardState: this.cardState});
-
- this.iccInfo = {iccType: null};
- this.context.ICCUtilsHelper.handleICCInfoChange();
- }
- return;
- }
-
- if (RILQUIRKS_SUBSCRIPTION_CONTROL) {
- // All appIndex is -1 means the subscription is not activated yet.
- // Note that we don't support "ims" for now, so we don't take it into
- // account.
- let neetToActivate = iccStatus.cdmaSubscriptionAppIndex === -1 &&
- iccStatus.gsmUmtsSubscriptionAppIndex === -1;
- if (neetToActivate &&
- // Note: setUiccSubscription works abnormally when RADIO is OFF,
- // which causes SMS function broken in Flame.
- // See bug 1008557 for detailed info.
- this.radioState === GECKO_RADIOSTATE_ENABLED) {
- for (let i = 0; i < iccStatus.apps.length; i++) {
- this.setUiccSubscription({appIndex: i, enabled: true});
- }
- }
- }
-
- let newCardState;
- let index = this._isCdma ? iccStatus.cdmaSubscriptionAppIndex
- : iccStatus.gsmUmtsSubscriptionAppIndex;
- let app = iccStatus.apps[index];
- if (app) {
- // fetchICCRecords will need to read aid, so read aid here.
- this.aid = app.aid;
- this.appType = app.app_type;
- this.iccInfo.iccType = GECKO_CARD_TYPE[this.appType];
-
- switch (app.app_state) {
- case CARD_APPSTATE_ILLEGAL:
- newCardState = GECKO_CARDSTATE_ILLEGAL;
- break;
- case CARD_APPSTATE_PIN:
- newCardState = GECKO_CARDSTATE_PIN_REQUIRED;
- break;
- case CARD_APPSTATE_PUK:
- newCardState = GECKO_CARDSTATE_PUK_REQUIRED;
- break;
- case CARD_APPSTATE_SUBSCRIPTION_PERSO:
- newCardState = PERSONSUBSTATE[app.perso_substate];
- break;
- case CARD_APPSTATE_READY:
- newCardState = GECKO_CARDSTATE_READY;
- break;
- case CARD_APPSTATE_UNKNOWN:
- case CARD_APPSTATE_DETECTED:
- // Fall through.
- default:
- newCardState = GECKO_CARDSTATE_UNKNOWN;
- }
-
- let pin1State = app.pin1_replaced ? iccStatus.universalPINState :
- app.pin1;
- if (pin1State === CARD_PINSTATE_ENABLED_PERM_BLOCKED) {
- newCardState = GECKO_CARDSTATE_PERMANENT_BLOCKED;
- }
- } else {
- // Having incorrect app information, set card state to unknown.
- newCardState = GECKO_CARDSTATE_UNKNOWN;
- }
-
- let ICCRecordHelper = this.context.ICCRecordHelper;
- // Try to get iccId only when cardState left GECKO_CARDSTATE_UNDETECTED.
- if (iccStatus.cardState === CARD_STATE_PRESENT &&
- (this.cardState === GECKO_CARDSTATE_UNINITIALIZED ||
- this.cardState === GECKO_CARDSTATE_UNDETECTED)) {
- ICCRecordHelper.readICCID();
- }
-
- if (this.cardState == newCardState) {
- return;
- }
-
- // This was moved down from CARD_APPSTATE_READY
- this.requestNetworkInfo();
- if (newCardState == GECKO_CARDSTATE_READY) {
- // For type SIM, we need to check EF_phase first.
- // Other types of ICC we can send Terminal_Profile immediately.
- if (this.appType == CARD_APPTYPE_SIM) {
- this.context.SimRecordHelper.readSimPhase();
- } else if (RILQUIRKS_SEND_STK_PROFILE_DOWNLOAD) {
- this.sendStkTerminalProfile(STK_SUPPORTED_TERMINAL_PROFILE);
- }
-
- ICCRecordHelper.fetchICCRecords();
- }
-
- this.cardState = newCardState;
- this.sendChromeMessage({rilMessageType: "cardstatechange",
- cardState: this.cardState});
- },
-
- /**
- * Helper for processing responses of functions such as enterICC* and changeICC*.
- */
- _processEnterAndChangeICCResponses: function(length, options) {
- options.retryCount = length ? this.context.Buf.readInt32List()[0] : -1;
- this.sendChromeMessage(options);
- },
-
- // We combine all of the NETWORK_INFO_MESSAGE_TYPES into one "networkinfochange"
- // message to the RadioInterfaceLayer, so we can avoid sending multiple
- // VoiceInfoChanged events for both operator / voice_data_registration
- //
- // State management here is a little tricky. We need to know both:
- // 1. Whether or not a response was received for each of the
- // NETWORK_INFO_MESSAGE_TYPES
- // 2. The outbound message that corresponds with that response -- but this
- // only happens when internal state changes (i.e. it isn't guaranteed)
- //
- // To collect this state, each message response function first calls
- // _receivedNetworkInfo, to mark the response as received. When the
- // final response is received, a call to _sendPendingNetworkInfo is placed
- // on the next tick of the worker thread.
- //
- // Since the original call to _receivedNetworkInfo happens at the top
- // of the response handler, this gives the final handler a chance to
- // queue up it's "changed" message by calling _sendNetworkInfoMessage if/when
- // the internal state has actually changed.
- _sendNetworkInfoMessage: function(type, message) {
- if (!this._processingNetworkInfo) {
- // We only combine these messages in the case of the combined request
- // in requestNetworkInfo()
- this.sendChromeMessage(message);
- return;
- }
-
- if (DEBUG) {
- this.context.debug("Queuing " + type + " network info message: " +
- JSON.stringify(message));
- }
- this._pendingNetworkInfo[type] = message;
- },
-
- _receivedNetworkInfo: function(type) {
- if (DEBUG) this.context.debug("Received " + type + " network info.");
- if (!this._processingNetworkInfo) {
- return;
- }
-
- let pending = this._pendingNetworkInfo;
-
- // We still need to track states for events that aren't fired.
- if (!(type in pending)) {
- pending[type] = this.pendingNetworkType;
- }
-
- // Pending network info is ready to be sent when no more messages
- // are waiting for responses, but the combined payload hasn't been sent.
- for (let i = 0; i < NETWORK_INFO_MESSAGE_TYPES.length; i++) {
- let msgType = NETWORK_INFO_MESSAGE_TYPES[i];
- if (!(msgType in pending)) {
- if (DEBUG) {
- this.context.debug("Still missing some more network info, not " +
- "notifying main thread.");
- }
- return;
- }
- }
-
- // Do a pass to clean up the processed messages that didn't create
- // a response message, so we don't have unused keys in the outbound
- // networkinfochanged message.
- for (let key in pending) {
- if (pending[key] == this.pendingNetworkType) {
- delete pending[key];
- }
- }
-
- if (DEBUG) {
- this.context.debug("All pending network info has been received: " +
- JSON.stringify(pending));
- }
-
- // Send the message on the next tick of the worker's loop, so we give the
- // last message a chance to call _sendNetworkInfoMessage first.
- setTimeout(this._sendPendingNetworkInfo.bind(this), 0);
- },
-
- _sendPendingNetworkInfo: function() {
- this.sendChromeMessage(this._pendingNetworkInfo);
-
- this._processingNetworkInfo = false;
- for (let i = 0; i < NETWORK_INFO_MESSAGE_TYPES.length; i++) {
- delete this._pendingNetworkInfo[NETWORK_INFO_MESSAGE_TYPES[i]];
- }
-
- if (this._needRepollNetworkInfo) {
- this._needRepollNetworkInfo = false;
- this.requestNetworkInfo();
- }
- },
-
- /**
- * Normalize the signal strength in dBm to the signal level from 0 to 100.
- *
- * @param signal
- * The signal strength in dBm to normalize.
- * @param min
- * The signal strength in dBm maps to level 0.
- * @param max
- * The signal strength in dBm maps to level 100.
- *
- * @return level
- * The signal level from 0 to 100.
- */
- _processSignalLevel: function(signal, min, max) {
- if (signal <= min) {
- return 0;
- }
-
- if (signal >= max) {
- return 100;
- }
-
- return Math.floor((signal - min) * 100 / (max - min));
- },
-
- /**
- * Process LTE signal strength to the signal info object.
- *
- * @param signal
- * The signal object reported from RIL/modem.
- *
- * @return The object of signal strength info.
- * Or null if invalid signal input.
- *
- * TODO: Bug 982013: reconsider the format of signal strength APIs for
- * GSM/CDMA/LTE to expose details, such as rsrp and rsnnr,
- * individually.
- */
- _processLteSignal: function(signal) {
- let info = {
- voice: {
- signalStrength: null,
- relSignalStrength: null
- },
- data: {
- signalStrength: null,
- relSignalStrength: null
- }
- };
-
- // Referring to AOSP, use lteRSRP for signalStrength in dBm.
- let signalStrength = (signal.lteRSRP === undefined || signal.lteRSRP === 0x7FFFFFFF) ?
- null : signal.lteRSRP;
- info.voice.signalStrength = info.data.signalStrength = signalStrength;
-
- // Referring to AOSP, first determine signalLevel based on RSRP and RSSNR,
- // then on lteSignalStrength if RSRP and RSSNR are invalid.
- let rsrpLevel = -1;
- let rssnrLevel = -1;
- if (signal.lteRSRP !== undefined &&
- signal.lteRSRP !== 0x7FFFFFFF &&
- signal.lteRSRP >= 44 &&
- signal.lteRSRP <= 140) {
- rsrpLevel = this._processSignalLevel(signal.lteRSRP * -1, -115, -85);
- }
-
- if (signal.lteRSSNR !== undefined &&
- signal.lteRSSNR !== 0x7FFFFFFF &&
- signal.lteRSSNR >= -200 &&
- signal.lteRSSNR <= 300) {
- rssnrLevel = this._processSignalLevel(signal.lteRSSNR, -30, 130);
- }
-
- if (rsrpLevel !== -1 && rssnrLevel !== -1) {
- info.voice.relSignalStrength = info.data.relSignalStrength =
- Math.min(rsrpLevel, rssnrLevel);
- return info;
- }
-
- let level = Math.max(rsrpLevel, rssnrLevel);
- if (level !== -1) {
- info.voice.relSignalStrength = info.data.relSignalStrength = level;
- return info;
- }
-
- // Valid values are 0-63 as defined in TS 27.007 clause 8.69.
- if (signal.lteSignalStrength !== undefined &&
- signal.lteSignalStrength >= 0 &&
- signal.lteSignalStrength <= 63) {
- level = this._processSignalLevel(signal.lteSignalStrength, 0, 12);
- info.voice.relSignalStrength = info.data.relSignalStrength = level;
- return info;
- }
-
- return null;
- },
-
- _processSignalStrength: function(signal) {
- let info = {
- voice: {
- signalStrength: null,
- relSignalStrength: null
- },
- data: {
- signalStrength: null,
- relSignalStrength: null
- }
- };
-
- // During startup, |radioTech| is not yet defined, so we need to
- // check it separately.
- if (("radioTech" in this.voiceRegistrationState) &&
- !this._isGsmTechGroup(this.voiceRegistrationState.radioTech)) {
- // CDMA RSSI.
- // Valid values are positive integers. This value is the actual RSSI value
- // multiplied by -1. Example: If the actual RSSI is -75, then this
- // response value will be 75.
- if (signal.cdmaDBM && signal.cdmaDBM > 0) {
- let signalStrength = -1 * signal.cdmaDBM;
- info.voice.signalStrength = signalStrength;
-
- // -105 and -70 are referred to AOSP's implementation. These values are
- // not constants and can be customized based on different requirement.
- let signalLevel = this._processSignalLevel(signalStrength, -105, -70);
- info.voice.relSignalStrength = signalLevel;
- }
-
- // EVDO RSSI.
- // Valid values are positive integers. This value is the actual RSSI value
- // multiplied by -1. Example: If the actual RSSI is -75, then this
- // response value will be 75.
- if (signal.evdoDBM && signal.evdoDBM > 0) {
- let signalStrength = -1 * signal.evdoDBM;
- info.data.signalStrength = signalStrength;
-
- // -105 and -70 are referred to AOSP's implementation. These values are
- // not constants and can be customized based on different requirement.
- let signalLevel = this._processSignalLevel(signalStrength, -105, -70);
- info.data.relSignalStrength = signalLevel;
- }
- } else {
- // Check LTE level first, and check GSM/UMTS level next if LTE one is not
- // valid.
- let lteInfo = this._processLteSignal(signal);
- if (lteInfo) {
- info = lteInfo;
- } else {
- // GSM signal strength.
- // Valid values are 0-31 as defined in TS 27.007 8.5.
- // 0 : -113 dBm or less
- // 1 : -111 dBm
- // 2...30: -109...-53 dBm
- // 31 : -51 dBm
- if (signal.gsmSignalStrength &&
- signal.gsmSignalStrength >= 0 &&
- signal.gsmSignalStrength <= 31) {
- let signalStrength = -113 + 2 * signal.gsmSignalStrength;
- info.voice.signalStrength = info.data.signalStrength = signalStrength;
-
- // -115 and -85 are referred to AOSP's implementation. These values are
- // not constants and can be customized based on different requirement.
- let signalLevel = this._processSignalLevel(signalStrength, -110, -85);
- info.voice.relSignalStrength = info.data.relSignalStrength = signalLevel;
- }
- }
- }
-
- info.rilMessageType = "signalstrengthchange";
- this._sendNetworkInfoMessage(NETWORK_INFO_SIGNAL, info);
- },
-
- /**
- * Process the network registration flags.
- *
- * @return true if the state changed, false otherwise.
- */
- _processCREG: function(curState, newState) {
- let changed = false;
-
- let regState = this.parseInt(newState[0], NETWORK_CREG_STATE_UNKNOWN);
- if (curState.regState === undefined || curState.regState !== regState) {
- changed = true;
- curState.regState = regState;
-
- curState.state = NETWORK_CREG_TO_GECKO_MOBILE_CONNECTION_STATE[regState];
- curState.connected = regState == NETWORK_CREG_STATE_REGISTERED_HOME ||
- regState == NETWORK_CREG_STATE_REGISTERED_ROAMING;
- curState.roaming = regState == NETWORK_CREG_STATE_REGISTERED_ROAMING;
- curState.emergencyCallsOnly = !curState.connected;
- }
-
- if (!curState.cell) {
- curState.cell = {};
- }
-
- // From TS 23.003, 0000 and 0xfffe are indicated that no valid LAI exists
- // in MS. So we still need to report the '0000' as well.
- let lac = this.parseInt(newState[1], -1, 16);
- if (curState.cell.gsmLocationAreaCode === undefined ||
- curState.cell.gsmLocationAreaCode !== lac) {
- curState.cell.gsmLocationAreaCode = lac;
- changed = true;
- }
-
- let cid = this.parseInt(newState[2], -1, 16);
- if (curState.cell.gsmCellId === undefined ||
- curState.cell.gsmCellId !== cid) {
- curState.cell.gsmCellId = cid;
- changed = true;
- }
-
- let radioTech = (newState[3] === undefined ?
- NETWORK_CREG_TECH_UNKNOWN :
- this.parseInt(newState[3], NETWORK_CREG_TECH_UNKNOWN));
- if (curState.radioTech === undefined || curState.radioTech !== radioTech) {
- changed = true;
- curState.radioTech = radioTech;
- curState.type = GECKO_RADIO_TECH[radioTech] || null;
- }
- return changed;
- },
-
- _processVoiceRegistrationState: function(state) {
- let rs = this.voiceRegistrationState;
- let stateChanged = this._processCREG(rs, state);
- if (stateChanged && rs.connected) {
- this.getSmscAddress();
- }
-
- let cell = rs.cell;
- if (this._isCdma) {
- // Some variables below are not used. Comment them instead of removing to
- // keep the information about state[x].
- let cdmaBaseStationId = this.parseInt(state[4], -1);
- let cdmaBaseStationLatitude = this.parseInt(state[5], -2147483648);
- let cdmaBaseStationLongitude = this.parseInt(state[6], -2147483648);
- // let cssIndicator = this.parseInt(state[7]);
- let cdmaSystemId = this.parseInt(state[8], -1);
- let cdmaNetworkId = this.parseInt(state[9], -1);
- // let roamingIndicator = this.parseInt(state[10]);
- // let systemIsInPRL = this.parseInt(state[11]);
- // let defaultRoamingIndicator = this.parseInt(state[12]);
- // let reasonForDenial = this.parseInt(state[13]);
-
- if (cell.cdmaBaseStationId !== cdmaBaseStationId ||
- cell.cdmaBaseStationLatitude !== cdmaBaseStationLatitude ||
- cell.cdmaBaseStationLongitude !== cdmaBaseStationLongitude ||
- cell.cdmaSystemId !== cdmaSystemId ||
- cell.cdmaNetworkId !== cdmaNetworkId) {
- stateChanged = true;
- cell.cdmaBaseStationId = cdmaBaseStationId;
- cell.cdmaBaseStationLatitude = cdmaBaseStationLatitude;
- cell.cdmaBaseStationLongitude = cdmaBaseStationLongitude;
- cell.cdmaSystemId = cdmaSystemId;
- cell.cdmaNetworkId = cdmaNetworkId;
- }
- }
-
- if (stateChanged) {
- rs.rilMessageType = "voiceregistrationstatechange";
- this._sendNetworkInfoMessage(NETWORK_INFO_VOICE_REGISTRATION_STATE, rs);
- }
- },
-
- _processDataRegistrationState: function(state) {
- let rs = this.dataRegistrationState;
- let stateChanged = this._processCREG(rs, state);
- if (stateChanged) {
- rs.rilMessageType = "dataregistrationstatechange";
- this._sendNetworkInfoMessage(NETWORK_INFO_DATA_REGISTRATION_STATE, rs);
- }
- },
-
- _processOperator: function(operatorData) {
- if (operatorData.length < 3) {
- if (DEBUG) {
- this.context.debug("Expected at least 3 strings for operator.");
- }
- }
-
- if (!this.operator) {
- this.operator = {
- rilMessageType: "operatorchange",
- longName: null,
- shortName: null
- };
- }
-
- let [longName, shortName, networkTuple] = operatorData;
- let thisTuple = (this.operator.mcc || "") + (this.operator.mnc || "");
-
- if (this.operator.longName !== longName ||
- this.operator.shortName !== shortName ||
- thisTuple !== networkTuple) {
-
- this.operator.mcc = null;
- this.operator.mnc = null;
-
- if (networkTuple) {
- try {
- this._processNetworkTuple(networkTuple, this.operator);
- } catch (e) {
- if (DEBUG) this.context.debug("Error processing operator tuple: " + e);
- }
- } else {
- // According to ril.h, the operator fields will be NULL when the operator
- // is not currently registered. We can avoid trying to parse the numeric
- // tuple in that case.
- if (DEBUG) {
- this.context.debug("Operator is currently unregistered");
- }
- }
-
- this.operator.longName = longName;
- this.operator.shortName = shortName;
-
- let ICCUtilsHelper = this.context.ICCUtilsHelper;
- if (ICCUtilsHelper.updateDisplayCondition()) {
- ICCUtilsHelper.handleICCInfoChange();
- }
-
- // NETWORK_INFO_OPERATOR message will be sent out by overrideICCNetworkName
- // itself if operator name is overridden after checking, or we have to
- // do it by ourself.
- if (!this.overrideICCNetworkName()) {
- this._sendNetworkInfoMessage(NETWORK_INFO_OPERATOR, this.operator);
- }
- }
- },
-
- _processSuppSvcNotification: function(info) {
- if (DEBUG) {
- this.context.debug("handle supp svc notification: " + JSON.stringify(info));
- }
-
- if (info.notificationType !== 1) {
- // We haven't supported MO intermediate result code, i.e.
- // info.notificationType === 0, which refers to code1 defined in 3GPP
- // 27.007 7.17. We only support partial MT unsolicited result code,
- // referring to code2, for now.
- return;
- }
-
- let notification = null;
-
- switch (info.code) {
- case SUPP_SVC_NOTIFICATION_CODE2_PUT_ON_HOLD:
- case SUPP_SVC_NOTIFICATION_CODE2_RETRIEVED:
- notification = GECKO_SUPP_SVC_NOTIFICATION_FROM_CODE2[info.code];
- break;
- default:
- // Notification type not supported.
- return;
- }
-
- let message = {rilMessageType: "suppSvcNotification",
- number: info.number, // could be empty.
- notification: notification};
- this.sendChromeMessage(message);
- },
-
- _cancelEmergencyCbModeTimeout: function() {
- if (this._exitEmergencyCbModeTimeoutID) {
- clearTimeout(this._exitEmergencyCbModeTimeoutID);
- this._exitEmergencyCbModeTimeoutID = null;
- }
- },
-
- _handleChangedEmergencyCbMode: function(active) {
- this._isInEmergencyCbMode = active;
-
- // Clear the existed timeout event.
- this._cancelEmergencyCbModeTimeout();
-
- // Start a new timeout event when entering the mode.
- if (active) {
- this._exitEmergencyCbModeTimeoutID = setTimeout(
- this.exitEmergencyCbMode.bind(this), EMERGENCY_CB_MODE_TIMEOUT_MS);
- }
-
- let message = {rilMessageType: "emergencyCbModeChange",
- active: active,
- timeoutMs: EMERGENCY_CB_MODE_TIMEOUT_MS};
- this.sendChromeMessage(message);
- },
-
- _updateNetworkSelectionMode: function(mode) {
- if (this.networkSelectionMode === mode) {
- return;
- }
-
- let options = {
- rilMessageType: "networkselectionmodechange",
- mode: mode
- };
- this.networkSelectionMode = mode;
- this._sendNetworkInfoMessage(NETWORK_INFO_NETWORK_SELECTION_MODE, options);
- },
-
- _processNetworks: function() {
- let strings = this.context.Buf.readStringList();
- let networks = [];
-
- for (let i = 0; i < strings.length;
- i += RILQUIRKS_AVAILABLE_NETWORKS_EXTRA_STRING ? 5 : 4) {
- let network = {
- longName: strings[i],
- shortName: strings[i + 1],
- mcc: null,
- mnc: null,
- state: null
- };
-
- let networkTuple = strings[i + 2];
- try {
- this._processNetworkTuple(networkTuple, network);
- } catch (e) {
- if (DEBUG) this.context.debug("Error processing operator tuple: " + e);
- }
-
- let state = strings[i + 3];
- network.state = RIL_QAN_STATE_TO_GECKO_STATE[state];
-
- networks.push(network);
- }
- return networks;
- },
-
- /**
- * The "numeric" portion of the operator info is a tuple
- * containing MCC (country code) and MNC (network code).
- * AFAICT, MCC should always be 3 digits, making the remaining
- * portion the MNC.
- */
- _processNetworkTuple: function(networkTuple, network) {
- let tupleLen = networkTuple.length;
-
- if (tupleLen == 5 || tupleLen == 6) {
- network.mcc = networkTuple.substr(0, 3);
- network.mnc = networkTuple.substr(3);
- } else {
- network.mcc = null;
- network.mnc = null;
-
- throw new Error("Invalid network tuple (should be 5 or 6 digits): " + networkTuple);
- }
- },
-
- /**
- * Check if GSM radio access technology group.
- */
- _isGsmTechGroup: function(radioTech) {
- if (!radioTech) {
- return true;
- }
-
- switch(radioTech) {
- case NETWORK_CREG_TECH_GPRS:
- case NETWORK_CREG_TECH_EDGE:
- case NETWORK_CREG_TECH_UMTS:
- case NETWORK_CREG_TECH_HSDPA:
- case NETWORK_CREG_TECH_HSUPA:
- case NETWORK_CREG_TECH_HSPA:
- case NETWORK_CREG_TECH_LTE:
- case NETWORK_CREG_TECH_HSPAP:
- case NETWORK_CREG_TECH_GSM:
- case NETWORK_CREG_TECH_DCHSPAP_1:
- case NETWORK_CREG_TECH_DCHSPAP_2:
- return true;
- }
-
- return false;
- },
-
- /**
- * Process radio technology change.
- */
- _processRadioTech: function(radioTech) {
- let isCdma = !this._isGsmTechGroup(radioTech);
- this.radioTech = radioTech;
-
- if (DEBUG) {
- this.context.debug("Radio tech is set to: " + GECKO_RADIO_TECH[radioTech] +
- ", it is a " + (isCdma?"cdma":"gsm") + " technology");
- }
-
- // We should request SIM information when
- // 1. Radio state has been changed, so we are waiting for radioTech or
- // 2. isCdma is different from this._isCdma.
- if (this._waitingRadioTech || isCdma != this._isCdma) {
- this._isCdma = isCdma;
- this._waitingRadioTech = false;
- this.getICCStatus();
- }
- },
-
- /**
- * Helper for returning the TOA for the given dial string.
- */
- _toaFromString: function(number) {
- let toa = TOA_UNKNOWN;
- if (number && number.length > 0 && number[0] == '+') {
- toa = TOA_INTERNATIONAL;
- }
- return toa;
- },
-
- /**
- * @param message A decoded SMS-DELIVER message.
- *
- * @see 3GPP TS 31.111 section 7.1.1
- */
- dataDownloadViaSMSPP: function(message) {
- let Buf = this.context.Buf;
- let GsmPDUHelper = this.context.GsmPDUHelper;
-
- let options = {
- pid: message.pid,
- dcs: message.dcs,
- encoding: message.encoding,
- };
- Buf.newParcel(REQUEST_STK_SEND_ENVELOPE_WITH_STATUS, options);
-
- Buf.seekIncoming(-1 * (Buf.getCurrentParcelSize() - Buf.getReadAvailable()
- - 2 * Buf.UINT32_SIZE)); // Skip response_type & request_type.
- let messageStringLength = Buf.readInt32(); // In semi-octets
- let smscLength = GsmPDUHelper.readHexOctet(); // In octets, inclusive of TOA
- let tpduLength = (messageStringLength / 2) - (smscLength + 1); // In octets
-
- // Device identities: 4 bytes
- // Address: 0 or (2 + smscLength)
- // SMS TPDU: (2 or 3) + tpduLength
- let berLen = 4 +
- (smscLength ? (2 + smscLength) : 0) +
- (tpduLength <= 127 ? 2 : 3) + tpduLength; // In octets
-
- let parcelLength = (berLen <= 127 ? 2 : 3) + berLen; // In octets
- Buf.writeInt32(parcelLength * 2); // In semi-octets
-
- // Write a BER-TLV
- GsmPDUHelper.writeHexOctet(BER_SMS_PP_DOWNLOAD_TAG);
- if (berLen > 127) {
- GsmPDUHelper.writeHexOctet(0x81);
- }
- GsmPDUHelper.writeHexOctet(berLen);
-
- // Device Identifies-TLV
- GsmPDUHelper.writeHexOctet(COMPREHENSIONTLV_TAG_DEVICE_ID |
- COMPREHENSIONTLV_FLAG_CR);
- GsmPDUHelper.writeHexOctet(0x02);
- GsmPDUHelper.writeHexOctet(STK_DEVICE_ID_NETWORK);
- GsmPDUHelper.writeHexOctet(STK_DEVICE_ID_SIM);
-
- // Address-TLV
- if (smscLength) {
- GsmPDUHelper.writeHexOctet(COMPREHENSIONTLV_TAG_ADDRESS);
- GsmPDUHelper.writeHexOctet(smscLength);
- Buf.copyIncomingToOutgoing(Buf.PDU_HEX_OCTET_SIZE * smscLength);
- }
-
- // SMS TPDU-TLV
- GsmPDUHelper.writeHexOctet(COMPREHENSIONTLV_TAG_SMS_TPDU |
- COMPREHENSIONTLV_FLAG_CR);
- if (tpduLength > 127) {
- GsmPDUHelper.writeHexOctet(0x81);
- }
- GsmPDUHelper.writeHexOctet(tpduLength);
- Buf.copyIncomingToOutgoing(Buf.PDU_HEX_OCTET_SIZE * tpduLength);
-
- // Write 2 string delimitors for the total string length must be even.
- Buf.writeStringDelimiter(0);
-
- Buf.sendParcel();
- },
-
- /**
- * @param success A boolean value indicating the result of previous
- * SMS-DELIVER message handling.
- * @param responsePduLen ICC IO response PDU length in octets.
- * @param options An object that contains four attributes: `pid`, `dcs`,
- * `encoding` and `responsePduLen`.
- *
- * @see 3GPP TS 23.040 section 9.2.2.1a
- */
- acknowledgeIncomingGsmSmsWithPDU: function(success, responsePduLen, options) {
- let Buf = this.context.Buf;
- let GsmPDUHelper = this.context.GsmPDUHelper;
-
- Buf.newParcel(REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU);
-
- // Two strings.
- Buf.writeInt32(2);
-
- // String 1: Success
- Buf.writeString(success ? "1" : "0");
-
- // String 2: RP-ACK/RP-ERROR PDU
- Buf.writeInt32(2 * (responsePduLen + (success ? 5 : 6))); // In semi-octet
- // 1. TP-MTI & TP-UDHI
- GsmPDUHelper.writeHexOctet(PDU_MTI_SMS_DELIVER);
- if (!success) {
- // 2. TP-FCS
- GsmPDUHelper.writeHexOctet(PDU_FCS_USIM_DATA_DOWNLOAD_ERROR);
- }
- // 3. TP-PI
- GsmPDUHelper.writeHexOctet(PDU_PI_USER_DATA_LENGTH |
- PDU_PI_DATA_CODING_SCHEME |
- PDU_PI_PROTOCOL_IDENTIFIER);
- // 4. TP-PID
- GsmPDUHelper.writeHexOctet(options.pid);
- // 5. TP-DCS
- GsmPDUHelper.writeHexOctet(options.dcs);
- // 6. TP-UDL
- if (options.encoding == PDU_DCS_MSG_CODING_7BITS_ALPHABET) {
- GsmPDUHelper.writeHexOctet(Math.floor(responsePduLen * 8 / 7));
- } else {
- GsmPDUHelper.writeHexOctet(responsePduLen);
- }
- // TP-UD
- Buf.copyIncomingToOutgoing(Buf.PDU_HEX_OCTET_SIZE * responsePduLen);
- // Write 2 string delimitors for the total string length must be even.
- Buf.writeStringDelimiter(0);
-
- Buf.sendParcel();
- },
-
- /**
- * @param message A decoded SMS-DELIVER message.
- */
- writeSmsToSIM: function(message) {
- let Buf = this.context.Buf;
- let GsmPDUHelper = this.context.GsmPDUHelper;
-
- Buf.newParcel(REQUEST_WRITE_SMS_TO_SIM);
-
- // Write EFsms Status
- Buf.writeInt32(EFSMS_STATUS_FREE);
-
- Buf.seekIncoming(-1 * (Buf.getCurrentParcelSize() - Buf.getReadAvailable()
- - 2 * Buf.UINT32_SIZE)); // Skip response_type & request_type.
- let messageStringLength = Buf.readInt32(); // In semi-octets
- let smscLength = GsmPDUHelper.readHexOctet(); // In octets, inclusive of TOA
- let pduLength = (messageStringLength / 2) - (smscLength + 1); // In octets
-
- // 1. Write PDU first.
- if (smscLength > 0) {
- Buf.seekIncoming(smscLength * Buf.PDU_HEX_OCTET_SIZE);
- }
- // Write EFsms PDU string length
- Buf.writeInt32(2 * pduLength); // In semi-octets
- if (pduLength) {
- Buf.copyIncomingToOutgoing(Buf.PDU_HEX_OCTET_SIZE * pduLength);
- }
- // Write 2 string delimitors for the total string length must be even.
- Buf.writeStringDelimiter(0);
-
- // 2. Write SMSC
- // Write EFsms SMSC string length
- Buf.writeInt32(2 * (smscLength + 1)); // Plus smscLength itself, in semi-octets
- // Write smscLength
- GsmPDUHelper.writeHexOctet(smscLength);
- // Write TOA & SMSC Address
- if (smscLength) {
- Buf.seekIncoming(-1 * (Buf.getCurrentParcelSize() - Buf.getReadAvailable()
- - 2 * Buf.UINT32_SIZE // Skip response_type, request_type.
- - 2 * Buf.PDU_HEX_OCTET_SIZE)); // Skip messageStringLength & smscLength.
- Buf.copyIncomingToOutgoing(Buf.PDU_HEX_OCTET_SIZE * smscLength);
- }
- // Write 2 string delimitors for the total string length must be even.
- Buf.writeStringDelimiter(0);
-
- Buf.sendParcel();
- },
-
- /**
- * Helper to delegate the received sms segment to RadioInterface to process.
- *
- * @param message
- * Received sms message.
- *
- * @return MOZ_FCS_WAIT_FOR_EXPLICIT_ACK
- */
- _processSmsMultipart: function(message) {
- message.rilMessageType = "sms-received";
-
- this.sendChromeMessage(message);
-
- return MOZ_FCS_WAIT_FOR_EXPLICIT_ACK;
- },
-
- /**
- * Helper for processing SMS-STATUS-REPORT PDUs.
- *
- * @param length
- * Length of SMS string in the incoming parcel.
- *
- * @return A failure cause defined in 3GPP 23.040 clause 9.2.3.22.
- */
- _processSmsStatusReport: function(length) {
- let [message, result] = this.context.GsmPDUHelper.processReceivedSms(length);
- if (!message) {
- if (DEBUG) this.context.debug("invalid SMS-STATUS-REPORT");
- return PDU_FCS_UNSPECIFIED;
- }
-
- let options = this._pendingSentSmsMap[message.messageRef];
- if (!options) {
- if (DEBUG) this.context.debug("no pending SMS-SUBMIT message");
- return PDU_FCS_OK;
- }
-
- let status = message.status;
-
- // 3GPP TS 23.040 9.2.3.15 `The MS shall interpret any reserved values as
- // "Service Rejected"(01100011) but shall store them exactly as received.`
- if ((status >= 0x80)
- || ((status >= PDU_ST_0_RESERVED_BEGIN)
- && (status < PDU_ST_0_SC_SPECIFIC_BEGIN))
- || ((status >= PDU_ST_1_RESERVED_BEGIN)
- && (status < PDU_ST_1_SC_SPECIFIC_BEGIN))
- || ((status >= PDU_ST_2_RESERVED_BEGIN)
- && (status < PDU_ST_2_SC_SPECIFIC_BEGIN))
- || ((status >= PDU_ST_3_RESERVED_BEGIN)
- && (status < PDU_ST_3_SC_SPECIFIC_BEGIN))
- ) {
- status = PDU_ST_3_SERVICE_REJECTED;
- }
-
- // Pending. Waiting for next status report.
- if ((status >>> 5) == 0x01) {
- if (DEBUG) this.context.debug("SMS-STATUS-REPORT: delivery still pending");
- return PDU_FCS_OK;
- }
-
- delete this._pendingSentSmsMap[message.messageRef];
-
- let deliveryStatus = ((status >>> 5) === 0x00)
- ? GECKO_SMS_DELIVERY_STATUS_SUCCESS
- : GECKO_SMS_DELIVERY_STATUS_ERROR;
- this.sendChromeMessage({
- rilMessageType: options.rilMessageType,
- rilMessageToken: options.rilMessageToken,
- deliveryStatus: deliveryStatus
- });
-
- return PDU_FCS_OK;
- },
-
- /**
- * Helper for processing CDMA SMS Delivery Acknowledgment Message
- *
- * @param message
- * decoded SMS Delivery ACK message from CdmaPDUHelper.
- *
- * @return A failure cause defined in 3GPP 23.040 clause 9.2.3.22.
- */
- _processCdmaSmsStatusReport: function(message) {
- let options = this._pendingSentSmsMap[message.msgId];
- if (!options) {
- if (DEBUG) this.context.debug("no pending SMS-SUBMIT message");
- return PDU_FCS_OK;
- }
-
- if (message.errorClass === 2) {
- if (DEBUG) {
- this.context.debug("SMS-STATUS-REPORT: delivery still pending, " +
- "msgStatus: " + message.msgStatus);
- }
- return PDU_FCS_OK;
- }
-
- delete this._pendingSentSmsMap[message.msgId];
-
- if (message.errorClass === -1 && message.body) {
- // Process as normal incoming SMS, if errorClass is invalid
- // but message body is available.
- return this._processSmsMultipart(message);
- }
-
- let deliveryStatus = (message.errorClass === 0)
- ? GECKO_SMS_DELIVERY_STATUS_SUCCESS
- : GECKO_SMS_DELIVERY_STATUS_ERROR;
- this.sendChromeMessage({
- rilMessageType: options.rilMessageType,
- rilMessageToken: options.rilMessageToken,
- deliveryStatus: deliveryStatus
- });
-
- return PDU_FCS_OK;
- },
-
- /**
- * Helper for processing CDMA SMS WAP Push Message
- *
- * @param message
- * decoded WAP message from CdmaPDUHelper.
- *
- * @return A failure cause defined in 3GPP 23.040 clause 9.2.3.22.
- */
- _processCdmaSmsWapPush: function(message) {
- if (!message.data) {
- if (DEBUG) this.context.debug("no data inside WAP Push message.");
- return PDU_FCS_OK;
- }
-
- // See 6.5. MAPPING OF WDP TO CDMA SMS in WAP-295-WDP.
- //
- // Field | Length (bits)
- // -----------------------------------------
- // MSG_TYPE | 8
- // TOTAL_SEGMENTS | 8
- // SEGMENT_NUMBER | 8
- // DATAGRAM | (NUM_FIELDS - 3) * 8
- let index = 0;
- if (message.data[index++] !== 0) {
- if (DEBUG) this.context.debug("Ignore a WAP Message which is not WDP.");
- return PDU_FCS_OK;
- }
-
- // 1. Originator Address in SMS-TL + Message_Id in SMS-TS are used to identify a unique WDP datagram.
- // 2. TOTAL_SEGMENTS, SEGMENT_NUMBER are used to verify that a complete
- // datagram has been received and is ready to be passed to a higher layer.
- message.header = {
- segmentRef: message.msgId,
- segmentMaxSeq: message.data[index++],
- segmentSeq: message.data[index++] + 1 // It's zero-based in CDMA WAP Push.
- };
-
- if (message.header.segmentSeq > message.header.segmentMaxSeq) {
- if (DEBUG) this.context.debug("Wrong WDP segment info.");
- return PDU_FCS_OK;
- }
-
- // Ports are only specified in 1st segment.
- if (message.header.segmentSeq == 1) {
- message.header.originatorPort = message.data[index++] << 8;
- message.header.originatorPort |= message.data[index++];
- message.header.destinationPort = message.data[index++] << 8;
- message.header.destinationPort |= message.data[index++];
- }
-
- message.data = message.data.subarray(index);
-
- return this._processSmsMultipart(message);
- },
-
- /**
- * Helper for processing sent multipart SMS.
- */
- _processSentSmsSegment: function(options) {
- // Setup attributes for sending next segment
- let next = options.segmentSeq;
- options.body = options.segments[next].body;
- options.encodedBodyLength = options.segments[next].encodedBodyLength;
- options.segmentSeq = next + 1;
-
- this.sendSMS(options);
- },
-
- /**
- * Helper for processing result of send SMS.
- *
- * @param length
- * Length of SMS string in the incoming parcel.
- * @param options
- * Sms information.
- */
- _processSmsSendResult: function(length, options) {
- if (options.errorMsg) {
- if (DEBUG) {
- this.context.debug("_processSmsSendResult: errorMsg = " +
- options.errorMsg);
- }
-
- this.sendChromeMessage({
- rilMessageType: options.rilMessageType,
- rilMessageToken: options.rilMessageToken,
- errorMsg: options.errorMsg,
- });
- return;
- }
-
- let Buf = this.context.Buf;
- options.messageRef = Buf.readInt32();
- options.ackPDU = Buf.readString();
- options.errorCode = Buf.readInt32();
-
- if ((options.segmentMaxSeq > 1)
- && (options.segmentSeq < options.segmentMaxSeq)) {
- // Not last segment
- this._processSentSmsSegment(options);
- } else {
- // Last segment sent with success.
- if (options.requestStatusReport) {
- if (DEBUG) {
- this.context.debug("waiting SMS-STATUS-REPORT for messageRef " +
- options.messageRef);
- }
- this._pendingSentSmsMap[options.messageRef] = options;
- }
-
- this.sendChromeMessage({
- rilMessageType: options.rilMessageType,
- rilMessageToken: options.rilMessageToken,
- });
- }
- },
-
- _processReceivedSmsCbPage: function(original) {
- if (original.numPages <= 1) {
- if (original.body) {
- original.fullBody = original.body;
- delete original.body;
- } else if (original.data) {
- original.fullData = original.data;
- delete original.data;
- }
- return original;
- }
-
- // Hash = <serial>:<mcc>:<mnc>:<lac>:<cid>
- let hash = original.serial + ":" + this.iccInfo.mcc + ":"
- + this.iccInfo.mnc + ":";
- switch (original.geographicalScope) {
- case CB_GSM_GEOGRAPHICAL_SCOPE_CELL_WIDE_IMMEDIATE:
- case CB_GSM_GEOGRAPHICAL_SCOPE_CELL_WIDE:
- hash += this.voiceRegistrationState.cell.gsmLocationAreaCode + ":"
- + this.voiceRegistrationState.cell.gsmCellId;
- break;
- case CB_GSM_GEOGRAPHICAL_SCOPE_LOCATION_AREA_WIDE:
- hash += this.voiceRegistrationState.cell.gsmLocationAreaCode + ":";
- break;
- default:
- hash += ":";
- break;
- }
-
- let index = original.pageIndex;
-
- let options = this._receivedSmsCbPagesMap[hash];
- if (!options) {
- options = original;
- this._receivedSmsCbPagesMap[hash] = options;
-
- options.receivedPages = 0;
- options.pages = [];
- } else if (options.pages[index]) {
- // Duplicated page?
- if (DEBUG) {
- this.context.debug("Got duplicated page no." + index +
- " of a multipage SMSCB: " + JSON.stringify(original));
- }
- return null;
- }
-
- if (options.encoding == PDU_DCS_MSG_CODING_8BITS_ALPHABET) {
- options.pages[index] = original.data;
- delete original.data;
- } else {
- options.pages[index] = original.body;
- delete original.body;
- }
- options.receivedPages++;
- if (options.receivedPages < options.numPages) {
- if (DEBUG) {
- this.context.debug("Got page no." + index + " of a multipage SMSCB: " +
- JSON.stringify(options));
- }
- return null;
- }
-
- // Remove from map
- delete this._receivedSmsCbPagesMap[hash];
-
- // Rebuild full body
- if (options.encoding == PDU_DCS_MSG_CODING_8BITS_ALPHABET) {
- // Uint8Array doesn't have `concat`, so we have to merge all pages by hand.
- let fullDataLen = 0;
- for (let i = 1; i <= options.numPages; i++) {
- fullDataLen += options.pages[i].length;
- }
-
- options.fullData = new Uint8Array(fullDataLen);
- for (let d= 0, i = 1; i <= options.numPages; i++) {
- let data = options.pages[i];
- for (let j = 0; j < data.length; j++) {
- options.fullData[d++] = data[j];
- }
- }
- } else {
- options.fullBody = options.pages.join("");
- }
-
- if (DEBUG) {
- this.context.debug("Got full multipage SMSCB: " + JSON.stringify(options));
- }
-
- return options;
- },
-
- _mergeCellBroadcastConfigs: function(list, from, to) {
- if (!list) {
- return [from, to];
- }
-
- for (let i = 0, f1, t1; i < list.length;) {
- f1 = list[i++];
- t1 = list[i++];
- if (to == f1) {
- // ...[from]...[to|f1]...(t1)
- list[i - 2] = from;
- return list;
- }
-
- if (to < f1) {
- // ...[from]...(to)...[f1] or ...[from]...(to)[f1]
- if (i > 2) {
- // Not the first range pair, merge three arrays.
- return list.slice(0, i - 2).concat([from, to]).concat(list.slice(i - 2));
- } else {
- return [from, to].concat(list);
- }
- }
-
- if (from > t1) {
- // ...[f1]...(t1)[from] or ...[f1]...(t1)...[from]
- continue;
- }
-
- // Have overlap or merge-able adjacency with [f1]...(t1). Replace it
- // with [min(from, f1)]...(max(to, t1)).
-
- let changed = false;
- if (from < f1) {
- // [from]...[f1]...(t1) or [from][f1]...(t1)
- // Save minimum from value.
- list[i - 2] = from;
- changed = true;
- }
-
- if (to <= t1) {
- // [from]...[to](t1) or [from]...(to|t1)
- // Can't have further merge-able adjacency. Return.
- return list;
- }
-
- // Try merging possible next adjacent range.
- let j = i;
- for (let f2, t2; j < list.length;) {
- f2 = list[j++];
- t2 = list[j++];
- if (to > t2) {
- // [from]...[f2]...[t2]...(to) or [from]...[f2]...[t2](to)
- // Merge next adjacent range again.
- continue;
- }
-
- if (to < t2) {
- if (to < f2) {
- // [from]...(to)[f2] or [from]...(to)...[f2]
- // Roll back and give up.
- j -= 2;
- } else if (to < t2) {
- // [from]...[to|f2]...(t2), or [from]...[f2]...[to](t2)
- // Merge to [from]...(t2) and give up.
- to = t2;
- }
- }
-
- break;
- }
-
- // Save maximum to value.
- list[i - 1] = to;
-
- if (j != i) {
- // Remove merged adjacent ranges.
- let ret = list.slice(0, i);
- if (j < list.length) {
- ret = ret.concat(list.slice(j));
- }
- return ret;
- }
-
- return list;
- }
-
- // Append to the end.
- list.push(from);
- list.push(to);
-
- return list;
- },
-
- _isCellBroadcastConfigReady: function() {
- if (!("MMI" in this.cellBroadcastConfigs)) {
- return false;
- }
-
- // CBMI should be ready in GSM.
- if (!this._isCdma &&
- (!("CBMI" in this.cellBroadcastConfigs) ||
- !("CBMID" in this.cellBroadcastConfigs) ||
- !("CBMIR" in this.cellBroadcastConfigs))) {
- return false;
- }
-
- return true;
- },
-
- /**
- * Merge all members of cellBroadcastConfigs into mergedCellBroadcastConfig.
- */
- _mergeAllCellBroadcastConfigs: function() {
- if (!this._isCellBroadcastConfigReady()) {
- if (DEBUG) {
- this.context.debug("cell broadcast configs not ready, waiting ...");
- }
- return;
- }
-
- // Prepare cell broadcast config. CBMI* are only used in GSM.
- let usedCellBroadcastConfigs = {MMI: this.cellBroadcastConfigs.MMI};
- if (!this._isCdma) {
- usedCellBroadcastConfigs.CBMI = this.cellBroadcastConfigs.CBMI;
- usedCellBroadcastConfigs.CBMID = this.cellBroadcastConfigs.CBMID;
- usedCellBroadcastConfigs.CBMIR = this.cellBroadcastConfigs.CBMIR;
- }
-
- if (DEBUG) {
- this.context.debug("Cell Broadcast search lists: " +
- JSON.stringify(usedCellBroadcastConfigs));
- }
-
- let list = null;
- for (let key in usedCellBroadcastConfigs) {
- let ll = usedCellBroadcastConfigs[key];
- if (ll == null) {
- continue;
- }
-
- for (let i = 0; i < ll.length; i += 2) {
- list = this._mergeCellBroadcastConfigs(list, ll[i], ll[i + 1]);
- }
- }
-
- if (DEBUG) {
- this.context.debug("Cell Broadcast search lists(merged): " +
- JSON.stringify(list));
- }
- this.mergedCellBroadcastConfig = list;
- this.updateCellBroadcastConfig();
- },
-
- /**
- * Check whether search list from settings is settable by MMI, that is,
- * whether the range is bounded in any entries of CB_NON_MMI_SETTABLE_RANGES.
- */
- _checkCellBroadcastMMISettable: function(from, to) {
- if ((to <= from) || (from >= 65536) || (from < 0)) {
- return false;
- }
-
- if (!this._isCdma) {
- // GSM not settable ranges.
- for (let i = 0, f, t; i < CB_NON_MMI_SETTABLE_RANGES.length;) {
- f = CB_NON_MMI_SETTABLE_RANGES[i++];
- t = CB_NON_MMI_SETTABLE_RANGES[i++];
- if ((from < t) && (to > f)) {
- // Have overlap.
- return false;
- }
- }
- }
-
- return true;
- },
-
- /**
- * Convert Cell Broadcast settings string into search list.
- */
- _convertCellBroadcastSearchList: function(searchListStr) {
- let parts = searchListStr && searchListStr.split(",");
- if (!parts) {
- return null;
- }
-
- let list = null;
- let result, from, to;
- for (let range of parts) {
- // Match "12" or "12-34". The result will be ["12", "12", null] or
- // ["12-34", "12", "34"].
- result = range.match(/^(\d+)(?:-(\d+))?$/);
- if (!result) {
- throw "Invalid format";
- }
-
- from = parseInt(result[1], 10);
- to = (result[2]) ? parseInt(result[2], 10) + 1 : from + 1;
- if (!this._checkCellBroadcastMMISettable(from, to)) {
- throw "Invalid range";
- }
-
- if (list == null) {
- list = [];
- }
- list.push(from);
- list.push(to);
- }
-
- return list;
- },
-
- /**
- * Handle incoming messages from the main UI thread.
- *
- * @param message
- * Object containing the message. Messages are supposed
- */
- handleChromeMessage: function(message) {
- if (DEBUG) {
- this.context.debug("Received chrome message " + JSON.stringify(message));
- }
- let method = this[message.rilMessageType];
- if (typeof method != "function") {
- if (DEBUG) {
- this.context.debug("Don't know what to do with message " +
- JSON.stringify(message));
- }
- return;
- }
- method.call(this, message);
- },
-
- /**
- * Process STK Proactive Command.
- */
- processStkProactiveCommand: function() {
- let Buf = this.context.Buf;
- let length = Buf.readInt32();
- let berTlv;
- try {
- berTlv = this.context.BerTlvHelper.decode(length / 2);
- } catch (e) {
- if (DEBUG) this.context.debug("processStkProactiveCommand : " + e);
- this.sendStkTerminalResponse({
- resultCode: STK_RESULT_CMD_DATA_NOT_UNDERSTOOD});
- return;
- }
-
- Buf.readStringDelimiter(length);
-
- let ctlvs = berTlv.value;
- let ctlv = this.context.StkProactiveCmdHelper.searchForTag(
- COMPREHENSIONTLV_TAG_COMMAND_DETAILS, ctlvs);
- if (!ctlv) {
- this.sendStkTerminalResponse({
- resultCode: STK_RESULT_CMD_DATA_NOT_UNDERSTOOD});
- throw new Error("Can't find COMMAND_DETAILS ComprehensionTlv");
- }
-
- let cmdDetails = ctlv.value;
- if (DEBUG) {
- this.context.debug("commandNumber = " + cmdDetails.commandNumber +
- " typeOfCommand = " + cmdDetails.typeOfCommand.toString(16) +
- " commandQualifier = " + cmdDetails.commandQualifier);
- }
-
- // STK_CMD_MORE_TIME need not to propagate event to chrome.
- if (cmdDetails.typeOfCommand == STK_CMD_MORE_TIME) {
- this.sendStkTerminalResponse({
- command: cmdDetails,
- resultCode: STK_RESULT_OK});
- return;
- }
-
- this.context.StkCommandParamsFactory.createParam(cmdDetails,
- ctlvs,
- (aResult) => {
- cmdDetails.options = aResult;
- cmdDetails.rilMessageType = "stkcommand";
- this.sendChromeMessage(cmdDetails);
- });
- },
-
- sendDefaultResponse: function(options) {
- if (!options.rilMessageType) {
- return;
- }
-
- this.sendChromeMessage(options);
- },
-
- /**
- * Send messages to the main thread.
- */
- sendChromeMessage: function(message) {
- message.rilMessageClientId = this.context.clientId;
- postMessage(message);
- },
-
- /**
- * Handle incoming requests from the RIL. We find the method that
- * corresponds to the request type. Incidentally, the request type
- * _is_ the method name, so that's easy.
- */
-
- handleParcel: function(request_type, length, options) {
- let method = this[request_type];
- if (typeof method == "function") {
- if (DEBUG) this.context.debug("Handling parcel as " + method.name);
- method.call(this, length, options);
- }
-
- if (this.telephonyRequestQueue.isValidRequest(request_type)) {
- this.telephonyRequestQueue.pop(request_type);
- }
- }
-};
-
-RilObject.prototype[REQUEST_GET_SIM_STATUS] = function REQUEST_GET_SIM_STATUS(length, options) {
- if (options.errorMsg) {
- return;
- }
-
- let iccStatus = {};
- let Buf = this.context.Buf;
- iccStatus.cardState = Buf.readInt32(); // CARD_STATE_*
- iccStatus.universalPINState = Buf.readInt32(); // CARD_PINSTATE_*
- iccStatus.gsmUmtsSubscriptionAppIndex = Buf.readInt32();
- iccStatus.cdmaSubscriptionAppIndex = Buf.readInt32();
- iccStatus.imsSubscriptionAppIndex = Buf.readInt32();
-
- let apps_length = Buf.readInt32();
- if (apps_length > CARD_MAX_APPS) {
- apps_length = CARD_MAX_APPS;
- }
-
- iccStatus.apps = [];
- for (let i = 0 ; i < apps_length ; i++) {
- iccStatus.apps.push({
- app_type: Buf.readInt32(), // CARD_APPTYPE_*
- app_state: Buf.readInt32(), // CARD_APPSTATE_*
- perso_substate: Buf.readInt32(), // CARD_PERSOSUBSTATE_*
- aid: Buf.readString(),
- app_label: Buf.readString(),
- pin1_replaced: Buf.readInt32(),
- pin1: Buf.readInt32(),
- pin2: Buf.readInt32()
- });
- if (RILQUIRKS_SIM_APP_STATE_EXTRA_FIELDS) {
- Buf.readInt32();
- Buf.readInt32();
- Buf.readInt32();
- Buf.readInt32();
- }
- }
-
- if (DEBUG) this.context.debug("iccStatus: " + JSON.stringify(iccStatus));
- this._processICCStatus(iccStatus);
-};
-RilObject.prototype[REQUEST_ENTER_SIM_PIN] = function REQUEST_ENTER_SIM_PIN(length, options) {
- this._processEnterAndChangeICCResponses(length, options);
-};
-RilObject.prototype[REQUEST_ENTER_SIM_PUK] = function REQUEST_ENTER_SIM_PUK(length, options) {
- this._processEnterAndChangeICCResponses(length, options);
-};
-RilObject.prototype[REQUEST_ENTER_SIM_PIN2] = function REQUEST_ENTER_SIM_PIN2(length, options) {
- this._processEnterAndChangeICCResponses(length, options);
-};
-RilObject.prototype[REQUEST_ENTER_SIM_PUK2] = function REQUEST_ENTER_SIM_PUK(length, options) {
- this._processEnterAndChangeICCResponses(length, options);
-};
-RilObject.prototype[REQUEST_CHANGE_SIM_PIN] = function REQUEST_CHANGE_SIM_PIN(length, options) {
- this._processEnterAndChangeICCResponses(length, options);
-};
-RilObject.prototype[REQUEST_CHANGE_SIM_PIN2] = function REQUEST_CHANGE_SIM_PIN2(length, options) {
- this._processEnterAndChangeICCResponses(length, options);
-};
-RilObject.prototype[REQUEST_ENTER_NETWORK_DEPERSONALIZATION_CODE] =
- function REQUEST_ENTER_NETWORK_DEPERSONALIZATION_CODE(length, options) {
- this._processEnterAndChangeICCResponses(length, options);
-};
-RilObject.prototype[REQUEST_GET_CURRENT_CALLS] = function REQUEST_GET_CURRENT_CALLS(length, options) {
- // Retry getCurrentCalls several times when error occurs.
- if (options.errorMsg) {
- if (this._getCurrentCallsRetryCount < GET_CURRENT_CALLS_RETRY_MAX) {
- this._getCurrentCallsRetryCount++;
- this.getCurrentCalls(options);
- } else {
- this.sendDefaultResponse(options);
- }
- return;
- }
-
- this._getCurrentCallsRetryCount = 0;
-
- let Buf = this.context.Buf;
- let calls_length = 0;
- // The RIL won't even send us the length integer if there are no active calls.
- // So only read this integer if the parcel actually has it.
- if (length) {
- calls_length = Buf.readInt32();
- }
-
- let calls = {};
- for (let i = 0; i < calls_length; i++) {
- let call = {};
-
- // Extra uint32 field to get correct callIndex and rest of call data for
- // call waiting feature.
- if (RILQUIRKS_EXTRA_UINT32_2ND_CALL && i > 0) {
- Buf.readInt32();
- }
-
- call.state = Buf.readInt32(); // CALL_STATE_*
- call.callIndex = Buf.readInt32(); // GSM index (1-based)
- call.toa = Buf.readInt32();
- call.isMpty = Boolean(Buf.readInt32());
- call.isMT = Boolean(Buf.readInt32());
- call.als = Buf.readInt32();
- call.isVoice = Boolean(Buf.readInt32());
- call.isVoicePrivacy = Boolean(Buf.readInt32());
- if (RILQUIRKS_CALLSTATE_EXTRA_UINT32) {
- Buf.readInt32();
- }
- call.number = Buf.readString();
- call.numberPresentation = Buf.readInt32(); // CALL_PRESENTATION_*
- call.name = Buf.readString();
- call.namePresentation = Buf.readInt32();
-
- call.uusInfo = null;
- let uusInfoPresent = Buf.readInt32();
- if (uusInfoPresent == 1) {
- call.uusInfo = {
- type: Buf.readInt32(),
- dcs: Buf.readInt32(),
- userData: null //XXX TODO byte array?!?
- };
- }
-
- if (call.isVoice) {
- calls[call.callIndex] = call;
- }
- }
-
- options.calls = calls;
- options.rilMessageType = options.rilMessageType || "currentCalls";
- this.sendChromeMessage(options);
-};
-RilObject.prototype[REQUEST_DIAL] = function REQUEST_DIAL(length, options) {
- this.sendDefaultResponse(options);
-};
-RilObject.prototype[REQUEST_DIAL_EMERGENCY_CALL] = function REQUEST_DIAL_EMERGENCY_CALL(length, options) {
- RilObject.prototype[REQUEST_DIAL].call(this, length, options);
-};
-RilObject.prototype[REQUEST_GET_IMSI] = function REQUEST_GET_IMSI(length, options) {
- if (options.errorMsg) {
- return;
- }
-
- this.iccInfoPrivate.imsi = this.context.Buf.readString();
- if (DEBUG) {
- this.context.debug("IMSI: " + this.iccInfoPrivate.imsi);
- }
-
- options.rilMessageType = "iccimsi";
- options.imsi = this.iccInfoPrivate.imsi;
- this.sendChromeMessage(options);
-};
-RilObject.prototype[REQUEST_HANGUP] = function REQUEST_HANGUP(length, options) {
- this.sendDefaultResponse(options);
-};
-RilObject.prototype[REQUEST_HANGUP_WAITING_OR_BACKGROUND] = function REQUEST_HANGUP_WAITING_OR_BACKGROUND(length, options) {
- this.sendDefaultResponse(options);
-};
-RilObject.prototype[REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND] = function REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND(length, options) {
- this.sendDefaultResponse(options);
-};
-RilObject.prototype[REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE] = function REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE(length, options) {
- this.sendDefaultResponse(options);
-};
-RilObject.prototype[REQUEST_CONFERENCE] = function REQUEST_CONFERENCE(length, options) {
- this.sendDefaultResponse(options);
-};
-RilObject.prototype[REQUEST_UDUB] = function REQUEST_UDUB(length, options) {
- this.sendDefaultResponse(options);
-};
-RilObject.prototype[REQUEST_LAST_CALL_FAIL_CAUSE] = function REQUEST_LAST_CALL_FAIL_CAUSE(length, options) {
- // Treat it as CALL_FAIL_ERROR_UNSPECIFIED if the request failed.
- let failCause = CALL_FAIL_ERROR_UNSPECIFIED;
-
- if (!options.errorMsg) {
- let Buf = this.context.Buf;
- let num = length ? Buf.readInt32() : 0;
-
- if (num) {
- let causeNum = Buf.readInt32();
- failCause = RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[causeNum] || failCause;
- }
- if (DEBUG) this.context.debug("Last call fail cause: " + failCause);
- }
-
- options.failCause = failCause;
- this.sendChromeMessage(options);
-};
-RilObject.prototype[REQUEST_SIGNAL_STRENGTH] = function REQUEST_SIGNAL_STRENGTH(length, options) {
- this._receivedNetworkInfo(NETWORK_INFO_SIGNAL);
-
- if (options.errorMsg) {
- return;
- }
-
- let Buf = this.context.Buf;
- let signal = {};
-
- signal.gsmSignalStrength = Buf.readInt32();
- signal.gsmBitErrorRate = Buf.readInt32();
- if (RILQUIRKS_SIGNAL_EXTRA_INT32) {
- Buf.readInt32();
- }
- signal.cdmaDBM = Buf.readInt32();
- signal.cdmaECIO = Buf.readInt32();
- signal.evdoDBM = Buf.readInt32();
- signal.evdoECIO = Buf.readInt32();
- signal.evdoSNR = Buf.readInt32();
-
- signal.lteSignalStrength = Buf.readInt32();
- signal.lteRSRP = Buf.readInt32();
- signal.lteRSRQ = Buf.readInt32();
- signal.lteRSSNR = Buf.readInt32();
- signal.lteCQI = Buf.readInt32();
-
- if (DEBUG) this.context.debug("signal strength: " + JSON.stringify(signal));
-
- this._processSignalStrength(signal);
-};
-RilObject.prototype[REQUEST_VOICE_REGISTRATION_STATE] = function REQUEST_VOICE_REGISTRATION_STATE(length, options) {
- this._receivedNetworkInfo(NETWORK_INFO_VOICE_REGISTRATION_STATE);
-
- if (options.errorMsg) {
- return;
- }
-
- let state = this.context.Buf.readStringList();
- if (DEBUG) this.context.debug("voice registration state: " + state);
-
- this._processVoiceRegistrationState(state);
-};
-RilObject.prototype[REQUEST_DATA_REGISTRATION_STATE] = function REQUEST_DATA_REGISTRATION_STATE(length, options) {
- this._receivedNetworkInfo(NETWORK_INFO_DATA_REGISTRATION_STATE);
-
- if (options.errorMsg) {
- return;
- }
-
- let state = this.context.Buf.readStringList();
- this._processDataRegistrationState(state);
-};
-RilObject.prototype[REQUEST_OPERATOR] = function REQUEST_OPERATOR(length, options) {
- this._receivedNetworkInfo(NETWORK_INFO_OPERATOR);
-
- if (options.errorMsg) {
- return;
- }
-
- let operatorData = this.context.Buf.readStringList();
- if (DEBUG) this.context.debug("Operator: " + operatorData);
- this._processOperator(operatorData);
-};
-RilObject.prototype[REQUEST_RADIO_POWER] = function REQUEST_RADIO_POWER(length, options) {
- this.sendDefaultResponse(options);
-};
-RilObject.prototype[REQUEST_DTMF] = null;
-RilObject.prototype[REQUEST_SEND_SMS] = function REQUEST_SEND_SMS(length, options) {
- this._processSmsSendResult(length, options);
-};
-RilObject.prototype[REQUEST_SEND_SMS_EXPECT_MORE] = null;
-
-RilObject.prototype[REQUEST_SETUP_DATA_CALL] = function REQUEST_SETUP_DATA_CALL(length, options) {
- if (options.errorMsg) {
- this.sendChromeMessage(options);
- return;
- }
-
- let Buf = this.context.Buf;
- let version = Buf.readInt32();
- // Skip number of data calls.
- Buf.readInt32();
-
- this.readDataCall(options, version);
- this.sendChromeMessage(options);
-};
-RilObject.prototype[REQUEST_SIM_IO] = function REQUEST_SIM_IO(length, options) {
- if (options.errorMsg) {
- if (options.onerror) {
- options.onerror(options.errorMsg);
- }
- return;
- }
-
- let Buf = this.context.Buf;
- options.sw1 = Buf.readInt32();
- options.sw2 = Buf.readInt32();
-
- // See 3GPP TS 11.11, clause 9.4.1 for operation success results.
- if (options.sw1 !== ICC_STATUS_NORMAL_ENDING &&
- options.sw1 !== ICC_STATUS_NORMAL_ENDING_WITH_EXTRA &&
- options.sw1 !== ICC_STATUS_WITH_SIM_DATA &&
- options.sw1 !== ICC_STATUS_WITH_RESPONSE_DATA) {
- if (DEBUG) {
- this.context.debug("ICC I/O Error EF id = 0x" + options.fileId.toString(16) +
- ", command = 0x" + options.command.toString(16) +
- ", sw1 = 0x" + options.sw1.toString(16) +
- ", sw2 = 0x" + options.sw2.toString(16));
- }
- if (options.onerror) {
- // We can get fail cause from sw1/sw2 (See TS 11.11 clause 9.4.1 and
- // ISO 7816-4 clause 6). But currently no one needs this information,
- // so simply reports "GenericFailure" for now.
- options.onerror(GECKO_ERROR_GENERIC_FAILURE);
- }
- return;
- }
- this.context.ICCIOHelper.processICCIO(options);
-};
-RilObject.prototype[REQUEST_SEND_USSD] = function REQUEST_SEND_USSD(length, options) {
- if (DEBUG) {
- this.context.debug("REQUEST_SEND_USSD " + JSON.stringify(options));
- }
- this.sendChromeMessage(options);
-};
-RilObject.prototype[REQUEST_CANCEL_USSD] = function REQUEST_CANCEL_USSD(length, options) {
- if (DEBUG) {
- this.context.debug("REQUEST_CANCEL_USSD" + JSON.stringify(options));
- }
- this.sendChromeMessage(options);
-};
-RilObject.prototype[REQUEST_GET_CLIR] = function REQUEST_GET_CLIR(length, options) {
- if (options.errorMsg) {
- this.sendChromeMessage(options);
- return;
- }
-
- let Buf = this.context.Buf;
- let bufLength = Buf.readInt32();
- if (!bufLength || bufLength < 2) {
- options.errorMsg = GECKO_ERROR_GENERIC_FAILURE;
- this.sendChromeMessage(options);
- return;
- }
-
- options.n = Buf.readInt32(); // Will be TS 27.007 +CLIR parameter 'n'.
- options.m = Buf.readInt32(); // Will be TS 27.007 +CLIR parameter 'm'.
- this.sendChromeMessage(options);
-};
-RilObject.prototype[REQUEST_SET_CLIR] = function REQUEST_SET_CLIR(length, options) {
- if (options.rilMessageType == null) {
- // The request was made by ril_worker itself automatically. Don't report.
- return;
- }
-
- this.sendChromeMessage(options);
-};
-
-RilObject.prototype[REQUEST_QUERY_CALL_FORWARD_STATUS] =
- function REQUEST_QUERY_CALL_FORWARD_STATUS(length, options) {
- if (options.errorMsg) {
- this.sendChromeMessage(options);
- return;
- }
-
- let Buf = this.context.Buf;
- let rulesLength = 0;
- if (length) {
- rulesLength = Buf.readInt32();
- }
- if (!rulesLength) {
- options.errorMsg = GECKO_ERROR_GENERIC_FAILURE;
- this.sendChromeMessage(options);
- return;
- }
- let rules = new Array(rulesLength);
- for (let i = 0; i < rulesLength; i++) {
- let rule = {};
- rule.active = Buf.readInt32() == 1; // CALL_FORWARD_STATUS_*
- rule.reason = Buf.readInt32(); // CALL_FORWARD_REASON_*
- rule.serviceClass = Buf.readInt32();
- rule.toa = Buf.readInt32();
- rule.number = Buf.readString();
- rule.timeSeconds = Buf.readInt32();
- rules[i] = rule;
- }
- options.rules = rules;
- this.sendChromeMessage(options);
-};
-RilObject.prototype[REQUEST_SET_CALL_FORWARD] =
- function REQUEST_SET_CALL_FORWARD(length, options) {
- this.sendChromeMessage(options);
-};
-RilObject.prototype[REQUEST_QUERY_CALL_WAITING] =
- function REQUEST_QUERY_CALL_WAITING(length, options) {
- if (options.errorMsg) {
- this.sendChromeMessage(options);
- return;
- }
-
- let Buf = this.context.Buf;
- let results = Buf.readInt32List();
- let enabled = (results[0] === 1);
- options.serviceClass = enabled ? results[1] : ICC_SERVICE_CLASS_NONE;
- this.sendChromeMessage(options);
-};
-
-RilObject.prototype[REQUEST_SET_CALL_WAITING] = function REQUEST_SET_CALL_WAITING(length, options) {
- this.sendChromeMessage(options);
-};
-RilObject.prototype[REQUEST_SMS_ACKNOWLEDGE] = null;
-RilObject.prototype[REQUEST_GET_IMEI] = null;
-RilObject.prototype[REQUEST_GET_IMEISV] = null;
-RilObject.prototype[REQUEST_ANSWER] = function REQUEST_ANSWER(length, options) {
- this.sendDefaultResponse(options);
-};
-RilObject.prototype[REQUEST_DEACTIVATE_DATA_CALL] = function REQUEST_DEACTIVATE_DATA_CALL(length, options) {
- this.sendChromeMessage(options);
-};
-RilObject.prototype[REQUEST_QUERY_FACILITY_LOCK] = function REQUEST_QUERY_FACILITY_LOCK(length, options) {
- if (options.errorMsg) {
- this.sendChromeMessage(options);
- return;
- }
-
- if (!length) {
- options.errorMsg = GECKO_ERROR_GENERIC_FAILURE;
- this.sendChromeMessage(options);
- return;
- }
-
- // Buf.readInt32List()[0] for Call Barring is a bit vector of services.
- options.serviceClass = this.context.Buf.readInt32List()[0];
- if (options.queryServiceClass) {
- options.enabled = (options.serviceClass & options.queryServiceClass) ? true : false;
- options.serviceClass = options.queryServiceClass;
- } else {
- options.enabled = options.serviceClass ? true : false;
- }
-
- this.sendChromeMessage(options);
-};
-RilObject.prototype[REQUEST_SET_FACILITY_LOCK] = function REQUEST_SET_FACILITY_LOCK(length, options) {
- options.retryCount = length ? this.context.Buf.readInt32List()[0] : -1;
- this.sendChromeMessage(options);
-};
-RilObject.prototype[REQUEST_CHANGE_BARRING_PASSWORD] =
- function REQUEST_CHANGE_BARRING_PASSWORD(length, options) {
- this.sendChromeMessage(options);
-};
-RilObject.prototype[REQUEST_QUERY_NETWORK_SELECTION_MODE] = function REQUEST_QUERY_NETWORK_SELECTION_MODE(length, options) {
- this._receivedNetworkInfo(NETWORK_INFO_NETWORK_SELECTION_MODE);
-
- if (options.errorMsg) {
- return;
- }
-
- let mode = this.context.Buf.readInt32List();
- let selectionMode;
-
- switch (mode[0]) {
- case NETWORK_SELECTION_MODE_AUTOMATIC:
- selectionMode = GECKO_NETWORK_SELECTION_AUTOMATIC;
- break;
- case NETWORK_SELECTION_MODE_MANUAL:
- selectionMode = GECKO_NETWORK_SELECTION_MANUAL;
- break;
- default:
- selectionMode = GECKO_NETWORK_SELECTION_UNKNOWN;
- break;
- }
-
- this._updateNetworkSelectionMode(selectionMode);
-};
-RilObject.prototype[REQUEST_SET_NETWORK_SELECTION_AUTOMATIC] = function REQUEST_SET_NETWORK_SELECTION_AUTOMATIC(length, options) {
- if (!options.errorMsg) {
- this._updateNetworkSelectionMode(GECKO_NETWORK_SELECTION_AUTOMATIC);
- }
- this.sendChromeMessage(options);
-};
-RilObject.prototype[REQUEST_SET_NETWORK_SELECTION_MANUAL] = function REQUEST_SET_NETWORK_SELECTION_MANUAL(length, options) {
- if (!options.errorMsg) {
- this._updateNetworkSelectionMode(GECKO_NETWORK_SELECTION_MANUAL);
- }
- this.sendChromeMessage(options);
-};
-RilObject.prototype[REQUEST_QUERY_AVAILABLE_NETWORKS] = function REQUEST_QUERY_AVAILABLE_NETWORKS(length, options) {
- if (!options.errorMsg) {
- options.networks = this._processNetworks();
- }
- this.sendChromeMessage(options);
-};
-RilObject.prototype[REQUEST_DTMF_START] = function REQUEST_DTMF_START(length, options) {
- this.sendChromeMessage(options);
-};
-RilObject.prototype[REQUEST_DTMF_STOP] = null;
-RilObject.prototype[REQUEST_BASEBAND_VERSION] = function REQUEST_BASEBAND_VERSION(length, options) {
- if (options.errorMsg) {
- return;
- }
-
- this.basebandVersion = this.context.Buf.readString();
- if (DEBUG) this.context.debug("Baseband version: " + this.basebandVersion);
-};
-RilObject.prototype[REQUEST_SEPARATE_CONNECTION] = function REQUEST_SEPARATE_CONNECTION(length, options) {
- this.sendDefaultResponse(options);
-};
-RilObject.prototype[REQUEST_SET_MUTE] = null;
-RilObject.prototype[REQUEST_GET_MUTE] = null;
-RilObject.prototype[REQUEST_QUERY_CLIP] = function REQUEST_QUERY_CLIP(length, options) {
- if (options.errorMsg) {
- this.sendChromeMessage(options);
- return;
- }
-
- let Buf = this.context.Buf;
- let bufLength = Buf.readInt32();
- if (!bufLength) {
- options.errorMsg = GECKO_ERROR_GENERIC_FAILURE;
- this.sendChromeMessage(options);
- return;
- }
-
- options.provisioned = Buf.readInt32();
- this.sendChromeMessage(options);
-};
-RilObject.prototype[REQUEST_LAST_DATA_CALL_FAIL_CAUSE] = null;
-
-/**
- * V6:
- * # addresses - A space-delimited list of addresses with optional "/" prefix
- * length.
- * # dnses - A space-delimited list of DNS server addresses.
- * # gateways - A space-delimited list of default gateway addresses.
- *
- * V10:
- * # pcscf - A space-delimited list of Proxy Call State Control Function
- * addresses.
- */
-
-RilObject.prototype.readDataCall = function(options, version) {
- if (!options) {
- options = {};
- }
- let Buf = this.context.Buf;
- options.failCause = Buf.readInt32(); // DATACALL_FAIL_*
- options.suggestedRetryTime = Buf.readInt32();
- options.cid = Buf.readInt32().toString();
- options.active = Buf.readInt32(); // DATACALL_ACTIVE_*
- options.type = Buf.readString();
- options.ifname = Buf.readString();
- options.addresses = Buf.readString();
- options.dnses = Buf.readString();
- options.gateways = Buf.readString();
-
- if (version >= 10) {
- options.pcscf = Buf.readString();
- }
-
- if (version >= 11) {
- let mtu = Buf.readInt32();
- options.mtu = (mtu > 0) ? mtu : -1 ;
- }
-
- return options;
-};
-
-RilObject.prototype[REQUEST_DATA_CALL_LIST] = function REQUEST_DATA_CALL_LIST(length, options) {
- if (options.errorMsg) {
- if (options.rilMessageType) {
- this.sendChromeMessage(options);
- }
- return;
- }
-
- if (!options.rilMessageType) {
- // This is an unsolicited data call list changed.
- options.rilMessageType = "datacalllistchanged";
- }
-
- if (!length) {
- options.datacalls = [];
- this.sendChromeMessage(options);
- return;
- }
-
- let Buf = this.context.Buf;
- let version = Buf.readInt32();
- let num = Buf.readInt32();
- let datacalls = [];
- for (let i = 0; i < num; i++) {
- let datacall;
- datacall = this.readDataCall({}, version);
- datacalls.push(datacall);
- }
-
- options.datacalls = datacalls;
- this.sendChromeMessage(options);
-};
-RilObject.prototype[REQUEST_RESET_RADIO] = null;
-RilObject.prototype[REQUEST_OEM_HOOK_RAW] = null;
-RilObject.prototype[REQUEST_OEM_HOOK_STRINGS] = null;
-RilObject.prototype[REQUEST_SCREEN_STATE] = null;
-RilObject.prototype[REQUEST_SET_SUPP_SVC_NOTIFICATION] = null;
-RilObject.prototype[REQUEST_WRITE_SMS_TO_SIM] = function REQUEST_WRITE_SMS_TO_SIM(length, options) {
- if (options.errorMsg) {
- // `The MS shall return a "protocol error, unspecified" error message if
- // the short message cannot be stored in the (U)SIM, and there is other
- // message storage available at the MS` ~ 3GPP TS 23.038 section 4. Here
- // we assume we always have indexed db as another storage.
- this.acknowledgeGsmSms(false, PDU_FCS_PROTOCOL_ERROR);
- } else {
- this.acknowledgeGsmSms(true, PDU_FCS_OK);
- }
-};
-RilObject.prototype[REQUEST_DELETE_SMS_ON_SIM] = null;
-RilObject.prototype[REQUEST_SET_BAND_MODE] = null;
-RilObject.prototype[REQUEST_QUERY_AVAILABLE_BAND_MODE] = null;
-RilObject.prototype[REQUEST_STK_GET_PROFILE] = null;
-RilObject.prototype[REQUEST_STK_SET_PROFILE] = null;
-RilObject.prototype[REQUEST_STK_SEND_ENVELOPE_COMMAND] = null;
-RilObject.prototype[REQUEST_STK_SEND_TERMINAL_RESPONSE] = null;
-RilObject.prototype[REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM] = null;
-RilObject.prototype[REQUEST_EXPLICIT_CALL_TRANSFER] = null;
-RilObject.prototype[REQUEST_SET_PREFERRED_NETWORK_TYPE] = function REQUEST_SET_PREFERRED_NETWORK_TYPE(length, options) {
- this.sendChromeMessage(options);
-};
-RilObject.prototype[REQUEST_GET_PREFERRED_NETWORK_TYPE] = function REQUEST_GET_PREFERRED_NETWORK_TYPE(length, options) {
- if (options.errorMsg) {
- this.sendChromeMessage(options);
- return;
- }
-
- options.type = this.context.Buf.readInt32List()[0];
- this.sendChromeMessage(options);
-};
-RilObject.prototype[REQUEST_GET_NEIGHBORING_CELL_IDS] = function REQUEST_GET_NEIGHBORING_CELL_IDS(length, options) {
- if (options.errorMsg) {
- this.sendChromeMessage(options);
- return;
- }
-
- let radioTech = this.voiceRegistrationState.radioTech;
- if (radioTech == undefined || radioTech == NETWORK_CREG_TECH_UNKNOWN) {
- options.errorMsg = "RadioTechUnavailable";
- this.sendChromeMessage(options);
- return;
- }
- if (!this._isGsmTechGroup(radioTech) || radioTech == NETWORK_CREG_TECH_LTE) {
- options.errorMsg = "UnsupportedRadioTech";
- this.sendChromeMessage(options);
- return;
- }
-
- let Buf = this.context.Buf;
- let neighboringCellIds = [];
- let num = Buf.readInt32();
-
- for (let i = 0; i < num; i++) {
- let cellId = {};
- cellId.networkType = GECKO_RADIO_TECH[radioTech];
- cellId.signalStrength = Buf.readInt32();
-
- let cid = Buf.readString();
- // pad cid string with leading "0"
- let length = cid.length;
- if (length > 8) {
- continue;
- }
- if (length < 8) {
- for (let j = 0; j < (8-length); j++) {
- cid = "0" + cid;
- }
- }
-
- switch (radioTech) {
- case NETWORK_CREG_TECH_GPRS:
- case NETWORK_CREG_TECH_EDGE:
- case NETWORK_CREG_TECH_GSM:
- cellId.gsmCellId = this.parseInt(cid.substring(4), -1, 16);
- cellId.gsmLocationAreaCode = this.parseInt(cid.substring(0, 4), -1, 16);
- break;
- case NETWORK_CREG_TECH_UMTS:
- case NETWORK_CREG_TECH_HSDPA:
- case NETWORK_CREG_TECH_HSUPA:
- case NETWORK_CREG_TECH_HSPA:
- case NETWORK_CREG_TECH_HSPAP:
- case NETWORK_CREG_TECH_DCHSPAP_1:
- case NETWORK_CREG_TECH_DCHSPAP_2:
- cellId.wcdmaPsc = this.parseInt(cid, -1, 16);
- break;
- }
-
- neighboringCellIds.push(cellId);
- }
-
- options.result = neighboringCellIds;
- this.sendChromeMessage(options);
-};
-RilObject.prototype[REQUEST_GET_CELL_INFO_LIST] = function REQUEST_GET_CELL_INFO_LIST(length, options) {
- if (options.errorMsg) {
- this.sendChromeMessage(options);
- return;
- }
-
- let Buf = this.context.Buf;
- let cellInfoList = [];
- let num = Buf.readInt32();
- for (let i = 0; i < num; i++) {
- let cellInfo = {};
- cellInfo.type = Buf.readInt32();
- cellInfo.registered = Buf.readInt32() ? true : false;
- cellInfo.timestampType = Buf.readInt32();
- cellInfo.timestamp = Buf.readInt64();
-
- switch(cellInfo.type) {
- case CELL_INFO_TYPE_GSM:
- case CELL_INFO_TYPE_WCDMA:
- cellInfo.mcc = Buf.readInt32();
- cellInfo.mnc = Buf.readInt32();
- cellInfo.lac = Buf.readInt32();
- cellInfo.cid = Buf.readInt32();
- if (cellInfo.type == CELL_INFO_TYPE_WCDMA) {
- cellInfo.psc = Buf.readInt32();
- }
- cellInfo.signalStrength = Buf.readInt32();
- cellInfo.bitErrorRate = Buf.readInt32();
- break;
- case CELL_INFO_TYPE_CDMA:
- cellInfo.networkId = Buf.readInt32();
- cellInfo.systemId = Buf.readInt32();
- cellInfo.basestationId = Buf.readInt32();
- cellInfo.longitude = Buf.readInt32();
- cellInfo.latitude = Buf.readInt32();
- cellInfo.cdmaDbm = Buf.readInt32();
- cellInfo.cdmaEcio = Buf.readInt32();
- cellInfo.evdoDbm = Buf.readInt32();
- cellInfo.evdoEcio = Buf.readInt32();
- cellInfo.evdoSnr = Buf.readInt32();
- break;
- case CELL_INFO_TYPE_LTE:
- cellInfo.mcc = Buf.readInt32();
- cellInfo.mnc = Buf.readInt32();
- cellInfo.cid = Buf.readInt32();
- cellInfo.pcid = Buf.readInt32();
- cellInfo.tac = Buf.readInt32();
- cellInfo.signalStrength = Buf.readInt32();
- cellInfo.rsrp = Buf.readInt32();
- cellInfo.rsrq = Buf.readInt32();
- cellInfo.rssnr = Buf.readInt32();
- cellInfo.cqi = Buf.readInt32();
- break;
- }
- cellInfoList.push(cellInfo);
- }
- options.result = cellInfoList;
- this.sendChromeMessage(options);
-};
-RilObject.prototype[REQUEST_SET_LOCATION_UPDATES] = null;
-RilObject.prototype[REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE] = null;
-RilObject.prototype[REQUEST_CDMA_SET_ROAMING_PREFERENCE] = function REQUEST_CDMA_SET_ROAMING_PREFERENCE(length, options) {
- this.sendChromeMessage(options);
-};
-RilObject.prototype[REQUEST_CDMA_QUERY_ROAMING_PREFERENCE] = function REQUEST_CDMA_QUERY_ROAMING_PREFERENCE(length, options) {
- if (!options.errorMsg) {
- options.mode = this.context.Buf.readInt32List()[0];
- }
- this.sendChromeMessage(options);
-};
-RilObject.prototype[REQUEST_SET_TTY_MODE] = null;
-RilObject.prototype[REQUEST_QUERY_TTY_MODE] = null;
-RilObject.prototype[REQUEST_CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE] = function REQUEST_CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE(length, options) {
- this.sendChromeMessage(options);
-};
-RilObject.prototype[REQUEST_CDMA_QUERY_PREFERRED_VOICE_PRIVACY_MODE] = function REQUEST_CDMA_QUERY_PREFERRED_VOICE_PRIVACY_MODE(length, options) {
- if (options.errorMsg) {
- this.sendChromeMessage(options);
- return;
- }
-
- let enabled = this.context.Buf.readInt32List();
- options.enabled = enabled[0] ? true : false;
- this.sendChromeMessage(options);
-};
-RilObject.prototype[REQUEST_CDMA_FLASH] = function REQUEST_CDMA_FLASH(length, options) {
- this.sendDefaultResponse(options);
-};
-RilObject.prototype[REQUEST_CDMA_BURST_DTMF] = null;
-RilObject.prototype[REQUEST_CDMA_VALIDATE_AND_WRITE_AKEY] = null;
-RilObject.prototype[REQUEST_CDMA_SEND_SMS] = function REQUEST_CDMA_SEND_SMS(length, options) {
- this._processSmsSendResult(length, options);
-};
-RilObject.prototype[REQUEST_CDMA_SMS_ACKNOWLEDGE] = null;
-RilObject.prototype[REQUEST_GSM_GET_BROADCAST_SMS_CONFIG] = null;
-RilObject.prototype[REQUEST_GSM_SET_BROADCAST_SMS_CONFIG] = function REQUEST_GSM_SET_BROADCAST_SMS_CONFIG(length, options) {
- if (options.errorMsg) {
- return;
- }
- this.setSmsBroadcastActivation(true);
-};
-RilObject.prototype[REQUEST_GSM_SMS_BROADCAST_ACTIVATION] = null;
-RilObject.prototype[REQUEST_CDMA_GET_BROADCAST_SMS_CONFIG] = null;
-RilObject.prototype[REQUEST_CDMA_SET_BROADCAST_SMS_CONFIG] = function REQUEST_CDMA_SET_BROADCAST_SMS_CONFIG(length, options) {
- if (options.errorMsg) {
- return;
- }
- this.setSmsBroadcastActivation(true);
-};
-RilObject.prototype[REQUEST_CDMA_SMS_BROADCAST_ACTIVATION] = null;
-RilObject.prototype[REQUEST_CDMA_SUBSCRIPTION] = function REQUEST_CDMA_SUBSCRIPTION(length, options) {
- if (options.errorMsg) {
- return;
- }
-
- let result = this.context.Buf.readStringList();
-
- this.iccInfo.mdn = result[0];
- // The result[1] is Home SID. (Already be handled in readCDMAHome())
- // The result[2] is Home NID. (Already be handled in readCDMAHome())
- // The result[3] is MIN.
- this.iccInfo.prlVersion = parseInt(result[4], 10);
-
- this.context.ICCUtilsHelper.handleICCInfoChange();
-};
-RilObject.prototype[REQUEST_CDMA_WRITE_SMS_TO_RUIM] = null;
-RilObject.prototype[REQUEST_CDMA_DELETE_SMS_ON_RUIM] = null;
-RilObject.prototype[REQUEST_DEVICE_IDENTITY] = function REQUEST_DEVICE_IDENTITY(length, options) {
- if (options.errorMsg) {
- this.context.debug("Failed to get device identities:" + options.errorMsg);
- return;
- }
-
- let result = this.context.Buf.readStringList();
- this.deviceIdentities = {
- imei: result[0] || null,
- imeisv: result[1] || null,
- esn: result[2] || null,
- meid: result[3] || null,
- };
-
- this.sendChromeMessage({
- rilMessageType: "deviceidentitieschange",
- deviceIdentities: this.deviceIdentities
- });
-};
-RilObject.prototype[REQUEST_EXIT_EMERGENCY_CALLBACK_MODE] = function REQUEST_EXIT_EMERGENCY_CALLBACK_MODE(length, options) {
- if (options.internal) {
- return;
- }
-
- this.sendChromeMessage(options);
-};
-RilObject.prototype[REQUEST_GET_SMSC_ADDRESS] = function REQUEST_GET_SMSC_ADDRESS(length, options) {
- if (!options.rilMessageType || options.rilMessageType !== "getSmscAddress") {
- return;
- }
-
- if (options.errorMsg) {
- this.sendChromeMessage(options);
- return;
- }
-
- let tosca = TOA_UNKNOWN;
- let smsc = "";
- let Buf = this.context.Buf;
- if (RILQUIRKS_SMSC_ADDRESS_FORMAT === "pdu") {
- let pduHelper = this.context.GsmPDUHelper;
- let strlen = Buf.readInt32();
- let length = pduHelper.readHexOctet();
-
- // As defined in |8.2.5.2 Destination address element| of 3GPP TS 24.011,
- // the value of length field can not exceed 11. Since the content might be
- // filled with 12 'F' when SMSC is cleared, we don't parse the TOA and
- // address fields if reported length exceeds 11 here. Instead, keep the
- // default value (TOA_UNKNOWN with an empty address) in this case.
- const MAX_LENGTH = 11
- if (length <= MAX_LENGTH) {
- tosca = pduHelper.readHexOctet();
-
- // Read and covert the decimal values back to special BCD digits defined in
- // |Called party BCD number| of 3GPP TS 24.008 (refer the following table).
- //
- // +=========+=======+=====+
- // | value | digit | hex |
- // +========================
- // | 1 0 1 0 | * | 0xA |
- // | 1 0 1 1 | # | 0xB |
- // | 1 1 0 0 | a | 0xC |
- // | 1 1 0 1 | b | 0xD |
- // | 1 1 1 0 | c | 0xE |
- // +=========+=======+=====+
- smsc = pduHelper.readSwappedNibbleBcdString(length - 1, true)
- .replace(/a/ig, "*")
- .replace(/b/ig, "#")
- .replace(/c/ig, "a")
- .replace(/d/ig, "b")
- .replace(/e/ig, "c");
-
- Buf.readStringDelimiter(strlen);
- }
- } else /* RILQUIRKS_SMSC_ADDRESS_FORMAT === "text" */ {
- let text = Buf.readString();
- let segments = text.split(",", 2);
- // Parse TOA only if it presents since some devices might omit the TOA
- // segment in the reported SMSC address. If TOA does not present, keep the
- // default value TOA_UNKNOWN.
- if (segments.length === 2) {
- tosca = this.parseInt(segments[1], TOA_UNKNOWN, 10);
- }
-
- smsc = segments[0].replace(/\"/g, "");
- }
-
- // Convert the NPI value to the corresponding index of CALLED_PARTY_BCD_NPI
- // array. If the value does not present in the array, use
- // CALLED_PARTY_BCD_NPI_ISDN.
- let npi = CALLED_PARTY_BCD_NPI.indexOf(tosca & 0xf);
- if (npi === -1) {
- npi = CALLED_PARTY_BCD_NPI.indexOf(CALLED_PARTY_BCD_NPI_ISDN);
- }
-
- // Extract TON.
- let ton = (tosca & 0x70) >> 4;
-
- // Ensure + sign if TON is international, and vice versa.
- const TON_INTERNATIONAL = (TOA_INTERNATIONAL & 0x70) >> 4;
- if (ton === TON_INTERNATIONAL && smsc.charAt(0) !== "+") {
- smsc = "+" + smsc;
- } else if (smsc.charAt(0) === "+" && ton !== TON_INTERNATIONAL) {
- if (DEBUG) {
- this.context.debug("SMSC address number begins with '+' while the TON is not international. Change TON to international.");
- }
- ton = TON_INTERNATIONAL;
- }
-
- options.smscAddress = smsc;
- options.typeOfNumber = ton;
- options.numberPlanIdentification = npi;
- this.sendChromeMessage(options);
-};
-RilObject.prototype[REQUEST_SET_SMSC_ADDRESS] = function REQUEST_SET_SMSC_ADDRESS(length, options) {
- if (!options.rilMessageType || options.rilMessageType !== "setSmscAddress") {
- return;
- }
-
- this.sendChromeMessage(options);
-};
-RilObject.prototype[REQUEST_REPORT_SMS_MEMORY_STATUS] = function REQUEST_REPORT_SMS_MEMORY_STATUS(length, options) {
- this.pendingToReportSmsMemoryStatus = !!options.errorMsg;
-};
-RilObject.prototype[REQUEST_REPORT_STK_SERVICE_IS_RUNNING] = null;
-RilObject.prototype[REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE] = null;
-RilObject.prototype[REQUEST_ISIM_AUTHENTICATION] = null;
-RilObject.prototype[REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU] = null;
-RilObject.prototype[REQUEST_STK_SEND_ENVELOPE_WITH_STATUS] = function REQUEST_STK_SEND_ENVELOPE_WITH_STATUS(length, options) {
- if (options.errorMsg) {
- this.acknowledgeGsmSms(false, PDU_FCS_UNSPECIFIED);
- return;
- }
-
- let Buf = this.context.Buf;
- let sw1 = Buf.readInt32();
- let sw2 = Buf.readInt32();
- if ((sw1 == ICC_STATUS_SAT_BUSY) && (sw2 === 0x00)) {
- this.acknowledgeGsmSms(false, PDU_FCS_USAT_BUSY);
- return;
- }
-
- let success = ((sw1 == ICC_STATUS_NORMAL_ENDING) && (sw2 === 0x00))
- || (sw1 == ICC_STATUS_NORMAL_ENDING_WITH_EXTRA);
-
- let messageStringLength = Buf.readInt32(); // In semi-octets
- let responsePduLen = messageStringLength / 2; // In octets
- if (!responsePduLen) {
- this.acknowledgeGsmSms(success, success ? PDU_FCS_OK
- : PDU_FCS_USIM_DATA_DOWNLOAD_ERROR);
- return;
- }
-
- this.acknowledgeIncomingGsmSmsWithPDU(success, responsePduLen, options);
-};
-RilObject.prototype[REQUEST_VOICE_RADIO_TECH] = function REQUEST_VOICE_RADIO_TECH(length, options) {
- if (options.errorMsg) {
- if (DEBUG) {
- this.context.debug("Error when getting voice radio tech: " +
- options.errorMsg);
- }
- return;
- }
- let radioTech = this.context.Buf.readInt32List();
- this._processRadioTech(radioTech[0]);
-};
-RilObject.prototype[REQUEST_SET_UNSOL_CELL_INFO_LIST_RATE] = null;
-RilObject.prototype[REQUEST_SET_INITIAL_ATTACH_APN] = null;
-RilObject.prototype[REQUEST_IMS_REGISTRATION_STATE] = null;
-RilObject.prototype[REQUEST_IMS_SEND_SMS] = null;
-RilObject.prototype[REQUEST_SIM_TRANSMIT_APDU_BASIC] = null;
-RilObject.prototype[REQUEST_SIM_OPEN_CHANNEL] = function REQUEST_SIM_OPEN_CHANNEL(length, options) {
- if (options.errorMsg) {
- this.sendChromeMessage(options);
- return;
- }
-
- options.channel = this.context.Buf.readInt32List()[0];
- // onwards may optionally contain the select response for the open channel
- // command with one byte per integer.
- this.sendChromeMessage(options);
-};
-RilObject.prototype[REQUEST_SIM_CLOSE_CHANNEL] = function REQUEST_SIM_CLOSE_CHANNEL(length, options) {
- this.sendDefaultResponse(options);
-};
-RilObject.prototype[REQUEST_SIM_TRANSMIT_APDU_CHANNEL] = function REQUEST_SIM_TRANSMIT_APDU_CHANNEL(length, options) {
- if (options.errorMsg) {
- this.sendChromeMessage(options);
- return;
- }
-
- let Buf = this.context.Buf;
- options.sw1 = Buf.readInt32();
- options.sw2 = Buf.readInt32();
- options.simResponse = Buf.readString();
- if (DEBUG) {
- this.context.debug("Setting return values for RIL[REQUEST_SIM_TRANSMIT_APDU_CHANNEL]: [" +
- options.sw1 + "," +
- options.sw2 + ", " +
- options.simResponse + "]");
- }
- this.sendChromeMessage(options);
-};
-RilObject.prototype[REQUEST_NV_READ_ITEM] = null;
-RilObject.prototype[REQUEST_NV_WRITE_ITEM] = null;
-RilObject.prototype[REQUEST_NV_WRITE_CDMA_PRL] = null;
-RilObject.prototype[REQUEST_NV_RESET_CONFIG] = null;
-RilObject.prototype[REQUEST_SET_UICC_SUBSCRIPTION] = function REQUEST_SET_UICC_SUBSCRIPTION(length, options) {
- // Resend data subscription after uicc subscription.
- if (this._attachDataRegistration) {
- this.setDataRegistration({attach: true});
- }
-};
-RilObject.prototype[REQUEST_ALLOW_DATA] = null;
-RilObject.prototype[REQUEST_GET_HARDWARE_CONFIG] = null;
-RilObject.prototype[REQUEST_SIM_AUTHENTICATION] = null;
-RilObject.prototype[REQUEST_GET_DC_RT_INFO] = null;
-RilObject.prototype[REQUEST_SET_DC_RT_INFO_RATE] = null;
-RilObject.prototype[REQUEST_SET_DATA_PROFILE] = null;
-RilObject.prototype[REQUEST_SHUTDOWN] = null;
-RilObject.prototype[REQUEST_SET_DATA_SUBSCRIPTION] = function REQUEST_SET_DATA_SUBSCRIPTION(length, options) {
- if (!options.rilMessageType) {
- // The request was made by ril_worker itself. Don't report.
- return;
- }
- this.sendChromeMessage(options);
-};
-RilObject.prototype[REQUEST_GET_UNLOCK_RETRY_COUNT] = function REQUEST_GET_UNLOCK_RETRY_COUNT(length, options) {
- options.retryCount = length ? this.context.Buf.readInt32List()[0] : -1;
- this.sendChromeMessage(options);
-};
-RilObject.prototype[RIL_REQUEST_GPRS_ATTACH] = function RIL_REQUEST_GPRS_ATTACH(length, options) {
- if (!options.rilMessageType) {
- // The request was made by ril_worker itself. Don't report.
- return;
- }
- this.sendChromeMessage(options);
-};
-RilObject.prototype[RIL_REQUEST_GPRS_DETACH] = function RIL_REQUEST_GPRS_DETACH(length, options) {
- this.sendChromeMessage(options);
-};
-RilObject.prototype[UNSOLICITED_RESPONSE_RADIO_STATE_CHANGED] = function UNSOLICITED_RESPONSE_RADIO_STATE_CHANGED() {
- let radioState = this.context.Buf.readInt32();
- let newState;
- switch (radioState) {
- case RADIO_STATE_UNAVAILABLE:
- newState = GECKO_RADIOSTATE_UNKNOWN;
- break;
- case RADIO_STATE_OFF:
- newState = GECKO_RADIOSTATE_DISABLED;
- break;
- default:
- newState = GECKO_RADIOSTATE_ENABLED;
- }
-
- if (DEBUG) {
- this.context.debug("Radio state changed from '" + this.radioState +
- "' to '" + newState + "'");
- }
- if (this.radioState == newState) {
- return;
- }
-
- if (radioState !== RADIO_STATE_UNAVAILABLE) {
- // Retrieve device identities once radio is available.
- this.getDeviceIdentity();
- }
-
- if (radioState == RADIO_STATE_ON) {
- // This value is defined in RIL v7, we will retrieve radio tech by another
- // request. We leave _isCdma untouched, and it will be set once we get the
- // radio technology.
- this._waitingRadioTech = true;
- this.getVoiceRadioTechnology();
- }
-
- if ((this.radioState == GECKO_RADIOSTATE_UNKNOWN ||
- this.radioState == GECKO_RADIOSTATE_DISABLED) &&
- newState == GECKO_RADIOSTATE_ENABLED) {
- // The radio became available, let's get its info.
- this.getBasebandVersion();
- this.updateCellBroadcastConfig();
- if ((RILQUIRKS_DATA_REGISTRATION_ON_DEMAND ||
- RILQUIRKS_SUBSCRIPTION_CONTROL) &&
- this._attachDataRegistration) {
- this.setDataRegistration({attach: true});
- }
-
- if (this.pendingToReportSmsMemoryStatus) {
- this._updateSmsMemoryStatus();
- }
- }
-
- this.radioState = newState;
- this.sendChromeMessage({
- rilMessageType: "radiostatechange",
- radioState: newState
- });
-
- // If the radio is up and on, so let's query the card state.
- // On older RILs only if the card is actually ready, though.
- // If _waitingRadioTech is set, we don't need to get icc status now.
- if (radioState == RADIO_STATE_UNAVAILABLE ||
- radioState == RADIO_STATE_OFF ||
- this._waitingRadioTech) {
- return;
- }
- this.getICCStatus();
-};
-RilObject.prototype[UNSOLICITED_RESPONSE_CALL_STATE_CHANGED] = function UNSOLICITED_RESPONSE_CALL_STATE_CHANGED() {
- this.getCurrentCalls();
-};
-RilObject.prototype[UNSOLICITED_RESPONSE_VOICE_NETWORK_STATE_CHANGED] = function UNSOLICITED_RESPONSE_VOICE_NETWORK_STATE_CHANGED() {
- if (DEBUG) {
- this.context.debug("Network state changed, re-requesting phone state and " +
- "ICC status");
- }
- this.getICCStatus();
- this.requestNetworkInfo();
-};
-RilObject.prototype[UNSOLICITED_RESPONSE_NEW_SMS] = function UNSOLICITED_RESPONSE_NEW_SMS(length) {
- let [message, result] = this.context.GsmPDUHelper.processReceivedSms(length);
-
- if (message) {
- result = this._processSmsMultipart(message);
- }
-
- if (result == PDU_FCS_RESERVED || result == MOZ_FCS_WAIT_FOR_EXPLICIT_ACK) {
- return;
- }
-
- // Not reserved FCS values, send ACK now.
- this.acknowledgeGsmSms(result == PDU_FCS_OK, result);
-};
-RilObject.prototype[UNSOLICITED_RESPONSE_NEW_SMS_STATUS_REPORT] = function UNSOLICITED_RESPONSE_NEW_SMS_STATUS_REPORT(length) {
- let result = this._processSmsStatusReport(length);
- this.acknowledgeGsmSms(result == PDU_FCS_OK, result);
-};
-RilObject.prototype[UNSOLICITED_RESPONSE_NEW_SMS_ON_SIM] = function UNSOLICITED_RESPONSE_NEW_SMS_ON_SIM(length) {
- let recordNumber = this.context.Buf.readInt32List()[0];
-
- this.context.SimRecordHelper.readSMS(
- recordNumber,
- function onsuccess(message) {
- if (message && message.simStatus === 3) { //New Unread SMS
- this._processSmsMultipart(message);
- }
- }.bind(this),
- function onerror(errorMsg) {
- if (DEBUG) {
- this.context.debug("Failed to Read NEW SMS on SIM #" + recordNumber +
- ", errorMsg: " + errorMsg);
- }
- });
-};
-RilObject.prototype[UNSOLICITED_ON_USSD] = function UNSOLICITED_ON_USSD() {
- let [typeCode, message] = this.context.Buf.readStringList();
- if (DEBUG) {
- this.context.debug("On USSD. Type Code: " + typeCode + " Message: " + message);
- }
-
- this.sendChromeMessage({rilMessageType: "ussdreceived",
- message: message,
- // Per ril.h the USSD session is assumed to persist if
- // the type code is "1", otherwise the current session
- // (if any) is assumed to have terminated.
- sessionEnded: typeCode !== "1"});
-};
-RilObject.prototype[UNSOLICITED_ON_USSD_REQUEST] = null;
-RilObject.prototype[UNSOLICITED_NITZ_TIME_RECEIVED] = function UNSOLICITED_NITZ_TIME_RECEIVED() {
- let dateString = this.context.Buf.readString();
-
- // The data contained in the NITZ message is
- // in the form "yy/mm/dd,hh:mm:ss(+/-)tz,dt"
- // for example: 12/02/16,03:36:08-20,00,310410
- // See also bug 714352 - Listen for NITZ updates from rild.
-
- if (DEBUG) this.context.debug("DateTimeZone string " + dateString);
-
- let now = Date.now();
-
- let year = parseInt(dateString.substr(0, 2), 10);
- let month = parseInt(dateString.substr(3, 2), 10);
- let day = parseInt(dateString.substr(6, 2), 10);
- let hours = parseInt(dateString.substr(9, 2), 10);
- let minutes = parseInt(dateString.substr(12, 2), 10);
- let seconds = parseInt(dateString.substr(15, 2), 10);
- // Note that |tz| is in 15-min units.
- let tz = parseInt(dateString.substr(17, 3), 10);
- // Note that |dst| is in 1-hour units and is already applied in |tz|.
- let dst = parseInt(dateString.substr(21, 2), 10);
-
- let timeInMS = Date.UTC(year + PDU_TIMESTAMP_YEAR_OFFSET, month - 1, day,
- hours, minutes, seconds);
-
- if (isNaN(timeInMS)) {
- if (DEBUG) this.context.debug("NITZ failed to convert date");
- return;
- }
-
- this.sendChromeMessage({rilMessageType: "nitzTime",
- networkTimeInMS: timeInMS,
- networkTimeZoneInMinutes: -(tz * 15),
- networkDSTInMinutes: -(dst * 60),
- receiveTimeInMS: now});
-};
-
-RilObject.prototype[UNSOLICITED_SIGNAL_STRENGTH] = function UNSOLICITED_SIGNAL_STRENGTH(length) {
- this[REQUEST_SIGNAL_STRENGTH](length, {});
-};
-RilObject.prototype[UNSOLICITED_DATA_CALL_LIST_CHANGED] = function UNSOLICITED_DATA_CALL_LIST_CHANGED(length) {
- this[REQUEST_DATA_CALL_LIST](length, {});
-};
-RilObject.prototype[UNSOLICITED_SUPP_SVC_NOTIFICATION] = function UNSOLICITED_SUPP_SVC_NOTIFICATION(length) {
- let Buf = this.context.Buf;
- let info = {};
- info.notificationType = Buf.readInt32();
- info.code = Buf.readInt32();
- info.index = Buf.readInt32();
- info.type = Buf.readInt32();
- info.number = Buf.readString();
-
- this._processSuppSvcNotification(info);
-};
-
-RilObject.prototype[UNSOLICITED_STK_SESSION_END] = function UNSOLICITED_STK_SESSION_END() {
- this.sendChromeMessage({rilMessageType: "stksessionend"});
-};
-RilObject.prototype[UNSOLICITED_STK_PROACTIVE_COMMAND] = function UNSOLICITED_STK_PROACTIVE_COMMAND() {
- this.processStkProactiveCommand();
-};
-RilObject.prototype[UNSOLICITED_STK_EVENT_NOTIFY] = function UNSOLICITED_STK_EVENT_NOTIFY() {
- this.processStkProactiveCommand();
-};
-RilObject.prototype[UNSOLICITED_STK_CALL_SETUP] = null;
-RilObject.prototype[UNSOLICITED_SIM_SMS_STORAGE_FULL] = null;
-RilObject.prototype[UNSOLICITED_SIM_REFRESH] = null;
-RilObject.prototype[UNSOLICITED_CALL_RING] = function UNSOLICITED_CALL_RING() {
- let Buf = this.context.Buf;
- let info = {rilMessageType: "callRing"};
- let isCDMA = false; //XXX TODO hard-code this for now
- if (isCDMA) {
- info.isPresent = Buf.readInt32();
- info.signalType = Buf.readInt32();
- info.alertPitch = Buf.readInt32();
- info.signal = Buf.readInt32();
- }
- // At this point we don't know much other than the fact there's an incoming
- // call, but that's enough to bring up the Phone app already. We'll know
- // details once we get a call state changed notification and can then
- // dispatch DOM events etc.
- this.sendChromeMessage(info);
-};
-RilObject.prototype[UNSOLICITED_RESPONSE_SIM_STATUS_CHANGED] = function UNSOLICITED_RESPONSE_SIM_STATUS_CHANGED() {
- this.getICCStatus();
-};
-RilObject.prototype[UNSOLICITED_RESPONSE_CDMA_NEW_SMS] = function UNSOLICITED_RESPONSE_CDMA_NEW_SMS(length) {
- let [message, result] = this.context.CdmaPDUHelper.processReceivedSms(length);
-
- if (message) {
- if (message.teleservice === PDU_CDMA_MSG_TELESERIVCIE_ID_WAP) {
- result = this._processCdmaSmsWapPush(message);
- } else if (message.subMsgType === PDU_CDMA_MSG_TYPE_DELIVER_ACK) {
- result = this._processCdmaSmsStatusReport(message);
- } else {
- result = this._processSmsMultipart(message);
- }
- }
-
- if (result == PDU_FCS_RESERVED || result == MOZ_FCS_WAIT_FOR_EXPLICIT_ACK) {
- return;
- }
-
- // Not reserved FCS values, send ACK now.
- this.acknowledgeCdmaSms(result == PDU_FCS_OK, result);
-};
-RilObject.prototype[UNSOLICITED_RESPONSE_NEW_BROADCAST_SMS] = function UNSOLICITED_RESPONSE_NEW_BROADCAST_SMS(length) {
- let message;
- try {
- message =
- this.context.GsmPDUHelper.readCbMessage(this.context.Buf.readInt32());
-
- // "Data-Download" message is expected to be handled by the modem.
- // Ignore it here to prevent any garbage messages to be displayed.
- // See 9.4.1.2.2 Message Identifier of TS 32.041 for the range of
- // Message-identifier of the Data-Download CB messages.
- if (message.messageId >= 0x1000 && message.messageId <= 0x10FF) {
- if (DEBUG) {
- this.context.debug("Ignore a Data-Download message, messageId: " +
- message.messageId);
- }
- return;
- }
- } catch (e) {
- if (DEBUG) {
- this.context.debug("Failed to parse Cell Broadcast message: " + e);
- }
- return;
- }
-
- message = this._processReceivedSmsCbPage(message);
- if (!message) {
- return;
- }
-
- // Bug 1235697, failed to deactivate CBS in some modem.
- // Workaround it according to the settings.
- // Note: ETWS/CMAS/PWS can be received even disabled.
- // It will be displayed according to the setting in application layer.
- if (this.cellBroadcastDisabled && (
- !(message.messageId >= 0x1100 && message.messageId <= 0x1107) && // ETWS
- !(message.messageId >= 0x1112 && message.messageId <= 0x112F) && // CMAS
- !(message.messageId >= 0x1130 && message.messageId <= 0x18FF) // PWS
- )) {
- if (DEBUG) {
- this.context.debug("Ignore a CB message when disabled, messageId: " +
- message.messageId);
- }
- return;
- }
-
- message.rilMessageType = "cellbroadcast-received";
- this.sendChromeMessage(message);
-};
-RilObject.prototype[UNSOLICITED_CDMA_RUIM_SMS_STORAGE_FULL] = null;
-RilObject.prototype[UNSOLICITED_RESTRICTED_STATE_CHANGED] = null;
-RilObject.prototype[UNSOLICITED_ENTER_EMERGENCY_CALLBACK_MODE] = function UNSOLICITED_ENTER_EMERGENCY_CALLBACK_MODE() {
- this._handleChangedEmergencyCbMode(true);
-};
-RilObject.prototype[UNSOLICITED_CDMA_CALL_WAITING] = function UNSOLICITED_CDMA_CALL_WAITING(length) {
- let Buf = this.context.Buf;
- let call = {};
- call.number = Buf.readString();
- call.numberPresentation = Buf.readInt32();
- call.name = Buf.readString();
- call.namePresentation = Buf.readInt32();
- call.isPresent = Buf.readInt32();
- call.signalType = Buf.readInt32();
- call.alertPitch = Buf.readInt32();
- call.signal = Buf.readInt32();
- this.sendChromeMessage({rilMessageType: "cdmaCallWaiting",
- waitingCall: call});
-};
-RilObject.prototype[UNSOLICITED_CDMA_OTA_PROVISION_STATUS] = function UNSOLICITED_CDMA_OTA_PROVISION_STATUS() {
- let status =
- CDMA_OTA_PROVISION_STATUS_TO_GECKO[this.context.Buf.readInt32List()[0]];
- if (!status) {
- return;
- }
- this.sendChromeMessage({rilMessageType: "otastatuschange",
- status: status});
-};
-RilObject.prototype[UNSOLICITED_CDMA_INFO_REC] = function UNSOLICITED_CDMA_INFO_REC(length) {
- this.sendChromeMessage({
- rilMessageType: "cdma-info-rec-received",
- records: this.context.CdmaPDUHelper.decodeInformationRecord()
- });
-};
-RilObject.prototype[UNSOLICITED_OEM_HOOK_RAW] = null;
-RilObject.prototype[UNSOLICITED_RINGBACK_TONE] = null;
-RilObject.prototype[UNSOLICITED_RESEND_INCALL_MUTE] = null;
-RilObject.prototype[UNSOLICITED_CDMA_SUBSCRIPTION_SOURCE_CHANGED] = null;
-RilObject.prototype[UNSOLICITED_CDMA_PRL_CHANGED] = function UNSOLICITED_CDMA_PRL_CHANGED(length) {
- let version = this.context.Buf.readInt32List()[0];
- if (version !== this.iccInfo.prlVersion) {
- this.iccInfo.prlVersion = version;
- this.context.ICCUtilsHelper.handleICCInfoChange();
- }
-};
-RilObject.prototype[UNSOLICITED_EXIT_EMERGENCY_CALLBACK_MODE] = function UNSOLICITED_EXIT_EMERGENCY_CALLBACK_MODE() {
- this._handleChangedEmergencyCbMode(false);
-};
-RilObject.prototype[UNSOLICITED_RIL_CONNECTED] = function UNSOLICITED_RIL_CONNECTED(length) {
- // Prevent response id collision between UNSOLICITED_RIL_CONNECTED and
- // UNSOLICITED_VOICE_RADIO_TECH_CHANGED for Akami on gingerbread branch.
- if (!length) {
- return;
- }
-
- this.version = this.context.Buf.readInt32List()[0];
- if (DEBUG) {
- this.context.debug("Detected RIL version " + this.version);
- }
-
- this.initRILState();
- // rild might have restarted, ensure data call list.
- this.getDataCallList();
- // Always ensure that we are not in emergency callback mode when init.
- this.exitEmergencyCbMode();
- // Reset radio in the case that b2g restart (or crash).
- this.setRadioEnabled({enabled: false});
-};
-RilObject.prototype[UNSOLICITED_VOICE_RADIO_TECH_CHANGED] = function UNSOLICITED_VOICE_RADIO_TECH_CHANGED(length) {
- // This unsolicited response will be sent when the technology of a multi-tech
- // modem is changed, ex. switch between gsm and cdma.
- // TODO: We may need to do more on updating data when switching between gsm
- // and cdma mode, e.g. IMEI, ESN, iccInfo, iccType ... etc.
- // See Bug 866038.
- this._processRadioTech(this.context.Buf.readInt32List()[0]);
-};
-RilObject.prototype[UNSOLICITED_CELL_INFO_LIST] = null;
-RilObject.prototype[UNSOLICITED_RESPONSE_IMS_NETWORK_STATE_CHANGED] = null;
-RilObject.prototype[UNSOLICITED_UICC_SUBSCRIPTION_STATUS_CHANGED] = null;
-RilObject.prototype[UNSOLICITED_SRVCC_STATE_NOTIFY] = null;
-RilObject.prototype[UNSOLICITED_HARDWARE_CONFIG_CHANGED] = null;
-RilObject.prototype[UNSOLICITED_DC_RT_INFO_CHANGED] = null;
-
-/**
- * This object exposes the functionality to parse and serialize PDU strings
- *
- * A PDU is a string containing a series of hexadecimally encoded octets
- * or nibble-swapped binary-coded decimals (BCDs). It contains not only the
- * message text but information about the sender, the SMS service center,
- * timestamp, etc.
- */
-function GsmPDUHelperObject(aContext) {
- this.context = aContext;
-}
-GsmPDUHelperObject.prototype = {
- context: null,
-
- /**
- * Read one character (2 bytes) from a RIL string and decode as hex.
- *
- * @return the nibble as a number.
- */
- readHexNibble: function() {
- let nibble = this.context.Buf.readUint16();
- if (nibble >= 48 && nibble <= 57) {
- nibble -= 48; // ASCII '0'..'9'
- } else if (nibble >= 65 && nibble <= 70) {
- nibble -= 55; // ASCII 'A'..'F'
- } else if (nibble >= 97 && nibble <= 102) {
- nibble -= 87; // ASCII 'a'..'f'
- } else {
- throw "Found invalid nibble during PDU parsing: " +
- String.fromCharCode(nibble);
- }
- return nibble;
- },
-
- /**
- * Encode a nibble as one hex character in a RIL string (2 bytes).
- *
- * @param nibble
- * The nibble to encode (represented as a number)
- */
- writeHexNibble: function(nibble) {
- nibble &= 0x0f;
- if (nibble < 10) {
- nibble += 48; // ASCII '0'
- } else {
- nibble += 55; // ASCII 'A'
- }
- this.context.Buf.writeUint16(nibble);
- },
-
- /**
- * Read a hex-encoded octet (two nibbles).
- *
- * @return the octet as a number.
- */
- readHexOctet: function() {
- return (this.readHexNibble() << 4) | this.readHexNibble();
- },
-
- /**
- * Write an octet as two hex-encoded nibbles.
- *
- * @param octet
- * The octet (represented as a number) to encode.
- */
- writeHexOctet: function(octet) {
- this.writeHexNibble(octet >> 4);
- this.writeHexNibble(octet);
- },
-
- /**
- * Read an array of hex-encoded octets.
- */
- readHexOctetArray: function(length) {
- let array = new Uint8Array(length);
- for (let i = 0; i < length; i++) {
- array[i] = this.readHexOctet();
- }
- return array;
- },
-
- /**
- * Helper to write data into a temporary buffer for easier length encoding when
- * the number of octets for the length encoding is varied.
- *
- * @param writeFunction
- * Function of how the data to be written into temporary buffer.
- *
- * @return array of written octets.
- **/
- writeWithBuffer: function(writeFunction) {
- let buf = [];
- let writeHexOctet = this.writeHexOctet;
- this.writeHexOctet = function(octet) {
- buf.push(octet);
- }
-
- try {
- writeFunction();
- } catch (e) {
- if (DEBUG) {
- debug("Error when writeWithBuffer: " + e);
- }
- buf = [];
- } finally {
- this.writeHexOctet = writeHexOctet;
- }
-
- return buf;
- },
-
- /**
- * Convert an octet (number) to a BCD number.
- *
- * Any nibbles that are not in the BCD range count as 0.
- *
- * @param octet
- * The octet (a number, as returned by getOctet())
- *
- * @return the corresponding BCD number.
- */
- octetToBCD: function(octet) {
- return ((octet & 0xf0) <= 0x90) * ((octet >> 4) & 0x0f) +
- ((octet & 0x0f) <= 0x09) * (octet & 0x0f) * 10;
- },
-
- /**
- * Convert a BCD number to an octet (number)
- *
- * Only take two digits with absolute value.
- *
- * @param bcd
- *
- * @return the corresponding octet.
- */
- BCDToOctet: function(bcd) {
- bcd = Math.abs(bcd);
- return ((bcd % 10) << 4) + (Math.floor(bcd / 10) % 10);
- },
-
- /**
- * Convert a semi-octet (number) to a GSM BCD char, or return empty
- * string if invalid semiOctet and suppressException is set to true.
- *
- * @param semiOctet
- * Nibble to be converted to.
- * @param suppressException [optional]
- * Suppress exception if invalid semiOctet and suppressException is set
- * to true.
- *
- * @return GSM BCD char, or empty string.
- */
- bcdChars: "0123456789",
- semiOctetToBcdChar: function(semiOctet, suppressException) {
- if (semiOctet >= this.bcdChars.length) {
- if (suppressException) {
- return "";
- } else {
- throw new RangeError();
- }
- }
-
- return this.bcdChars.charAt(semiOctet);
- },
-
- /**
- * Convert a semi-octet (number) to a GSM extended BCD char, or return empty
- * string if invalid semiOctet and suppressException is set to true.
- *
- * @param semiOctet
- * Nibble to be converted to.
- * @param suppressException [optional]
- * Suppress exception if invalid semiOctet and suppressException is set
- * to true.
- *
- * @return GSM extended BCD char, or empty string.
- */
- extendedBcdChars: "0123456789*#,;",
- semiOctetToExtendedBcdChar: function(semiOctet, suppressException) {
- if (semiOctet >= this.extendedBcdChars.length) {
- if (suppressException) {
- return "";
- } else {
- throw new RangeError();
- }
- }
-
- return this.extendedBcdChars.charAt(semiOctet);
- },
-
- /**
- * Convert string to a GSM extended BCD string
- */
- stringToExtendedBcd: function(string) {
- return string.replace(/[^0-9*#,]/g, "")
- .replace(/\*/g, "a")
- .replace(/\#/g, "b")
- .replace(/\,/g, "c");
- },
-
- /**
- * Read a *swapped nibble* binary coded decimal (BCD)
- *
- * @param pairs
- * Number of nibble *pairs* to read.
- *
- * @return the decimal as a number.
- */
- readSwappedNibbleBcdNum: function(pairs) {
- let number = 0;
- for (let i = 0; i < pairs; i++) {
- let octet = this.readHexOctet();
- // Ignore 'ff' octets as they're often used as filler.
- if (octet == 0xff) {
- continue;
- }
- // If the first nibble is an "F" , only the second nibble is to be taken
- // into account.
- if ((octet & 0xf0) == 0xf0) {
- number *= 10;
- number += octet & 0x0f;
- continue;
- }
- number *= 100;
- number += this.octetToBCD(octet);
- }
- return number;
- },
-
- /**
- * Read a *swapped nibble* binary coded decimal (BCD) string
- *
- * @param pairs
- * Number of nibble *pairs* to read.
- * @param suppressException [optional]
- * Suppress exception if invalid semiOctet and suppressException is set
- * to true.
- *
- * @return The BCD string.
- */
- readSwappedNibbleBcdString: function(pairs, suppressException) {
- let str = "";
- for (let i = 0; i < pairs; i++) {
- let nibbleH = this.readHexNibble();
- let nibbleL = this.readHexNibble();
- if (nibbleL == 0x0F) {
- break;
- }
-
- str += this.semiOctetToBcdChar(nibbleL, suppressException);
- if (nibbleH != 0x0F) {
- str += this.semiOctetToBcdChar(nibbleH, suppressException);
- }
- }
-
- return str;
- },
-
- /**
- * Read a *swapped nibble* extended binary coded decimal (BCD) string
- *
- * @param pairs
- * Number of nibble *pairs* to read.
- * @param suppressException [optional]
- * Suppress exception if invalid semiOctet and suppressException is set
- * to true.
- *
- * @return The BCD string.
- */
- readSwappedNibbleExtendedBcdString: function(pairs, suppressException) {
- let str = "";
- for (let i = 0; i < pairs; i++) {
- let nibbleH = this.readHexNibble();
- let nibbleL = this.readHexNibble();
- if (nibbleL == 0x0F) {
- break;
- }
-
- str += this.semiOctetToExtendedBcdChar(nibbleL, suppressException);
- if (nibbleH != 0x0F) {
- str += this.semiOctetToExtendedBcdChar(nibbleH, suppressException);
- }
- }
-
- return str;
- },
-
- /**
- * Write numerical data as swapped nibble BCD.
- *
- * @param data
- * Data to write (as a string or a number)
- */
- writeSwappedNibbleBCD: function(data) {
- data = data.toString();
- if (data.length % 2) {
- data += "F";
- }
- let Buf = this.context.Buf;
- for (let i = 0; i < data.length; i += 2) {
- Buf.writeUint16(data.charCodeAt(i + 1));
- Buf.writeUint16(data.charCodeAt(i));
- }
- },
-
- /**
- * Write numerical data as swapped nibble BCD.
- * If the number of digit of data is even, add '0' at the beginning.
- *
- * @param data
- * Data to write (as a string or a number)
- */
- writeSwappedNibbleBCDNum: function(data) {
- data = data.toString();
- if (data.length % 2) {
- data = "0" + data;
- }
- let Buf = this.context.Buf;
- for (let i = 0; i < data.length; i += 2) {
- Buf.writeUint16(data.charCodeAt(i + 1));
- Buf.writeUint16(data.charCodeAt(i));
- }
- },
-
- /**
- * Read user data, convert to septets, look up relevant characters in a
- * 7-bit alphabet, and construct string.
- *
- * @param length
- * Number of septets to read (*not* octets)
- * @param paddingBits
- * Number of padding bits in the first byte of user data.
- * @param langIndex
- * Table index used for normal 7-bit encoded character lookup.
- * @param langShiftIndex
- * Table index used for escaped 7-bit encoded character lookup.
- *
- * @return a string.
- */
- readSeptetsToString: function(length, paddingBits, langIndex, langShiftIndex) {
- let ret = "";
- let byteLength = Math.ceil((length * 7 + paddingBits) / 8);
-
- /**
- * |<- last byte in header ->|
- * |<- incompleteBits ->|<- last header septet->|
- * +===7===|===6===|===5===|===4===|===3===|===2===|===1===|===0===|
- *
- * |<- 1st byte in user data ->|
- * |<- data septet 1 ->|<-paddingBits->|
- * +===7===|===6===|===5===|===4===|===3===|===2===|===1===|===0===|
- *
- * |<- 2nd byte in user data ->|
- * |<- data spetet 2 ->|<-ds1->|
- * +===7===|===6===|===5===|===4===|===3===|===2===|===1===|===0===|
- */
- let data = 0;
- let dataBits = 0;
- if (paddingBits) {
- data = this.readHexOctet() >> paddingBits;
- dataBits = 8 - paddingBits;
- --byteLength;
- }
-
- let escapeFound = false;
- const langTable = PDU_NL_LOCKING_SHIFT_TABLES[langIndex];
- const langShiftTable = PDU_NL_SINGLE_SHIFT_TABLES[langShiftIndex];
- do {
- // Read as much as fits in 32bit word
- let bytesToRead = Math.min(byteLength, dataBits ? 3 : 4);
- for (let i = 0; i < bytesToRead; i++) {
- data |= this.readHexOctet() << dataBits;
- dataBits += 8;
- --byteLength;
- }
-
- // Consume available full septets
- for (; dataBits >= 7; dataBits -= 7) {
- let septet = data & 0x7F;
- data >>>= 7;
-
- if (escapeFound) {
- escapeFound = false;
- if (septet == PDU_NL_EXTENDED_ESCAPE) {
- // According to 3GPP TS 23.038, section 6.2.1.1, NOTE 1, "On
- // receipt of this code, a receiving entity shall display a space
- // until another extensiion table is defined."
- ret += " ";
- } else if (septet == PDU_NL_RESERVED_CONTROL) {
- // According to 3GPP TS 23.038 B.2, "This code represents a control
- // character and therefore must not be used for language specific
- // characters."
- ret += " ";
- } else {
- ret += langShiftTable[septet];
- }
- } else if (septet == PDU_NL_EXTENDED_ESCAPE) {
- escapeFound = true;
-
- // <escape> is not an effective character
- --length;
- } else {
- ret += langTable[septet];
- }
- }
- } while (byteLength);
-
- if (ret.length != length) {
- /**
- * If num of effective characters does not equal to the length of read
- * string, cut the tail off. This happens when the last octet of user
- * data has following layout:
- *
- * |<- penultimate octet in user data ->|
- * |<- data septet N ->|<- dsN-1 ->|
- * +===7===|===6===|===5===|===4===|===3===|===2===|===1===|===0===|
- *
- * |<- last octet in user data ->|
- * |<- fill bits ->|<-dsN->|
- * +===7===|===6===|===5===|===4===|===3===|===2===|===1===|===0===|
- *
- * The fill bits in the last octet may happen to form a full septet and
- * be appended at the end of result string.
- */
- ret = ret.slice(0, length);
- }
- return ret;
- },
-
- writeStringAsSeptets: function(message, paddingBits, langIndex, langShiftIndex) {
- const langTable = PDU_NL_LOCKING_SHIFT_TABLES[langIndex];
- const langShiftTable = PDU_NL_SINGLE_SHIFT_TABLES[langShiftIndex];
-
- let dataBits = paddingBits;
- let data = 0;
- for (let i = 0; i < message.length; i++) {
- let c = message.charAt(i);
- let septet = langTable.indexOf(c);
- if (septet == PDU_NL_EXTENDED_ESCAPE) {
- continue;
- }
-
- if (septet >= 0) {
- data |= septet << dataBits;
- dataBits += 7;
- } else {
- septet = langShiftTable.indexOf(c);
- if (septet == -1) {
- throw new Error("'" + c + "' is not in 7 bit alphabet "
- + langIndex + ":" + langShiftIndex + "!");
- }
-
- if (septet == PDU_NL_RESERVED_CONTROL) {
- continue;
- }
-
- data |= PDU_NL_EXTENDED_ESCAPE << dataBits;
- dataBits += 7;
- data |= septet << dataBits;
- dataBits += 7;
- }
-
- for (; dataBits >= 8; dataBits -= 8) {
- this.writeHexOctet(data & 0xFF);
- data >>>= 8;
- }
- }
-
- if (dataBits !== 0) {
- this.writeHexOctet(data & 0xFF);
- }
- },
-
- writeStringAs8BitUnpacked: function(text) {
- const langTable = PDU_NL_LOCKING_SHIFT_TABLES[PDU_NL_IDENTIFIER_DEFAULT];
- const langShiftTable = PDU_NL_SINGLE_SHIFT_TABLES[PDU_NL_IDENTIFIER_DEFAULT];
-
- let len = text ? text.length : 0;
- for (let i = 0; i < len; i++) {
- let c = text.charAt(i);
- let octet = langTable.indexOf(c);
-
- if (octet == -1) {
- octet = langShiftTable.indexOf(c);
- if (octet == -1) {
- // Fallback to ASCII space.
- octet = langTable.indexOf(' ');
- } else {
- this.writeHexOctet(PDU_NL_EXTENDED_ESCAPE);
- }
- }
- this.writeHexOctet(octet);
- }
- },
-
- /**
- * Read user data and decode as a UCS2 string.
- *
- * @param numOctets
- * Number of octets to be read as UCS2 string.
- *
- * @return a string.
- */
- readUCS2String: function(numOctets) {
- let str = "";
- let length = numOctets / 2;
- for (let i = 0; i < length; ++i) {
- let code = (this.readHexOctet() << 8) | this.readHexOctet();
- str += String.fromCharCode(code);
- }
-
- if (DEBUG) this.context.debug("Read UCS2 string: " + str);
-
- return str;
- },
-
- /**
- * Write user data as a UCS2 string.
- *
- * @param message
- * Message string to encode as UCS2 in hex-encoded octets.
- */
- writeUCS2String: function(message) {
- for (let i = 0; i < message.length; ++i) {
- let code = message.charCodeAt(i);
- this.writeHexOctet((code >> 8) & 0xFF);
- this.writeHexOctet(code & 0xFF);
- }
- },
-
- /**
- * Read 1 + UDHL octets and construct user data header.
- *
- * @param msg
- * message object for output.
- *
- * @see 3GPP TS 23.040 9.2.3.24
- */
- readUserDataHeader: function(msg) {
- /**
- * A header object with properties contained in received message.
- * The properties set include:
- *
- * length: totoal length of the header, default 0.
- * langIndex: used locking shift table index, default
- * PDU_NL_IDENTIFIER_DEFAULT.
- * langShiftIndex: used locking shift table index, default
- * PDU_NL_IDENTIFIER_DEFAULT.
- *
- */
- let header = {
- length: 0,
- langIndex: PDU_NL_IDENTIFIER_DEFAULT,
- langShiftIndex: PDU_NL_IDENTIFIER_DEFAULT
- };
-
- header.length = this.readHexOctet();
- if (DEBUG) this.context.debug("Read UDH length: " + header.length);
-
- let dataAvailable = header.length;
- while (dataAvailable >= 2) {
- let id = this.readHexOctet();
- let length = this.readHexOctet();
- if (DEBUG) this.context.debug("Read UDH id: " + id + ", length: " + length);
-
- dataAvailable -= 2;
-
- switch (id) {
- case PDU_IEI_CONCATENATED_SHORT_MESSAGES_8BIT: {
- let ref = this.readHexOctet();
- let max = this.readHexOctet();
- let seq = this.readHexOctet();
- dataAvailable -= 3;
- if (max && seq && (seq <= max)) {
- header.segmentRef = ref;
- header.segmentMaxSeq = max;
- header.segmentSeq = seq;
- }
- break;
- }
- case PDU_IEI_APPLICATION_PORT_ADDRESSING_SCHEME_8BIT: {
- let dstp = this.readHexOctet();
- let orip = this.readHexOctet();
- dataAvailable -= 2;
- if ((dstp < PDU_APA_RESERVED_8BIT_PORTS)
- || (orip < PDU_APA_RESERVED_8BIT_PORTS)) {
- // 3GPP TS 23.040 clause 9.2.3.24.3: "A receiving entity shall
- // ignore any information element where the value of the
- // Information-Element-Data is Reserved or not supported"
- break;
- }
- header.destinationPort = dstp;
- header.originatorPort = orip;
- break;
- }
- case PDU_IEI_APPLICATION_PORT_ADDRESSING_SCHEME_16BIT: {
- let dstp = (this.readHexOctet() << 8) | this.readHexOctet();
- let orip = (this.readHexOctet() << 8) | this.readHexOctet();
- dataAvailable -= 4;
- if ((dstp >= PDU_APA_VALID_16BIT_PORTS) ||
- (orip >= PDU_APA_VALID_16BIT_PORTS)) {
- // 3GPP TS 23.040 clause 9.2.3.24.4: "A receiving entity shall
- // ignore any information element where the value of the
- // Information-Element-Data is Reserved or not supported"
- // Bug 1130292, some carriers set originatorPort to reserved port
- // numbers for wap push. We rise this as a warning in debug message
- // instead of ingoring this IEI to allow user to receive Wap Push
- // under these carriers.
- this.context.debug("Warning: Invalid port numbers [dstp, orip]: " +
- JSON.stringify([dstp, orip]));
- }
- header.destinationPort = dstp;
- header.originatorPort = orip;
- break;
- }
- case PDU_IEI_CONCATENATED_SHORT_MESSAGES_16BIT: {
- let ref = (this.readHexOctet() << 8) | this.readHexOctet();
- let max = this.readHexOctet();
- let seq = this.readHexOctet();
- dataAvailable -= 4;
- if (max && seq && (seq <= max)) {
- header.segmentRef = ref;
- header.segmentMaxSeq = max;
- header.segmentSeq = seq;
- }
- break;
- }
- case PDU_IEI_NATIONAL_LANGUAGE_SINGLE_SHIFT:
- let langShiftIndex = this.readHexOctet();
- --dataAvailable;
- if (langShiftIndex < PDU_NL_SINGLE_SHIFT_TABLES.length) {
- header.langShiftIndex = langShiftIndex;
- }
- break;
- case PDU_IEI_NATIONAL_LANGUAGE_LOCKING_SHIFT:
- let langIndex = this.readHexOctet();
- --dataAvailable;
- if (langIndex < PDU_NL_LOCKING_SHIFT_TABLES.length) {
- header.langIndex = langIndex;
- }
- break;
- case PDU_IEI_SPECIAL_SMS_MESSAGE_INDICATION:
- let msgInd = this.readHexOctet() & 0xFF;
- let msgCount = this.readHexOctet();
- dataAvailable -= 2;
-
-
- /*
- * TS 23.040 V6.8.1 Sec 9.2.3.24.2
- * bits 1 0 : basic message indication type
- * bits 4 3 2 : extended message indication type
- * bits 6 5 : Profile id
- * bit 7 : storage type
- */
- let storeType = msgInd & PDU_MWI_STORE_TYPE_BIT;
- let mwi = msg.mwi;
- if (!mwi) {
- mwi = msg.mwi = {};
- }
-
- if (storeType == PDU_MWI_STORE_TYPE_STORE) {
- // Store message because TP_UDH indicates so, note this may override
- // the setting in DCS, but that is expected
- mwi.discard = false;
- } else if (mwi.discard === undefined) {
- // storeType == PDU_MWI_STORE_TYPE_DISCARD
- // only override mwi.discard here if it hasn't already been set
- mwi.discard = true;
- }
-
- mwi.msgCount = msgCount & 0xFF;
- mwi.active = mwi.msgCount > 0;
-
- if (DEBUG) {
- this.context.debug("MWI in TP_UDH received: " + JSON.stringify(mwi));
- }
-
- break;
- default:
- if (DEBUG) {
- this.context.debug("readUserDataHeader: unsupported IEI(" + id +
- "), " + length + " bytes.");
- }
-
- // Read out unsupported data
- if (length) {
- let octets;
- if (DEBUG) octets = new Uint8Array(length);
-
- for (let i = 0; i < length; i++) {
- let octet = this.readHexOctet();
- if (DEBUG) octets[i] = octet;
- }
- dataAvailable -= length;
-
- if (DEBUG) {
- this.context.debug("readUserDataHeader: " + Array.slice(octets));
- }
- }
- break;
- }
- }
-
- if (dataAvailable !== 0) {
- throw new Error("Illegal user data header found!");
- }
-
- msg.header = header;
- },
-
- /**
- * Write out user data header.
- *
- * @param options
- * Options containing information for user data header write-out. The
- * `userDataHeaderLength` property must be correctly pre-calculated.
- */
- writeUserDataHeader: function(options) {
- this.writeHexOctet(options.userDataHeaderLength);
-
- if (options.segmentMaxSeq > 1) {
- if (options.segmentRef16Bit) {
- this.writeHexOctet(PDU_IEI_CONCATENATED_SHORT_MESSAGES_16BIT);
- this.writeHexOctet(4);
- this.writeHexOctet((options.segmentRef >> 8) & 0xFF);
- } else {
- this.writeHexOctet(PDU_IEI_CONCATENATED_SHORT_MESSAGES_8BIT);
- this.writeHexOctet(3);
- }
- this.writeHexOctet(options.segmentRef & 0xFF);
- this.writeHexOctet(options.segmentMaxSeq & 0xFF);
- this.writeHexOctet(options.segmentSeq & 0xFF);
- }
-
- if (options.dcs == PDU_DCS_MSG_CODING_7BITS_ALPHABET) {
- if (options.langIndex != PDU_NL_IDENTIFIER_DEFAULT) {
- this.writeHexOctet(PDU_IEI_NATIONAL_LANGUAGE_LOCKING_SHIFT);
- this.writeHexOctet(1);
- this.writeHexOctet(options.langIndex);
- }
-
- if (options.langShiftIndex != PDU_NL_IDENTIFIER_DEFAULT) {
- this.writeHexOctet(PDU_IEI_NATIONAL_LANGUAGE_SINGLE_SHIFT);
- this.writeHexOctet(1);
- this.writeHexOctet(options.langShiftIndex);
- }
- }
- },
-
- /**
- * Read SM-TL Address.
- *
- * @param len
- * Length of useful semi-octets within the Address-Value field. For
- * example, the lenth of "12345" should be 5, and 4 for "1234".
- *
- * @see 3GPP TS 23.040 9.1.2.5
- */
- readAddress: function(len) {
- // Address Length
- if (!len || (len < 0)) {
- if (DEBUG) {
- this.context.debug("PDU error: invalid sender address length: " + len);
- }
- return null;
- }
- if (len % 2 == 1) {
- len += 1;
- }
- if (DEBUG) this.context.debug("PDU: Going to read address: " + len);
-
- // Type-of-Address
- let toa = this.readHexOctet();
- let addr = "";
-
- if ((toa & 0xF0) == PDU_TOA_ALPHANUMERIC) {
- addr = this.readSeptetsToString(Math.floor(len * 4 / 7), 0,
- PDU_NL_IDENTIFIER_DEFAULT , PDU_NL_IDENTIFIER_DEFAULT );
- return addr;
- }
- addr = this.readSwappedNibbleExtendedBcdString(len / 2);
- if (addr.length <= 0) {
- if (DEBUG) this.context.debug("PDU error: no number provided");
- return null;
- }
- if ((toa & 0xF0) == (PDU_TOA_INTERNATIONAL)) {
- addr = '+' + addr;
- }
-
- return addr;
- },
-
- /**
- * Read TP-Protocol-Indicator(TP-PID).
- *
- * @param msg
- * message object for output.
- *
- * @see 3GPP TS 23.040 9.2.3.9
- */
- readProtocolIndicator: function(msg) {
- // `The MS shall interpret reserved, obsolete, or unsupported values as the
- // value 00000000 but shall store them exactly as received.`
- msg.pid = this.readHexOctet();
-
- msg.epid = msg.pid;
- switch (msg.epid & 0xC0) {
- case 0x40:
- // Bit 7..0 = 01xxxxxx
- switch (msg.epid) {
- case PDU_PID_SHORT_MESSAGE_TYPE_0:
- case PDU_PID_ANSI_136_R_DATA:
- case PDU_PID_USIM_DATA_DOWNLOAD:
- return;
- }
- break;
- }
-
- msg.epid = PDU_PID_DEFAULT;
- },
-
- /**
- * Read TP-Data-Coding-Scheme(TP-DCS)
- *
- * @param msg
- * message object for output.
- *
- * @see 3GPP TS 23.040 9.2.3.10, 3GPP TS 23.038 4.
- */
- readDataCodingScheme: function(msg) {
- let dcs = this.readHexOctet();
- if (DEBUG) this.context.debug("PDU: read SMS dcs: " + dcs);
-
- // No message class by default.
- let messageClass = PDU_DCS_MSG_CLASS_NORMAL;
- // 7 bit is the default fallback encoding.
- let encoding = PDU_DCS_MSG_CODING_7BITS_ALPHABET;
- switch (dcs & PDU_DCS_CODING_GROUP_BITS) {
- case 0x40: // bits 7..4 = 01xx
- case 0x50:
- case 0x60:
- case 0x70:
- // Bit 5..0 are coded exactly the same as Group 00xx
- case 0x00: // bits 7..4 = 00xx
- case 0x10:
- case 0x20:
- case 0x30:
- if (dcs & 0x10) {
- messageClass = dcs & PDU_DCS_MSG_CLASS_BITS;
- }
- switch (dcs & 0x0C) {
- case 0x4:
- encoding = PDU_DCS_MSG_CODING_8BITS_ALPHABET;
- break;
- case 0x8:
- encoding = PDU_DCS_MSG_CODING_16BITS_ALPHABET;
- break;
- }
- break;
-
- case 0xE0: // bits 7..4 = 1110
- encoding = PDU_DCS_MSG_CODING_16BITS_ALPHABET;
- // Bit 3..0 are coded exactly the same as Message Waiting Indication
- // Group 1101.
- // Fall through.
- case 0xC0: // bits 7..4 = 1100
- case 0xD0: // bits 7..4 = 1101
- // Indiciates voicemail indicator set or clear
- let active = (dcs & PDU_DCS_MWI_ACTIVE_BITS) == PDU_DCS_MWI_ACTIVE_VALUE;
-
- // If TP-UDH is present, these values will be overwritten
- switch (dcs & PDU_DCS_MWI_TYPE_BITS) {
- case PDU_DCS_MWI_TYPE_VOICEMAIL:
- let mwi = msg.mwi;
- if (!mwi) {
- mwi = msg.mwi = {};
- }
-
- mwi.active = active;
- mwi.discard = (dcs & PDU_DCS_CODING_GROUP_BITS) == 0xC0;
- mwi.msgCount = active ? GECKO_VOICEMAIL_MESSAGE_COUNT_UNKNOWN : 0;
-
- if (DEBUG) {
- this.context.debug("MWI in DCS received for voicemail: " +
- JSON.stringify(mwi));
- }
- break;
- case PDU_DCS_MWI_TYPE_FAX:
- if (DEBUG) this.context.debug("MWI in DCS received for fax");
- break;
- case PDU_DCS_MWI_TYPE_EMAIL:
- if (DEBUG) this.context.debug("MWI in DCS received for email");
- break;
- default:
- if (DEBUG) this.context.debug("MWI in DCS received for \"other\"");
- break;
- }
- break;
-
- case 0xF0: // bits 7..4 = 1111
- if (dcs & 0x04) {
- encoding = PDU_DCS_MSG_CODING_8BITS_ALPHABET;
- }
- messageClass = dcs & PDU_DCS_MSG_CLASS_BITS;
- break;
-
- default:
- // Falling back to default encoding.
- break;
- }
-
- msg.dcs = dcs;
- msg.encoding = encoding;
- msg.messageClass = GECKO_SMS_MESSAGE_CLASSES[messageClass];
-
- if (DEBUG) this.context.debug("PDU: message encoding is " + encoding + " bit.");
- },
-
- /**
- * Read GSM TP-Service-Centre-Time-Stamp(TP-SCTS).
- *
- * @see 3GPP TS 23.040 9.2.3.11
- */
- readTimestamp: function() {
- let year = this.readSwappedNibbleBcdNum(1) + PDU_TIMESTAMP_YEAR_OFFSET;
- let month = this.readSwappedNibbleBcdNum(1) - 1;
- let day = this.readSwappedNibbleBcdNum(1);
- let hour = this.readSwappedNibbleBcdNum(1);
- let minute = this.readSwappedNibbleBcdNum(1);
- let second = this.readSwappedNibbleBcdNum(1);
- let timestamp = Date.UTC(year, month, day, hour, minute, second);
-
- // If the most significant bit of the least significant nibble is 1,
- // the timezone offset is negative (fourth bit from the right => 0x08):
- // localtime = UTC + tzOffset
- // therefore
- // UTC = localtime - tzOffset
- let tzOctet = this.readHexOctet();
- let tzOffset = this.octetToBCD(tzOctet & ~0x08) * 15 * 60 * 1000;
- tzOffset = (tzOctet & 0x08) ? -tzOffset : tzOffset;
- timestamp -= tzOffset;
-
- return timestamp;
- },
-
- /**
- * Write GSM TP-Service-Centre-Time-Stamp(TP-SCTS).
- *
- * @see 3GPP TS 23.040 9.2.3.11
- */
- writeTimestamp: function(date) {
- this.writeSwappedNibbleBCDNum(date.getFullYear() - PDU_TIMESTAMP_YEAR_OFFSET);
-
- // The value returned by getMonth() is an integer between 0 and 11.
- // 0 is corresponds to January, 1 to February, and so on.
- this.writeSwappedNibbleBCDNum(date.getMonth() + 1);
- this.writeSwappedNibbleBCDNum(date.getDate());
- this.writeSwappedNibbleBCDNum(date.getHours());
- this.writeSwappedNibbleBCDNum(date.getMinutes());
- this.writeSwappedNibbleBCDNum(date.getSeconds());
-
- // the value returned by getTimezoneOffset() is the difference,
- // in minutes, between UTC and local time.
- // For example, if your time zone is UTC+10 (Australian Eastern Standard Time),
- // -600 will be returned.
- // In TS 23.040 9.2.3.11, the Time Zone field of TP-SCTS indicates
- // the different between the local time and GMT.
- // And expressed in quarters of an hours. (so need to divid by 15)
- let zone = date.getTimezoneOffset() / 15;
- let octet = this.BCDToOctet(zone);
-
- // the bit3 of the Time Zone field represents the algebraic sign.
- // (0: positive, 1: negative).
- // For example, if the time zone is -0800 GMT,
- // 480 will be returned by getTimezoneOffset().
- // In this case, need to mark sign bit as 1. => 0x08
- if (zone > 0) {
- octet = octet | 0x08;
- }
- this.writeHexOctet(octet);
- },
-
- /**
- * User data can be 7 bit (default alphabet) data, 8 bit data, or 16 bit
- * (UCS2) data.
- *
- * @param msg
- * message object for output.
- * @param length
- * length of user data to read in octets.
- */
- readUserData: function(msg, length) {
- if (DEBUG) {
- this.context.debug("Reading " + length + " bytes of user data.");
- }
-
- let paddingBits = 0;
- if (msg.udhi) {
- this.readUserDataHeader(msg);
-
- if (msg.encoding == PDU_DCS_MSG_CODING_7BITS_ALPHABET) {
- let headerBits = (msg.header.length + 1) * 8;
- let headerSeptets = Math.ceil(headerBits / 7);
-
- length -= headerSeptets;
- paddingBits = headerSeptets * 7 - headerBits;
- } else {
- length -= (msg.header.length + 1);
- }
- }
-
- if (DEBUG) {
- this.context.debug("After header, " + length + " septets left of user data");
- }
-
- msg.body = null;
- msg.data = null;
-
- if (length <= 0) {
- // No data to read.
- return;
- }
-
- switch (msg.encoding) {
- case PDU_DCS_MSG_CODING_7BITS_ALPHABET:
- // 7 bit encoding allows 140 octets, which means 160 characters
- // ((140x8) / 7 = 160 chars)
- if (length > PDU_MAX_USER_DATA_7BIT) {
- if (DEBUG) {
- this.context.debug("PDU error: user data is too long: " + length);
- }
- break;
- }
-
- let langIndex = msg.udhi ? msg.header.langIndex : PDU_NL_IDENTIFIER_DEFAULT;
- let langShiftIndex = msg.udhi ? msg.header.langShiftIndex : PDU_NL_IDENTIFIER_DEFAULT;
- msg.body = this.readSeptetsToString(length, paddingBits, langIndex,
- langShiftIndex);
- break;
- case PDU_DCS_MSG_CODING_8BITS_ALPHABET:
- msg.data = this.readHexOctetArray(length);
- break;
- case PDU_DCS_MSG_CODING_16BITS_ALPHABET:
- msg.body = this.readUCS2String(length);
- break;
- }
- },
-
- /**
- * Read extra parameters if TP-PI is set.
- *
- * @param msg
- * message object for output.
- */
- readExtraParams: function(msg) {
- // Because each PDU octet is converted to two UCS2 char2, we should always
- // get even messageStringLength in this#_processReceivedSms(). So, we'll
- // always need two delimitors at the end.
- if (this.context.Buf.getReadAvailable() <= 4) {
- return;
- }
-
- // TP-Parameter-Indicator
- let pi;
- do {
- // `The most significant bit in octet 1 and any other TP-PI octets which
- // may be added later is reserved as an extension bit which when set to a
- // 1 shall indicate that another TP-PI octet follows immediately
- // afterwards.` ~ 3GPP TS 23.040 9.2.3.27
- pi = this.readHexOctet();
- } while (pi & PDU_PI_EXTENSION);
-
- // `If the TP-UDL bit is set to "1" but the TP-DCS bit is set to "0" then
- // the receiving entity shall for TP-DCS assume a value of 0x00, i.e. the
- // 7bit default alphabet.` ~ 3GPP 23.040 9.2.3.27
- msg.dcs = 0;
- msg.encoding = PDU_DCS_MSG_CODING_7BITS_ALPHABET;
-
- // TP-Protocol-Identifier
- if (pi & PDU_PI_PROTOCOL_IDENTIFIER) {
- this.readProtocolIndicator(msg);
- }
- // TP-Data-Coding-Scheme
- if (pi & PDU_PI_DATA_CODING_SCHEME) {
- this.readDataCodingScheme(msg);
- }
- // TP-User-Data-Length
- if (pi & PDU_PI_USER_DATA_LENGTH) {
- let userDataLength = this.readHexOctet();
- this.readUserData(msg, userDataLength);
- }
- },
-
- /**
- * Read and decode a PDU-encoded message from the stream.
- *
- * TODO: add some basic sanity checks like:
- * - do we have the minimum number of chars available
- */
- readMessage: function() {
- // An empty message object. This gets filled below and then returned.
- let msg = {
- // D:DELIVER, DR:DELIVER-REPORT, S:SUBMIT, SR:SUBMIT-REPORT,
- // ST:STATUS-REPORT, C:COMMAND
- // M:Mandatory, O:Optional, X:Unavailable
- // D DR S SR ST C
- SMSC: null, // M M M M M M
- mti: null, // M M M M M M
- udhi: null, // M M O M M M
- sender: null, // M X X X X X
- recipient: null, // X X M X M M
- pid: null, // M O M O O M
- epid: null, // M O M O O M
- dcs: null, // M O M O O X
- mwi: null, // O O O O O O
- replace: false, // O O O O O O
- header: null, // M M O M M M
- body: null, // M O M O O O
- data: null, // M O M O O O
- sentTimestamp: null, // M X X X X X
- status: null, // X X X X M X
- scts: null, // X X X M M X
- dt: null, // X X X X M X
- };
-
- // SMSC info
- let smscLength = this.readHexOctet();
- if (smscLength > 0) {
- let smscTypeOfAddress = this.readHexOctet();
- // Subtract the type-of-address octet we just read from the length.
- msg.SMSC = this.readSwappedNibbleExtendedBcdString(smscLength - 1);
- if ((smscTypeOfAddress >> 4) == (PDU_TOA_INTERNATIONAL >> 4)) {
- msg.SMSC = '+' + msg.SMSC;
- }
- }
-
- // First octet of this SMS-DELIVER or SMS-SUBMIT message
- let firstOctet = this.readHexOctet();
- // Message Type Indicator
- msg.mti = firstOctet & 0x03;
- // User data header indicator
- msg.udhi = firstOctet & PDU_UDHI;
-
- switch (msg.mti) {
- case PDU_MTI_SMS_RESERVED:
- // `If an MS receives a TPDU with a "Reserved" value in the TP-MTI it
- // shall process the message as if it were an "SMS-DELIVER" but store
- // the message exactly as received.` ~ 3GPP TS 23.040 9.2.3.1
- case PDU_MTI_SMS_DELIVER:
- return this.readDeliverMessage(msg);
- case PDU_MTI_SMS_STATUS_REPORT:
- return this.readStatusReportMessage(msg);
- default:
- return null;
- }
- },
-
- /**
- * Helper for processing received SMS parcel data.
- *
- * @param length
- * Length of SMS string in the incoming parcel.
- *
- * @return Message parsed or null for invalid message.
- */
- processReceivedSms: function(length) {
- if (!length) {
- if (DEBUG) this.context.debug("Received empty SMS!");
- return [null, PDU_FCS_UNSPECIFIED];
- }
-
- let Buf = this.context.Buf;
-
- // An SMS is a string, but we won't read it as such, so let's read the
- // string length and then defer to PDU parsing helper.
- let messageStringLength = Buf.readInt32();
- if (DEBUG) this.context.debug("Got new SMS, length " + messageStringLength);
- let message = this.readMessage();
- if (DEBUG) this.context.debug("Got new SMS: " + JSON.stringify(message));
-
- // Read string delimiters. See Buf.readString().
- Buf.readStringDelimiter(length);
-
- // Determine result
- if (!message) {
- return [null, PDU_FCS_UNSPECIFIED];
- }
-
- if (message.epid == PDU_PID_SHORT_MESSAGE_TYPE_0) {
- // `A short message type 0 indicates that the ME must acknowledge receipt
- // of the short message but shall discard its contents.` ~ 3GPP TS 23.040
- // 9.2.3.9
- return [null, PDU_FCS_OK];
- }
-
- if (message.messageClass == GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_2]) {
- let RIL = this.context.RIL;
- switch (message.epid) {
- case PDU_PID_ANSI_136_R_DATA:
- case PDU_PID_USIM_DATA_DOWNLOAD:
- let ICCUtilsHelper = this.context.ICCUtilsHelper;
- if (ICCUtilsHelper.isICCServiceAvailable("DATA_DOWNLOAD_SMS_PP")) {
- // `If the service "data download via SMS Point-to-Point" is
- // allocated and activated in the (U)SIM Service Table, ... then the
- // ME shall pass the message transparently to the UICC using the
- // ENVELOPE (SMS-PP DOWNLOAD).` ~ 3GPP TS 31.111 7.1.1.1
- RIL.dataDownloadViaSMSPP(message);
-
- // `the ME shall not display the message, or alert the user of a
- // short message waiting.` ~ 3GPP TS 31.111 7.1.1.1
- return [null, PDU_FCS_RESERVED];
- }
-
- // If the service "data download via SMS-PP" is not available in the
- // (U)SIM Service Table, ..., then the ME shall store the message in
- // EFsms in accordance with TS 31.102` ~ 3GPP TS 31.111 7.1.1.1
-
- // Fall through.
- default:
- RIL.writeSmsToSIM(message);
- break;
- }
- }
-
- // TODO: Bug 739143: B2G SMS: Support SMS Storage Full event
- if ((message.messageClass != GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_0]) && !true) {
- // `When a mobile terminated message is class 0..., the MS shall display
- // the message immediately and send a ACK to the SC ..., irrespective of
- // whether there is memory available in the (U)SIM or ME.` ~ 3GPP 23.038
- // clause 4.
-
- if (message.messageClass == GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_2]) {
- // `If all the short message storage at the MS is already in use, the
- // MS shall return "memory capacity exceeded".` ~ 3GPP 23.038 clause 4.
- return [null, PDU_FCS_MEMORY_CAPACITY_EXCEEDED];
- }
-
- return [null, PDU_FCS_UNSPECIFIED];
- }
-
- return [message, PDU_FCS_OK];
- },
-
- /**
- * Read and decode a SMS-DELIVER PDU.
- *
- * @param msg
- * message object for output.
- */
- readDeliverMessage: function(msg) {
- // - Sender Address info -
- let senderAddressLength = this.readHexOctet();
- msg.sender = this.readAddress(senderAddressLength);
- // - TP-Protocolo-Identifier -
- this.readProtocolIndicator(msg);
- // - TP-Data-Coding-Scheme -
- this.readDataCodingScheme(msg);
- // - TP-Service-Center-Time-Stamp -
- msg.sentTimestamp = this.readTimestamp();
- // - TP-User-Data-Length -
- let userDataLength = this.readHexOctet();
-
- // - TP-User-Data -
- if (userDataLength > 0) {
- this.readUserData(msg, userDataLength);
- }
-
- return msg;
- },
-
- /**
- * Read and decode a SMS-STATUS-REPORT PDU.
- *
- * @param msg
- * message object for output.
- */
- readStatusReportMessage: function(msg) {
- // TP-Message-Reference
- msg.messageRef = this.readHexOctet();
- // TP-Recipient-Address
- let recipientAddressLength = this.readHexOctet();
- msg.recipient = this.readAddress(recipientAddressLength);
- // TP-Service-Centre-Time-Stamp
- msg.scts = this.readTimestamp();
- // TP-Discharge-Time
- msg.dt = this.readTimestamp();
- // TP-Status
- msg.status = this.readHexOctet();
-
- this.readExtraParams(msg);
-
- return msg;
- },
-
- /**
- * Serialize a SMS-SUBMIT PDU message and write it to the output stream.
- *
- * This method expects that a data coding scheme has been chosen already
- * and that the length of the user data payload in that encoding is known,
- * too. Both go hand in hand together anyway.
- *
- * @param address
- * String containing the address (number) of the SMS receiver
- * @param userData
- * String containing the message to be sent as user data
- * @param dcs
- * Data coding scheme. One of the PDU_DCS_MSG_CODING_*BITS_ALPHABET
- * constants.
- * @param userDataHeaderLength
- * Length of embedded user data header, in bytes. The whole header
- * size will be userDataHeaderLength + 1; 0 for no header.
- * @param encodedBodyLength
- * Length of the user data when encoded with the given DCS. For UCS2,
- * in bytes; for 7-bit, in septets.
- * @param langIndex
- * Table index used for normal 7-bit encoded character lookup.
- * @param langShiftIndex
- * Table index used for escaped 7-bit encoded character lookup.
- * @param requestStatusReport
- * Request status report.
- */
- writeMessage: function(options) {
- if (DEBUG) {
- this.context.debug("writeMessage: " + JSON.stringify(options));
- }
- let Buf = this.context.Buf;
- let address = options.number;
- let body = options.body;
- let dcs = options.dcs;
- let userDataHeaderLength = options.userDataHeaderLength;
- let encodedBodyLength = options.encodedBodyLength;
- let langIndex = options.langIndex;
- let langShiftIndex = options.langShiftIndex;
-
- // SMS-SUBMIT Format:
- //
- // PDU Type - 1 octet
- // Message Reference - 1 octet
- // DA - Destination Address - 2 to 12 octets
- // PID - Protocol Identifier - 1 octet
- // DCS - Data Coding Scheme - 1 octet
- // VP - Validity Period - 0, 1 or 7 octets
- // UDL - User Data Length - 1 octet
- // UD - User Data - 140 octets
-
- let addressFormat = PDU_TOA_ISDN; // 81
- if (address[0] == '+') {
- addressFormat = PDU_TOA_INTERNATIONAL | PDU_TOA_ISDN; // 91
- address = address.substring(1);
- }
- //TODO validity is unsupported for now
- let validity = 0;
-
- let headerOctets = (userDataHeaderLength ? userDataHeaderLength + 1 : 0);
- let paddingBits;
- let userDataLengthInSeptets;
- let userDataLengthInOctets;
- if (dcs == PDU_DCS_MSG_CODING_7BITS_ALPHABET) {
- let headerSeptets = Math.ceil(headerOctets * 8 / 7);
- userDataLengthInSeptets = headerSeptets + encodedBodyLength;
- userDataLengthInOctets = Math.ceil(userDataLengthInSeptets * 7 / 8);
- paddingBits = headerSeptets * 7 - headerOctets * 8;
- } else {
- userDataLengthInOctets = headerOctets + encodedBodyLength;
- paddingBits = 0;
- }
-
- let pduOctetLength = 4 + // PDU Type, Message Ref, address length + format
- Math.ceil(address.length / 2) +
- 3 + // PID, DCS, UDL
- userDataLengthInOctets;
- if (validity) {
- //TODO: add more to pduOctetLength
- }
-
- // Start the string. Since octets are represented in hex, we will need
- // twice as many characters as octets.
- Buf.writeInt32(pduOctetLength * 2);
-
- // - PDU-TYPE-
-
- // +--------+----------+---------+---------+--------+---------+
- // | RP (1) | UDHI (1) | SRR (1) | VPF (2) | RD (1) | MTI (2) |
- // +--------+----------+---------+---------+--------+---------+
- // RP: 0 Reply path parameter is not set
- // 1 Reply path parameter is set
- // UDHI: 0 The UD Field contains only the short message
- // 1 The beginning of the UD field contains a header in addition
- // of the short message
- // SRR: 0 A status report is not requested
- // 1 A status report is requested
- // VPF: bit4 bit3
- // 0 0 VP field is not present
- // 0 1 Reserved
- // 1 0 VP field present an integer represented (relative)
- // 1 1 VP field present a semi-octet represented (absolute)
- // RD: Instruct the SMSC to accept(0) or reject(1) an SMS-SUBMIT
- // for a short message still held in the SMSC which has the same
- // MR and DA as a previously submitted short message from the
- // same OA
- // MTI: bit1 bit0 Message Type
- // 0 0 SMS-DELIVER (SMSC ==> MS)
- // 0 1 SMS-SUBMIT (MS ==> SMSC)
-
- // PDU type. MTI is set to SMS-SUBMIT
- let firstOctet = PDU_MTI_SMS_SUBMIT;
-
- // Status-Report-Request
- if (options.requestStatusReport) {
- firstOctet |= PDU_SRI_SRR;
- }
-
- // Validity period
- if (validity) {
- //TODO: not supported yet, OR with one of PDU_VPF_*
- }
- // User data header indicator
- if (headerOctets) {
- firstOctet |= PDU_UDHI;
- }
- this.writeHexOctet(firstOctet);
-
- // Message reference 00
- this.writeHexOctet(0x00);
-
- // - Destination Address -
- this.writeHexOctet(address.length);
- this.writeHexOctet(addressFormat);
- this.writeSwappedNibbleBCD(address);
-
- // - Protocol Identifier -
- this.writeHexOctet(0x00);
-
- // - Data coding scheme -
- // For now it assumes bits 7..4 = 1111 except for the 16 bits use case
- this.writeHexOctet(dcs);
-
- // - Validity Period -
- if (validity) {
- this.writeHexOctet(validity);
- }
-
- // - User Data -
- if (dcs == PDU_DCS_MSG_CODING_7BITS_ALPHABET) {
- this.writeHexOctet(userDataLengthInSeptets);
- } else {
- this.writeHexOctet(userDataLengthInOctets);
- }
-
- if (headerOctets) {
- this.writeUserDataHeader(options);
- }
-
- switch (dcs) {
- case PDU_DCS_MSG_CODING_7BITS_ALPHABET:
- this.writeStringAsSeptets(body, paddingBits, langIndex, langShiftIndex);
- break;
- case PDU_DCS_MSG_CODING_8BITS_ALPHABET:
- // Unsupported.
- break;
- case PDU_DCS_MSG_CODING_16BITS_ALPHABET:
- this.writeUCS2String(body);
- break;
- }
-
- // End of the string. The string length is always even by definition, so
- // we write two \0 delimiters.
- Buf.writeUint16(0);
- Buf.writeUint16(0);
- },
-
- /**
- * Read GSM CBS message serial number.
- *
- * @param msg
- * message object for output.
- *
- * @see 3GPP TS 23.041 section 9.4.1.2.1
- */
- readCbSerialNumber: function(msg) {
- let Buf = this.context.Buf;
- msg.serial = Buf.readUint8() << 8 | Buf.readUint8();
- msg.geographicalScope = (msg.serial >>> 14) & 0x03;
- msg.messageCode = (msg.serial >>> 4) & 0x03FF;
- msg.updateNumber = msg.serial & 0x0F;
- },
-
- /**
- * Read GSM CBS message message identifier.
- *
- * @param msg
- * message object for output.
- *
- * @see 3GPP TS 23.041 section 9.4.1.2.2
- */
- readCbMessageIdentifier: function(msg) {
- let Buf = this.context.Buf;
- msg.messageId = Buf.readUint8() << 8 | Buf.readUint8();
- },
-
- /**
- * Read ETWS information from message identifier and serial Number
- * @param msg
- * message object for output.
- *
- * @see 3GPP TS 23.041 section 9.4.1.2.1 & 9.4.1.2.2
- */
- readCbEtwsInfo: function(msg) {
- if ((msg.format != CB_FORMAT_ETWS)
- && (msg.messageId >= CB_GSM_MESSAGEID_ETWS_BEGIN)
- && (msg.messageId <= CB_GSM_MESSAGEID_ETWS_END)) {
- // `In the case of transmitting CBS message for ETWS, a part of
- // Message Code can be used to command mobile terminals to activate
- // emergency user alert and message popup in order to alert the users.`
- msg.etws = {
- emergencyUserAlert: msg.messageCode & 0x0200 ? true : false,
- popup: msg.messageCode & 0x0100 ? true : false
- };
-
- let warningType = msg.messageId - CB_GSM_MESSAGEID_ETWS_BEGIN;
- if (warningType < CB_ETWS_WARNING_TYPE_NAMES.length) {
- msg.etws.warningType = warningType;
- }
- }
- },
-
- /**
- * Read CBS Data Coding Scheme.
- *
- * @param msg
- * message object for output.
- *
- * @see 3GPP TS 23.038 section 5.
- */
- readCbDataCodingScheme: function(msg) {
- let dcs = this.context.Buf.readUint8();
- if (DEBUG) this.context.debug("PDU: read CBS dcs: " + dcs);
-
- let language = null, hasLanguageIndicator = false;
- // `Any reserved codings shall be assumed to be the GSM 7bit default
- // alphabet.`
- let encoding = PDU_DCS_MSG_CODING_7BITS_ALPHABET;
- let messageClass = PDU_DCS_MSG_CLASS_NORMAL;
-
- switch (dcs & PDU_DCS_CODING_GROUP_BITS) {
- case 0x00: // 0000
- language = CB_DCS_LANG_GROUP_1[dcs & 0x0F];
- break;
-
- case 0x10: // 0001
- switch (dcs & 0x0F) {
- case 0x00:
- hasLanguageIndicator = true;
- break;
- case 0x01:
- encoding = PDU_DCS_MSG_CODING_16BITS_ALPHABET;
- hasLanguageIndicator = true;
- break;
- }
- break;
-
- case 0x20: // 0010
- language = CB_DCS_LANG_GROUP_2[dcs & 0x0F];
- break;
-
- case 0x40: // 01xx
- case 0x50:
- //case 0x60: Text Compression, not supported
- //case 0x70: Text Compression, not supported
- case 0x90: // 1001
- encoding = (dcs & 0x0C);
- if (encoding == 0x0C) {
- encoding = PDU_DCS_MSG_CODING_7BITS_ALPHABET;
- }
- messageClass = (dcs & PDU_DCS_MSG_CLASS_BITS);
- break;
-
- case 0xF0:
- encoding = (dcs & 0x04) ? PDU_DCS_MSG_CODING_8BITS_ALPHABET
- : PDU_DCS_MSG_CODING_7BITS_ALPHABET;
- switch(dcs & PDU_DCS_MSG_CLASS_BITS) {
- case 0x01: messageClass = PDU_DCS_MSG_CLASS_USER_1; break;
- case 0x02: messageClass = PDU_DCS_MSG_CLASS_USER_2; break;
- case 0x03: messageClass = PDU_DCS_MSG_CLASS_3; break;
- }
- break;
-
- case 0x30: // 0011 (Reserved)
- case 0x80: // 1000 (Reserved)
- case 0xA0: // 1010..1100 (Reserved)
- case 0xB0:
- case 0xC0:
- break;
-
- default:
- throw new Error("Unsupported CBS data coding scheme: " + dcs);
- }
-
- msg.dcs = dcs;
- msg.encoding = encoding;
- msg.language = language;
- msg.messageClass = GECKO_SMS_MESSAGE_CLASSES[messageClass];
- msg.hasLanguageIndicator = hasLanguageIndicator;
- },
-
- /**
- * Read GSM CBS message page parameter.
- *
- * @param msg
- * message object for output.
- *
- * @see 3GPP TS 23.041 section 9.4.1.2.4
- */
- readCbPageParameter: function(msg) {
- let octet = this.context.Buf.readUint8();
- msg.pageIndex = (octet >>> 4) & 0x0F;
- msg.numPages = octet & 0x0F;
- if (!msg.pageIndex || !msg.numPages) {
- // `If a mobile receives the code 0000 in either the first field or the
- // second field then it shall treat the CBS message exactly the same as a
- // CBS message with page parameter 0001 0001 (i.e. a single page message).`
- msg.pageIndex = msg.numPages = 1;
- }
- },
-
- /**
- * Read ETWS Primary Notification message warning type.
- *
- * @param msg
- * message object for output.
- *
- * @see 3GPP TS 23.041 section 9.3.24
- */
- readCbWarningType: function(msg) {
- let Buf = this.context.Buf;
- let word = Buf.readUint8() << 8 | Buf.readUint8();
- msg.etws = {
- warningType: (word >>> 9) & 0x7F,
- popup: word & 0x80 ? true : false,
- emergencyUserAlert: word & 0x100 ? true : false
- };
- },
-
- /**
- * Read GSM CB Data
- *
- * This parameter is a copy of the 'CBS-Message-Information-Page' as sent
- * from the CBC to the BSC.
- *
- * @see 3GPP TS 23.041 section 9.4.1.2.5
- */
- readGsmCbData: function(msg, length) {
- let Buf = this.context.Buf;
- let bufAdapter = {
- context: this.context,
- readHexOctet: function() {
- return Buf.readUint8();
- }
- };
-
- msg.body = null;
- msg.data = null;
- switch (msg.encoding) {
- case PDU_DCS_MSG_CODING_7BITS_ALPHABET:
- msg.body = this.readSeptetsToString.call(bufAdapter,
- Math.floor(length * 8 / 7), 0,
- PDU_NL_IDENTIFIER_DEFAULT,
- PDU_NL_IDENTIFIER_DEFAULT);
- if (msg.hasLanguageIndicator) {
- msg.language = msg.body.substring(0, 2);
- msg.body = msg.body.substring(3);
- }
- break;
-
- case PDU_DCS_MSG_CODING_8BITS_ALPHABET:
- msg.data = Buf.readUint8Array(length);
- break;
-
- case PDU_DCS_MSG_CODING_16BITS_ALPHABET:
- if (msg.hasLanguageIndicator) {
- msg.language = this.readSeptetsToString.call(bufAdapter, 2, 0,
- PDU_NL_IDENTIFIER_DEFAULT,
- PDU_NL_IDENTIFIER_DEFAULT);
- length -= 2;
- }
- msg.body = this.readUCS2String.call(bufAdapter, length);
- break;
- }
-
- if (msg.data || !msg.body) {
- return;
- }
-
- // According to 9.3.19 CBS-Message-Information-Page in TS 23.041:
- // "
- // This parameter is of a fixed length of 82 octets and carries up to and
- // including 82 octets of user information. Where the user information is
- // less than 82 octets, the remaining octets must be filled with padding.
- // "
- // According to 6.2.1.1 GSM 7 bit Default Alphabet and 6.2.3 UCS2 in
- // TS 23.038, the padding character is <CR>.
- for (let i = msg.body.length - 1; i >= 0; i--) {
- if (msg.body.charAt(i) !== '\r') {
- msg.body = msg.body.substring(0, i + 1);
- break;
- }
- }
- },
-
- /**
- * Read UMTS CB Data
- *
- * Octet Number(s) Parameter
- * 1 Number-of-Pages
- * 2 - 83 CBS-Message-Information-Page 1
- * 84 CBS-Message-Information-Length 1
- * ...
- * CBS-Message-Information-Page n
- * CBS-Message-Information-Length n
- *
- * @see 3GPP TS 23.041 section 9.4.2.2.5
- */
- readUmtsCbData: function(msg) {
- let Buf = this.context.Buf;
- let numOfPages = Buf.readUint8();
- if (numOfPages < 0 || numOfPages > 15) {
- throw new Error("Invalid numOfPages: " + numOfPages);
- }
-
- let bufAdapter = {
- context: this.context,
- readHexOctet: function() {
- return Buf.readUint8();
- }
- };
-
- let removePaddingCharactors = function (text) {
- for (let i = text.length - 1; i >= 0; i--) {
- if (text.charAt(i) !== '\r') {
- return text.substring(0, i + 1);
- }
- }
- return text;
- };
-
- let totalLength = 0, length, pageLengths = [];
- for (let i = 0; i < numOfPages; i++) {
- Buf.seekIncoming(CB_MSG_PAGE_INFO_SIZE);
- length = Buf.readUint8();
- totalLength += length;
- pageLengths.push(length);
- }
-
- // Seek back to beginning of CB Data.
- Buf.seekIncoming(-numOfPages * (CB_MSG_PAGE_INFO_SIZE + 1));
-
- switch (msg.encoding) {
- case PDU_DCS_MSG_CODING_7BITS_ALPHABET: {
- let body;
- msg.body = "";
- for (let i = 0; i < numOfPages; i++) {
- body = this.readSeptetsToString.call(bufAdapter,
- Math.floor(pageLengths[i] * 8 / 7),
- 0,
- PDU_NL_IDENTIFIER_DEFAULT,
- PDU_NL_IDENTIFIER_DEFAULT);
- if (msg.hasLanguageIndicator) {
- if (!msg.language) {
- msg.language = body.substring(0, 2);
- }
- body = body.substring(3);
- }
-
- msg.body += removePaddingCharactors(body);
-
- // Skip padding octets
- Buf.seekIncoming(CB_MSG_PAGE_INFO_SIZE - pageLengths[i]);
- // Read the octet of CBS-Message-Information-Length
- Buf.readUint8();
- }
-
- break;
- }
-
- case PDU_DCS_MSG_CODING_8BITS_ALPHABET: {
- msg.data = new Uint8Array(totalLength);
- for (let i = 0, j = 0; i < numOfPages; i++) {
- for (let pageLength = pageLengths[i]; pageLength > 0; pageLength--) {
- msg.data[j++] = Buf.readUint8();
- }
-
- // Skip padding octets
- Buf.seekIncoming(CB_MSG_PAGE_INFO_SIZE - pageLengths[i]);
- // Read the octet of CBS-Message-Information-Length
- Buf.readUint8();
- }
-
- break;
- }
-
- case PDU_DCS_MSG_CODING_16BITS_ALPHABET: {
- msg.body = "";
- for (let i = 0; i < numOfPages; i++) {
- let pageLength = pageLengths[i];
- if (msg.hasLanguageIndicator) {
- if (!msg.language) {
- msg.language = this.readSeptetsToString.call(bufAdapter,
- 2,
- 0,
- PDU_NL_IDENTIFIER_DEFAULT,
- PDU_NL_IDENTIFIER_DEFAULT);
- } else {
- Buf.readUint16();
- }
-
- pageLength -= 2;
- }
-
- msg.body += removePaddingCharactors(
- this.readUCS2String.call(bufAdapter, pageLength));
-
- // Skip padding octets
- Buf.seekIncoming(CB_MSG_PAGE_INFO_SIZE - pageLengths[i]);
- // Read the octet of CBS-Message-Information-Length
- Buf.readUint8();
- }
-
- break;
- }
- }
- },
-
- /**
- * Read Cell GSM/ETWS/UMTS Broadcast Message.
- *
- * @param pduLength
- * total length of the incoming PDU in octets.
- */
- readCbMessage: function(pduLength) {
- // Validity GSM ETWS UMTS
- let msg = {
- // Internally used in ril_worker:
- serial: null, // O O O
- updateNumber: null, // O O O
- format: null, // O O O
- dcs: 0x0F, // O X O
- encoding: PDU_DCS_MSG_CODING_7BITS_ALPHABET, // O X O
- hasLanguageIndicator: false, // O X O
- data: null, // O X O
- body: null, // O X O
- pageIndex: 1, // O X X
- numPages: 1, // O X X
-
- // DOM attributes:
- geographicalScope: null, // O O O
- messageCode: null, // O O O
- messageId: null, // O O O
- language: null, // O X O
- fullBody: null, // O X O
- fullData: null, // O X O
- messageClass: GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_NORMAL], // O x O
- etws: null // ? O ?
- /*{
- warningType: null, // X O X
- popup: false, // X O X
- emergencyUserAlert: false, // X O X
- }*/
- };
-
- if (pduLength <= CB_MESSAGE_SIZE_ETWS) {
- msg.format = CB_FORMAT_ETWS;
- return this.readEtwsCbMessage(msg);
- }
-
- if (pduLength <= CB_MESSAGE_SIZE_GSM) {
- msg.format = CB_FORMAT_GSM;
- return this.readGsmCbMessage(msg, pduLength);
- }
-
- if (pduLength >= CB_MESSAGE_SIZE_UMTS_MIN &&
- pduLength <= CB_MESSAGE_SIZE_UMTS_MAX) {
- msg.format = CB_FORMAT_UMTS;
- return this.readUmtsCbMessage(msg);
- }
-
- throw new Error("Invalid PDU Length: " + pduLength);
- },
-
- /**
- * Read UMTS CBS Message.
- *
- * @param msg
- * message object for output.
- *
- * @see 3GPP TS 23.041 section 9.4.2
- * @see 3GPP TS 25.324 section 10.2
- */
- readUmtsCbMessage: function(msg) {
- let Buf = this.context.Buf;
- let type = Buf.readUint8();
- if (type != CB_UMTS_MESSAGE_TYPE_CBS) {
- throw new Error("Unsupported UMTS Cell Broadcast message type: " + type);
- }
-
- this.readCbMessageIdentifier(msg);
- this.readCbSerialNumber(msg);
- this.readCbEtwsInfo(msg);
- this.readCbDataCodingScheme(msg);
- this.readUmtsCbData(msg);
-
- return msg;
- },
-
- /**
- * Read GSM Cell Broadcast Message.
- *
- * @param msg
- * message object for output.
- * @param pduLength
- * total length of the incomint PDU in octets.
- *
- * @see 3GPP TS 23.041 clause 9.4.1.2
- */
- readGsmCbMessage: function(msg, pduLength) {
- this.readCbSerialNumber(msg);
- this.readCbMessageIdentifier(msg);
- this.readCbEtwsInfo(msg);
- this.readCbDataCodingScheme(msg);
- this.readCbPageParameter(msg);
-
- // GSM CB message header takes 6 octets.
- this.readGsmCbData(msg, pduLength - 6);
-
- return msg;
- },
-
- /**
- * Read ETWS Primary Notification Message.
- *
- * @param msg
- * message object for output.
- *
- * @see 3GPP TS 23.041 clause 9.4.1.3
- */
- readEtwsCbMessage: function(msg) {
- this.readCbSerialNumber(msg);
- this.readCbMessageIdentifier(msg);
- this.readCbWarningType(msg);
-
- // Octet 7..56 is Warning Security Information. However, according to
- // section 9.4.1.3.6, `The UE shall ignore this parameter.` So we just skip
- // processing it here.
-
- return msg;
- },
-
- /**
- * Read network name.
- *
- * @param len Length of the information element.
- * @return
- * {
- * networkName: network name.
- * shouldIncludeCi: Should Country's initials included in text string.
- * }
- * @see TS 24.008 clause 10.5.3.5a.
- */
- readNetworkName: function(len) {
- // According to TS 24.008 Sec. 10.5.3.5a, the first octet is:
- // bit 8: must be 1.
- // bit 5-7: Text encoding.
- // 000 - GSM default alphabet.
- // 001 - UCS2 (16 bit).
- // else - reserved.
- // bit 4: MS should add the letters for Country's Initials and a space
- // to the text string if this bit is true.
- // bit 1-3: number of spare bits in last octet.
-
- let codingInfo = this.readHexOctet();
- if (!(codingInfo & 0x80)) {
- return null;
- }
-
- let textEncoding = (codingInfo & 0x70) >> 4;
- let shouldIncludeCountryInitials = !!(codingInfo & 0x08);
- let spareBits = codingInfo & 0x07;
- let resultString;
-
- switch (textEncoding) {
- case 0:
- // GSM Default alphabet.
- resultString = this.readSeptetsToString(
- Math.floor(((len - 1) * 8 - spareBits) / 7), 0,
- PDU_NL_IDENTIFIER_DEFAULT,
- PDU_NL_IDENTIFIER_DEFAULT);
- break;
- case 1:
- // UCS2 encoded.
- resultString = this.context.ICCPDUHelper.readAlphaIdentifier(len - 1);
- break;
- default:
- // Not an available text coding.
- return null;
- }
-
- // TODO - Bug 820286: According to shouldIncludeCountryInitials, add
- // country initials to the resulting string.
- return resultString;
- }
-};
-
-/**
- * Provide buffer with bitwise read/write function so make encoding/decoding easier.
- */
-function BitBufferHelperObject(/* unused */aContext) {
- this.readBuffer = [];
- this.writeBuffer = [];
-}
-BitBufferHelperObject.prototype = {
- readCache: 0,
- readCacheSize: 0,
- readBuffer: null,
- readIndex: 0,
- writeCache: 0,
- writeCacheSize: 0,
- writeBuffer: null,
-
- // Max length is 32 because we use integer as read/write cache.
- // All read/write functions are implemented based on bitwise operation.
- readBits: function(length) {
- if (length <= 0 || length > 32) {
- return null;
- }
-
- if (length > this.readCacheSize) {
- let bytesToRead = Math.ceil((length - this.readCacheSize) / 8);
- for(let i = 0; i < bytesToRead; i++) {
- this.readCache = (this.readCache << 8) | (this.readBuffer[this.readIndex++] & 0xFF);
- this.readCacheSize += 8;
- }
- }
-
- let bitOffset = (this.readCacheSize - length),
- resultMask = (1 << length) - 1,
- result = 0;
-
- result = (this.readCache >> bitOffset) & resultMask;
- this.readCacheSize -= length;
-
- return result;
- },
-
- backwardReadPilot: function(length) {
- if (length <= 0) {
- return;
- }
-
- // Zero-based position.
- let bitIndexToRead = this.readIndex * 8 - this.readCacheSize - length;
-
- if (bitIndexToRead < 0) {
- return;
- }
-
- // Update readIndex, readCache, readCacheSize accordingly.
- let readBits = bitIndexToRead % 8;
- this.readIndex = Math.floor(bitIndexToRead / 8) + ((readBits) ? 1 : 0);
- this.readCache = (readBits) ? this.readBuffer[this.readIndex - 1] : 0;
- this.readCacheSize = (readBits) ? (8 - readBits) : 0;
- },
-
- writeBits: function(value, length) {
- if (length <= 0 || length > 32) {
- return;
- }
-
- let totalLength = length + this.writeCacheSize;
-
- // 8-byte cache not full
- if (totalLength < 8) {
- let valueMask = (1 << length) - 1;
- this.writeCache = (this.writeCache << length) | (value & valueMask);
- this.writeCacheSize += length;
- return;
- }
-
- // Deal with unaligned part
- if (this.writeCacheSize) {
- let mergeLength = 8 - this.writeCacheSize,
- valueMask = (1 << mergeLength) - 1;
-
- this.writeCache = (this.writeCache << mergeLength) | ((value >> (length - mergeLength)) & valueMask);
- this.writeBuffer.push(this.writeCache & 0xFF);
- length -= mergeLength;
- }
-
- // Aligned part, just copy
- while (length >= 8) {
- length -= 8;
- this.writeBuffer.push((value >> length) & 0xFF);
- }
-
- // Rest part is saved into cache
- this.writeCacheSize = length;
- this.writeCache = value & ((1 << length) - 1);
-
- return;
- },
-
- // Drop what still in read cache and goto next 8-byte alignment.
- // There might be a better naming.
- nextOctetAlign: function() {
- this.readCache = 0;
- this.readCacheSize = 0;
- },
-
- // Flush current write cache to Buf with padding 0s.
- // There might be a better naming.
- flushWithPadding: function() {
- if (this.writeCacheSize) {
- this.writeBuffer.push(this.writeCache << (8 - this.writeCacheSize));
- }
- this.writeCache = 0;
- this.writeCacheSize = 0;
- },
-
- startWrite: function(dataBuffer) {
- this.writeBuffer = dataBuffer;
- this.writeCache = 0;
- this.writeCacheSize = 0;
- },
-
- startRead: function(dataBuffer) {
- this.readBuffer = dataBuffer;
- this.readCache = 0;
- this.readCacheSize = 0;
- this.readIndex = 0;
- },
-
- getWriteBufferSize: function() {
- return this.writeBuffer.length;
- },
-
- overwriteWriteBuffer: function(position, data) {
- let writeLength = data.length;
- if (writeLength + position >= this.writeBuffer.length) {
- writeLength = this.writeBuffer.length - position;
- }
- for (let i = 0; i < writeLength; i++) {
- this.writeBuffer[i + position] = data[i];
- }
- }
-};
-
-/**
- * Helper for CDMA PDU
- *
- * Currently, some function are shared with GsmPDUHelper, they should be
- * moved from GsmPDUHelper to a common object shared among GsmPDUHelper and
- * CdmaPDUHelper.
- */
-function CdmaPDUHelperObject(aContext) {
- this.context = aContext;
-}
-CdmaPDUHelperObject.prototype = {
- context: null,
-
- // 1..........C
- // Only "1234567890*#" is defined in C.S0005-D v2.0
- dtmfChars: ".1234567890*#...",
-
- /**
- * Entry point for SMS encoding, the options object is made compatible
- * with existing writeMessage() of GsmPDUHelper, but less key is used.
- *
- * Current used key in options:
- * @param number
- * String containing the address (number) of the SMS receiver
- * @param body
- * String containing the message to be sent, segmented part
- * @param dcs
- * Data coding scheme. One of the PDU_DCS_MSG_CODING_*BITS_ALPHABET
- * constants.
- * @param encodedBodyLength
- * Length of the user data when encoded with the given DCS. For UCS2,
- * in bytes; for 7-bit, in septets.
- * @param requestStatusReport
- * Request status report.
- * @param segmentRef
- * Reference number of concatenated SMS message
- * @param segmentMaxSeq
- * Total number of concatenated SMS message
- * @param segmentSeq
- * Sequence number of concatenated SMS message
- */
- writeMessage: function(options) {
- if (DEBUG) {
- this.context.debug("cdma_writeMessage: " + JSON.stringify(options));
- }
-
- // Get encoding
- options.encoding = this.gsmDcsToCdmaEncoding(options.dcs);
-
- // Common Header
- if (options.segmentMaxSeq > 1) {
- this.writeInt(PDU_CDMA_MSG_TELESERIVCIE_ID_WEMT);
- } else {
- this.writeInt(PDU_CDMA_MSG_TELESERIVCIE_ID_SMS);
- }
-
- this.writeInt(0);
- this.writeInt(PDU_CDMA_MSG_CATEGORY_UNSPEC);
-
- // Just fill out address info in byte, rild will encap them for us
- let addrInfo = this.encodeAddr(options.number);
- this.writeByte(addrInfo.digitMode);
- this.writeByte(addrInfo.numberMode);
- this.writeByte(addrInfo.numberType);
- this.writeByte(addrInfo.numberPlan);
- this.writeByte(addrInfo.address.length);
- for (let i = 0; i < addrInfo.address.length; i++) {
- this.writeByte(addrInfo.address[i]);
- }
-
- // Subaddress, not supported
- this.writeByte(0); // Subaddress : Type
- this.writeByte(0); // Subaddress : Odd
- this.writeByte(0); // Subaddress : length
-
- // User Data
- let encodeResult = this.encodeUserData(options);
- this.writeByte(encodeResult.length);
- for (let i = 0; i < encodeResult.length; i++) {
- this.writeByte(encodeResult[i]);
- }
-
- encodeResult = null;
- },
-
- /**
- * Data writters
- */
- writeInt: function(value) {
- this.context.Buf.writeInt32(value);
- },
-
- writeByte: function(value) {
- this.context.Buf.writeInt32(value & 0xFF);
- },
-
- /**
- * Transform GSM DCS to CDMA encoding.
- */
- gsmDcsToCdmaEncoding: function(encoding) {
- switch (encoding) {
- case PDU_DCS_MSG_CODING_7BITS_ALPHABET:
- return PDU_CDMA_MSG_CODING_7BITS_ASCII;
- case PDU_DCS_MSG_CODING_8BITS_ALPHABET:
- return PDU_CDMA_MSG_CODING_OCTET;
- case PDU_DCS_MSG_CODING_16BITS_ALPHABET:
- return PDU_CDMA_MSG_CODING_UNICODE;
- }
- throw new Error("gsmDcsToCdmaEncoding(): Invalid GSM SMS DCS value: " + encoding);
- },
-
- /**
- * Encode address into CDMA address format, as a byte array.
- *
- * @see 3GGP2 C.S0015-B 2.0, 3.4.3.3 Address Parameters
- *
- * @param address
- * String of address to be encoded
- */
- encodeAddr: function(address) {
- let result = {};
-
- result.numberType = PDU_CDMA_MSG_ADDR_NUMBER_TYPE_UNKNOWN;
- result.numberPlan = PDU_CDMA_MSG_ADDR_NUMBER_TYPE_UNKNOWN;
-
- if (address[0] === '+') {
- address = address.substring(1);
- }
-
- // Try encode with DTMF first
- result.digitMode = PDU_CDMA_MSG_ADDR_DIGIT_MODE_DTMF;
- result.numberMode = PDU_CDMA_MSG_ADDR_NUMBER_MODE_ANSI;
-
- result.address = [];
- for (let i = 0; i < address.length; i++) {
- let addrDigit = this.dtmfChars.indexOf(address.charAt(i));
- if (addrDigit < 0) {
- result.digitMode = PDU_CDMA_MSG_ADDR_DIGIT_MODE_ASCII;
- result.numberMode = PDU_CDMA_MSG_ADDR_NUMBER_MODE_ASCII;
- result.address = [];
- break;
- }
- result.address.push(addrDigit);
- }
-
- // Address can't be encoded with DTMF, then use 7-bit ASCII
- if (result.digitMode !== PDU_CDMA_MSG_ADDR_DIGIT_MODE_DTMF) {
- if (address.indexOf("@") !== -1) {
- result.numberType = PDU_CDMA_MSG_ADDR_NUMBER_TYPE_NATIONAL;
- }
-
- for (let i = 0; i < address.length; i++) {
- result.address.push(address.charCodeAt(i) & 0x7F);
- }
- }
-
- return result;
- },
-
- /**
- * Encode SMS contents in options into CDMA userData field.
- * Corresponding and required subparameters will be added automatically.
- *
- * @see 3GGP2 C.S0015-B 2.0, 3.4.3.7 Bearer Data
- * 4.5 Bearer Data Parameters
- *
- * Current used key in options:
- * @param body
- * String containing the message to be sent, segmented part
- * @param encoding
- * Encoding method of CDMA, can be transformed from GSM DCS by function
- * cdmaPduHelp.gsmDcsToCdmaEncoding()
- * @param encodedBodyLength
- * Length of the user data when encoded with the given DCS. For UCS2,
- * in bytes; for 7-bit, in septets.
- * @param requestStatusReport
- * Request status report.
- * @param segmentRef
- * Reference number of concatenated SMS message
- * @param segmentMaxSeq
- * Total number of concatenated SMS message
- * @param segmentSeq
- * Sequence number of concatenated SMS message
- */
- encodeUserData: function(options) {
- let userDataBuffer = [];
- this.context.BitBufferHelper.startWrite(userDataBuffer);
-
- // Message Identifier
- this.encodeUserDataMsgId(options);
-
- // User Data
- this.encodeUserDataMsg(options);
-
- // Reply Option
- this.encodeUserDataReplyOption(options);
-
- return userDataBuffer;
- },
-
- /**
- * User data subparameter encoder : Message Identifier
- *
- * @see 3GGP2 C.S0015-B 2.0, 4.5.1 Message Identifier
- */
- encodeUserDataMsgId: function(options) {
- let BitBufferHelper = this.context.BitBufferHelper;
- BitBufferHelper.writeBits(PDU_CDMA_MSG_USERDATA_MSG_ID, 8);
- BitBufferHelper.writeBits(3, 8);
- BitBufferHelper.writeBits(PDU_CDMA_MSG_TYPE_SUBMIT, 4);
- BitBufferHelper.writeBits(1, 16); // TODO: How to get message ID?
- if (options.segmentMaxSeq > 1) {
- BitBufferHelper.writeBits(1, 1);
- } else {
- BitBufferHelper.writeBits(0, 1);
- }
-
- BitBufferHelper.flushWithPadding();
- },
-
- /**
- * User data subparameter encoder : User Data
- *
- * @see 3GGP2 C.S0015-B 2.0, 4.5.2 User Data
- */
- encodeUserDataMsg: function(options) {
- let BitBufferHelper = this.context.BitBufferHelper;
- BitBufferHelper.writeBits(PDU_CDMA_MSG_USERDATA_BODY, 8);
- // Reserve space for length
- BitBufferHelper.writeBits(0, 8);
- let lengthPosition = BitBufferHelper.getWriteBufferSize();
-
- BitBufferHelper.writeBits(options.encoding, 5);
-
- // Add user data header for message segement
- let msgBody = options.body,
- msgBodySize = (options.encoding === PDU_CDMA_MSG_CODING_7BITS_ASCII ?
- options.encodedBodyLength :
- msgBody.length);
- if (options.segmentMaxSeq > 1) {
- if (options.encoding === PDU_CDMA_MSG_CODING_7BITS_ASCII) {
- BitBufferHelper.writeBits(msgBodySize + 7, 8); // Required length for user data header, in septet(7-bit)
-
- BitBufferHelper.writeBits(5, 8); // total header length 5 bytes
- BitBufferHelper.writeBits(PDU_IEI_CONCATENATED_SHORT_MESSAGES_8BIT, 8); // header id 0
- BitBufferHelper.writeBits(3, 8); // length of element for id 0 is 3
- BitBufferHelper.writeBits(options.segmentRef & 0xFF, 8); // Segement reference
- BitBufferHelper.writeBits(options.segmentMaxSeq & 0xFF, 8); // Max segment
- BitBufferHelper.writeBits(options.segmentSeq & 0xFF, 8); // Current segment
- BitBufferHelper.writeBits(0, 1); // Padding to make header data septet(7-bit) aligned
- } else {
- if (options.encoding === PDU_CDMA_MSG_CODING_UNICODE) {
- BitBufferHelper.writeBits(msgBodySize + 3, 8); // Required length for user data header, in 16-bit
- } else {
- BitBufferHelper.writeBits(msgBodySize + 6, 8); // Required length for user data header, in octet(8-bit)
- }
-
- BitBufferHelper.writeBits(5, 8); // total header length 5 bytes
- BitBufferHelper.writeBits(PDU_IEI_CONCATENATED_SHORT_MESSAGES_8BIT, 8); // header id 0
- BitBufferHelper.writeBits(3, 8); // length of element for id 0 is 3
- BitBufferHelper.writeBits(options.segmentRef & 0xFF, 8); // Segement reference
- BitBufferHelper.writeBits(options.segmentMaxSeq & 0xFF, 8); // Max segment
- BitBufferHelper.writeBits(options.segmentSeq & 0xFF, 8); // Current segment
- }
- } else {
- BitBufferHelper.writeBits(msgBodySize, 8);
- }
-
- // Encode message based on encoding method
- const langTable = PDU_NL_LOCKING_SHIFT_TABLES[PDU_NL_IDENTIFIER_DEFAULT];
- const langShiftTable = PDU_NL_SINGLE_SHIFT_TABLES[PDU_NL_IDENTIFIER_DEFAULT];
- for (let i = 0; i < msgBody.length; i++) {
- switch (options.encoding) {
- case PDU_CDMA_MSG_CODING_OCTET: {
- let msgDigit = msgBody.charCodeAt(i);
- BitBufferHelper.writeBits(msgDigit, 8);
- break;
- }
- case PDU_CDMA_MSG_CODING_7BITS_ASCII: {
- let msgDigit = msgBody.charCodeAt(i),
- msgDigitChar = msgBody.charAt(i);
-
- if (msgDigit >= 32) {
- BitBufferHelper.writeBits(msgDigit, 7);
- } else {
- msgDigit = langTable.indexOf(msgDigitChar);
-
- if (msgDigit === PDU_NL_EXTENDED_ESCAPE) {
- break;
- }
- if (msgDigit >= 0) {
- BitBufferHelper.writeBits(msgDigit, 7);
- } else {
- msgDigit = langShiftTable.indexOf(msgDigitChar);
- if (msgDigit == -1) {
- throw new Error("'" + msgDigitChar + "' is not in 7 bit alphabet "
- + langIndex + ":" + langShiftIndex + "!");
- }
-
- if (msgDigit === PDU_NL_RESERVED_CONTROL) {
- break;
- }
-
- BitBufferHelper.writeBits(PDU_NL_EXTENDED_ESCAPE, 7);
- BitBufferHelper.writeBits(msgDigit, 7);
- }
- }
- break;
- }
- case PDU_CDMA_MSG_CODING_UNICODE: {
- let msgDigit = msgBody.charCodeAt(i);
- BitBufferHelper.writeBits(msgDigit, 16);
- break;
- }
- }
- }
- BitBufferHelper.flushWithPadding();
-
- // Fill length
- let currentPosition = BitBufferHelper.getWriteBufferSize();
- BitBufferHelper.overwriteWriteBuffer(lengthPosition - 1, [currentPosition - lengthPosition]);
- },
-
- /**
- * User data subparameter encoder : Reply Option
- *
- * @see 3GGP2 C.S0015-B 2.0, 4.5.11 Reply Option
- */
- encodeUserDataReplyOption: function(options) {
- if (options.requestStatusReport) {
- let BitBufferHelper = this.context.BitBufferHelper;
- BitBufferHelper.writeBits(PDU_CDMA_MSG_USERDATA_REPLY_OPTION, 8);
- BitBufferHelper.writeBits(1, 8);
- BitBufferHelper.writeBits(0, 1); // USER_ACK_REQ
- BitBufferHelper.writeBits(1, 1); // DAK_REQ
- BitBufferHelper.flushWithPadding();
- }
- },
-
- /**
- * Entry point for SMS decoding, the returned object is made compatible
- * with existing readMessage() of GsmPDUHelper
- */
- readMessage: function() {
- let message = {};
-
- // Teleservice Identifier
- message.teleservice = this.readInt();
-
- // Message Type
- let isServicePresent = this.readByte();
- if (isServicePresent) {
- message.messageType = PDU_CDMA_MSG_TYPE_BROADCAST;
- } else {
- if (message.teleservice) {
- message.messageType = PDU_CDMA_MSG_TYPE_P2P;
- } else {
- message.messageType = PDU_CDMA_MSG_TYPE_ACK;
- }
- }
-
- // Service Category
- message.service = this.readInt();
-
- // Originated Address
- let addrInfo = {};
- addrInfo.digitMode = (this.readInt() & 0x01);
- addrInfo.numberMode = (this.readInt() & 0x01);
- addrInfo.numberType = (this.readInt() & 0x01);
- addrInfo.numberPlan = (this.readInt() & 0x01);
- addrInfo.addrLength = this.readByte();
- addrInfo.address = [];
- for (let i = 0; i < addrInfo.addrLength; i++) {
- addrInfo.address.push(this.readByte());
- }
- message.sender = this.decodeAddr(addrInfo);
-
- // Originated Subaddress
- addrInfo.Type = (this.readInt() & 0x07);
- addrInfo.Odd = (this.readByte() & 0x01);
- addrInfo.addrLength = this.readByte();
- for (let i = 0; i < addrInfo.addrLength; i++) {
- let addrDigit = this.readByte();
- message.sender += String.fromCharCode(addrDigit);
- }
-
- // Bearer Data
- this.decodeUserData(message);
-
- // Bearer Data Sub-Parameter: User Data
- let userData = message[PDU_CDMA_MSG_USERDATA_BODY];
- [message.header, message.body, message.encoding, message.data] =
- (userData) ? [userData.header, userData.body, userData.encoding, userData.data]
- : [null, null, null, null];
-
- // Bearer Data Sub-Parameter: Message Status
- // Success Delivery (0) if both Message Status and User Data are absent.
- // Message Status absent (-1) if only User Data is available.
- let msgStatus = message[PDU_CDMA_MSG_USER_DATA_MSG_STATUS];
- [message.errorClass, message.msgStatus] =
- (msgStatus) ? [msgStatus.errorClass, msgStatus.msgStatus]
- : ((message.body) ? [-1, -1] : [0, 0]);
-
- // Transform message to GSM msg
- let msg = {
- SMSC: "",
- mti: 0,
- udhi: 0,
- sender: message.sender,
- recipient: null,
- pid: PDU_PID_DEFAULT,
- epid: PDU_PID_DEFAULT,
- dcs: 0,
- mwi: null,
- replace: false,
- header: message.header,
- body: message.body,
- data: message.data,
- sentTimestamp: message[PDU_CDMA_MSG_USERDATA_TIMESTAMP],
- language: message[PDU_CDMA_LANGUAGE_INDICATOR],
- status: null,
- scts: null,
- dt: null,
- encoding: message.encoding,
- messageClass: GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_NORMAL],
- messageType: message.messageType,
- serviceCategory: message.service,
- subMsgType: message[PDU_CDMA_MSG_USERDATA_MSG_ID].msgType,
- msgId: message[PDU_CDMA_MSG_USERDATA_MSG_ID].msgId,
- errorClass: message.errorClass,
- msgStatus: message.msgStatus,
- teleservice: message.teleservice
- };
-
- return msg;
- },
-
- /**
- * Helper for processing received SMS parcel data.
- *
- * @param length
- * Length of SMS string in the incoming parcel.
- *
- * @return Message parsed or null for invalid message.
- */
- processReceivedSms: function(length) {
- if (!length) {
- if (DEBUG) this.context.debug("Received empty SMS!");
- return [null, PDU_FCS_UNSPECIFIED];
- }
-
- let message = this.readMessage();
- if (DEBUG) this.context.debug("Got new SMS: " + JSON.stringify(message));
-
- // Determine result
- if (!message) {
- return [null, PDU_FCS_UNSPECIFIED];
- }
-
- return [message, PDU_FCS_OK];
- },
-
- /**
- * Data readers
- */
- readInt: function() {
- return this.context.Buf.readInt32();
- },
-
- readByte: function() {
- return (this.context.Buf.readInt32() & 0xFF);
- },
-
- /**
- * Decode CDMA address data into address string
- *
- * @see 3GGP2 C.S0015-B 2.0, 3.4.3.3 Address Parameters
- *
- * Required key in addrInfo
- * @param addrLength
- * Length of address
- * @param digitMode
- * Address encoding method
- * @param address
- * Array of encoded address data
- */
- decodeAddr: function(addrInfo) {
- let result = "";
- for (let i = 0; i < addrInfo.addrLength; i++) {
- if (addrInfo.digitMode === PDU_CDMA_MSG_ADDR_DIGIT_MODE_DTMF) {
- result += this.dtmfChars.charAt(addrInfo.address[i]);
- } else {
- result += String.fromCharCode(addrInfo.address[i]);
- }
- }
- return result;
- },
-
- /**
- * Read userData in parcel buffer and decode into message object.
- * Each subparameter will be stored in corresponding key.
- *
- * @see 3GGP2 C.S0015-B 2.0, 3.4.3.7 Bearer Data
- * 4.5 Bearer Data Parameters
- */
- decodeUserData: function(message) {
- let userDataLength = this.readInt();
-
- while (userDataLength > 0) {
- let id = this.readByte(),
- length = this.readByte(),
- userDataBuffer = [];
-
- for (let i = 0; i < length; i++) {
- userDataBuffer.push(this.readByte());
- }
-
- this.context.BitBufferHelper.startRead(userDataBuffer);
-
- switch (id) {
- case PDU_CDMA_MSG_USERDATA_MSG_ID:
- message[id] = this.decodeUserDataMsgId();
- break;
- case PDU_CDMA_MSG_USERDATA_BODY:
- message[id] = this.decodeUserDataMsg(message[PDU_CDMA_MSG_USERDATA_MSG_ID].userHeader);
- break;
- case PDU_CDMA_MSG_USERDATA_TIMESTAMP:
- message[id] = this.decodeUserDataTimestamp();
- break;
- case PDU_CDMA_MSG_USERDATA_REPLY_OPTION:
- message[id] = this.decodeUserDataReplyOption();
- break;
- case PDU_CDMA_LANGUAGE_INDICATOR:
- message[id] = this.decodeLanguageIndicator();
- break;
- case PDU_CDMA_MSG_USERDATA_CALLBACK_NUMBER:
- message[id] = this.decodeUserDataCallbackNumber();
- break;
- case PDU_CDMA_MSG_USER_DATA_MSG_STATUS:
- message[id] = this.decodeUserDataMsgStatus();
- break;
- }
-
- userDataLength -= (length + 2);
- userDataBuffer = [];
- }
- },
-
- /**
- * User data subparameter decoder: Message Identifier
- *
- * @see 3GGP2 C.S0015-B 2.0, 4.5.1 Message Identifier
- */
- decodeUserDataMsgId: function() {
- let result = {};
- let BitBufferHelper = this.context.BitBufferHelper;
- result.msgType = BitBufferHelper.readBits(4);
- result.msgId = BitBufferHelper.readBits(16);
- result.userHeader = BitBufferHelper.readBits(1);
-
- return result;
- },
-
- /**
- * Decode user data header, we only care about segment information
- * on CDMA.
- *
- * This function is mostly copied from gsmPduHelper.readUserDataHeader() but
- * change the read function, because CDMA user header decoding is't byte-wise
- * aligned.
- */
- decodeUserDataHeader: function(encoding) {
- let BitBufferHelper = this.context.BitBufferHelper;
- let header = {},
- headerSize = BitBufferHelper.readBits(8),
- userDataHeaderSize = headerSize + 1,
- headerPaddingBits = 0;
-
- // Calculate header size
- if (encoding === PDU_DCS_MSG_CODING_7BITS_ALPHABET) {
- // Length is in 7-bit
- header.length = Math.ceil(userDataHeaderSize * 8 / 7);
- // Calulate padding length
- headerPaddingBits = (header.length * 7) - (userDataHeaderSize * 8);
- } else if (encoding === PDU_DCS_MSG_CODING_8BITS_ALPHABET) {
- header.length = userDataHeaderSize;
- } else {
- header.length = userDataHeaderSize / 2;
- }
-
- while (headerSize) {
- let identifier = BitBufferHelper.readBits(8),
- length = BitBufferHelper.readBits(8);
-
- headerSize -= (2 + length);
-
- switch (identifier) {
- case PDU_IEI_CONCATENATED_SHORT_MESSAGES_8BIT: {
- let ref = BitBufferHelper.readBits(8),
- max = BitBufferHelper.readBits(8),
- seq = BitBufferHelper.readBits(8);
- if (max && seq && (seq <= max)) {
- header.segmentRef = ref;
- header.segmentMaxSeq = max;
- header.segmentSeq = seq;
- }
- break;
- }
- case PDU_IEI_APPLICATION_PORT_ADDRESSING_SCHEME_8BIT: {
- let dstp = BitBufferHelper.readBits(8),
- orip = BitBufferHelper.readBits(8);
- if ((dstp < PDU_APA_RESERVED_8BIT_PORTS)
- || (orip < PDU_APA_RESERVED_8BIT_PORTS)) {
- // 3GPP TS 23.040 clause 9.2.3.24.3: "A receiving entity shall
- // ignore any information element where the value of the
- // Information-Element-Data is Reserved or not supported"
- break;
- }
- header.destinationPort = dstp;
- header.originatorPort = orip;
- break;
- }
- case PDU_IEI_APPLICATION_PORT_ADDRESSING_SCHEME_16BIT: {
- let dstp = (BitBufferHelper.readBits(8) << 8) | BitBufferHelper.readBits(8),
- orip = (BitBufferHelper.readBits(8) << 8) | BitBufferHelper.readBits(8);
- // 3GPP TS 23.040 clause 9.2.3.24.4: "A receiving entity shall
- // ignore any information element where the value of the
- // Information-Element-Data is Reserved or not supported"
- if ((dstp < PDU_APA_VALID_16BIT_PORTS)
- && (orip < PDU_APA_VALID_16BIT_PORTS)) {
- header.destinationPort = dstp;
- header.originatorPort = orip;
- }
- break;
- }
- case PDU_IEI_CONCATENATED_SHORT_MESSAGES_16BIT: {
- let ref = (BitBufferHelper.readBits(8) << 8) | BitBufferHelper.readBits(8),
- max = BitBufferHelper.readBits(8),
- seq = BitBufferHelper.readBits(8);
- if (max && seq && (seq <= max)) {
- header.segmentRef = ref;
- header.segmentMaxSeq = max;
- header.segmentSeq = seq;
- }
- break;
- }
- case PDU_IEI_NATIONAL_LANGUAGE_SINGLE_SHIFT: {
- let langShiftIndex = BitBufferHelper.readBits(8);
- if (langShiftIndex < PDU_NL_SINGLE_SHIFT_TABLES.length) {
- header.langShiftIndex = langShiftIndex;
- }
- break;
- }
- case PDU_IEI_NATIONAL_LANGUAGE_LOCKING_SHIFT: {
- let langIndex = BitBufferHelper.readBits(8);
- if (langIndex < PDU_NL_LOCKING_SHIFT_TABLES.length) {
- header.langIndex = langIndex;
- }
- break;
- }
- case PDU_IEI_SPECIAL_SMS_MESSAGE_INDICATION: {
- let msgInd = BitBufferHelper.readBits(8) & 0xFF,
- msgCount = BitBufferHelper.readBits(8);
- /*
- * TS 23.040 V6.8.1 Sec 9.2.3.24.2
- * bits 1 0 : basic message indication type
- * bits 4 3 2 : extended message indication type
- * bits 6 5 : Profile id
- * bit 7 : storage type
- */
- let storeType = msgInd & PDU_MWI_STORE_TYPE_BIT;
- header.mwi = {};
- mwi = header.mwi;
-
- if (storeType == PDU_MWI_STORE_TYPE_STORE) {
- // Store message because TP_UDH indicates so, note this may override
- // the setting in DCS, but that is expected
- mwi.discard = false;
- } else if (mwi.discard === undefined) {
- // storeType == PDU_MWI_STORE_TYPE_DISCARD
- // only override mwi.discard here if it hasn't already been set
- mwi.discard = true;
- }
-
- mwi.msgCount = msgCount & 0xFF;
- mwi.active = mwi.msgCount > 0;
-
- if (DEBUG) {
- this.context.debug("MWI in TP_UDH received: " + JSON.stringify(mwi));
- }
- break;
- }
- default:
- // Drop unsupported id
- for (let i = 0; i < length; i++) {
- BitBufferHelper.readBits(8);
- }
- }
- }
-
- // Consume padding bits
- if (headerPaddingBits) {
- BitBufferHelper.readBits(headerPaddingBits);
- }
-
- return header;
- },
-
- getCdmaMsgEncoding: function(encoding) {
- // Determine encoding method
- switch (encoding) {
- case PDU_CDMA_MSG_CODING_7BITS_ASCII:
- case PDU_CDMA_MSG_CODING_IA5:
- case PDU_CDMA_MSG_CODING_7BITS_GSM:
- return PDU_DCS_MSG_CODING_7BITS_ALPHABET;
- case PDU_CDMA_MSG_CODING_OCTET:
- case PDU_CDMA_MSG_CODING_IS_91:
- case PDU_CDMA_MSG_CODING_LATIN_HEBREW:
- case PDU_CDMA_MSG_CODING_LATIN:
- return PDU_DCS_MSG_CODING_8BITS_ALPHABET;
- case PDU_CDMA_MSG_CODING_UNICODE:
- case PDU_CDMA_MSG_CODING_SHIFT_JIS:
- case PDU_CDMA_MSG_CODING_KOREAN:
- return PDU_DCS_MSG_CODING_16BITS_ALPHABET;
- }
- return null;
- },
-
- decodeCdmaPDUMsg: function(encoding, msgType, msgBodySize) {
- const langTable = PDU_NL_LOCKING_SHIFT_TABLES[PDU_NL_IDENTIFIER_DEFAULT];
- const langShiftTable = PDU_NL_SINGLE_SHIFT_TABLES[PDU_NL_IDENTIFIER_DEFAULT];
- let BitBufferHelper = this.context.BitBufferHelper;
- let result = "";
- let msgDigit;
- switch (encoding) {
- case PDU_CDMA_MSG_CODING_OCTET: // TODO : Require Test
- while(msgBodySize > 0) {
- msgDigit = String.fromCharCode(BitBufferHelper.readBits(8));
- result += msgDigit;
- msgBodySize--;
- }
- break;
- case PDU_CDMA_MSG_CODING_IS_91: // TODO : Require Test
- // Referenced from android code
- switch (msgType) {
- case PDU_CDMA_MSG_CODING_IS_91_TYPE_SMS:
- case PDU_CDMA_MSG_CODING_IS_91_TYPE_SMS_FULL:
- case PDU_CDMA_MSG_CODING_IS_91_TYPE_VOICEMAIL_STATUS:
- while(msgBodySize > 0) {
- msgDigit = String.fromCharCode(BitBufferHelper.readBits(6) + 0x20);
- result += msgDigit;
- msgBodySize--;
- }
- break;
- case PDU_CDMA_MSG_CODING_IS_91_TYPE_CLI:
- let addrInfo = {};
- addrInfo.digitMode = PDU_CDMA_MSG_ADDR_DIGIT_MODE_DTMF;
- addrInfo.numberMode = PDU_CDMA_MSG_ADDR_NUMBER_MODE_ANSI;
- addrInfo.numberType = PDU_CDMA_MSG_ADDR_NUMBER_TYPE_UNKNOWN;
- addrInfo.numberPlan = PDU_CDMA_MSG_ADDR_NUMBER_PLAN_UNKNOWN;
- addrInfo.addrLength = msgBodySize;
- addrInfo.address = [];
- for (let i = 0; i < addrInfo.addrLength; i++) {
- addrInfo.address.push(BitBufferHelper.readBits(4));
- }
- result = this.decodeAddr(addrInfo);
- break;
- }
- // Fall through.
- case PDU_CDMA_MSG_CODING_7BITS_ASCII:
- case PDU_CDMA_MSG_CODING_IA5: // TODO : Require Test
- while(msgBodySize > 0) {
- msgDigit = BitBufferHelper.readBits(7);
- if (msgDigit >= 32) {
- msgDigit = String.fromCharCode(msgDigit);
- } else {
- if (msgDigit !== PDU_NL_EXTENDED_ESCAPE) {
- msgDigit = langTable[msgDigit];
- } else {
- msgDigit = BitBufferHelper.readBits(7);
- msgBodySize--;
- msgDigit = langShiftTable[msgDigit];
- }
- }
- result += msgDigit;
- msgBodySize--;
- }
- break;
- case PDU_CDMA_MSG_CODING_UNICODE:
- while(msgBodySize > 0) {
- msgDigit = String.fromCharCode(BitBufferHelper.readBits(16));
- result += msgDigit;
- msgBodySize--;
- }
- break;
- case PDU_CDMA_MSG_CODING_7BITS_GSM: // TODO : Require Test
- while(msgBodySize > 0) {
- msgDigit = BitBufferHelper.readBits(7);
- if (msgDigit !== PDU_NL_EXTENDED_ESCAPE) {
- msgDigit = langTable[msgDigit];
- } else {
- msgDigit = BitBufferHelper.readBits(7);
- msgBodySize--;
- msgDigit = langShiftTable[msgDigit];
- }
- result += msgDigit;
- msgBodySize--;
- }
- break;
- case PDU_CDMA_MSG_CODING_LATIN: // TODO : Require Test
- // Reference : http://en.wikipedia.org/wiki/ISO/IEC_8859-1
- while(msgBodySize > 0) {
- msgDigit = String.fromCharCode(BitBufferHelper.readBits(8));
- result += msgDigit;
- msgBodySize--;
- }
- break;
- case PDU_CDMA_MSG_CODING_LATIN_HEBREW: // TODO : Require Test
- // Reference : http://en.wikipedia.org/wiki/ISO/IEC_8859-8
- while(msgBodySize > 0) {
- msgDigit = BitBufferHelper.readBits(8);
- if (msgDigit === 0xDF) {
- msgDigit = String.fromCharCode(0x2017);
- } else if (msgDigit === 0xFD) {
- msgDigit = String.fromCharCode(0x200E);
- } else if (msgDigit === 0xFE) {
- msgDigit = String.fromCharCode(0x200F);
- } else if (msgDigit >= 0xE0 && msgDigit <= 0xFA) {
- msgDigit = String.fromCharCode(0x4F0 + msgDigit);
- } else {
- msgDigit = String.fromCharCode(msgDigit);
- }
- result += msgDigit;
- msgBodySize--;
- }
- break;
- case PDU_CDMA_MSG_CODING_SHIFT_JIS:
- // Reference : http://msdn.microsoft.com/en-US/goglobal/cc305152.aspx
- // http://demo.icu-project.org/icu-bin/convexp?conv=Shift_JIS
- let shift_jis_message = [];
-
- while (msgBodySize > 0) {
- shift_jis_message.push(BitBufferHelper.readBits(8));
- msgBodySize--;
- }
-
- let decoder = new TextDecoder("shift_jis");
- result = decoder.decode(new Uint8Array(shift_jis_message));
- break;
- case PDU_CDMA_MSG_CODING_KOREAN:
- case PDU_CDMA_MSG_CODING_GSM_DCS:
- // Fall through.
- default:
- break;
- }
- return result;
- },
-
- /**
- * User data subparameter decoder : User Data
- *
- * @see 3GGP2 C.S0015-B 2.0, 4.5.2 User Data
- */
- decodeUserDataMsg: function(hasUserHeader) {
- let BitBufferHelper = this.context.BitBufferHelper;
- let result = {},
- encoding = BitBufferHelper.readBits(5),
- msgType;
-
- if (encoding === PDU_CDMA_MSG_CODING_IS_91) {
- msgType = BitBufferHelper.readBits(8);
- }
- result.encoding = this.getCdmaMsgEncoding(encoding);
-
- let msgBodySize = BitBufferHelper.readBits(8);
-
- // For segmented SMS, a user header is included before sms content
- if (hasUserHeader) {
- result.header = this.decodeUserDataHeader(result.encoding);
- // header size is included in body size, they are decoded
- msgBodySize -= result.header.length;
- }
-
- // Store original payload if enconding is OCTET for further handling of WAP Push, etc.
- if (encoding === PDU_CDMA_MSG_CODING_OCTET && msgBodySize > 0) {
- result.data = new Uint8Array(msgBodySize);
- for (let i = 0; i < msgBodySize; i++) {
- result.data[i] = BitBufferHelper.readBits(8);
- }
- BitBufferHelper.backwardReadPilot(8 * msgBodySize);
- }
-
- // Decode sms content
- result.body = this.decodeCdmaPDUMsg(encoding, msgType, msgBodySize);
-
- return result;
- },
-
- decodeBcd: function(value) {
- return ((value >> 4) & 0xF) * 10 + (value & 0x0F);
- },
-
- /**
- * User data subparameter decoder : Time Stamp
- *
- * @see 3GGP2 C.S0015-B 2.0, 4.5.4 Message Center Time Stamp
- */
- decodeUserDataTimestamp: function() {
- let BitBufferHelper = this.context.BitBufferHelper;
- let year = this.decodeBcd(BitBufferHelper.readBits(8)),
- month = this.decodeBcd(BitBufferHelper.readBits(8)) - 1,
- date = this.decodeBcd(BitBufferHelper.readBits(8)),
- hour = this.decodeBcd(BitBufferHelper.readBits(8)),
- min = this.decodeBcd(BitBufferHelper.readBits(8)),
- sec = this.decodeBcd(BitBufferHelper.readBits(8));
-
- if (year >= 96 && year <= 99) {
- year += 1900;
- } else {
- year += 2000;
- }
-
- let result = (new Date(year, month, date, hour, min, sec, 0)).valueOf();
-
- return result;
- },
-
- /**
- * User data subparameter decoder : Reply Option
- *
- * @see 3GGP2 C.S0015-B 2.0, 4.5.11 Reply Option
- */
- decodeUserDataReplyOption: function() {
- let replyAction = this.context.BitBufferHelper.readBits(4),
- result = { userAck: (replyAction & 0x8) ? true : false,
- deliverAck: (replyAction & 0x4) ? true : false,
- readAck: (replyAction & 0x2) ? true : false,
- report: (replyAction & 0x1) ? true : false
- };
-
- return result;
- },
-
- /**
- * User data subparameter decoder : Language Indicator
- *
- * @see 3GGP2 C.S0015-B 2.0, 4.5.14 Language Indicator
- */
- decodeLanguageIndicator: function() {
- let language = this.context.BitBufferHelper.readBits(8);
- let result = CB_CDMA_LANG_GROUP[language];
- return result;
- },
-
- /**
- * User data subparameter decoder : Call-Back Number
- *
- * @see 3GGP2 C.S0015-B 2.0, 4.5.15 Call-Back Number
- */
- decodeUserDataCallbackNumber: function() {
- let BitBufferHelper = this.context.BitBufferHelper;
- let digitMode = BitBufferHelper.readBits(1);
- if (digitMode) {
- let numberType = BitBufferHelper.readBits(3),
- numberPlan = BitBufferHelper.readBits(4);
- }
- let numberFields = BitBufferHelper.readBits(8),
- result = "";
- for (let i = 0; i < numberFields; i++) {
- if (digitMode === PDU_CDMA_MSG_ADDR_DIGIT_MODE_DTMF) {
- let addrDigit = BitBufferHelper.readBits(4);
- result += this.dtmfChars.charAt(addrDigit);
- } else {
- let addrDigit = BitBufferHelper.readBits(8);
- result += String.fromCharCode(addrDigit);
- }
- }
-
- return result;
- },
-
- /**
- * User data subparameter decoder : Message Status
- *
- * @see 3GGP2 C.S0015-B 2.0, 4.5.21 Message Status
- */
- decodeUserDataMsgStatus: function() {
- let BitBufferHelper = this.context.BitBufferHelper;
- let result = {
- errorClass: BitBufferHelper.readBits(2),
- msgStatus: BitBufferHelper.readBits(6)
- };
-
- return result;
- },
-
- /**
- * Decode information record parcel.
- */
- decodeInformationRecord: function() {
- let Buf = this.context.Buf;
- let records = [];
- let numOfRecords = Buf.readInt32();
-
- let type;
- let record;
- for (let i = 0; i < numOfRecords; i++) {
- record = {};
- type = Buf.readInt32();
-
- switch (type) {
- /*
- * Every type is encaped by ril, except extended display
- */
- case PDU_CDMA_INFO_REC_TYPE_DISPLAY:
- case PDU_CDMA_INFO_REC_TYPE_EXTENDED_DISPLAY:
- record.display = Buf.readString();
- break;
- case PDU_CDMA_INFO_REC_TYPE_CALLED_PARTY_NUMBER:
- record.calledNumber = {};
- record.calledNumber.number = Buf.readString();
- record.calledNumber.type = Buf.readInt32();
- record.calledNumber.plan = Buf.readInt32();
- record.calledNumber.pi = Buf.readInt32();
- record.calledNumber.si = Buf.readInt32();
- break;
- case PDU_CDMA_INFO_REC_TYPE_CALLING_PARTY_NUMBER:
- record.callingNumber = {};
- record.callingNumber.number = Buf.readString();
- record.callingNumber.type = Buf.readInt32();
- record.callingNumber.plan = Buf.readInt32();
- record.callingNumber.pi = Buf.readInt32();
- record.callingNumber.si = Buf.readInt32();
- break;
- case PDU_CDMA_INFO_REC_TYPE_CONNECTED_NUMBER:
- record.connectedNumber = {};
- record.connectedNumber.number = Buf.readString();
- record.connectedNumber.type = Buf.readInt32();
- record.connectedNumber.plan = Buf.readInt32();
- record.connectedNumber.pi = Buf.readInt32();
- record.connectedNumber.si = Buf.readInt32();
- break;
- case PDU_CDMA_INFO_REC_TYPE_SIGNAL:
- record.signal = {};
- if (!Buf.readInt32()) { // Non-zero if signal is present.
- Buf.seekIncoming(3 * Buf.UINT32_SIZE);
- continue;
- }
- record.signal.type = Buf.readInt32();
- record.signal.alertPitch = Buf.readInt32();
- record.signal.signal = Buf.readInt32();
- break;
- case PDU_CDMA_INFO_REC_TYPE_REDIRECTING_NUMBER:
- record.redirect = {};
- record.redirect.number = Buf.readString();
- record.redirect.type = Buf.readInt32();
- record.redirect.plan = Buf.readInt32();
- record.redirect.pi = Buf.readInt32();
- record.redirect.si = Buf.readInt32();
- record.redirect.reason = Buf.readInt32();
- break;
- case PDU_CDMA_INFO_REC_TYPE_LINE_CONTROL:
- record.lineControl = {};
- record.lineControl.polarityIncluded = Buf.readInt32();
- record.lineControl.toggle = Buf.readInt32();
- record.lineControl.reverse = Buf.readInt32();
- record.lineControl.powerDenial = Buf.readInt32();
- break;
- case PDU_CDMA_INFO_REC_TYPE_T53_CLIR:
- record.clirCause = Buf.readInt32();
- break;
- case PDU_CDMA_INFO_REC_TYPE_T53_AUDIO_CONTROL:
- record.audioControl = {};
- record.audioControl.upLink = Buf.readInt32();
- record.audioControl.downLink = Buf.readInt32();
- break;
- case PDU_CDMA_INFO_REC_TYPE_T53_RELEASE:
- // Fall through
- default:
- throw new Error("UNSOLICITED_CDMA_INFO_REC(), Unsupported information record type " + type + "\n");
- }
-
- records.push(record);
- }
-
- return records;
- }
-};
-
-/**
- * Helper for processing ICC PDUs.
- */
-function ICCPDUHelperObject(aContext) {
- this.context = aContext;
-}
-ICCPDUHelperObject.prototype = {
- context: null,
-
- /**
- * Read GSM 8-bit unpacked octets,
- * which are default 7-bit alphabets with bit 8 set to 0.
- *
- * @param numOctets
- * Number of octets to be read.
- */
- read8BitUnpackedToString: function(numOctets) {
- let GsmPDUHelper = this.context.GsmPDUHelper;
-
- let ret = "";
- let escapeFound = false;
- let i;
- const langTable = PDU_NL_LOCKING_SHIFT_TABLES[PDU_NL_IDENTIFIER_DEFAULT];
- const langShiftTable = PDU_NL_SINGLE_SHIFT_TABLES[PDU_NL_IDENTIFIER_DEFAULT];
-
- for(i = 0; i < numOctets; i++) {
- let octet = GsmPDUHelper.readHexOctet();
- if (octet == 0xff) {
- i++;
- break;
- }
-
- if (escapeFound) {
- escapeFound = false;
- if (octet == PDU_NL_EXTENDED_ESCAPE) {
- // According to 3GPP TS 23.038, section 6.2.1.1, NOTE 1, "On
- // receipt of this code, a receiving entity shall display a space
- // until another extensiion table is defined."
- ret += " ";
- } else if (octet == PDU_NL_RESERVED_CONTROL) {
- // According to 3GPP TS 23.038 B.2, "This code represents a control
- // character and therefore must not be used for language specific
- // characters."
- ret += " ";
- } else {
- ret += langShiftTable[octet];
- }
- } else if (octet == PDU_NL_EXTENDED_ESCAPE) {
- escapeFound = true;
- } else {
- ret += langTable[octet];
- }
- }
-
- let Buf = this.context.Buf;
- Buf.seekIncoming((numOctets - i) * Buf.PDU_HEX_OCTET_SIZE);
- return ret;
- },
-
- /**
- * Write GSM 8-bit unpacked octets.
- *
- * @param numOctets Number of total octets to be writen, including trailing
- * 0xff.
- * @param str String to be written. Could be null.
- *
- * @return The string has been written into Buf. "" if str is null.
- */
- writeStringTo8BitUnpacked: function(numOctets, str) {
- const langTable = PDU_NL_LOCKING_SHIFT_TABLES[PDU_NL_IDENTIFIER_DEFAULT];
- const langShiftTable = PDU_NL_SINGLE_SHIFT_TABLES[PDU_NL_IDENTIFIER_DEFAULT];
-
- let GsmPDUHelper = this.context.GsmPDUHelper;
-
- // If the character is GSM extended alphabet, two octets will be written.
- // So we need to keep track of number of octets to be written.
- let i, j;
- let len = str ? str.length : 0;
- for (i = 0, j = 0; i < len && j < numOctets; i++) {
- let c = str.charAt(i);
- let octet = langTable.indexOf(c);
-
- if (octet == -1) {
- // Make sure we still have enough space to write two octets.
- if (j + 2 > numOctets) {
- break;
- }
-
- octet = langShiftTable.indexOf(c);
- if (octet == -1) {
- // Fallback to ASCII space.
- octet = langTable.indexOf(' ');
- } else {
- GsmPDUHelper.writeHexOctet(PDU_NL_EXTENDED_ESCAPE);
- j++;
- }
- }
- GsmPDUHelper.writeHexOctet(octet);
- j++;
- }
-
- // trailing 0xff
- while (j++ < numOctets) {
- GsmPDUHelper.writeHexOctet(0xff);
- }
-
- return (str) ? str.substring(0, i) : "";
- },
-
- /**
- * Write UCS2 String on UICC.
- * The default choose 0x81 or 0x82 encode, otherwise use 0x80 encode.
- *
- * @see TS 102.221, Annex A.
- * @param numOctets
- * Total number of octets to be written. This includes the length of
- * alphaId and the length of trailing unused octets(0xff).
- * @param str
- * String to be written.
- *
- * @return The string has been written into Buf.
- */
- writeICCUCS2String: function(numOctets, str) {
- let GsmPDUHelper = this.context.GsmPDUHelper;
- let scheme = 0x80;
- let basePointer;
-
- if (str.length > 2) {
- let min = 0xFFFF;
- let max = 0;
- for (let i = 0; i < str.length; i++) {
- let code = str.charCodeAt(i);
- // filter out GSM Default Alphabet character
- if (code & 0xFF80) {
- if (min > code) {
- min = code;
- }
- if (max < code) {
- max = code;
- }
- }
- }
-
- // 0x81 and 0x82 only support 'half-page', i.e., 128 characters.
- if ((max - min) >= 0 && (max - min) < 128) {
- // 0x81 base pointer is 0hhh hhhh h000 0000, and bit 16 is set to zero,
- // therefore it can't compute 0x8000~0xFFFF.
- // Since 0x81 only support 128 characters,
- // either XX00~XX7f(bit 8 are 0) or XX80~XXff(bit 8 are 1)
- if (((min & 0x7f80) == (max & 0x7f80)) &&
- ((max & 0x8000) == 0)) {
- scheme = 0x81;
- basePointer = min & 0x7f80;
- } else {
- scheme = 0x82;
- basePointer = min;
- }
- }
- }
-
- switch (scheme) {
- /**
- * +------+---------+---------+---------+---------+------+------+
- * | 0x80 | Ch1_msb | Ch1_lsb | Ch2_msb | Ch2_lsb | 0xff | 0xff |
- * +------+---------+---------+---------+---------+------+------+
- */
- case 0x80: {
- // 0x80 support UCS2 0000~ffff
- GsmPDUHelper.writeHexOctet(0x80);
- numOctets--;
- // Now the str is UCS2 string, each character will take 2 octets.
- if (str.length * 2 > numOctets) {
- str = str.substring(0, Math.floor(numOctets / 2));
- }
- GsmPDUHelper.writeUCS2String(str);
-
- // trailing 0xff
- for (let i = str.length * 2; i < numOctets; i++) {
- GsmPDUHelper.writeHexOctet(0xff);
- }
- return str;
- }
- /**
- * +------+-----+--------------+-----+-----+-----+--------+------+
- * | 0x81 | len | base_pointer | Ch1 | Ch2 | ... | Ch_len | 0xff |
- * +------+-----+--------------+-----+-----+-----+--------+------+
- *
- * len: The length of characters.
- * base_pointer: 0hhh hhhh h000 0000
- * Ch_n: bit 8 = 0
- * GSM default alphabets
- * bit 8 = 1
- * UCS2 character whose char code is (Ch_n - base_pointer) | 0x80
- *
- */
- case 0x81: {
- GsmPDUHelper.writeHexOctet(0x81);
-
- if (str.length > (numOctets - 3)) {
- str = str.substring(0, numOctets - 3);
- }
-
- GsmPDUHelper.writeHexOctet(str.length);
- GsmPDUHelper.writeHexOctet((basePointer >> 7) & 0xff);
- numOctets -= 3;
- break;
- }
- /* +------+-----+------------------+------------------+-----+-----+-----+--------+
- * | 0x82 | len | base_pointer_msb | base_pointer_lsb | Ch1 | Ch2 | ... | Ch_len |
- * +------+-----+------------------+------------------+-----+-----+-----+--------+
- *
- * len: The length of characters.
- * base_pointer_msb, base_pointer_lsn: base_pointer
- * Ch_n: bit 8 = 0
- * GSM default alphabets
- * bit 8 = 1
- * UCS2 character whose char code is (Ch_n - base_pointer) | 0x80
- */
- case 0x82: {
- GsmPDUHelper.writeHexOctet(0x82);
-
- if (str.length > (numOctets - 4)) {
- str = str.substring(0, numOctets - 4);
- }
-
- GsmPDUHelper.writeHexOctet(str.length);
- GsmPDUHelper.writeHexOctet((basePointer >> 8) & 0xff);
- GsmPDUHelper.writeHexOctet(basePointer & 0xff);
- numOctets -= 4;
- break;
- }
- }
-
- if (scheme == 0x81 || scheme == 0x82) {
- for (let i = 0; i < str.length; i++) {
- let code = str.charCodeAt(i);
-
- // bit 8 = 0,
- // GSM default alphabets
- if (code >> 8 == 0) {
- GsmPDUHelper.writeHexOctet(code & 0x7F);
- } else {
- // bit 8 = 1,
- // UCS2 character whose char code is (code - basePointer) | 0x80
- GsmPDUHelper.writeHexOctet((code - basePointer) | 0x80);
- }
- }
-
- // trailing 0xff
- for (let i = 0; i < numOctets - str.length; i++) {
- GsmPDUHelper.writeHexOctet(0xff);
- }
- }
- return str;
- },
-
- /**
- * Read UCS2 String on UICC.
- *
- * @see TS 101.221, Annex A.
- * @param scheme
- * Coding scheme for UCS2 on UICC. One of 0x80, 0x81 or 0x82.
- * @param numOctets
- * Number of octets to be read as UCS2 string.
- */
- readICCUCS2String: function(scheme, numOctets) {
- let Buf = this.context.Buf;
- let GsmPDUHelper = this.context.GsmPDUHelper;
-
- let str = "";
- switch (scheme) {
- /**
- * +------+---------+---------+---------+---------+------+------+
- * | 0x80 | Ch1_msb | Ch1_lsb | Ch2_msb | Ch2_lsb | 0xff | 0xff |
- * +------+---------+---------+---------+---------+------+------+
- */
- case 0x80:
- let isOdd = numOctets % 2;
- let i;
- for (i = 0; i < numOctets - isOdd; i += 2) {
- let code = (GsmPDUHelper.readHexOctet() << 8) | GsmPDUHelper.readHexOctet();
- if (code == 0xffff) {
- i += 2;
- break;
- }
- str += String.fromCharCode(code);
- }
-
- // Skip trailing 0xff
- Buf.seekIncoming((numOctets - i) * Buf.PDU_HEX_OCTET_SIZE);
- break;
- case 0x81: // Fall through
- case 0x82:
- /**
- * +------+-----+--------+-----+-----+-----+--------+------+
- * | 0x81 | len | offset | Ch1 | Ch2 | ... | Ch_len | 0xff |
- * +------+-----+--------+-----+-----+-----+--------+------+
- *
- * len : The length of characters.
- * offset : 0hhh hhhh h000 0000
- * Ch_n: bit 8 = 0
- * GSM default alphabets
- * bit 8 = 1
- * UCS2 character whose char code is (Ch_n & 0x7f) + offset
- *
- * +------+-----+------------+------------+-----+-----+-----+--------+
- * | 0x82 | len | offset_msb | offset_lsb | Ch1 | Ch2 | ... | Ch_len |
- * +------+-----+------------+------------+-----+-----+-----+--------+
- *
- * len : The length of characters.
- * offset_msb, offset_lsn: offset
- * Ch_n: bit 8 = 0
- * GSM default alphabets
- * bit 8 = 1
- * UCS2 character whose char code is (Ch_n & 0x7f) + offset
- */
- let len = GsmPDUHelper.readHexOctet();
- let offset, headerLen;
- if (scheme == 0x81) {
- offset = GsmPDUHelper.readHexOctet() << 7;
- headerLen = 2;
- } else {
- offset = (GsmPDUHelper.readHexOctet() << 8) | GsmPDUHelper.readHexOctet();
- headerLen = 3;
- }
-
- for (let i = 0; i < len; i++) {
- let ch = GsmPDUHelper.readHexOctet();
- if (ch & 0x80) {
- // UCS2
- str += String.fromCharCode((ch & 0x7f) + offset);
- } else {
- // GSM 8bit
- let count = 0, gotUCS2 = 0;
- while ((i + count + 1 < len)) {
- count++;
- if (GsmPDUHelper.readHexOctet() & 0x80) {
- gotUCS2 = 1;
- break;
- }
- }
- // Unread.
- // +1 for the GSM alphabet indexed at i,
- Buf.seekIncoming(-1 * (count + 1) * Buf.PDU_HEX_OCTET_SIZE);
- str += this.read8BitUnpackedToString(count + 1 - gotUCS2);
- i += count - gotUCS2;
- }
- }
-
- // Skipping trailing 0xff
- Buf.seekIncoming((numOctets - len - headerLen) * Buf.PDU_HEX_OCTET_SIZE);
- break;
- }
- return str;
- },
-
- /**
- * Read Alpha Id and Dialling number from TS TS 151.011 clause 10.5.1
- *
- * @param recordSize The size of linear fixed record.
- */
- readAlphaIdDiallingNumber: function(recordSize) {
- let Buf = this.context.Buf;
- let length = Buf.readInt32();
-
- let alphaLen = recordSize - ADN_FOOTER_SIZE_BYTES;
- let alphaId = this.readAlphaIdentifier(alphaLen);
-
- let number = this.readNumberWithLength();
-
- // Skip unused octet, CCP
- Buf.seekIncoming(Buf.PDU_HEX_OCTET_SIZE);
-
- let extRecordNumber = this.context.GsmPDUHelper.readHexOctet();
- Buf.readStringDelimiter(length);
-
- let contact = null;
- if (alphaId || number) {
- contact = {alphaId: alphaId,
- number: number,
- extRecordNumber: extRecordNumber};
- }
-
- return contact;
- },
-
- /**
- * Write Alpha Identifier and Dialling number from TS 151.011 clause 10.5.1
- *
- * @param recordSize The size of linear fixed record.
- * @param alphaId Alpha Identifier to be written.
- * @param number Dialling Number to be written.
- * @param extRecordNumber The record identifier of the EXT.
- *
- * @return An object contains the alphaId and number
- * that have been written into Buf.
- */
- writeAlphaIdDiallingNumber: function(recordSize, alphaId, number, extRecordNumber) {
- let Buf = this.context.Buf;
- let GsmPDUHelper = this.context.GsmPDUHelper;
-
- // Write String length
- let strLen = recordSize * 2;
- Buf.writeInt32(strLen);
-
- let alphaLen = recordSize - ADN_FOOTER_SIZE_BYTES;
- let writtenAlphaId = this.writeAlphaIdentifier(alphaLen, alphaId);
- let writtenNumber = this.writeNumberWithLength(number);
-
- // Write unused CCP octet 0xff.
- GsmPDUHelper.writeHexOctet(0xff);
- GsmPDUHelper.writeHexOctet((extRecordNumber != null) ? extRecordNumber : 0xff);
-
- Buf.writeStringDelimiter(strLen);
-
- return {alphaId: writtenAlphaId,
- number: writtenNumber};
- },
-
- /**
- * Read Alpha Identifier.
- *
- * @see TS 131.102
- *
- * @param numOctets
- * Number of octets to be read.
- *
- * It uses either
- * 1. SMS default 7-bit alphabet with bit 8 set to 0.
- * 2. UCS2 string.
- *
- * Unused bytes should be set to 0xff.
- */
- readAlphaIdentifier: function(numOctets) {
- if (numOctets === 0) {
- return "";
- }
-
- let temp;
- // Read the 1st octet to determine the encoding.
- if ((temp = this.context.GsmPDUHelper.readHexOctet()) == 0x80 ||
- temp == 0x81 ||
- temp == 0x82) {
- numOctets--;
- return this.readICCUCS2String(temp, numOctets);
- } else {
- let Buf = this.context.Buf;
- Buf.seekIncoming(-1 * Buf.PDU_HEX_OCTET_SIZE);
- return this.read8BitUnpackedToString(numOctets);
- }
- },
-
- /**
- * Write Alpha Identifier.
- *
- * @param numOctets
- * Total number of octets to be written. This includes the length of
- * alphaId and the length of trailing unused octets(0xff).
- * @param alphaId
- * Alpha Identifier to be written.
- *
- * @return The Alpha Identifier has been written into Buf.
- *
- * Unused octets will be written as 0xff.
- */
- writeAlphaIdentifier: function(numOctets, alphaId) {
- if (numOctets === 0) {
- return "";
- }
-
- // If alphaId is empty or it's of GSM 8 bit.
- if (!alphaId || this.context.ICCUtilsHelper.isGsm8BitAlphabet(alphaId)) {
- return this.writeStringTo8BitUnpacked(numOctets, alphaId);
- } else {
- return this.writeICCUCS2String(numOctets, alphaId);
- }
- },
-
- /**
- * Read Dialling number.
- *
- * @see TS 131.102
- *
- * @param len
- * The Length of BCD number.
- *
- * From TS 131.102, in EF_ADN, EF_FDN, the field 'Length of BCD number'
- * means the total bytes should be allocated to store the TON/NPI and
- * the dialing number.
- * For example, if the dialing number is 1234567890,
- * and the TON/NPI is 0x81,
- * The field 'Length of BCD number' should be 06, which is
- * 1 byte to store the TON/NPI, 0x81
- * 5 bytes to store the BCD number 2143658709.
- *
- * Here the definition of the length is different from SMS spec,
- * TS 23.040 9.1.2.5, which the length means
- * "number of useful semi-octets within the Address-Value field".
- */
- readDiallingNumber: function(len) {
- if (DEBUG) this.context.debug("PDU: Going to read Dialling number: " + len);
- if (len === 0) {
- return "";
- }
-
- let GsmPDUHelper = this.context.GsmPDUHelper;
-
- // TOA = TON + NPI
- let toa = GsmPDUHelper.readHexOctet();
-
- let number = GsmPDUHelper.readSwappedNibbleExtendedBcdString(len - 1);
- if (number.length <= 0) {
- if (DEBUG) this.context.debug("No number provided");
- return "";
- }
- if ((toa >> 4) == (PDU_TOA_INTERNATIONAL >> 4)) {
- number = '+' + number;
- }
- return number;
- },
-
- /**
- * Write Dialling Number.
- *
- * @param number The Dialling number
- */
- writeDiallingNumber: function(number) {
- let GsmPDUHelper = this.context.GsmPDUHelper;
-
- let toa = PDU_TOA_ISDN; // 81
- if (number[0] == '+') {
- toa = PDU_TOA_INTERNATIONAL | PDU_TOA_ISDN; // 91
- number = number.substring(1);
- }
- GsmPDUHelper.writeHexOctet(toa);
- GsmPDUHelper.writeSwappedNibbleBCD(number);
- },
-
- readNumberWithLength: function() {
- let Buf = this.context.Buf;
- let number = "";
- let numLen = this.context.GsmPDUHelper.readHexOctet();
- if (numLen != 0xff) {
- if (numLen > ADN_MAX_BCD_NUMBER_BYTES) {
- if (DEBUG) {
- this.context.debug(
- "Error: invalid length of BCD number/SSC contents - " + numLen);
- }
- Buf.seekIncoming(ADN_MAX_BCD_NUMBER_BYTES * Buf.PDU_HEX_OCTET_SIZE);
- return number;
- }
-
- number = this.readDiallingNumber(numLen);
- Buf.seekIncoming((ADN_MAX_BCD_NUMBER_BYTES - numLen) * Buf.PDU_HEX_OCTET_SIZE);
- } else {
- Buf.seekIncoming(ADN_MAX_BCD_NUMBER_BYTES * Buf.PDU_HEX_OCTET_SIZE);
- }
-
- return number;
- },
-
- /**
- * Write Number with Length
- *
- * @param number The value to be written.
- *
- * @return The number has been written into Buf.
- */
- writeNumberWithLength: function(number) {
- let GsmPDUHelper = this.context.GsmPDUHelper;
-
- if (number) {
- let numStart = number[0] == "+" ? 1 : 0;
- let writtenNumber = number.substring(0, numStart) +
- number.substring(numStart)
- .replace(/[^0-9*#,]/g, "");
- let numDigits = writtenNumber.length - numStart;
-
- if (numDigits > ADN_MAX_NUMBER_DIGITS) {
- writtenNumber = writtenNumber.substring(0, ADN_MAX_NUMBER_DIGITS + numStart);
- numDigits = writtenNumber.length - numStart;
- }
-
- // +1 for TON/NPI
- let numLen = Math.ceil(numDigits / 2) + 1;
- GsmPDUHelper.writeHexOctet(numLen);
- this.writeDiallingNumber(writtenNumber.replace(/\*/g, "a")
- .replace(/\#/g, "b")
- .replace(/\,/g, "c"));
- // Write trailing 0xff of Dialling Number.
- for (let i = 0; i < ADN_MAX_BCD_NUMBER_BYTES - numLen; i++) {
- GsmPDUHelper.writeHexOctet(0xff);
- }
- return writtenNumber;
- } else {
- // +1 for numLen
- for (let i = 0; i < ADN_MAX_BCD_NUMBER_BYTES + 1; i++) {
- GsmPDUHelper.writeHexOctet(0xff);
- }
- return "";
- }
- }
-};
-
-function StkCommandParamsFactoryObject(aContext) {
- this.context = aContext;
-}
-StkCommandParamsFactoryObject.prototype = {
- context: null,
-
- createParam: function(cmdDetails, ctlvs, onComplete) {
- let method = this[cmdDetails.typeOfCommand];
- if (typeof method != "function") {
- if (DEBUG) {
- this.context.debug("Unknown proactive command " +
- cmdDetails.typeOfCommand.toString(16));
- }
- return;
- }
- method.call(this, cmdDetails, ctlvs, onComplete);
- },
-
- loadIcons: function(iconIdCtlvs, callback) {
- if (!iconIdCtlvs ||
- !this.context.ICCUtilsHelper.isICCServiceAvailable("IMG")) {
- callback(null);
- return;
- }
-
- let onerror = (function() {
- callback(null);
- }).bind(this);
-
- let onsuccess = (function(aIcons) {
- callback(aIcons);
- }).bind(this);
-
- this.context.IconLoader.loadIcons(iconIdCtlvs.map(aCtlv => aCtlv.value.identifier),
- onsuccess,
- onerror);
- },
-
- appendIconIfNecessary: function(iconIdCtlvs, result, onComplete) {
- this.loadIcons(iconIdCtlvs, (aIcons) => {
- if (aIcons) {
- result.icons = aIcons[0];
- result.iconSelfExplanatory =
- iconIdCtlvs[0].value.qualifier == 0 ? true : false;
- }
-
- onComplete(result);
- });
- },
-
- /**
- * Construct a param for Refresh.
- *
- * @param cmdDetails
- * The value object of CommandDetails TLV.
- * @param ctlvs
- * The all TLVs in this proactive command.
- * @param onComplete
- * Callback to be called when complete.
- */
- processRefresh: function(cmdDetails, ctlvs, onComplete) {
- let refreshType = cmdDetails.commandQualifier;
- switch (refreshType) {
- case STK_REFRESH_FILE_CHANGE:
- case STK_REFRESH_NAA_INIT_AND_FILE_CHANGE:
- let ctlv = this.context.StkProactiveCmdHelper.searchForTag(
- COMPREHENSIONTLV_TAG_FILE_LIST, ctlvs);
- if (ctlv) {
- let list = ctlv.value.fileList;
- if (DEBUG) {
- this.context.debug("Refresh, list = " + list);
- }
- this.context.ICCRecordHelper.fetchICCRecords();
- }
- break;
- }
-
- onComplete(null);
- },
-
- /**
- * Construct a param for Poll Interval.
- *
- * @param cmdDetails
- * The value object of CommandDetails TLV.
- * @param ctlvs
- * The all TLVs in this proactive command.
- * @param onComplete
- * Callback to be called when complete.
- */
- processPollInterval: function(cmdDetails, ctlvs, onComplete) {
- // Duration is mandatory.
- let ctlv = this.context.StkProactiveCmdHelper.searchForTag(
- COMPREHENSIONTLV_TAG_DURATION, ctlvs);
- if (!ctlv) {
- this.context.RIL.sendStkTerminalResponse({
- command: cmdDetails,
- resultCode: STK_RESULT_REQUIRED_VALUES_MISSING});
- throw new Error("Stk Poll Interval: Required value missing : Duration");
- }
-
- onComplete(ctlv.value);
- },
-
- /**
- * Construct a param for Poll Off.
- *
- * @param cmdDetails
- * The value object of CommandDetails TLV.
- * @param ctlvs
- * The all TLVs in this proactive command.
- * @param onComplete
- * Callback to be called when complete.
- */
- processPollOff: function(cmdDetails, ctlvs, onComplete) {
- onComplete(null);
- },
-
- /**
- * Construct a param for Set Up Event list.
- *
- * @param cmdDetails
- * The value object of CommandDetails TLV.
- * @param ctlvs
- * The all TLVs in this proactive command.
- * @param onComplete
- * Callback to be called when complete.
- */
- processSetUpEventList: function(cmdDetails, ctlvs, onComplete) {
- // Event list is mandatory.
- let ctlv = this.context.StkProactiveCmdHelper.searchForTag(
- COMPREHENSIONTLV_TAG_EVENT_LIST, ctlvs);
- if (!ctlv) {
- this.context.RIL.sendStkTerminalResponse({
- command: cmdDetails,
- resultCode: STK_RESULT_REQUIRED_VALUES_MISSING});
- throw new Error("Stk Event List: Required value missing : Event List");
- }
-
- onComplete(ctlv.value || { eventList: null });
- },
-
- /**
- * Construct a param for Setup Menu.
- *
- * @param cmdDetails
- * The value object of CommandDetails TLV.
- * @param ctlvs
- * The all TLVs in this proactive command.
- * @param onComplete
- * Callback to be called when complete.
- */
- processSetupMenu: function(cmdDetails, ctlvs, onComplete) {
- let StkProactiveCmdHelper = this.context.StkProactiveCmdHelper;
- let menu = {
- // Help information available.
- isHelpAvailable: !!(cmdDetails.commandQualifier & 0x80)
- };
-
- let selectedCtlvs = StkProactiveCmdHelper.searchForSelectedTags(ctlvs, [
- COMPREHENSIONTLV_TAG_ALPHA_ID,
- COMPREHENSIONTLV_TAG_ITEM,
- COMPREHENSIONTLV_TAG_ITEM_ID,
- COMPREHENSIONTLV_TAG_NEXT_ACTION_IND,
- COMPREHENSIONTLV_TAG_ICON_ID,
- COMPREHENSIONTLV_TAG_ICON_ID_LIST
- ]);
-
- // Alpha identifier is optional.
- let ctlv = selectedCtlvs.retrieve(COMPREHENSIONTLV_TAG_ALPHA_ID);
- if (ctlv) {
- menu.title = ctlv.value.identifier;
- }
-
- // Item data object for item 1 is mandatory.
- let menuCtlvs = selectedCtlvs[COMPREHENSIONTLV_TAG_ITEM];
- if (!menuCtlvs) {
- this.context.RIL.sendStkTerminalResponse({
- command: cmdDetails,
- resultCode: STK_RESULT_REQUIRED_VALUES_MISSING});
- throw new Error("Stk Menu: Required value missing : items");
- }
- menu.items = menuCtlvs.map(aCtlv => aCtlv.value);
-
- // Item identifier is optional.
- ctlv = selectedCtlvs.retrieve(COMPREHENSIONTLV_TAG_ITEM_ID);
- if (ctlv) {
- menu.defaultItem = ctlv.value.identifier - 1;
- }
-
- // Items next action indicator is optional.
- ctlv = selectedCtlvs.retrieve(COMPREHENSIONTLV_TAG_NEXT_ACTION_IND);
- if (ctlv) {
- menu.nextActionList = ctlv.value;
- }
-
- // Icon identifier is optional.
- let iconIdCtlvs = null;
- let menuIconCtlv = selectedCtlvs.retrieve(COMPREHENSIONTLV_TAG_ICON_ID);
- if (menuIconCtlv) {
- iconIdCtlvs = [menuIconCtlv];
- }
-
- // Item icon identifier list is optional.
- ctlv = selectedCtlvs.retrieve(COMPREHENSIONTLV_TAG_ICON_ID_LIST);
- if (ctlv) {
- if (!iconIdCtlvs) {
- iconIdCtlvs = [];
- };
- let iconIdList = ctlv.value;
- iconIdCtlvs = iconIdCtlvs.concat(iconIdList.identifiers.map((aId) => {
- return {
- value: { qualifier: iconIdList.qualifier, identifier: aId }
- };
- }));
- }
-
- this.loadIcons(iconIdCtlvs, (aIcons) => {
- if (aIcons) {
- if (menuIconCtlv) {
- menu.iconSelfExplanatory =
- (iconIdCtlvs.shift().value.qualifier == 0) ? true: false;
- menu.icons = aIcons.shift();
- }
-
- for (let i = 0; i < aIcons.length; i++) {
- menu.items[i].icons = aIcons[i];
- menu.items[i].iconSelfExplanatory =
- (iconIdCtlvs[i].value.qualifier == 0) ? true: false;
- }
- }
-
- onComplete(menu);
- });
- },
-
- /**
- * Construct a param for Select Item.
- *
- * @param cmdDetails
- * The value object of CommandDetails TLV.
- * @param ctlvs
- * The all TLVs in this proactive command.
- * @param onComplete
- * Callback to be called when complete.
- */
- processSelectItem: function(cmdDetails, ctlvs, onComplete) {
- this.processSetupMenu(cmdDetails, ctlvs, (menu) => {
- // The 1st bit and 2nd bit determines the presentation type.
- menu.presentationType = cmdDetails.commandQualifier & 0x03;
- onComplete(menu);
- });
- },
-
- /**
- * Construct a param for Display Text.
- *
- * @param cmdDetails
- * The value object of CommandDetails TLV.
- * @param ctlvs
- * The all TLVs in this proactive command.
- * @param onComplete
- * Callback to be called when complete.
- */
- processDisplayText: function(cmdDetails, ctlvs, onComplete) {
- let StkProactiveCmdHelper = this.context.StkProactiveCmdHelper;
- let textMsg = {
- isHighPriority: !!(cmdDetails.commandQualifier & 0x01),
- userClear: !!(cmdDetails.commandQualifier & 0x80)
- };
-
- let selectedCtlvs = StkProactiveCmdHelper.searchForSelectedTags(ctlvs, [
- COMPREHENSIONTLV_TAG_TEXT_STRING,
- COMPREHENSIONTLV_TAG_IMMEDIATE_RESPONSE,
- COMPREHENSIONTLV_TAG_DURATION,
- COMPREHENSIONTLV_TAG_ICON_ID
- ]);
-
- // Text string is mandatory.
- let ctlv = selectedCtlvs.retrieve(COMPREHENSIONTLV_TAG_TEXT_STRING);
- if (!ctlv) {
- this.context.RIL.sendStkTerminalResponse({
- command: cmdDetails,
- resultCode: STK_RESULT_REQUIRED_VALUES_MISSING});
- throw new Error("Stk Display Text: Required value missing : Text String");
- }
- textMsg.text = ctlv.value.textString;
-
- // Immediate response is optional.
- textMsg.responseNeeded =
- !!(selectedCtlvs.retrieve(COMPREHENSIONTLV_TAG_IMMEDIATE_RESPONSE));
-
- // Duration is optional.
- ctlv = selectedCtlvs.retrieve(COMPREHENSIONTLV_TAG_DURATION);
- if (ctlv) {
- textMsg.duration = ctlv.value;
- }
-
- // Icon identifier is optional.
- this.appendIconIfNecessary(selectedCtlvs[COMPREHENSIONTLV_TAG_ICON_ID] || null,
- textMsg,
- onComplete);
- },
-
- /**
- * Construct a param for Setup Idle Mode Text.
- *
- * @param cmdDetails
- * The value object of CommandDetails TLV.
- * @param ctlvs
- * The all TLVs in this proactive command.
- * @param onComplete
- * Callback to be called when complete.
- */
- processSetUpIdleModeText: function(cmdDetails, ctlvs, onComplete) {
- let StkProactiveCmdHelper = this.context.StkProactiveCmdHelper;
- let textMsg = {};
-
- let selectedCtlvs = StkProactiveCmdHelper.searchForSelectedTags(ctlvs, [
- COMPREHENSIONTLV_TAG_TEXT_STRING,
- COMPREHENSIONTLV_TAG_ICON_ID
- ]);
-
- // Text string is mandatory.
- let ctlv = selectedCtlvs.retrieve(COMPREHENSIONTLV_TAG_TEXT_STRING);
- if (!ctlv) {
- this.context.RIL.sendStkTerminalResponse({
- command: cmdDetails,
- resultCode: STK_RESULT_REQUIRED_VALUES_MISSING});
- throw new Error("Stk Set Up Idle Text: Required value missing : Text String");
- }
- textMsg.text = ctlv.value.textString;
-
- // Icon identifier is optional.
- this.appendIconIfNecessary(selectedCtlvs[COMPREHENSIONTLV_TAG_ICON_ID] || null,
- textMsg,
- onComplete);
- },
-
- /**
- * Construct a param for Get Inkey.
- *
- * @param cmdDetails
- * The value object of CommandDetails TLV.
- * @param ctlvs
- * The all TLVs in this proactive command.
- * @param onComplete
- * Callback to be called when complete.
- */
- processGetInkey: function(cmdDetails, ctlvs, onComplete) {
- let StkProactiveCmdHelper = this.context.StkProactiveCmdHelper;
- let input = {
- minLength: 1,
- maxLength: 1,
- isAlphabet: !!(cmdDetails.commandQualifier & 0x01),
- isUCS2: !!(cmdDetails.commandQualifier & 0x02),
- // Character sets defined in bit 1 and bit 2 are disable and
- // the YES/NO reponse is required.
- isYesNoRequested: !!(cmdDetails.commandQualifier & 0x04),
- // Help information available.
- isHelpAvailable: !!(cmdDetails.commandQualifier & 0x80)
- };
-
- let selectedCtlvs = StkProactiveCmdHelper.searchForSelectedTags(ctlvs, [
- COMPREHENSIONTLV_TAG_TEXT_STRING,
- COMPREHENSIONTLV_TAG_DURATION,
- COMPREHENSIONTLV_TAG_ICON_ID
- ]);
-
- // Text string is mandatory.
- let ctlv = selectedCtlvs.retrieve(COMPREHENSIONTLV_TAG_TEXT_STRING);
- if (!ctlv) {
- this.context.RIL.sendStkTerminalResponse({
- command: cmdDetails,
- resultCode: STK_RESULT_REQUIRED_VALUES_MISSING});
- throw new Error("Stk Get InKey: Required value missing : Text String");
- }
- input.text = ctlv.value.textString;
-
- // Duration is optional.
- ctlv = selectedCtlvs.retrieve(COMPREHENSIONTLV_TAG_DURATION);
- if (ctlv) {
- input.duration = ctlv.value;
- }
-
- // Icon identifier is optional.
- this.appendIconIfNecessary(selectedCtlvs[COMPREHENSIONTLV_TAG_ICON_ID] || null,
- input,
- onComplete);
- },
-
- /**
- * Construct a param for Get Input.
- *
- * @param cmdDetails
- * The value object of CommandDetails TLV.
- * @param ctlvs
- * The all TLVs in this proactive command.
- * @param onComplete
- * Callback to be called when complete.
- */
- processGetInput: function(cmdDetails, ctlvs, onComplete) {
- let StkProactiveCmdHelper = this.context.StkProactiveCmdHelper;
- let input = {
- isAlphabet: !!(cmdDetails.commandQualifier & 0x01),
- isUCS2: !!(cmdDetails.commandQualifier & 0x02),
- // User input shall not be revealed
- hideInput: !!(cmdDetails.commandQualifier & 0x04),
- // User input in SMS packed format
- isPacked: !!(cmdDetails.commandQualifier & 0x08),
- // Help information available.
- isHelpAvailable: !!(cmdDetails.commandQualifier & 0x80)
- };
-
- let selectedCtlvs = StkProactiveCmdHelper.searchForSelectedTags(ctlvs, [
- COMPREHENSIONTLV_TAG_TEXT_STRING,
- COMPREHENSIONTLV_TAG_RESPONSE_LENGTH,
- COMPREHENSIONTLV_TAG_DEFAULT_TEXT,
- COMPREHENSIONTLV_TAG_ICON_ID
- ]);
-
- // Text string is mandatory.
- let ctlv = selectedCtlvs.retrieve(COMPREHENSIONTLV_TAG_TEXT_STRING);
- if (!ctlv) {
- this.context.RIL.sendStkTerminalResponse({
- command: cmdDetails,
- resultCode: STK_RESULT_REQUIRED_VALUES_MISSING});
- throw new Error("Stk Get Input: Required value missing : Text String");
- }
- input.text = ctlv.value.textString;
-
- // Response length is mandatory.
- ctlv = selectedCtlvs.retrieve(COMPREHENSIONTLV_TAG_RESPONSE_LENGTH);
- if (!ctlv) {
- this.context.RIL.sendStkTerminalResponse({
- command: cmdDetails,
- resultCode: STK_RESULT_REQUIRED_VALUES_MISSING});
- throw new Error("Stk Get Input: Required value missing : Response Length");
- }
- input.minLength = ctlv.value.minLength;
- input.maxLength = ctlv.value.maxLength;
-
- // Default text is optional.
- ctlv = selectedCtlvs.retrieve(COMPREHENSIONTLV_TAG_DEFAULT_TEXT);
- if (ctlv) {
- input.defaultText = ctlv.value.textString;
- }
-
- // Icon identifier is optional.
- this.appendIconIfNecessary(selectedCtlvs[COMPREHENSIONTLV_TAG_ICON_ID] || null,
- input,
- onComplete);
- },
-
- /**
- * Construct a param for SendSS/SMS/USSD/DTMF.
- *
- * @param cmdDetails
- * The value object of CommandDetails TLV.
- * @param ctlvs
- * The all TLVs in this proactive command.
- * @param onComplete
- * Callback to be called when complete.
- */
- processEventNotify: function(cmdDetails, ctlvs, onComplete) {
- let StkProactiveCmdHelper = this.context.StkProactiveCmdHelper;
- let textMsg = {};
-
- let selectedCtlvs = StkProactiveCmdHelper.searchForSelectedTags(ctlvs, [
- COMPREHENSIONTLV_TAG_ALPHA_ID,
- COMPREHENSIONTLV_TAG_ICON_ID
- ]);
-
- // Alpha identifier is optional.
- let ctlv = selectedCtlvs.retrieve(COMPREHENSIONTLV_TAG_ALPHA_ID);
- if (ctlv) {
- textMsg.text = ctlv.value.identifier;
- }
-
- // According to section 6.4.10 of |ETSI TS 102 223|:
- //
- // - if the alpha identifier is provided by the UICC and is a null data
- // object (i.e. length = '00' and no value part), this is an indication
- // that the terminal should not give any information to the user on the
- // fact that the terminal is sending a short message;
- //
- // - if the alpha identifier is not provided by the UICC, the terminal may
- // give information to the user concerning what is happening.
- //
- // ICCPDUHelper reads alpha id as an empty string if the length is zero,
- // hence we'll notify the caller when it's not an empty string.
- if (textMsg.text !== "") {
- // Icon identifier is optional.
- this.appendIconIfNecessary(selectedCtlvs[COMPREHENSIONTLV_TAG_ICON_ID] || null,
- textMsg,
- onComplete);
- }
- },
-
- /**
- * Construct a param for Setup Call.
- *
- * @param cmdDetails
- * The value object of CommandDetails TLV.
- * @param ctlvs
- * The all TLVs in this proactive command.
- * @param onComplete
- * Callback to be called when complete.
- */
- processSetupCall: function(cmdDetails, ctlvs, onComplete) {
- let StkProactiveCmdHelper = this.context.StkProactiveCmdHelper;
- let call = {};
- let confirmMessage = {};
- let callMessage = {};
-
- let selectedCtlvs = StkProactiveCmdHelper.searchForSelectedTags(ctlvs, [
- COMPREHENSIONTLV_TAG_ADDRESS,
- COMPREHENSIONTLV_TAG_ALPHA_ID,
- COMPREHENSIONTLV_TAG_ICON_ID,
- COMPREHENSIONTLV_TAG_DURATION
- ]);
-
- // Address is mandatory.
- let ctlv = selectedCtlvs.retrieve(COMPREHENSIONTLV_TAG_ADDRESS);
- if (!ctlv) {
- this.context.RIL.sendStkTerminalResponse({
- command: cmdDetails,
- resultCode: STK_RESULT_REQUIRED_VALUES_MISSING});
- throw new Error("Stk Set Up Call: Required value missing : Address");
- }
- call.address = ctlv.value.number;
-
- // Alpha identifier (user confirmation phase) is optional.
- ctlv = selectedCtlvs.retrieve(COMPREHENSIONTLV_TAG_ALPHA_ID);
- if (ctlv) {
- confirmMessage.text = ctlv.value.identifier;
- call.confirmMessage = confirmMessage;
- }
-
- // Alpha identifier (call set up phase) is optional.
- ctlv = selectedCtlvs.retrieve(COMPREHENSIONTLV_TAG_ALPHA_ID);
- if (ctlv) {
- callMessage.text = ctlv.value.identifier;
- call.callMessage = callMessage;
- }
-
- // Duration is optional.
- ctlv = selectedCtlvs.retrieve(COMPREHENSIONTLV_TAG_DURATION);
- if (ctlv) {
- call.duration = ctlv.value;
- }
-
- // Icon identifier is optional.
- let iconIdCtlvs = selectedCtlvs[COMPREHENSIONTLV_TAG_ICON_ID] || null;
- this.loadIcons(iconIdCtlvs, (aIcons) => {
- if (aIcons) {
- confirmMessage.icons = aIcons[0];
- confirmMessage.iconSelfExplanatory =
- (iconIdCtlvs[0].value.qualifier == 0) ? true: false;
- call.confirmMessage = confirmMessage;
-
- if (aIcons.length > 1) {
- callMessage.icons = aIcons[1];
- callMessage.iconSelfExplanatory =
- (iconIdCtlvs[1].value.qualifier == 0) ? true: false;
- call.callMessage = callMessage;
- }
- }
-
- onComplete(call);
- });
- },
-
- /**
- * Construct a param for Launch Browser.
- *
- * @param cmdDetails
- * The value object of CommandDetails TLV.
- * @param ctlvs
- * The all TLVs in this proactive command.
- * @param onComplete
- * Callback to be called when complete.
- */
- processLaunchBrowser: function(cmdDetails, ctlvs, onComplete) {
- let StkProactiveCmdHelper = this.context.StkProactiveCmdHelper;
- let browser = {
- mode: cmdDetails.commandQualifier & 0x03
- };
- let confirmMessage = {};
-
- let selectedCtlvs = StkProactiveCmdHelper.searchForSelectedTags(ctlvs, [
- COMPREHENSIONTLV_TAG_URL,
- COMPREHENSIONTLV_TAG_ALPHA_ID,
- COMPREHENSIONTLV_TAG_ICON_ID
- ]);
-
- // URL is mandatory.
- let ctlv = selectedCtlvs.retrieve(COMPREHENSIONTLV_TAG_URL);
- if (!ctlv) {
- this.context.RIL.sendStkTerminalResponse({
- command: cmdDetails,
- resultCode: STK_RESULT_REQUIRED_VALUES_MISSING});
- throw new Error("Stk Launch Browser: Required value missing : URL");
- }
- browser.url = ctlv.value.url;
-
- // Alpha identifier is optional.
- ctlv = selectedCtlvs.retrieve(COMPREHENSIONTLV_TAG_ALPHA_ID);
- if (ctlv) {
- confirmMessage.text = ctlv.value.identifier;
- browser.confirmMessage = confirmMessage;
- }
-
- // Icon identifier is optional.
- let iconIdCtlvs = selectedCtlvs[COMPREHENSIONTLV_TAG_ICON_ID] || null;
- this.loadIcons(iconIdCtlvs, (aIcons) => {
- if (aIcons) {
- confirmMessage.icons = aIcons[0];
- confirmMessage.iconSelfExplanatory =
- (iconIdCtlvs[0].value.qualifier == 0) ? true: false;
- browser.confirmMessage = confirmMessage;
- }
-
- onComplete(browser);
- });
- },
-
- /**
- * Construct a param for Play Tone.
- *
- * @param cmdDetails
- * The value object of CommandDetails TLV.
- * @param ctlvs
- * The all TLVs in this proactive command.
- * @param onComplete
- * Callback to be called when complete.
- */
- processPlayTone: function(cmdDetails, ctlvs, onComplete) {
- let StkProactiveCmdHelper = this.context.StkProactiveCmdHelper;
- let playTone = {
- // The vibrate is only defined in TS 102.223.
- isVibrate: !!(cmdDetails.commandQualifier & 0x01)
- };
-
- let selectedCtlvs = StkProactiveCmdHelper.searchForSelectedTags(ctlvs, [
- COMPREHENSIONTLV_TAG_ALPHA_ID,
- COMPREHENSIONTLV_TAG_TONE,
- COMPREHENSIONTLV_TAG_DURATION,
- COMPREHENSIONTLV_TAG_ICON_ID
- ]);
-
- // Alpha identifier is optional.
- let ctlv = selectedCtlvs.retrieve(COMPREHENSIONTLV_TAG_ALPHA_ID);
- if (ctlv) {
- playTone.text = ctlv.value.identifier;
- }
-
- // Tone is optional.
- ctlv = selectedCtlvs.retrieve(COMPREHENSIONTLV_TAG_TONE);
- if (ctlv) {
- playTone.tone = ctlv.value.tone;
- }
-
- // Duration is optional.
- ctlv = selectedCtlvs.retrieve(COMPREHENSIONTLV_TAG_DURATION);
- if (ctlv) {
- playTone.duration = ctlv.value;
- }
-
- // Icon identifier is optional.
- this.appendIconIfNecessary(selectedCtlvs[COMPREHENSIONTLV_TAG_ICON_ID] || null,
- playTone,
- onComplete);
- },
-
- /**
- * Construct a param for Provide Local Information.
- *
- * @param cmdDetails
- * The value object of CommandDetails TLV.
- * @param ctlvs
- * The all TLVs in this proactive command.
- * @param onComplete
- * Callback to be called when complete.
- */
- processProvideLocalInfo: function(cmdDetails, ctlvs, onComplete) {
- let provideLocalInfo = {
- localInfoType: cmdDetails.commandQualifier
- };
-
- onComplete(provideLocalInfo);
- },
-
- /**
- * Construct a param for Timer Management.
- *
- * @param cmdDetails
- * The value object of CommandDetails TLV.
- * @param ctlvs
- * The all TLVs in this proactive command.
- * @param onComplete
- * Callback to be called when complete.
- */
- processTimerManagement: function(cmdDetails, ctlvs, onComplete) {
- let StkProactiveCmdHelper = this.context.StkProactiveCmdHelper;
- let timer = {
- timerAction: cmdDetails.commandQualifier
- };
-
- let selectedCtlvs = StkProactiveCmdHelper.searchForSelectedTags(ctlvs, [
- COMPREHENSIONTLV_TAG_TIMER_IDENTIFIER,
- COMPREHENSIONTLV_TAG_TIMER_VALUE
- ]);
-
- // Timer identifier is mandatory.
- let ctlv = selectedCtlvs.retrieve(COMPREHENSIONTLV_TAG_TIMER_IDENTIFIER);
- if (!ctlv) {
- this.context.RIL.sendStkTerminalResponse({
- command: cmdDetails,
- resultCode: STK_RESULT_REQUIRED_VALUES_MISSING});
- throw new Error("Stk Timer Management: Required value missing : Timer Identifier");
- }
- timer.timerId = ctlv.value.timerId;
-
- // Timer value is conditional.
- ctlv = selectedCtlvs.retrieve(COMPREHENSIONTLV_TAG_TIMER_VALUE);
- if (ctlv) {
- timer.timerValue = ctlv.value.timerValue;
- }
-
- onComplete(timer);
- },
-
- /**
- * Construct a param for BIP commands.
- *
- * @param cmdDetails
- * The value object of CommandDetails TLV.
- * @param ctlvs
- * The all TLVs in this proactive command.
- * @param onComplete
- * Callback to be called when complete.
- */
- processBipMessage: function(cmdDetails, ctlvs, onComplete) {
- let StkProactiveCmdHelper = this.context.StkProactiveCmdHelper;
- let bipMsg = {};
-
- let selectedCtlvs = StkProactiveCmdHelper.searchForSelectedTags(ctlvs, [
- COMPREHENSIONTLV_TAG_ALPHA_ID,
- COMPREHENSIONTLV_TAG_ICON_ID
- ]);
-
- // Alpha identifier is optional.
- let ctlv = selectedCtlvs.retrieve(COMPREHENSIONTLV_TAG_ALPHA_ID);
- if (ctlv) {
- bipMsg.text = ctlv.value.identifier;
- }
-
- // Icon identifier is optional.
- this.appendIconIfNecessary(selectedCtlvs[COMPREHENSIONTLV_TAG_ICON_ID] || null,
- bipMsg,
- onComplete);
- }
-};
-StkCommandParamsFactoryObject.prototype[STK_CMD_REFRESH] = function STK_CMD_REFRESH(cmdDetails, ctlvs, onComplete) {
- return this.processRefresh(cmdDetails, ctlvs, onComplete);
-};
-StkCommandParamsFactoryObject.prototype[STK_CMD_POLL_INTERVAL] = function STK_CMD_POLL_INTERVAL(cmdDetails, ctlvs, onComplete) {
- return this.processPollInterval(cmdDetails, ctlvs, onComplete);
-};
-StkCommandParamsFactoryObject.prototype[STK_CMD_POLL_OFF] = function STK_CMD_POLL_OFF(cmdDetails, ctlvs, onComplete) {
- return this.processPollOff(cmdDetails, ctlvs, onComplete);
-};
-StkCommandParamsFactoryObject.prototype[STK_CMD_PROVIDE_LOCAL_INFO] = function STK_CMD_PROVIDE_LOCAL_INFO(cmdDetails, ctlvs, onComplete) {
- return this.processProvideLocalInfo(cmdDetails, ctlvs, onComplete);
-};
-StkCommandParamsFactoryObject.prototype[STK_CMD_SET_UP_EVENT_LIST] = function STK_CMD_SET_UP_EVENT_LIST(cmdDetails, ctlvs, onComplete) {
- return this.processSetUpEventList(cmdDetails, ctlvs, onComplete);
-};
-StkCommandParamsFactoryObject.prototype[STK_CMD_SET_UP_MENU] = function STK_CMD_SET_UP_MENU(cmdDetails, ctlvs, onComplete) {
- return this.processSetupMenu(cmdDetails, ctlvs, onComplete);
-};
-StkCommandParamsFactoryObject.prototype[STK_CMD_SELECT_ITEM] = function STK_CMD_SELECT_ITEM(cmdDetails, ctlvs, onComplete) {
- return this.processSelectItem(cmdDetails, ctlvs, onComplete);
-};
-StkCommandParamsFactoryObject.prototype[STK_CMD_DISPLAY_TEXT] = function STK_CMD_DISPLAY_TEXT(cmdDetails, ctlvs, onComplete) {
- return this.processDisplayText(cmdDetails, ctlvs, onComplete);
-};
-StkCommandParamsFactoryObject.prototype[STK_CMD_SET_UP_IDLE_MODE_TEXT] = function STK_CMD_SET_UP_IDLE_MODE_TEXT(cmdDetails, ctlvs, onComplete) {
- return this.processSetUpIdleModeText(cmdDetails, ctlvs, onComplete);
-};
-StkCommandParamsFactoryObject.prototype[STK_CMD_GET_INKEY] = function STK_CMD_GET_INKEY(cmdDetails, ctlvs, onComplete) {
- return this.processGetInkey(cmdDetails, ctlvs, onComplete);
-};
-StkCommandParamsFactoryObject.prototype[STK_CMD_GET_INPUT] = function STK_CMD_GET_INPUT(cmdDetails, ctlvs, onComplete) {
- return this.processGetInput(cmdDetails, ctlvs, onComplete);
-};
-StkCommandParamsFactoryObject.prototype[STK_CMD_SEND_SS] = function STK_CMD_SEND_SS(cmdDetails, ctlvs, onComplete) {
- return this.processEventNotify(cmdDetails, ctlvs, onComplete);
-};
-StkCommandParamsFactoryObject.prototype[STK_CMD_SEND_USSD] = function STK_CMD_SEND_USSD(cmdDetails, ctlvs, onComplete) {
- return this.processEventNotify(cmdDetails, ctlvs, onComplete);
-};
-StkCommandParamsFactoryObject.prototype[STK_CMD_SEND_SMS] = function STK_CMD_SEND_SMS(cmdDetails, ctlvs, onComplete) {
- return this.processEventNotify(cmdDetails, ctlvs, onComplete);
-};
-StkCommandParamsFactoryObject.prototype[STK_CMD_SEND_DTMF] = function STK_CMD_SEND_DTMF(cmdDetails, ctlvs, onComplete) {
- return this.processEventNotify(cmdDetails, ctlvs, onComplete);
-};
-StkCommandParamsFactoryObject.prototype[STK_CMD_SET_UP_CALL] = function STK_CMD_SET_UP_CALL(cmdDetails, ctlvs, onComplete) {
- return this.processSetupCall(cmdDetails, ctlvs, onComplete);
-};
-StkCommandParamsFactoryObject.prototype[STK_CMD_LAUNCH_BROWSER] = function STK_CMD_LAUNCH_BROWSER(cmdDetails, ctlvs, onComplete) {
- return this.processLaunchBrowser(cmdDetails, ctlvs, onComplete);
-};
-StkCommandParamsFactoryObject.prototype[STK_CMD_PLAY_TONE] = function STK_CMD_PLAY_TONE(cmdDetails, ctlvs, onComplete) {
- return this.processPlayTone(cmdDetails, ctlvs, onComplete);
-};
-StkCommandParamsFactoryObject.prototype[STK_CMD_TIMER_MANAGEMENT] = function STK_CMD_TIMER_MANAGEMENT(cmdDetails, ctlvs, onComplete) {
- return this.processTimerManagement(cmdDetails, ctlvs, onComplete);
-};
-StkCommandParamsFactoryObject.prototype[STK_CMD_OPEN_CHANNEL] = function STK_CMD_OPEN_CHANNEL(cmdDetails, ctlvs, onComplete) {
- return this.processBipMessage(cmdDetails, ctlvs, onComplete);
-};
-StkCommandParamsFactoryObject.prototype[STK_CMD_CLOSE_CHANNEL] = function STK_CMD_CLOSE_CHANNEL(cmdDetails, ctlvs, onComplete) {
- return this.processBipMessage(cmdDetails, ctlvs, onComplete);
-};
-StkCommandParamsFactoryObject.prototype[STK_CMD_RECEIVE_DATA] = function STK_CMD_RECEIVE_DATA(cmdDetails, ctlvs, onComplete) {
- return this.processBipMessage(cmdDetails, ctlvs, onComplete);
-};
-StkCommandParamsFactoryObject.prototype[STK_CMD_SEND_DATA] = function STK_CMD_SEND_DATA(cmdDetails, ctlvs, onComplete) {
- return this.processBipMessage(cmdDetails, ctlvs, onComplete);
-};
-
-function StkProactiveCmdHelperObject(aContext) {
- this.context = aContext;
-}
-StkProactiveCmdHelperObject.prototype = {
- context: null,
-
- retrieve: function(tag, length) {
- let method = this[tag];
- if (typeof method != "function") {
- if (DEBUG) {
- this.context.debug("Unknown comprehension tag " + tag.toString(16));
- }
- let Buf = this.context.Buf;
- Buf.seekIncoming(length * Buf.PDU_HEX_OCTET_SIZE);
- return null;
- }
- return method.call(this, length);
- },
-
- /**
- * Command Details.
- *
- * | Byte | Description | Length |
- * | 1 | Command details Tag | 1 |
- * | 2 | Length = 03 | 1 |
- * | 3 | Command number | 1 |
- * | 4 | Type of Command | 1 |
- * | 5 | Command Qualifier | 1 |
- */
- retrieveCommandDetails: function(length) {
- let GsmPDUHelper = this.context.GsmPDUHelper;
- let cmdDetails = {
- commandNumber: GsmPDUHelper.readHexOctet(),
- typeOfCommand: GsmPDUHelper.readHexOctet(),
- commandQualifier: GsmPDUHelper.readHexOctet()
- };
- return cmdDetails;
- },
-
- /**
- * Device Identities.
- *
- * | Byte | Description | Length |
- * | 1 | Device Identity Tag | 1 |
- * | 2 | Length = 02 | 1 |
- * | 3 | Source device Identity | 1 |
- * | 4 | Destination device Id | 1 |
- */
- retrieveDeviceId: function(length) {
- let GsmPDUHelper = this.context.GsmPDUHelper;
- let deviceId = {
- sourceId: GsmPDUHelper.readHexOctet(),
- destinationId: GsmPDUHelper.readHexOctet()
- };
- return deviceId;
- },
-
- /**
- * Alpha Identifier.
- *
- * | Byte | Description | Length |
- * | 1 | Alpha Identifier Tag | 1 |
- * | 2 ~ (Y-1)+2 | Length (X) | Y |
- * | (Y-1)+3 ~ | Alpha identfier | X |
- * | (Y-1)+X+2 | | |
- */
- retrieveAlphaId: function(length) {
- let alphaId = {
- identifier: this.context.ICCPDUHelper.readAlphaIdentifier(length)
- };
- return alphaId;
- },
-
- /**
- * Duration.
- *
- * | Byte | Description | Length |
- * | 1 | Response Length Tag | 1 |
- * | 2 | Lenth = 02 | 1 |
- * | 3 | Time unit | 1 |
- * | 4 | Time interval | 1 |
- */
- retrieveDuration: function(length) {
- let GsmPDUHelper = this.context.GsmPDUHelper;
- let duration = {
- timeUnit: GsmPDUHelper.readHexOctet(),
- timeInterval: GsmPDUHelper.readHexOctet(),
- };
- return duration;
- },
-
- /**
- * Address.
- *
- * | Byte | Description | Length |
- * | 1 | Alpha Identifier Tag | 1 |
- * | 2 ~ (Y-1)+2 | Length (X) | Y |
- * | (Y-1)+3 | TON and NPI | 1 |
- * | (Y-1)+4 ~ | Dialling number | X |
- * | (Y-1)+X+2 | | |
- */
- retrieveAddress: function(length) {
- let address = {
- number : this.context.ICCPDUHelper.readDiallingNumber(length)
- };
- return address;
- },
-
- /**
- * Text String.
- *
- * | Byte | Description | Length |
- * | 1 | Text String Tag | 1 |
- * | 2 ~ (Y-1)+2 | Length (X) | Y |
- * | (Y-1)+3 | Data coding scheme | 1 |
- * | (Y-1)+4~ | Text String | X |
- * | (Y-1)+X+2 | | |
- */
- retrieveTextString: function(length) {
- if (!length) {
- // null string.
- return {textString: null};
- }
-
- let GsmPDUHelper = this.context.GsmPDUHelper;
- let text = {
- codingScheme: GsmPDUHelper.readHexOctet()
- };
-
- length--; // -1 for the codingScheme.
- switch (text.codingScheme & 0x0c) {
- case STK_TEXT_CODING_GSM_7BIT_PACKED:
- text.textString =
- GsmPDUHelper.readSeptetsToString(Math.floor(length * 8 / 7), 0, 0, 0);
- break;
- case STK_TEXT_CODING_GSM_8BIT:
- text.textString =
- this.context.ICCPDUHelper.read8BitUnpackedToString(length);
- break;
- case STK_TEXT_CODING_UCS2:
- text.textString = GsmPDUHelper.readUCS2String(length);
- break;
- }
- return text;
- },
-
- /**
- * Tone.
- *
- * | Byte | Description | Length |
- * | 1 | Tone Tag | 1 |
- * | 2 | Lenth = 01 | 1 |
- * | 3 | Tone | 1 |
- */
- retrieveTone: function(length) {
- let tone = {
- tone: this.context.GsmPDUHelper.readHexOctet(),
- };
- return tone;
- },
-
- /**
- * Item.
- *
- * | Byte | Description | Length |
- * | 1 | Item Tag | 1 |
- * | 2 ~ (Y-1)+2 | Length (X) | Y |
- * | (Y-1)+3 | Identifier of item | 1 |
- * | (Y-1)+4 ~ | Text string of item | X |
- * | (Y-1)+X+2 | | |
- */
- retrieveItem: function(length) {
- // TS 102.223 ,clause 6.6.7 SET-UP MENU
- // If the "Item data object for item 1" is a null data object
- // (i.e. length = '00' and no value part), this is an indication to the ME
- // to remove the existing menu from the menu system in the ME.
- if (!length) {
- return null;
- }
- let item = {
- identifier: this.context.GsmPDUHelper.readHexOctet(),
- text: this.context.ICCPDUHelper.readAlphaIdentifier(length - 1)
- };
- return item;
- },
-
- /**
- * Item Identifier.
- *
- * | Byte | Description | Length |
- * | 1 | Item Identifier Tag | 1 |
- * | 2 | Lenth = 01 | 1 |
- * | 3 | Identifier of Item chosen | 1 |
- */
- retrieveItemId: function(length) {
- let itemId = {
- identifier: this.context.GsmPDUHelper.readHexOctet()
- };
- return itemId;
- },
-
- /**
- * Response Length.
- *
- * | Byte | Description | Length |
- * | 1 | Response Length Tag | 1 |
- * | 2 | Lenth = 02 | 1 |
- * | 3 | Minimum length of response | 1 |
- * | 4 | Maximum length of response | 1 |
- */
- retrieveResponseLength: function(length) {
- let GsmPDUHelper = this.context.GsmPDUHelper;
- let rspLength = {
- minLength : GsmPDUHelper.readHexOctet(),
- maxLength : GsmPDUHelper.readHexOctet()
- };
- return rspLength;
- },
-
- /**
- * File List.
- *
- * | Byte | Description | Length |
- * | 1 | File List Tag | 1 |
- * | 2 ~ (Y-1)+2 | Length (X) | Y |
- * | (Y-1)+3 | Number of files | 1 |
- * | (Y-1)+4 ~ | Files | X |
- * | (Y-1)+X+2 | | |
- */
- retrieveFileList: function(length) {
- let num = this.context.GsmPDUHelper.readHexOctet();
- let fileList = "";
- length--; // -1 for the num octet.
- for (let i = 0; i < 2 * length; i++) {
- // Didn't use readHexOctet here,
- // otherwise 0x00 will be "0", not "00"
- fileList += String.fromCharCode(this.context.Buf.readUint16());
- }
- return {
- fileList: fileList
- };
- },
-
- /**
- * Default Text.
- *
- * Same as Text String.
- */
- retrieveDefaultText: function(length) {
- return this.retrieveTextString(length);
- },
-
- /**
- * Event List.
- */
- retrieveEventList: function(length) {
- if (!length) {
- // null means an indication to ME to remove the existing list of events
- // in ME.
- return null;
- }
-
- let GsmPDUHelper = this.context.GsmPDUHelper;
- let eventList = [];
- for (let i = 0; i < length; i++) {
- eventList.push(GsmPDUHelper.readHexOctet());
- }
- return {
- eventList: eventList
- };
- },
-
- /**
- * Icon Id.
- *
- * | Byte | Description | Length |
- * | 1 | Icon Identifier Tag | 1 |
- * | 2 | Length = 02 | 1 |
- * | 3 | Icon qualifier | 1 |
- * | 4 | Icon identifier | 1 |
- */
- retrieveIconId: function(length) {
- if (!length) {
- return null;
- }
-
- let iconId = {
- qualifier: this.context.GsmPDUHelper.readHexOctet(),
- identifier: this.context.GsmPDUHelper.readHexOctet()
- };
- return iconId;
- },
-
- /**
- * Icon Id List.
- *
- * | Byte | Description | Length |
- * | 1 | Icon Identifier Tag | 1 |
- * | 2 | Length = X | 1 |
- * | 3 | Icon qualifier | 1 |
- * | 4~ | Icon identifier | X-1 |
- * | 4+X-2 | | |
- */
- retrieveIconIdList: function(length) {
- if (!length) {
- return null;
- }
-
- let iconIdList = {
- qualifier: this.context.GsmPDUHelper.readHexOctet(),
- identifiers: []
- };
- for (let i = 0; i < length - 1; i++) {
- iconIdList.identifiers.push(this.context.GsmPDUHelper.readHexOctet());
- }
- return iconIdList;
- },
-
- /**
- * Timer Identifier.
- *
- * | Byte | Description | Length |
- * | 1 | Timer Identifier Tag | 1 |
- * | 2 | Length = 01 | 1 |
- * | 3 | Timer Identifier | 1 |
- */
- retrieveTimerId: function(length) {
- let id = {
- timerId: this.context.GsmPDUHelper.readHexOctet()
- };
- return id;
- },
-
- /**
- * Timer Value.
- *
- * | Byte | Description | Length |
- * | 1 | Timer Value Tag | 1 |
- * | 2 | Length = 03 | 1 |
- * | 3 | Hour | 1 |
- * | 4 | Minute | 1 |
- * | 5 | Second | 1 |
- */
- retrieveTimerValue: function(length) {
- let GsmPDUHelper = this.context.GsmPDUHelper;
- let value = {
- timerValue: (GsmPDUHelper.readSwappedNibbleBcdNum(1) * 60 * 60) +
- (GsmPDUHelper.readSwappedNibbleBcdNum(1) * 60) +
- (GsmPDUHelper.readSwappedNibbleBcdNum(1))
- };
- return value;
- },
-
- /**
- * Immediate Response.
- *
- * | Byte | Description | Length |
- * | 1 | Immediate Response Tag | 1 |
- * | 2 | Length = 00 | 1 |
- */
- retrieveImmediaResponse: function(length) {
- return {};
- },
-
- /**
- * URL
- *
- * | Byte | Description | Length |
- * | 1 | URL Tag | 1 |
- * | 2 ~ (Y+1) | Length(X) | Y |
- * | (Y+2) ~ | URL | X |
- * | (Y+1+X) | | |
- */
- retrieveUrl: function(length) {
- let GsmPDUHelper = this.context.GsmPDUHelper;
- let s = "";
- for (let i = 0; i < length; i++) {
- s += String.fromCharCode(GsmPDUHelper.readHexOctet());
- }
- return {url: s};
- },
-
- /**
- * Next Action Indicator List.
- *
- * | Byte | Description | Length |
- * | 1 | Next Action tag | 1 |
- * | 1 | Length(X) | 1 |
- * | 3~ | Next Action List | X |
- * | 3+X-1 | | |
- */
- retrieveNextActionList: function(length) {
- let GsmPDUHelper = this.context.GsmPDUHelper;
- let nextActionList = [];
- for (let i = 0; i < length; i++) {
- nextActionList.push(GsmPDUHelper.readHexOctet());
- }
- return nextActionList;
- },
-
- searchForTag: function(tag, ctlvs) {
- for (let ctlv of ctlvs) {
- if ((ctlv.tag & ~COMPREHENSIONTLV_FLAG_CR) == tag) {
- return ctlv;
- }
- }
- return null;
- },
-
- searchForSelectedTags: function(ctlvs, tags) {
- let ret = {
- // Handy utility to de-queue the 1st ctlv of the specified tag.
- retrieve: function(aTag) {
- return (this[aTag]) ? this[aTag].shift() : null;
- }
- };
-
- ctlvs.forEach((aCtlv) => {
- tags.forEach((aTag) => {
- if ((aCtlv.tag & ~COMPREHENSIONTLV_FLAG_CR) == aTag) {
- if (!ret[aTag]) {
- ret[aTag] = [];
- }
- ret[aTag].push(aCtlv);
- }
- });
- });
-
- return ret;
- },
-};
-StkProactiveCmdHelperObject.prototype[COMPREHENSIONTLV_TAG_COMMAND_DETAILS] = function COMPREHENSIONTLV_TAG_COMMAND_DETAILS(length) {
- return this.retrieveCommandDetails(length);
-};
-StkProactiveCmdHelperObject.prototype[COMPREHENSIONTLV_TAG_DEVICE_ID] = function COMPREHENSIONTLV_TAG_DEVICE_ID(length) {
- return this.retrieveDeviceId(length);
-};
-StkProactiveCmdHelperObject.prototype[COMPREHENSIONTLV_TAG_ALPHA_ID] = function COMPREHENSIONTLV_TAG_ALPHA_ID(length) {
- return this.retrieveAlphaId(length);
-};
-StkProactiveCmdHelperObject.prototype[COMPREHENSIONTLV_TAG_DURATION] = function COMPREHENSIONTLV_TAG_DURATION(length) {
- return this.retrieveDuration(length);
-};
-StkProactiveCmdHelperObject.prototype[COMPREHENSIONTLV_TAG_ADDRESS] = function COMPREHENSIONTLV_TAG_ADDRESS(length) {
- return this.retrieveAddress(length);
-};
-StkProactiveCmdHelperObject.prototype[COMPREHENSIONTLV_TAG_TEXT_STRING] = function COMPREHENSIONTLV_TAG_TEXT_STRING(length) {
- return this.retrieveTextString(length);
-};
-StkProactiveCmdHelperObject.prototype[COMPREHENSIONTLV_TAG_TONE] = function COMPREHENSIONTLV_TAG_TONE(length) {
- return this.retrieveTone(length);
-};
-StkProactiveCmdHelperObject.prototype[COMPREHENSIONTLV_TAG_ITEM] = function COMPREHENSIONTLV_TAG_ITEM(length) {
- return this.retrieveItem(length);
-};
-StkProactiveCmdHelperObject.prototype[COMPREHENSIONTLV_TAG_ITEM_ID] = function COMPREHENSIONTLV_TAG_ITEM_ID(length) {
- return this.retrieveItemId(length);
-};
-StkProactiveCmdHelperObject.prototype[COMPREHENSIONTLV_TAG_RESPONSE_LENGTH] = function COMPREHENSIONTLV_TAG_RESPONSE_LENGTH(length) {
- return this.retrieveResponseLength(length);
-};
-StkProactiveCmdHelperObject.prototype[COMPREHENSIONTLV_TAG_FILE_LIST] = function COMPREHENSIONTLV_TAG_FILE_LIST(length) {
- return this.retrieveFileList(length);
-};
-StkProactiveCmdHelperObject.prototype[COMPREHENSIONTLV_TAG_DEFAULT_TEXT] = function COMPREHENSIONTLV_TAG_DEFAULT_TEXT(length) {
- return this.retrieveDefaultText(length);
-};
-StkProactiveCmdHelperObject.prototype[COMPREHENSIONTLV_TAG_EVENT_LIST] = function COMPREHENSIONTLV_TAG_EVENT_LIST(length) {
- return this.retrieveEventList(length);
-};
-StkProactiveCmdHelperObject.prototype[COMPREHENSIONTLV_TAG_ICON_ID] = function COMPREHENSIONTLV_TAG_ICON_ID(length) {
- return this.retrieveIconId(length);
-};
-StkProactiveCmdHelperObject.prototype[COMPREHENSIONTLV_TAG_ICON_ID_LIST] = function COMPREHENSIONTLV_TAG_ICON_ID_LIST(length) {
- return this.retrieveIconIdList(length);
-};
-StkProactiveCmdHelperObject.prototype[COMPREHENSIONTLV_TAG_TIMER_IDENTIFIER] = function COMPREHENSIONTLV_TAG_TIMER_IDENTIFIER(length) {
- return this.retrieveTimerId(length);
-};
-StkProactiveCmdHelperObject.prototype[COMPREHENSIONTLV_TAG_TIMER_VALUE] = function COMPREHENSIONTLV_TAG_TIMER_VALUE(length) {
- return this.retrieveTimerValue(length);
-};
-StkProactiveCmdHelperObject.prototype[COMPREHENSIONTLV_TAG_IMMEDIATE_RESPONSE] = function COMPREHENSIONTLV_TAG_IMMEDIATE_RESPONSE(length) {
- return this.retrieveImmediaResponse(length);
-};
-StkProactiveCmdHelperObject.prototype[COMPREHENSIONTLV_TAG_URL] = function COMPREHENSIONTLV_TAG_URL(length) {
- return this.retrieveUrl(length);
-};
-StkProactiveCmdHelperObject.prototype[COMPREHENSIONTLV_TAG_NEXT_ACTION_IND] = function COMPREHENSIONTLV_TAG_NEXT_ACTION_IND(length) {
- return this.retrieveNextActionList(length);
-};
-
-function ComprehensionTlvHelperObject(aContext) {
- this.context = aContext;
-}
-ComprehensionTlvHelperObject.prototype = {
- context: null,
-
- /**
- * Decode raw data to a Comprehension-TLV.
- */
- decode: function() {
- let GsmPDUHelper = this.context.GsmPDUHelper;
-
- let hlen = 0; // For header(tag field + length field) length.
- let temp = GsmPDUHelper.readHexOctet();
- hlen++;
-
- // TS 101.220, clause 7.1.1
- let tag, cr;
- switch (temp) {
- // TS 101.220, clause 7.1.1
- case 0x0: // Not used.
- case 0xff: // Not used.
- case 0x80: // Reserved for future use.
- throw new Error("Invalid octet when parsing Comprehension TLV :" + temp);
- case 0x7f: // Tag is three byte format.
- // TS 101.220 clause 7.1.1.2.
- // | Byte 1 | Byte 2 | Byte 3 |
- // | | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | |
- // | 0x7f |CR | Tag Value |
- tag = (GsmPDUHelper.readHexOctet() << 8) | GsmPDUHelper.readHexOctet();
- hlen += 2;
- cr = (tag & 0x8000) !== 0;
- tag &= ~0x8000;
- break;
- default: // Tag is single byte format.
- tag = temp;
- // TS 101.220 clause 7.1.1.1.
- // | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 |
- // |CR | Tag Value |
- cr = (tag & 0x80) !== 0;
- tag &= ~0x80;
- }
-
- // TS 101.220 clause 7.1.2, Length Encoding.
- // Length | Byte 1 | Byte 2 | Byte 3 | Byte 4 |
- // 0 - 127 | 00 - 7f | N/A | N/A | N/A |
- // 128-255 | 81 | 80 - ff| N/A | N/A |
- // 256-65535| 82 | 0100 - ffff | N/A |
- // 65536- | 83 | 010000 - ffffff |
- // 16777215
- //
- // Length errors: TS 11.14, clause 6.10.6
-
- let length; // Data length.
- temp = GsmPDUHelper.readHexOctet();
- hlen++;
- if (temp < 0x80) {
- length = temp;
- } else if (temp == 0x81) {
- length = GsmPDUHelper.readHexOctet();
- hlen++;
- if (length < 0x80) {
- throw new Error("Invalid length in Comprehension TLV :" + length);
- }
- } else if (temp == 0x82) {
- length = (GsmPDUHelper.readHexOctet() << 8) | GsmPDUHelper.readHexOctet();
- hlen += 2;
- if (lenth < 0x0100) {
- throw new Error("Invalid length in 3-byte Comprehension TLV :" + length);
- }
- } else if (temp == 0x83) {
- length = (GsmPDUHelper.readHexOctet() << 16) |
- (GsmPDUHelper.readHexOctet() << 8) |
- GsmPDUHelper.readHexOctet();
- hlen += 3;
- if (length < 0x010000) {
- throw new Error("Invalid length in 4-byte Comprehension TLV :" + length);
- }
- } else {
- throw new Error("Invalid octet in Comprehension TLV :" + temp);
- }
-
- let ctlv = {
- tag: tag,
- length: length,
- value: this.context.StkProactiveCmdHelper.retrieve(tag, length),
- cr: cr,
- hlen: hlen
- };
- return ctlv;
- },
-
- decodeChunks: function(length) {
- let chunks = [];
- let index = 0;
- while (index < length) {
- let tlv = this.decode();
- chunks.push(tlv);
- index += tlv.length;
- index += tlv.hlen;
- }
- return chunks;
- },
-
- /**
- * Write Location Info Comprehension TLV.
- *
- * @param loc location Information.
- */
- writeLocationInfoTlv: function(loc) {
- let GsmPDUHelper = this.context.GsmPDUHelper;
-
- GsmPDUHelper.writeHexOctet(COMPREHENSIONTLV_TAG_LOCATION_INFO |
- COMPREHENSIONTLV_FLAG_CR);
- GsmPDUHelper.writeHexOctet(loc.gsmCellId > 0xffff ? 9 : 7);
- // From TS 11.14, clause 12.19
- // "The mobile country code (MCC), the mobile network code (MNC),
- // the location area code (LAC) and the cell ID are
- // coded as in TS 04.08."
- // And from TS 04.08 and TS 24.008,
- // the format is as follows:
- //
- // MCC = MCC_digit_1 + MCC_digit_2 + MCC_digit_3
- //
- // 8 7 6 5 4 3 2 1
- // +-------------+-------------+
- // | MCC digit 2 | MCC digit 1 | octet 2
- // | MNC digit 3 | MCC digit 3 | octet 3
- // | MNC digit 2 | MNC digit 1 | octet 4
- // +-------------+-------------+
- //
- // Also in TS 24.008
- // "However a network operator may decide to
- // use only two digits in the MNC in the LAI over the
- // radio interface. In this case, bits 5 to 8 of octet 3
- // shall be coded as '1111'".
-
- // MCC & MNC, 3 octets
- let mcc = loc.mcc, mnc;
- if (loc.mnc.length == 2) {
- mnc = "F" + loc.mnc;
- } else {
- mnc = loc.mnc[2] + loc.mnc[0] + loc.mnc[1];
- }
- GsmPDUHelper.writeSwappedNibbleBCD(mcc + mnc);
-
- // LAC, 2 octets
- GsmPDUHelper.writeHexOctet((loc.gsmLocationAreaCode >> 8) & 0xff);
- GsmPDUHelper.writeHexOctet(loc.gsmLocationAreaCode & 0xff);
-
- // Cell Id
- if (loc.gsmCellId > 0xffff) {
- // UMTS/WCDMA, gsmCellId is 28 bits.
- GsmPDUHelper.writeHexOctet((loc.gsmCellId >> 24) & 0xff);
- GsmPDUHelper.writeHexOctet((loc.gsmCellId >> 16) & 0xff);
- GsmPDUHelper.writeHexOctet((loc.gsmCellId >> 8) & 0xff);
- GsmPDUHelper.writeHexOctet(loc.gsmCellId & 0xff);
- } else {
- // GSM, gsmCellId is 16 bits.
- GsmPDUHelper.writeHexOctet((loc.gsmCellId >> 8) & 0xff);
- GsmPDUHelper.writeHexOctet(loc.gsmCellId & 0xff);
- }
- },
-
- /**
- * Given a geckoError string, this function translates it into cause value
- * and write the value into buffer.
- *
- * @param geckoError Error string that is passed to gecko.
- */
- writeCauseTlv: function(geckoError) {
- let GsmPDUHelper = this.context.GsmPDUHelper;
-
- let cause = -1;
- for (let errorNo in RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR) {
- if (geckoError == RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[errorNo]) {
- cause = errorNo;
- break;
- }
- }
-
- // Causes specified in 10.5.4.11 of TS 04.08 are less than 128.
- // we can ignore causes > 127 since Cause TLV is optional in
- // STK_EVENT_TYPE_CALL_DISCONNECTED.
- if (cause > 127) {
- return;
- }
-
- cause = (cause == -1) ? ERROR_SUCCESS : cause;
-
- GsmPDUHelper.writeHexOctet(COMPREHENSIONTLV_TAG_CAUSE |
- COMPREHENSIONTLV_FLAG_CR);
- GsmPDUHelper.writeHexOctet(2); // For single cause value.
-
- // TS 04.08, clause 10.5.4.11:
- // Code Standard : Standard defined for GSM PLMNS
- // Location: User
- GsmPDUHelper.writeHexOctet(0x60);
-
- // TS 04.08, clause 10.5.4.11: ext bit = 1 + 7 bits for cause.
- // +-----------------+----------------------------------+
- // | Ext = 1 (1 bit) | Cause (7 bits) |
- // +-----------------+----------------------------------+
- GsmPDUHelper.writeHexOctet(0x80 | cause);
- },
-
- writeDateTimeZoneTlv: function(date) {
- let GsmPDUHelper = this.context.GsmPDUHelper;
-
- GsmPDUHelper.writeHexOctet(COMPREHENSIONTLV_TAG_DATE_TIME_ZONE);
- GsmPDUHelper.writeHexOctet(7);
- GsmPDUHelper.writeTimestamp(date);
- },
-
- writeLanguageTlv: function(language) {
- let GsmPDUHelper = this.context.GsmPDUHelper;
-
- GsmPDUHelper.writeHexOctet(COMPREHENSIONTLV_TAG_LANGUAGE);
- GsmPDUHelper.writeHexOctet(2);
-
- // ISO 639-1, Alpha-2 code
- // TS 123.038, clause 6.2.1, GSM 7 bit Default Alphabet
- GsmPDUHelper.writeHexOctet(
- PDU_NL_LOCKING_SHIFT_TABLES[PDU_NL_IDENTIFIER_DEFAULT].indexOf(language[0]));
- GsmPDUHelper.writeHexOctet(
- PDU_NL_LOCKING_SHIFT_TABLES[PDU_NL_IDENTIFIER_DEFAULT].indexOf(language[1]));
- },
-
- /**
- * Write Timer Value Comprehension TLV.
- *
- * @param seconds length of time during of the timer.
- * @param cr Comprehension Required or not
- */
- writeTimerValueTlv: function(seconds, cr) {
- let GsmPDUHelper = this.context.GsmPDUHelper;
-
- GsmPDUHelper.writeHexOctet(COMPREHENSIONTLV_TAG_TIMER_VALUE |
- (cr ? COMPREHENSIONTLV_FLAG_CR : 0));
- GsmPDUHelper.writeHexOctet(3);
-
- // TS 102.223, clause 8.38
- // +----------------+------------------+-------------------+
- // | hours (1 byte) | minutes (1 btye) | seconds (1 byte) |
- // +----------------+------------------+-------------------+
- GsmPDUHelper.writeSwappedNibbleBCDNum(Math.floor(seconds / 60 / 60));
- GsmPDUHelper.writeSwappedNibbleBCDNum(Math.floor(seconds / 60) % 60);
- GsmPDUHelper.writeSwappedNibbleBCDNum(Math.floor(seconds) % 60);
- },
-
- writeTextStringTlv: function(text, coding) {
- let GsmPDUHelper = this.context.GsmPDUHelper;
- let buf = GsmPDUHelper.writeWithBuffer(() => {
- // Write Coding.
- GsmPDUHelper.writeHexOctet(coding);
-
- // Write Text String.
- switch (coding) {
- case STK_TEXT_CODING_UCS2:
- GsmPDUHelper.writeUCS2String(text);
- break;
- case STK_TEXT_CODING_GSM_7BIT_PACKED:
- GsmPDUHelper.writeStringAsSeptets(text, 0, 0, 0);
- break;
- case STK_TEXT_CODING_GSM_8BIT:
- GsmPDUHelper.writeStringAs8BitUnpacked(text);
- break;
- }
- });
-
- let length = buf.length;
- if (length) {
- // Write Tag.
- GsmPDUHelper.writeHexOctet(COMPREHENSIONTLV_TAG_TEXT_STRING |
- COMPREHENSIONTLV_FLAG_CR);
- // Write Length.
- this.writeLength(length);
- // Write Value.
- for (let i = 0; i < length; i++) {
- GsmPDUHelper.writeHexOctet(buf[i]);
- }
- }
- },
-
- getSizeOfLengthOctets: function(length) {
- if (length >= 0x10000) {
- return 4; // 0x83, len_1, len_2, len_3
- } else if (length >= 0x100) {
- return 3; // 0x82, len_1, len_2
- } else if (length >= 0x80) {
- return 2; // 0x81, len
- } else {
- return 1; // len
- }
- },
-
- writeLength: function(length) {
- let GsmPDUHelper = this.context.GsmPDUHelper;
-
- // TS 101.220 clause 7.1.2, Length Encoding.
- // Length | Byte 1 | Byte 2 | Byte 3 | Byte 4 |
- // 0 - 127 | 00 - 7f | N/A | N/A | N/A |
- // 128-255 | 81 | 80 - ff| N/A | N/A |
- // 256-65535| 82 | 0100 - ffff | N/A |
- // 65536- | 83 | 010000 - ffffff |
- // 16777215
- if (length < 0x80) {
- GsmPDUHelper.writeHexOctet(length);
- } else if (0x80 <= length && length < 0x100) {
- GsmPDUHelper.writeHexOctet(0x81);
- GsmPDUHelper.writeHexOctet(length);
- } else if (0x100 <= length && length < 0x10000) {
- GsmPDUHelper.writeHexOctet(0x82);
- GsmPDUHelper.writeHexOctet((length >> 8) & 0xff);
- GsmPDUHelper.writeHexOctet(length & 0xff);
- } else if (0x10000 <= length && length < 0x1000000) {
- GsmPDUHelper.writeHexOctet(0x83);
- GsmPDUHelper.writeHexOctet((length >> 16) & 0xff);
- GsmPDUHelper.writeHexOctet((length >> 8) & 0xff);
- GsmPDUHelper.writeHexOctet(length & 0xff);
- } else {
- throw new Error("Invalid length value :" + length);
- }
- },
-};
-
-function BerTlvHelperObject(aContext) {
- this.context = aContext;
-}
-BerTlvHelperObject.prototype = {
- context: null,
-
- /**
- * Decode Ber TLV.
- *
- * @param dataLen
- * The length of data in bytes.
- */
- decode: function(dataLen) {
- let GsmPDUHelper = this.context.GsmPDUHelper;
-
- let hlen = 0;
- let tag = GsmPDUHelper.readHexOctet();
- hlen++;
-
- // The length is coded onto 1 or 2 bytes.
- // Length | Byte 1 | Byte 2
- // 0 - 127 | length ('00' to '7f') | N/A
- // 128 - 255 | '81' | length ('80' to 'ff')
- let length;
- let temp = GsmPDUHelper.readHexOctet();
- hlen++;
- if (temp < 0x80) {
- length = temp;
- } else if (temp === 0x81) {
- length = GsmPDUHelper.readHexOctet();
- hlen++;
- if (length < 0x80) {
- throw new Error("Invalid length " + length);
- }
- } else {
- throw new Error("Invalid length octet " + temp);
- }
-
- // Header + body length check.
- if (dataLen - hlen !== length) {
- throw new Error("Unexpected BerTlvHelper value length!!");
- }
-
- let method = this[tag];
- if (typeof method != "function") {
- throw new Error("Unknown Ber tag 0x" + tag.toString(16));
- }
-
- let value = method.call(this, length);
-
- return {
- tag: tag,
- length: length,
- value: value
- };
- },
-
- /**
- * Process the value part for FCP template TLV.
- *
- * @param length
- * The length of data in bytes.
- */
- processFcpTemplate: function(length) {
- let tlvs = this.decodeChunks(length);
- return tlvs;
- },
-
- /**
- * Process the value part for proactive command TLV.
- *
- * @param length
- * The length of data in bytes.
- */
- processProactiveCommand: function(length) {
- let ctlvs = this.context.ComprehensionTlvHelper.decodeChunks(length);
- return ctlvs;
- },
-
- /**
- * Decode raw data to a Ber-TLV.
- */
- decodeInnerTlv: function() {
- let GsmPDUHelper = this.context.GsmPDUHelper;
- let tag = GsmPDUHelper.readHexOctet();
- let length = GsmPDUHelper.readHexOctet();
- return {
- tag: tag,
- length: length,
- value: this.retrieve(tag, length)
- };
- },
-
- decodeChunks: function(length) {
- let chunks = [];
- let index = 0;
- while (index < length) {
- let tlv = this.decodeInnerTlv();
- if (tlv.value) {
- chunks.push(tlv);
- }
- index += tlv.length;
- // tag + length fields consume 2 bytes.
- index += 2;
- }
- return chunks;
- },
-
- retrieve: function(tag, length) {
- let method = this[tag];
- if (typeof method != "function") {
- if (DEBUG) {
- this.context.debug("Unknown Ber tag : 0x" + tag.toString(16));
- }
- let Buf = this.context.Buf;
- Buf.seekIncoming(length * Buf.PDU_HEX_OCTET_SIZE);
- return null;
- }
- return method.call(this, length);
- },
-
- /**
- * File Size Data.
- *
- * | Byte | Description | Length |
- * | 1 | Tag | 1 |
- * | 2 | Length | 1 |
- * | 3 to X+24 | Number of allocated data bytes in the file | X |
- * | | , excluding structural information | |
- */
- retrieveFileSizeData: function(length) {
- let GsmPDUHelper = this.context.GsmPDUHelper;
- let fileSizeData = 0;
- for (let i = 0; i < length; i++) {
- fileSizeData = fileSizeData << 8;
- fileSizeData += GsmPDUHelper.readHexOctet();
- }
-
- return {fileSizeData: fileSizeData};
- },
-
- /**
- * File Descriptor.
- *
- * | Byte | Description | Length |
- * | 1 | Tag | 1 |
- * | 2 | Length | 1 |
- * | 3 | File descriptor byte | 1 |
- * | 4 | Data coding byte | 1 |
- * | 5 ~ 6 | Record length | 2 |
- * | 7 | Number of records | 1 |
- */
- retrieveFileDescriptor: function(length) {
- let GsmPDUHelper = this.context.GsmPDUHelper;
- let fileDescriptorByte = GsmPDUHelper.readHexOctet();
- let dataCodingByte = GsmPDUHelper.readHexOctet();
- // See TS 102 221 Table 11.5, we only care the least 3 bits for the
- // structure of file.
- let fileStructure = fileDescriptorByte & 0x07;
-
- let fileDescriptor = {
- fileStructure: fileStructure
- };
- // byte 5 ~ 7 are mandatory for linear fixed and cyclic files, otherwise
- // they are not applicable.
- if (fileStructure === UICC_EF_STRUCTURE[EF_STRUCTURE_LINEAR_FIXED] ||
- fileStructure === UICC_EF_STRUCTURE[EF_STRUCTURE_CYCLIC]) {
- fileDescriptor.recordLength = (GsmPDUHelper.readHexOctet() << 8) +
- GsmPDUHelper.readHexOctet();
- fileDescriptor.numOfRecords = GsmPDUHelper.readHexOctet();
- }
-
- return fileDescriptor;
- },
-
- /**
- * File identifier.
- *
- * | Byte | Description | Length |
- * | 1 | Tag | 1 |
- * | 2 | Length | 1 |
- * | 3 ~ 4 | File identifier | 2 |
- */
- retrieveFileIdentifier: function(length) {
- let GsmPDUHelper = this.context.GsmPDUHelper;
- return {fileId : (GsmPDUHelper.readHexOctet() << 8) +
- GsmPDUHelper.readHexOctet()};
- },
-
- searchForNextTag: function(tag, iter) {
- for (let tlv of iter) {
- if (tlv.tag === tag) {
- return tlv;
- }
- }
- return null;
- }
-};
-BerTlvHelperObject.prototype[BER_FCP_TEMPLATE_TAG] = function BER_FCP_TEMPLATE_TAG(length) {
- return this.processFcpTemplate(length);
-};
-BerTlvHelperObject.prototype[BER_PROACTIVE_COMMAND_TAG] = function BER_PROACTIVE_COMMAND_TAG(length) {
- return this.processProactiveCommand(length);
-};
-BerTlvHelperObject.prototype[BER_FCP_FILE_SIZE_DATA_TAG] = function BER_FCP_FILE_SIZE_DATA_TAG(length) {
- return this.retrieveFileSizeData(length);
-};
-BerTlvHelperObject.prototype[BER_FCP_FILE_DESCRIPTOR_TAG] = function BER_FCP_FILE_DESCRIPTOR_TAG(length) {
- return this.retrieveFileDescriptor(length);
-};
-BerTlvHelperObject.prototype[BER_FCP_FILE_IDENTIFIER_TAG] = function BER_FCP_FILE_IDENTIFIER_TAG(length) {
- return this.retrieveFileIdentifier(length);
-};
-
-/**
- * ICC Helper for getting EF path.
- */
-function ICCFileHelperObject(aContext) {
- this.context = aContext;
-}
-ICCFileHelperObject.prototype = {
- context: null,
-
- /**
- * This function handles only EFs that are common to RUIM, SIM, USIM
- * and other types of ICC cards.
- */
- getCommonEFPath: function(fileId) {
- switch (fileId) {
- case ICC_EF_ICCID:
- return EF_PATH_MF_SIM;
- case ICC_EF_ADN:
- case ICC_EF_SDN: // Fall through.
- return EF_PATH_MF_SIM + EF_PATH_DF_TELECOM;
- case ICC_EF_PBR:
- return EF_PATH_MF_SIM + EF_PATH_DF_TELECOM + EF_PATH_DF_PHONEBOOK;
- case ICC_EF_IMG:
- return EF_PATH_MF_SIM + EF_PATH_DF_TELECOM + EF_PATH_GRAPHICS;
- }
- return null;
- },
-
- /**
- * This function handles EFs for SIM.
- */
- getSimEFPath: function(fileId) {
- switch (fileId) {
- case ICC_EF_FDN:
- case ICC_EF_MSISDN:
- case ICC_EF_SMS:
- case ICC_EF_EXT1:
- case ICC_EF_EXT2:
- case ICC_EF_EXT3:
- return EF_PATH_MF_SIM + EF_PATH_DF_TELECOM;
- case ICC_EF_AD:
- case ICC_EF_MBDN:
- case ICC_EF_MWIS:
- case ICC_EF_PLMNsel:
- case ICC_EF_SPN:
- case ICC_EF_SPDI:
- case ICC_EF_SST:
- case ICC_EF_PHASE:
- case ICC_EF_CBMI:
- case ICC_EF_CBMID:
- case ICC_EF_CBMIR:
- case ICC_EF_OPL:
- case ICC_EF_PNN:
- case ICC_EF_GID1:
- case ICC_EF_CPHS_INFO:
- case ICC_EF_CPHS_MBN:
- return EF_PATH_MF_SIM + EF_PATH_DF_GSM;
- default:
- return null;
- }
- },
-
- /**
- * This function handles EFs for USIM.
- */
- getUSimEFPath: function(fileId) {
- switch (fileId) {
- case ICC_EF_AD:
- case ICC_EF_FDN:
- case ICC_EF_MBDN:
- case ICC_EF_MWIS:
- case ICC_EF_UST:
- case ICC_EF_MSISDN:
- case ICC_EF_SPN:
- case ICC_EF_SPDI:
- case ICC_EF_CBMI:
- case ICC_EF_CBMID:
- case ICC_EF_CBMIR:
- case ICC_EF_OPL:
- case ICC_EF_PNN:
- case ICC_EF_SMS:
- case ICC_EF_GID1:
- // CPHS spec was provided in 1997 based on SIM requirement, there is no
- // detailed info about how these ICC_EF_CPHS_XXX are allocated in USIM.
- // What we can do now is to follow what has been done in AOSP to have file
- // path equal to MF_SIM/DF_GSM.
- case ICC_EF_CPHS_INFO:
- case ICC_EF_CPHS_MBN:
- return EF_PATH_MF_SIM + EF_PATH_ADF_USIM;
- default:
- // The file ids in USIM phone book entries are decided by the
- // card manufacturer. So if we don't match any of the cases
- // above and if its a USIM return the phone book path.
- return EF_PATH_MF_SIM + EF_PATH_DF_TELECOM + EF_PATH_DF_PHONEBOOK;
- }
- },
-
- /**
- * This function handles EFs for RUIM
- */
- getRuimEFPath: function(fileId) {
- switch(fileId) {
- case ICC_EF_CSIM_IMSI_M:
- case ICC_EF_CSIM_CDMAHOME:
- case ICC_EF_CSIM_CST:
- case ICC_EF_CSIM_SPN:
- return EF_PATH_MF_SIM + EF_PATH_DF_CDMA;
- case ICC_EF_FDN:
- case ICC_EF_EXT1:
- case ICC_EF_EXT2:
- case ICC_EF_EXT3:
- return EF_PATH_MF_SIM + EF_PATH_DF_TELECOM;
- default:
- return null;
- }
- },
-
- /**
- * Helper function for getting the pathId for the specific ICC record
- * depeding on which type of ICC card we are using.
- *
- * @param fileId
- * File id.
- * @return The pathId or null in case of an error or invalid input.
- */
- getEFPath: function(fileId) {
- let path = this.getCommonEFPath(fileId);
- if (path) {
- return path;
- }
-
- switch (this.context.RIL.appType) {
- case CARD_APPTYPE_SIM:
- return this.getSimEFPath(fileId);
- case CARD_APPTYPE_USIM:
- return this.getUSimEFPath(fileId);
- case CARD_APPTYPE_RUIM:
- return this.getRuimEFPath(fileId);
- default:
- return null;
- }
- }
-};
-
-/**
- * Helper for ICC IO functionalities.
- */
-function ICCIOHelperObject(aContext) {
- this.context = aContext;
-}
-ICCIOHelperObject.prototype = {
- context: null,
-
- /**
- * Load EF with type 'Linear Fixed'.
- *
- * @param fileId
- * The file to operate on, one of the ICC_EF_* constants.
- * @param recordNumber [optional]
- * The number of the record shall be loaded.
- * @param recordSize [optional]
- * The size of the record.
- * @param callback [optional]
- * The callback function shall be called when the record(s) is read.
- * @param onerror [optional]
- * The callback function shall be called when failure.
- */
- loadLinearFixedEF: function(options) {
- let cb;
- let readRecord = (function(options) {
- options.command = ICC_COMMAND_READ_RECORD;
- options.p1 = options.recordNumber || 1; // Record number
- options.p2 = READ_RECORD_ABSOLUTE_MODE;
- options.p3 = options.recordSize;
- options.callback = cb || options.callback;
- this.context.RIL.iccIO(options);
- }).bind(this);
-
- options.structure = EF_STRUCTURE_LINEAR_FIXED;
- options.pathId = this.context.ICCFileHelper.getEFPath(options.fileId);
- if (options.recordSize) {
- readRecord(options);
- return;
- }
-
- cb = options.callback;
- options.callback = readRecord;
- this.getResponse(options);
- },
-
- /**
- * Load next record from current record Id.
- */
- loadNextRecord: function(options) {
- options.p1++;
- this.context.RIL.iccIO(options);
- },
-
- /**
- * Update EF with type 'Linear Fixed'.
- *
- * @param fileId
- * The file to operate on, one of the ICC_EF_* constants.
- * @param recordNumber
- * The number of the record shall be updated.
- * @param dataWriter [optional]
- * The function for writing string parameter for the ICC_COMMAND_UPDATE_RECORD.
- * @param pin2 [optional]
- * PIN2 is required when updating ICC_EF_FDN.
- * @param callback [optional]
- * The callback function shall be called when the record is updated.
- * @param onerror [optional]
- * The callback function shall be called when failure.
- */
- updateLinearFixedEF: function(options) {
- if (!options.fileId || !options.recordNumber) {
- throw new Error("Unexpected fileId " + options.fileId +
- " or recordNumber " + options.recordNumber);
- }
-
- options.structure = EF_STRUCTURE_LINEAR_FIXED;
- options.pathId = this.context.ICCFileHelper.getEFPath(options.fileId);
- let cb = options.callback;
- options.callback = function callback(options) {
- options.callback = cb;
- options.command = ICC_COMMAND_UPDATE_RECORD;
- options.p1 = options.recordNumber;
- options.p2 = READ_RECORD_ABSOLUTE_MODE;
- options.p3 = options.recordSize;
- this.context.RIL.iccIO(options);
- }.bind(this);
- this.getResponse(options);
- },
-
- /**
- * Load EF with type 'Transparent'.
- *
- * @param fileId
- * The file to operate on, one of the ICC_EF_* constants.
- * @param callback [optional]
- * The callback function shall be called when the record(s) is read.
- * @param onerror [optional]
- * The callback function shall be called when failure.
- */
- loadTransparentEF: function(options) {
- options.structure = EF_STRUCTURE_TRANSPARENT;
- let cb = options.callback;
- options.callback = function callback(options) {
- options.callback = cb;
- options.command = ICC_COMMAND_READ_BINARY;
- options.p2 = 0x00;
- options.p3 = options.fileSize;
- this.context.RIL.iccIO(options);
- }.bind(this);
- this.getResponse(options);
- },
-
- /**
- * Use ICC_COMMAND_GET_RESPONSE to query the EF.
- *
- * @param fileId
- * The file to operate on, one of the ICC_EF_* constants.
- */
- getResponse: function(options) {
- options.command = ICC_COMMAND_GET_RESPONSE;
- options.pathId = options.pathId ||
- this.context.ICCFileHelper.getEFPath(options.fileId);
- if (!options.pathId) {
- throw new Error("Unknown pathId for " + options.fileId.toString(16));
- }
- options.p1 = 0; // For GET_RESPONSE, p1 = 0
- switch (this.context.RIL.appType) {
- case CARD_APPTYPE_USIM:
- options.p2 = GET_RESPONSE_FCP_TEMPLATE;
- options.p3 = 0x00;
- break;
- // For RUIM, CSIM and ISIM, cf bug 955946: keep the old behavior
- case CARD_APPTYPE_RUIM:
- case CARD_APPTYPE_CSIM:
- case CARD_APPTYPE_ISIM:
- // For SIM, this is what we want
- case CARD_APPTYPE_SIM:
- default:
- options.p2 = 0x00;
- options.p3 = GET_RESPONSE_EF_SIZE_BYTES;
- break;
- }
- this.context.RIL.iccIO(options);
- },
-
- /**
- * Process ICC I/O response.
- */
- processICCIO: function(options) {
- let func = this[options.command];
- func.call(this, options);
- },
-
- /**
- * Process a ICC_COMMAND_GET_RESPONSE type command for REQUEST_SIM_IO.
- */
- processICCIOGetResponse: function(options) {
- let Buf = this.context.Buf;
- let strLen = Buf.readInt32();
-
- let peek = this.context.GsmPDUHelper.readHexOctet();
- Buf.seekIncoming(-1 * Buf.PDU_HEX_OCTET_SIZE);
- if (peek === BER_FCP_TEMPLATE_TAG) {
- this.processUSimGetResponse(options, strLen / 2);
- } else {
- this.processSimGetResponse(options);
- }
- Buf.readStringDelimiter(strLen);
-
- if (options.callback) {
- options.callback(options);
- }
- },
-
- /**
- * Helper function for processing USIM get response.
- */
- processUSimGetResponse: function(options, octetLen) {
- let BerTlvHelper = this.context.BerTlvHelper;
-
- let berTlv = BerTlvHelper.decode(octetLen);
- // See TS 102 221 Table 11.4 for the content order of getResponse.
- let iter = berTlv.value.values();
- let tlv = BerTlvHelper.searchForNextTag(BER_FCP_FILE_DESCRIPTOR_TAG,
- iter);
- if (!tlv ||
- (tlv.value.fileStructure !== UICC_EF_STRUCTURE[options.structure])) {
- throw new Error("Expected EF structure " +
- UICC_EF_STRUCTURE[options.structure] +
- " but read " + tlv.value.fileStructure);
- }
-
- if (tlv.value.fileStructure === UICC_EF_STRUCTURE[EF_STRUCTURE_LINEAR_FIXED] ||
- tlv.value.fileStructure === UICC_EF_STRUCTURE[EF_STRUCTURE_CYCLIC]) {
- options.recordSize = tlv.value.recordLength;
- options.totalRecords = tlv.value.numOfRecords;
- }
-
- tlv = BerTlvHelper.searchForNextTag(BER_FCP_FILE_IDENTIFIER_TAG, iter);
- if (!tlv || (tlv.value.fileId !== options.fileId)) {
- throw new Error("Expected file ID " + options.fileId.toString(16) +
- " but read " + fileId.toString(16));
- }
-
- tlv = BerTlvHelper.searchForNextTag(BER_FCP_FILE_SIZE_DATA_TAG, iter);
- if (!tlv) {
- throw new Error("Unexpected file size data");
- }
- options.fileSize = tlv.value.fileSizeData;
- },
-
- /**
- * Helper function for processing SIM get response.
- */
- processSimGetResponse: function(options) {
- let Buf = this.context.Buf;
- let GsmPDUHelper = this.context.GsmPDUHelper;
-
- // The format is from TS 51.011, clause 9.2.1
-
- // Skip RFU, data[0] data[1].
- Buf.seekIncoming(2 * Buf.PDU_HEX_OCTET_SIZE);
-
- // File size, data[2], data[3]
- options.fileSize = (GsmPDUHelper.readHexOctet() << 8) |
- GsmPDUHelper.readHexOctet();
-
- // 2 bytes File id. data[4], data[5]
- let fileId = (GsmPDUHelper.readHexOctet() << 8) |
- GsmPDUHelper.readHexOctet();
- if (fileId != options.fileId) {
- throw new Error("Expected file ID " + options.fileId.toString(16) +
- " but read " + fileId.toString(16));
- }
-
- // Type of file, data[6]
- let fileType = GsmPDUHelper.readHexOctet();
- if (fileType != TYPE_EF) {
- throw new Error("Unexpected file type " + fileType);
- }
-
- // Skip 1 byte RFU, data[7],
- // 3 bytes Access conditions, data[8] data[9] data[10],
- // 1 byte File status, data[11],
- // 1 byte Length of the following data, data[12].
- Buf.seekIncoming(((RESPONSE_DATA_STRUCTURE - RESPONSE_DATA_FILE_TYPE - 1) *
- Buf.PDU_HEX_OCTET_SIZE));
-
- // Read Structure of EF, data[13]
- let efStructure = GsmPDUHelper.readHexOctet();
- if (efStructure != options.structure) {
- throw new Error("Expected EF structure " + options.structure +
- " but read " + efStructure);
- }
-
- // Length of a record, data[14].
- // Only available for LINEAR_FIXED and CYCLIC.
- if (efStructure == EF_STRUCTURE_LINEAR_FIXED ||
- efStructure == EF_STRUCTURE_CYCLIC) {
- options.recordSize = GsmPDUHelper.readHexOctet();
- options.totalRecords = options.fileSize / options.recordSize;
- } else {
- Buf.seekIncoming(1 * Buf.PDU_HEX_OCTET_SIZE);
- }
- },
-
- /**
- * Process a ICC_COMMAND_READ_RECORD type command for REQUEST_SIM_IO.
- */
- processICCIOReadRecord: function(options) {
- if (options.callback) {
- options.callback(options);
- }
- },
-
- /**
- * Process a ICC_COMMAND_READ_BINARY type command for REQUEST_SIM_IO.
- */
- processICCIOReadBinary: function(options) {
- if (options.callback) {
- options.callback(options);
- }
- },
-
- /**
- * Process a ICC_COMMAND_UPDATE_RECORD type command for REQUEST_SIM_IO.
- */
- processICCIOUpdateRecord: function(options) {
- if (options.callback) {
- options.callback(options);
- }
- },
-};
-ICCIOHelperObject.prototype[ICC_COMMAND_SEEK] = null;
-ICCIOHelperObject.prototype[ICC_COMMAND_READ_BINARY] = function ICC_COMMAND_READ_BINARY(options) {
- this.processICCIOReadBinary(options);
-};
-ICCIOHelperObject.prototype[ICC_COMMAND_READ_RECORD] = function ICC_COMMAND_READ_RECORD(options) {
- this.processICCIOReadRecord(options);
-};
-ICCIOHelperObject.prototype[ICC_COMMAND_GET_RESPONSE] = function ICC_COMMAND_GET_RESPONSE(options) {
- this.processICCIOGetResponse(options);
-};
-ICCIOHelperObject.prototype[ICC_COMMAND_UPDATE_BINARY] = null;
-ICCIOHelperObject.prototype[ICC_COMMAND_UPDATE_RECORD] = function ICC_COMMAND_UPDATE_RECORD(options) {
- this.processICCIOUpdateRecord(options);
-};
-
-/**
- * Helper for ICC records.
- */
-function ICCRecordHelperObject(aContext) {
- this.context = aContext;
- // Cache the possible free record id for all files, use fileId as key.
- this._freeRecordIds = {};
-}
-ICCRecordHelperObject.prototype = {
- context: null,
-
- /**
- * Fetch ICC records.
- */
- fetchICCRecords: function() {
- switch (this.context.RIL.appType) {
- case CARD_APPTYPE_SIM:
- case CARD_APPTYPE_USIM:
- this.context.SimRecordHelper.fetchSimRecords();
- break;
- case CARD_APPTYPE_RUIM:
- this.context.RuimRecordHelper.fetchRuimRecords();
- break;
- }
- },
-
- /**
- * Read the ICCID.
- */
- readICCID: function() {
- function callback() {
- let Buf = this.context.Buf;
- let RIL = this.context.RIL;
- let GsmPDUHelper = this.context.GsmPDUHelper;
-
- let strLen = Buf.readInt32();
- let octetLen = strLen / 2;
- RIL.iccInfo.iccid =
- GsmPDUHelper.readSwappedNibbleBcdString(octetLen, true);
- // Consumes the remaining buffer if any.
- let unReadBuffer = this.context.Buf.getReadAvailable() -
- this.context.Buf.PDU_HEX_OCTET_SIZE;
- if (unReadBuffer > 0) {
- this.context.Buf.seekIncoming(unReadBuffer);
- }
- Buf.readStringDelimiter(strLen);
-
- if (DEBUG) this.context.debug("ICCID: " + RIL.iccInfo.iccid);
- if (RIL.iccInfo.iccid) {
- this.context.ICCUtilsHelper.handleICCInfoChange();
- RIL.reportStkServiceIsRunning();
- }
- }
-
- this.context.ICCIOHelper.loadTransparentEF({
- fileId: ICC_EF_ICCID,
- callback: callback.bind(this)
- });
- },
-
- /**
- * Read ICC ADN like EF, i.e. EF_ADN, EF_FDN.
- *
- * @param fileId EF id of the ADN, FDN or SDN.
- * @param extFileId EF id of the EXT.
- * @param onsuccess Callback to be called when success.
- * @param onerror Callback to be called when error.
- */
- readADNLike: function(fileId, extFileId, onsuccess, onerror) {
- let ICCIOHelper = this.context.ICCIOHelper;
-
- function callback(options) {
- let loadNextContactRecord = () => {
- if (options.p1 < options.totalRecords) {
- ICCIOHelper.loadNextRecord(options);
- return;
- }
- if (DEBUG) {
- for (let i = 0; i < contacts.length; i++) {
- this.context.debug("contact [" + i + "] " +
- JSON.stringify(contacts[i]));
- }
- }
- if (onsuccess) {
- onsuccess(contacts);
- }
- };
-
- let contact =
- this.context.ICCPDUHelper.readAlphaIdDiallingNumber(options.recordSize);
- if (contact) {
- let record = {
- recordId: options.p1,
- alphaId: contact.alphaId,
- number: contact.number
- };
- contacts.push(record);
-
- if (extFileId && contact.extRecordNumber != 0xff) {
- this.readExtension(extFileId, contact.extRecordNumber, (number) => {
- if (number) {
- record.number += number;
- }
- loadNextContactRecord();
- }, () => loadNextContactRecord());
- return;
- }
- }
- loadNextContactRecord();
- }
-
- let contacts = [];
- ICCIOHelper.loadLinearFixedEF({fileId: fileId,
- callback: callback.bind(this),
- onerror: onerror});
- },
-
- /**
- * Update ICC ADN like EFs, like EF_ADN, EF_FDN.
- *
- * @param fileId EF id of the ADN or FDN.
- * @param extRecordNumber The record identifier of the EXT.
- * @param contact The contact will be updated. (Shall have recordId property)
- * @param pin2 PIN2 is required when updating ICC_EF_FDN.
- * @param onsuccess Callback to be called when success.
- * @param onerror Callback to be called when error.
- */
- updateADNLike: function(fileId, extRecordNumber, contact, pin2, onsuccess, onerror) {
- let updatedContact;
- function dataWriter(recordSize) {
- updatedContact = this.context.ICCPDUHelper.writeAlphaIdDiallingNumber(recordSize,
- contact.alphaId,
- contact.number,
- extRecordNumber);
- }
-
- function callback(options) {
- if (onsuccess) {
- onsuccess(updatedContact);
- }
- }
-
- if (!contact || !contact.recordId) {
- if (onerror) onerror(GECKO_ERROR_INVALID_PARAMETER);
- return;
- }
-
- this.context.ICCIOHelper.updateLinearFixedEF({
- fileId: fileId,
- recordNumber: contact.recordId,
- dataWriter: dataWriter.bind(this),
- pin2: pin2,
- callback: callback.bind(this),
- onerror: onerror
- });
- },
-
- /**
- * Read USIM/RUIM Phonebook.
- *
- * @param onsuccess Callback to be called when success.
- * @param onerror Callback to be called when error.
- */
- readPBR: function(onsuccess, onerror) {
- let Buf = this.context.Buf;
- let GsmPDUHelper = this.context.GsmPDUHelper;
- let ICCIOHelper = this.context.ICCIOHelper;
- let ICCUtilsHelper = this.context.ICCUtilsHelper;
- let RIL = this.context.RIL;
-
- function callback(options) {
- let strLen = Buf.readInt32();
- let octetLen = strLen / 2, readLen = 0;
-
- let pbrTlvs = [];
- while (readLen < octetLen) {
- let tag = GsmPDUHelper.readHexOctet();
- if (tag == 0xff) {
- readLen++;
- Buf.seekIncoming((octetLen - readLen) * Buf.PDU_HEX_OCTET_SIZE);
- break;
- }
-
- let tlvLen = GsmPDUHelper.readHexOctet();
- let tlvs = ICCUtilsHelper.decodeSimTlvs(tlvLen);
- pbrTlvs.push({tag: tag,
- length: tlvLen,
- value: tlvs});
-
- readLen += tlvLen + 2; // +2 for tag and tlvLen
- }
- Buf.readStringDelimiter(strLen);
-
- if (pbrTlvs.length > 0) {
- let pbr = ICCUtilsHelper.parsePbrTlvs(pbrTlvs);
- // EF_ADN is mandatory if and only if DF_PHONEBOOK is present.
- if (!pbr.adn) {
- if (onerror) onerror("Cannot access ADN.");
- return;
- }
- pbrs.push(pbr);
- }
-
- if (options.p1 < options.totalRecords) {
- ICCIOHelper.loadNextRecord(options);
- } else {
- if (onsuccess) {
- RIL.iccInfoPrivate.pbrs = pbrs;
- onsuccess(pbrs);
- }
- }
- }
-
- if (RIL.iccInfoPrivate.pbrs) {
- onsuccess(RIL.iccInfoPrivate.pbrs);
- return;
- }
-
- let pbrs = [];
- ICCIOHelper.loadLinearFixedEF({fileId : ICC_EF_PBR,
- callback: callback.bind(this),
- onerror: onerror});
- },
-
- /**
- * Cache EF_IAP record size.
- */
- _iapRecordSize: null,
-
- /**
- * Read ICC EF_IAP. (Index Administration Phonebook)
- *
- * @see TS 131.102, clause 4.4.2.2
- *
- * @param fileId EF id of the IAP.
- * @param recordNumber The number of the record shall be loaded.
- * @param onsuccess Callback to be called when success.
- * @param onerror Callback to be called when error.
- */
- readIAP: function(fileId, recordNumber, onsuccess, onerror) {
- function callback(options) {
- let Buf = this.context.Buf;
- let strLen = Buf.readInt32();
- let octetLen = strLen / 2;
- this._iapRecordSize = options.recordSize;
-
- let iap = this.context.GsmPDUHelper.readHexOctetArray(octetLen);
- Buf.readStringDelimiter(strLen);
-
- if (onsuccess) {
- onsuccess(iap);
- }
- }
-
- this.context.ICCIOHelper.loadLinearFixedEF({
- fileId: fileId,
- recordNumber: recordNumber,
- recordSize: this._iapRecordSize,
- callback: callback.bind(this),
- onerror: onerror
- });
- },
-
- /**
- * Update USIM/RUIM Phonebook EF_IAP.
- *
- * @see TS 131.102, clause 4.4.2.13
- *
- * @param fileId EF id of the IAP.
- * @param recordNumber The identifier of the record shall be updated.
- * @param iap The IAP value to be written.
- * @param onsuccess Callback to be called when success.
- * @param onerror Callback to be called when error.
- */
- updateIAP: function(fileId, recordNumber, iap, onsuccess, onerror) {
- let dataWriter = function dataWriter(recordSize) {
- let Buf = this.context.Buf;
- let GsmPDUHelper = this.context.GsmPDUHelper;
-
- // Write String length
- let strLen = recordSize * 2;
- Buf.writeInt32(strLen);
-
- for (let i = 0; i < iap.length; i++) {
- GsmPDUHelper.writeHexOctet(iap[i]);
- }
-
- Buf.writeStringDelimiter(strLen);
- }.bind(this);
-
- this.context.ICCIOHelper.updateLinearFixedEF({
- fileId: fileId,
- recordNumber: recordNumber,
- dataWriter: dataWriter,
- callback: onsuccess,
- onerror: onerror
- });
- },
-
- /**
- * Cache EF_Email record size.
- */
- _emailRecordSize: null,
-
- /**
- * Read USIM/RUIM Phonebook EF_EMAIL.
- *
- * @see TS 131.102, clause 4.4.2.13
- *
- * @param fileId EF id of the EMAIL.
- * @param fileType The type of the EMAIL, one of the ICC_USIM_TYPE* constants.
- * @param recordNumber The number of the record shall be loaded.
- * @param onsuccess Callback to be called when success.
- * @param onerror Callback to be called when error.
- */
- readEmail: function(fileId, fileType, recordNumber, onsuccess, onerror) {
- function callback(options) {
- let Buf = this.context.Buf;
- let ICCPDUHelper = this.context.ICCPDUHelper;
-
- let strLen = Buf.readInt32();
- let octetLen = strLen / 2;
- let email = null;
- this._emailRecordSize = options.recordSize;
-
- // Read contact's email
- //
- // | Byte | Description | Length | M/O
- // | 1 ~ X | E-mail Address | X | M
- // | X+1 | ADN file SFI | 1 | C
- // | X+2 | ADN file Record Identifier | 1 | C
- // Note: The fields marked as C above are mandatort if the file
- // is not type 1 (as specified in EF_PBR)
- if (fileType == ICC_USIM_TYPE1_TAG) {
- email = ICCPDUHelper.read8BitUnpackedToString(octetLen);
- } else {
- email = ICCPDUHelper.read8BitUnpackedToString(octetLen - 2);
-
- // Consumes the remaining buffer
- Buf.seekIncoming(2 * Buf.PDU_HEX_OCTET_SIZE); // For ADN SFI and Record Identifier
- }
-
- Buf.readStringDelimiter(strLen);
-
- if (onsuccess) {
- onsuccess(email);
- }
- }
-
- this.context.ICCIOHelper.loadLinearFixedEF({
- fileId: fileId,
- recordNumber: recordNumber,
- recordSize: this._emailRecordSize,
- callback: callback.bind(this),
- onerror: onerror
- });
- },
-
- /**
- * Update USIM/RUIM Phonebook EF_EMAIL.
- *
- * @see TS 131.102, clause 4.4.2.13
- *
- * @param pbr Phonebook Reference File.
- * @param recordNumber The identifier of the record shall be updated.
- * @param email The value to be written.
- * @param adnRecordId The record Id of ADN, only needed if the fileType of Email is TYPE2.
- * @param onsuccess Callback to be called when success.
- * @param onerror Callback to be called when error.
- */
- updateEmail: function(pbr, recordNumber, email, adnRecordId, onsuccess, onerror) {
- let fileId = pbr[USIM_PBR_EMAIL].fileId;
- let fileType = pbr[USIM_PBR_EMAIL].fileType;
- let writtenEmail;
- let dataWriter = function dataWriter(recordSize) {
- let Buf = this.context.Buf;
- let GsmPDUHelper = this.context.GsmPDUHelper;
- let ICCPDUHelper = this.context.ICCPDUHelper;
-
- // Write String length
- let strLen = recordSize * 2;
- Buf.writeInt32(strLen);
-
- if (fileType == ICC_USIM_TYPE1_TAG) {
- writtenEmail = ICCPDUHelper.writeStringTo8BitUnpacked(recordSize, email);
- } else {
- writtenEmail = ICCPDUHelper.writeStringTo8BitUnpacked(recordSize - 2, email);
- GsmPDUHelper.writeHexOctet(pbr.adn.sfi || 0xff);
- GsmPDUHelper.writeHexOctet(adnRecordId);
- }
-
- Buf.writeStringDelimiter(strLen);
- }.bind(this);
-
- let callback = (options) => {
- if (onsuccess) {
- onsuccess(writtenEmail);
- }
- }
-
- this.context.ICCIOHelper.updateLinearFixedEF({
- fileId: fileId,
- recordNumber: recordNumber,
- dataWriter: dataWriter,
- callback: callback,
- onerror: onerror
- });
- },
-
- /**
- * Cache EF_ANR record size.
- */
- _anrRecordSize: null,
-
- /**
- * Read USIM/RUIM Phonebook EF_ANR.
- *
- * @see TS 131.102, clause 4.4.2.9
- *
- * @param fileId EF id of the ANR.
- * @param fileType One of the ICC_USIM_TYPE* constants.
- * @param recordNumber The number of the record shall be loaded.
- * @param onsuccess Callback to be called when success.
- * @param onerror Callback to be called when error.
- */
- readANR: function(fileId, fileType, recordNumber, onsuccess, onerror) {
- function callback(options) {
- let Buf = this.context.Buf;
- let strLen = Buf.readInt32();
- let number = null;
- this._anrRecordSize = options.recordSize;
-
- // Skip EF_AAS Record ID.
- Buf.seekIncoming(1 * Buf.PDU_HEX_OCTET_SIZE);
-
- number = this.context.ICCPDUHelper.readNumberWithLength();
-
- // Skip 2 unused octets, CCP and EXT1.
- Buf.seekIncoming(2 * Buf.PDU_HEX_OCTET_SIZE);
-
- // For Type 2 there are two extra octets.
- if (fileType == ICC_USIM_TYPE2_TAG) {
- // Skip 2 unused octets, ADN SFI and Record Identifier.
- Buf.seekIncoming(2 * Buf.PDU_HEX_OCTET_SIZE);
- }
-
- Buf.readStringDelimiter(strLen);
-
- if (onsuccess) {
- onsuccess(number);
- }
- }
-
- this.context.ICCIOHelper.loadLinearFixedEF({
- fileId: fileId,
- recordNumber: recordNumber,
- recordSize: this._anrRecordSize,
- callback: callback.bind(this),
- onerror: onerror
- });
- },
-
- /**
- * Update USIM/RUIM Phonebook EF_ANR.
- *
- * @see TS 131.102, clause 4.4.2.9
- *
- * @param pbr Phonebook Reference File.
- * @param recordNumber The identifier of the record shall be updated.
- * @param number The value to be written.
- * @param adnRecordId The record Id of ADN, only needed if the fileType of Email is TYPE2.
- * @param onsuccess Callback to be called when success.
- * @param onerror Callback to be called when error.
- */
- updateANR: function(pbr, recordNumber, number, adnRecordId, onsuccess, onerror) {
- let fileId = pbr[USIM_PBR_ANR0].fileId;
- let fileType = pbr[USIM_PBR_ANR0].fileType;
- let writtenNumber;
- let dataWriter = function dataWriter(recordSize) {
- let Buf = this.context.Buf;
- let GsmPDUHelper = this.context.GsmPDUHelper;
-
- // Write String length
- let strLen = recordSize * 2;
- Buf.writeInt32(strLen);
-
- // EF_AAS record Id. Unused for now.
- GsmPDUHelper.writeHexOctet(0xff);
-
- writtenNumber = this.context.ICCPDUHelper.writeNumberWithLength(number);
-
- // Write unused octets 0xff, CCP and EXT1.
- GsmPDUHelper.writeHexOctet(0xff);
- GsmPDUHelper.writeHexOctet(0xff);
-
- // For Type 2 there are two extra octets.
- if (fileType == ICC_USIM_TYPE2_TAG) {
- GsmPDUHelper.writeHexOctet(pbr.adn.sfi || 0xff);
- GsmPDUHelper.writeHexOctet(adnRecordId);
- }
-
- Buf.writeStringDelimiter(strLen);
- }.bind(this);
-
- let callback = (options) => {
- if (onsuccess) {
- onsuccess(writtenNumber);
- }
- }
-
- this.context.ICCIOHelper.updateLinearFixedEF({
- fileId: fileId,
- recordNumber: recordNumber,
- dataWriter: dataWriter,
- callback: callback,
- onerror: onerror
- });
- },
-
- /**
- * Cache the possible free record id for all files.
- */
- _freeRecordIds: null,
-
- /**
- * Find free record id.
- *
- * @param fileId EF id.
- * @param onsuccess Callback to be called when success.
- * @param onerror Callback to be called when error.
- */
- findFreeRecordId: function(fileId, onsuccess, onerror) {
- let ICCIOHelper = this.context.ICCIOHelper;
-
- function callback(options) {
- let Buf = this.context.Buf;
- let GsmPDUHelper = this.context.GsmPDUHelper;
-
- let strLen = Buf.readInt32();
- let octetLen = strLen / 2;
- let readLen = 0;
-
- while (readLen < octetLen) {
- let octet = GsmPDUHelper.readHexOctet();
- readLen++;
- if (octet != 0xff) {
- break;
- }
- }
-
- let nextRecord = (options.p1 % options.totalRecords) + 1;
-
- if (readLen == octetLen) {
- // Find free record, assume next record is probably free.
- this._freeRecordIds[fileId] = nextRecord;
- if (onsuccess) {
- onsuccess(options.p1);
- }
- return;
- } else {
- Buf.seekIncoming((octetLen - readLen) * Buf.PDU_HEX_OCTET_SIZE);
- }
-
- Buf.readStringDelimiter(strLen);
-
- if (nextRecord !== recordNumber) {
- options.p1 = nextRecord;
- this.context.RIL.iccIO(options);
- } else {
- // No free record found.
- delete this._freeRecordIds[fileId];
- if (DEBUG) {
- this.context.debug(CONTACT_ERR_NO_FREE_RECORD_FOUND);
- }
- onerror(CONTACT_ERR_NO_FREE_RECORD_FOUND);
- }
- }
-
- // Start searching free records from the possible one.
- let recordNumber = this._freeRecordIds[fileId] || 1;
- ICCIOHelper.loadLinearFixedEF({fileId: fileId,
- recordNumber: recordNumber,
- callback: callback.bind(this),
- onerror: onerror});
- },
-
- /**
- * Read Extension Number from TS 151.011 clause 10.5.10, TS 31.102, clause 4.4.2.4
- *
- * @param fileId EF Extension id
- * @param recordNumber The number of the record shall be loaded.
- * @param onsuccess Callback to be called when success.
- * @param onerror Callback to be called when error.
- */
- readExtension: function(fileId, recordNumber, onsuccess, onerror) {
- let callback = (options) => {
- let Buf = this.context.Buf;
- let length = Buf.readInt32();
- let recordType = this.context.GsmPDUHelper.readHexOctet();
- let number = "";
-
- // TS 31.102, clause 4.4.2.4 EFEXT1
- // Case 1, Extension1 record is additional data
- if (recordType & 0x02) {
- let numLen = this.context.GsmPDUHelper.readHexOctet();
- if (numLen != 0xff) {
- if (numLen > EXT_MAX_BCD_NUMBER_BYTES) {
- if (DEBUG) {
- this.context.debug(
- "Error: invalid length of BCD number/SSC contents - " + numLen);
- }
- // +1 to skip Identifier
- Buf.seekIncoming((EXT_MAX_BCD_NUMBER_BYTES + 1) * Buf.PDU_HEX_OCTET_SIZE);
- Buf.readStringDelimiter(length);
- onerror();
- return;
- }
-
- number = this.context.GsmPDUHelper.readSwappedNibbleExtendedBcdString(numLen);
- if (DEBUG) this.context.debug("Contact Extension Number: "+ number);
- Buf.seekIncoming((EXT_MAX_BCD_NUMBER_BYTES - numLen) * Buf.PDU_HEX_OCTET_SIZE);
- } else {
- Buf.seekIncoming(EXT_MAX_BCD_NUMBER_BYTES * Buf.PDU_HEX_OCTET_SIZE);
- }
- } else {
- // Don't support Case 2, Extension1 record is Called Party Subaddress.
- // +1 skip numLen
- Buf.seekIncoming((EXT_MAX_BCD_NUMBER_BYTES + 1) * Buf.PDU_HEX_OCTET_SIZE);
- }
-
- // Skip Identifier
- Buf.seekIncoming(Buf.PDU_HEX_OCTET_SIZE);
- Buf.readStringDelimiter(length);
- onsuccess(number);
- }
-
- this.context.ICCIOHelper.loadLinearFixedEF({
- fileId: fileId,
- recordNumber: recordNumber,
- callback: callback,
- onerror: onerror
- });
- },
-
- /**
- * Update Extension.
- *
- * @param fileId EF id of the EXT.
- * @param recordNumber The number of the record shall be updated.
- * @param number Dialling Number to be written.
- * @param onsuccess Callback to be called when success.
- * @param onerror Callback to be called when error.
- */
- updateExtension: function(fileId, recordNumber, number, onsuccess, onerror) {
- let dataWriter = (recordSize) => {
- let GsmPDUHelper = this.context.GsmPDUHelper;
- // Write String length
- let strLen = recordSize * 2;
- let Buf = this.context.Buf;
- Buf.writeInt32(strLen);
-
- // We don't support extension chain.
- if (number.length > EXT_MAX_NUMBER_DIGITS) {
- number = number.substring(0, EXT_MAX_NUMBER_DIGITS);
- }
-
- let numLen = Math.ceil(number.length / 2);
- // Write Extension record
- GsmPDUHelper.writeHexOctet(0x02);
- GsmPDUHelper.writeHexOctet(numLen);
- GsmPDUHelper.writeSwappedNibbleBCD(number);
- // Write trailing 0xff of Extension data.
- for (let i = 0; i < EXT_MAX_BCD_NUMBER_BYTES - numLen; i++) {
- GsmPDUHelper.writeHexOctet(0xff);
- }
- // Write trailing 0xff for Identifier.
- GsmPDUHelper.writeHexOctet(0xff);
- Buf.writeStringDelimiter(strLen);
- };
-
- this.context.ICCIOHelper.updateLinearFixedEF({
- fileId: fileId,
- recordNumber: recordNumber,
- dataWriter: dataWriter,
- callback: onsuccess,
- onerror: onerror
- });
- },
-
- /**
- * Clean an EF record.
- *
- * @param fileId EF id.
- * @param recordNumber The number of the record shall be updated.
- * @param onsuccess Callback to be called when success.
- * @param onerror Callback to be called when error.
- */
- cleanEFRecord: function(fileId, recordNumber, onsuccess, onerror) {
- let dataWriter = (recordSize) => {
- let GsmPDUHelper = this.context.GsmPDUHelper;
- let Buf = this.context.Buf;
- // Write String length
- let strLen = recordSize * 2;
-
- Buf.writeInt32(strLen);
- // Write record to 0xff
- for (let i = 0; i < recordSize; i++) {
- GsmPDUHelper.writeHexOctet(0xff);
- }
- Buf.writeStringDelimiter(strLen);
- }
-
- this.context.ICCIOHelper.updateLinearFixedEF({
- fileId: fileId,
- recordNumber: recordNumber,
- dataWriter: dataWriter,
- callback: onsuccess,
- onerror: onerror
- });
- },
-
- /**
- * Get ADNLike extension record number.
- *
- * @param fileId EF id of the ADN or FDN.
- * @param recordNumber EF record id of the ADN or FDN.
- * @param onsuccess Callback to be called when success.
- * @param onerror Callback to be called when error.
- */
- getADNLikeExtensionRecordNumber: function(fileId, recordNumber, onsuccess, onerror) {
- let callback = (options) => {
- let Buf = this.context.Buf;
- let length = Buf.readInt32();
-
- // Skip alphaLen, numLen, BCD Number, CCP octets.
- Buf.seekIncoming((options.recordSize -1) * Buf.PDU_HEX_OCTET_SIZE);
-
- let extRecordNumber = this.context.GsmPDUHelper.readHexOctet();
- Buf.readStringDelimiter(length);
-
- onsuccess(extRecordNumber);
- }
-
- this.context.ICCIOHelper.loadLinearFixedEF({
- fileId: fileId,
- recordNumber: recordNumber,
- callback: callback,
- onerror: onerror
- });
- },
-};
-
-/**
- * Helper for (U)SIM Records.
- */
-function SimRecordHelperObject(aContext) {
- this.context = aContext;
-}
-SimRecordHelperObject.prototype = {
- context: null,
-
- /**
- * Fetch (U)SIM records.
- */
- fetchSimRecords: function() {
- this.context.RIL.getIMSI();
- this.readAD();
- // CPHS was widely introduced in Europe during GSM(2G) era to provide easier
- // access to carrier's core service like voicemail, call forwarding, manual
- // PLMN selection, and etc.
- // Addition EF like EF_CPHS_MBN, EF_CPHS_CPHS_CFF, EF_CPHS_VWI, etc are
- // introduced to support these feature.
- // In USIM, the replancement of these EFs are provided. (EF_MBDN, EF_MWIS, ...)
- // However, some carriers in Europe still rely on these EFs.
- this.readCphsInfo(() => this.readSST(),
- (aErrorMsg) => {
- this.context.debug("Failed to read CPHS_INFO: " + aErrorMsg);
- this.readSST();
- });
- },
-
- /**
- * Read EF_phase.
- * This EF is only available in SIM.
- */
- readSimPhase: function() {
- function callback() {
- let Buf = this.context.Buf;
- let strLen = Buf.readInt32();
-
- let GsmPDUHelper = this.context.GsmPDUHelper;
- let phase = GsmPDUHelper.readHexOctet();
- // If EF_phase is coded '03' or greater, an ME supporting STK shall
- // perform the PROFILE DOWNLOAD procedure.
- if (RILQUIRKS_SEND_STK_PROFILE_DOWNLOAD &&
- phase >= ICC_PHASE_2_PROFILE_DOWNLOAD_REQUIRED) {
- this.context.RIL.sendStkTerminalProfile(STK_SUPPORTED_TERMINAL_PROFILE);
- }
-
- Buf.readStringDelimiter(strLen);
- }
-
- this.context.ICCIOHelper.loadTransparentEF({
- fileId: ICC_EF_PHASE,
- callback: callback.bind(this)
- });
- },
-
- /**
- * Read the MSISDN from the (U)SIM.
- */
- readMSISDN: function() {
- function callback(options) {
- let RIL = this.context.RIL;
-
- let contact =
- this.context.ICCPDUHelper.readAlphaIdDiallingNumber(options.recordSize);
- if (!contact ||
- (RIL.iccInfo.msisdn !== undefined &&
- RIL.iccInfo.msisdn === contact.number)) {
- return;
- }
- RIL.iccInfo.msisdn = contact.number;
- if (DEBUG) this.context.debug("MSISDN: " + RIL.iccInfo.msisdn);
- this.context.ICCUtilsHelper.handleICCInfoChange();
- }
-
- this.context.ICCIOHelper.loadLinearFixedEF({
- fileId: ICC_EF_MSISDN,
- callback: callback.bind(this)
- });
- },
-
- /**
- * Read the AD (Administrative Data) from the (U)SIM.
- */
- readAD: function() {
- function callback() {
- let Buf = this.context.Buf;
- let strLen = Buf.readInt32();
- // Each octet is encoded into two chars.
- let octetLen = strLen / 2;
- let ad = this.context.GsmPDUHelper.readHexOctetArray(octetLen);
- Buf.readStringDelimiter(strLen);
-
- if (DEBUG) {
- let str = "";
- for (let i = 0; i < ad.length; i++) {
- str += ad[i] + ", ";
- }
- this.context.debug("AD: " + str);
- }
-
- let ICCUtilsHelper = this.context.ICCUtilsHelper;
- let RIL = this.context.RIL;
- // TS 31.102, clause 4.2.18 EFAD
- let mncLength = 0;
- if (ad && ad[3]) {
- mncLength = ad[3] & 0x0f;
- if (mncLength != 0x02 && mncLength != 0x03) {
- mncLength = 0;
- }
- }
- // The 4th byte of the response is the length of MNC.
- let mccMnc = ICCUtilsHelper.parseMccMncFromImsi(RIL.iccInfoPrivate.imsi,
- mncLength);
- if (mccMnc) {
- RIL.iccInfo.mcc = mccMnc.mcc;
- RIL.iccInfo.mnc = mccMnc.mnc;
- ICCUtilsHelper.handleICCInfoChange();
- }
- }
-
- this.context.ICCIOHelper.loadTransparentEF({
- fileId: ICC_EF_AD,
- callback: callback.bind(this)
- });
- },
-
- /**
- * Read the SPN (Service Provider Name) from the (U)SIM.
- */
- readSPN: function() {
- function callback() {
- let Buf = this.context.Buf;
- let strLen = Buf.readInt32();
- // Each octet is encoded into two chars.
- let octetLen = strLen / 2;
- let spnDisplayCondition = this.context.GsmPDUHelper.readHexOctet();
- // Minus 1 because the first octet is used to store display condition.
- let spn = this.context.ICCPDUHelper.readAlphaIdentifier(octetLen - 1);
- Buf.readStringDelimiter(strLen);
-
- if (DEBUG) {
- this.context.debug("SPN: spn = " + spn +
- ", spnDisplayCondition = " + spnDisplayCondition);
- }
-
- let RIL = this.context.RIL;
- RIL.iccInfoPrivate.spnDisplayCondition = spnDisplayCondition;
- RIL.iccInfo.spn = spn;
- let ICCUtilsHelper = this.context.ICCUtilsHelper;
- ICCUtilsHelper.updateDisplayCondition();
- ICCUtilsHelper.handleICCInfoChange();
- }
-
- this.context.ICCIOHelper.loadTransparentEF({
- fileId: ICC_EF_SPN,
- callback: callback.bind(this)
- });
- },
-
- readIMG: function(recordNumber, onsuccess, onerror) {
- function callback(options) {
- let RIL = this.context.RIL;
- let Buf = this.context.Buf;
- let GsmPDUHelper = this.context.GsmPDUHelper;
- let strLen = Buf.readInt32();
- // Each octet is encoded into two chars.
- let octetLen = strLen / 2;
-
- let numInstances = GsmPDUHelper.readHexOctet();
-
- // Data length is defined as 9n+1 or 9n+2. See TS 31.102, sub-clause
- // 4.6.1.1. However, it's likely to have padding appended so we have a
- // rather loose check.
- if (octetLen < (9 * numInstances + 1)) {
- Buf.seekIncoming((octetLen - 1) * Buf.PDU_HEX_OCTET_SIZE);
- Buf.readStringDelimiter(strLen);
- if (onerror) {
- onerror();
- }
- return;
- }
-
- let imgDescriptors = [];
- for (let i = 0; i < numInstances; i++) {
- imgDescriptors[i] = {
- width: GsmPDUHelper.readHexOctet(),
- height: GsmPDUHelper.readHexOctet(),
- codingScheme: GsmPDUHelper.readHexOctet(),
- fileId: (GsmPDUHelper.readHexOctet() << 8) |
- GsmPDUHelper.readHexOctet(),
- offset: (GsmPDUHelper.readHexOctet() << 8) |
- GsmPDUHelper.readHexOctet(),
- dataLen: (GsmPDUHelper.readHexOctet() << 8) |
- GsmPDUHelper.readHexOctet()
- };
- }
- Buf.seekIncoming((octetLen - 9 * numInstances - 1) * Buf.PDU_HEX_OCTET_SIZE);
- Buf.readStringDelimiter(strLen);
-
- let instances = [];
- let currentInstance = 0;
- let readNextInstance = (function(img) {
- instances[currentInstance] = img;
- currentInstance++;
-
- if (currentInstance < numInstances) {
- let imgDescriptor = imgDescriptors[currentInstance];
- this.readIIDF(imgDescriptor.fileId,
- imgDescriptor.offset,
- imgDescriptor.dataLen,
- imgDescriptor.codingScheme,
- readNextInstance,
- onerror);
- } else {
- if (onsuccess) {
- onsuccess(instances);
- }
- }
- }).bind(this);
-
- this.readIIDF(imgDescriptors[0].fileId,
- imgDescriptors[0].offset,
- imgDescriptors[0].dataLen,
- imgDescriptors[0].codingScheme,
- readNextInstance,
- onerror);
- }
-
- this.context.ICCIOHelper.loadLinearFixedEF({
- fileId: ICC_EF_IMG,
- recordNumber: recordNumber,
- callback: callback.bind(this),
- onerror: onerror
- });
- },
-
- readIIDF: function(fileId, offset, dataLen, codingScheme, onsuccess, onerror) {
- // Valid fileId is '4FXX', see TS 31.102, clause 4.6.1.2.
- if ((fileId >> 8) != 0x4F) {
- if (onerror) {
- onerror();
- }
- return;
- }
-
- function callback() {
- let Buf = this.context.Buf;
- let RIL = this.context.RIL;
- let GsmPDUHelper = this.context.GsmPDUHelper;
- let strLen = Buf.readInt32();
- // Each octet is encoded into two chars.
- let octetLen = strLen / 2;
-
- if (octetLen < offset + dataLen) {
- // Data length is not enough. See TS 31.102, clause 4.6.1.1, the
- // paragraph "Bytes 8 and 9: Length of Image Instance Data."
- Buf.seekIncoming(octetLen * Buf.PDU_HEX_OCTET_SIZE);
- Buf.readStringDelimiter(strLen);
- if (onerror) {
- onerror();
- }
- return;
- }
-
- Buf.seekIncoming(offset * Buf.PDU_HEX_OCTET_SIZE);
-
- let rawData = {
- width: GsmPDUHelper.readHexOctet(),
- height: GsmPDUHelper.readHexOctet(),
- codingScheme: codingScheme
- };
-
- switch (codingScheme) {
- case ICC_IMG_CODING_SCHEME_BASIC:
- rawData.body = GsmPDUHelper.readHexOctetArray(
- dataLen - ICC_IMG_HEADER_SIZE_BASIC);
- Buf.seekIncoming((octetLen - offset - dataLen) * Buf.PDU_HEX_OCTET_SIZE);
- break;
-
- case ICC_IMG_CODING_SCHEME_COLOR:
- case ICC_IMG_CODING_SCHEME_COLOR_TRANSPARENCY:
- rawData.bitsPerImgPoint = GsmPDUHelper.readHexOctet();
- let num = GsmPDUHelper.readHexOctet();
- // The value 0 shall be interpreted as 256. See TS 31.102, Annex B.2.
- rawData.numOfClutEntries = (num === 0) ? 0x100 : num;
- rawData.clutOffset = (GsmPDUHelper.readHexOctet() << 8) |
- GsmPDUHelper.readHexOctet();
- rawData.body = GsmPDUHelper.readHexOctetArray(
- dataLen - ICC_IMG_HEADER_SIZE_COLOR);
-
- Buf.seekIncoming((rawData.clutOffset - offset - dataLen) *
- Buf.PDU_HEX_OCTET_SIZE);
- let clut = GsmPDUHelper.readHexOctetArray(rawData.numOfClutEntries *
- ICC_CLUT_ENTRY_SIZE);
-
- rawData.clut = clut;
- }
-
- Buf.readStringDelimiter(strLen);
-
- if (onsuccess) {
- onsuccess(rawData);
- }
- }
-
- this.context.ICCIOHelper.loadTransparentEF({
- fileId: fileId,
- pathId: this.context.ICCFileHelper.getEFPath(ICC_EF_IMG),
- callback: callback.bind(this),
- onerror: onerror
- });
- },
-
- /**
- * Read the (U)SIM Service Table from the (U)SIM.
- */
- readSST: function() {
- function callback() {
- let Buf = this.context.Buf;
- let RIL = this.context.RIL;
-
- let strLen = Buf.readInt32();
- // Each octet is encoded into two chars.
- let octetLen = strLen / 2;
- let sst = this.context.GsmPDUHelper.readHexOctetArray(octetLen);
- Buf.readStringDelimiter(strLen);
- RIL.iccInfoPrivate.sst = sst;
- if (DEBUG) {
- let str = "";
- for (let i = 0; i < sst.length; i++) {
- str += sst[i] + ", ";
- }
- this.context.debug("SST: " + str);
- }
-
- let ICCUtilsHelper = this.context.ICCUtilsHelper;
- if (ICCUtilsHelper.isICCServiceAvailable("MSISDN")) {
- if (DEBUG) this.context.debug("MSISDN: MSISDN is available");
- this.readMSISDN();
- } else {
- if (DEBUG) this.context.debug("MSISDN: MSISDN service is not available");
- }
-
- // Fetch SPN and PLMN list, if some of them are available.
- if (ICCUtilsHelper.isICCServiceAvailable("SPN")) {
- if (DEBUG) this.context.debug("SPN: SPN is available");
- this.readSPN();
- } else {
- if (DEBUG) this.context.debug("SPN: SPN service is not available");
- }
-
- if (ICCUtilsHelper.isICCServiceAvailable("MDN")) {
- if (DEBUG) this.context.debug("MDN: MDN available.");
- this.readMBDN();
- } else {
- if (DEBUG) this.context.debug("MDN: MDN service is not available");
-
- if (ICCUtilsHelper.isCphsServiceAvailable("MBN")) {
- // read CPHS_MBN in advance if MBDN is not available.
- this.readCphsMBN();
- } else {
- if (DEBUG) this.context.debug("CPHS_MBN: CPHS_MBN service is not available");
- }
- }
-
- if (ICCUtilsHelper.isICCServiceAvailable("MWIS")) {
- if (DEBUG) this.context.debug("MWIS: MWIS is available");
- this.readMWIS();
- } else {
- if (DEBUG) this.context.debug("MWIS: MWIS is not available");
- }
-
- if (ICCUtilsHelper.isICCServiceAvailable("SPDI")) {
- if (DEBUG) this.context.debug("SPDI: SPDI available.");
- this.readSPDI();
- } else {
- if (DEBUG) this.context.debug("SPDI: SPDI service is not available");
- }
-
- if (ICCUtilsHelper.isICCServiceAvailable("PNN")) {
- if (DEBUG) this.context.debug("PNN: PNN is available");
- this.readPNN();
- } else {
- if (DEBUG) this.context.debug("PNN: PNN is not available");
- }
-
- if (ICCUtilsHelper.isICCServiceAvailable("OPL")) {
- if (DEBUG) this.context.debug("OPL: OPL is available");
- this.readOPL();
- } else {
- if (DEBUG) this.context.debug("OPL: OPL is not available");
- }
-
- if (ICCUtilsHelper.isICCServiceAvailable("GID1")) {
- if (DEBUG) this.context.debug("GID1: GID1 is available");
- this.readGID1();
- } else {
- if (DEBUG) this.context.debug("GID1: GID1 is not available");
- }
-
- if (ICCUtilsHelper.isICCServiceAvailable("CBMI")) {
- this.readCBMI();
- } else {
- RIL.cellBroadcastConfigs.CBMI = null;
- }
- if (ICCUtilsHelper.isICCServiceAvailable("DATA_DOWNLOAD_SMS_CB")) {
- this.readCBMID();
- } else {
- RIL.cellBroadcastConfigs.CBMID = null;
- }
- if (ICCUtilsHelper.isICCServiceAvailable("CBMIR")) {
- this.readCBMIR();
- } else {
- RIL.cellBroadcastConfigs.CBMIR = null;
- }
- RIL._mergeAllCellBroadcastConfigs();
- }
-
- // ICC_EF_UST has the same value with ICC_EF_SST.
- this.context.ICCIOHelper.loadTransparentEF({
- fileId: ICC_EF_SST,
- callback: callback.bind(this)
- });
- },
-
- /**
- * Read (U)SIM MBDN. (Mailbox Dialling Number)
- *
- * @see TS 131.102, clause 4.2.60
- */
- readMBDN: function() {
- function callback(options) {
- let RIL = this.context.RIL;
- let contact =
- this.context.ICCPDUHelper.readAlphaIdDiallingNumber(options.recordSize);
- if ((!contact ||
- ((!contact.alphaId || contact.alphaId == "") &&
- (!contact.number || contact.number == ""))) &&
- this.context.ICCUtilsHelper.isCphsServiceAvailable("MBN")) {
- // read CPHS_MBN in advance if MBDN is invalid or empty.
- this.readCphsMBN();
- return;
- }
-
- if (!contact ||
- (RIL.iccInfoPrivate.mbdn !== undefined &&
- RIL.iccInfoPrivate.mbdn === contact.number)) {
- return;
- }
- RIL.iccInfoPrivate.mbdn = contact.number;
- if (DEBUG) {
- this.context.debug("MBDN, alphaId=" + contact.alphaId +
- " number=" + contact.number);
- }
- contact.rilMessageType = "iccmbdn";
- RIL.sendChromeMessage(contact);
- }
-
- this.context.ICCIOHelper.loadLinearFixedEF({
- fileId: ICC_EF_MBDN,
- callback: callback.bind(this)
- });
- },
-
- /**
- * Read ICC MWIS. (Message Waiting Indication Status)
- *
- * @see TS 31.102, clause 4.2.63 for USIM and TS 51.011, clause 10.3.45 for SIM.
- */
- readMWIS: function() {
- function callback(options) {
- let Buf = this.context.Buf;
- let RIL = this.context.RIL;
-
- let strLen = Buf.readInt32();
- // Each octet is encoded into two chars.
- let octetLen = strLen / 2;
- let mwis = this.context.GsmPDUHelper.readHexOctetArray(octetLen);
- Buf.readStringDelimiter(strLen);
- if (!mwis) {
- return;
- }
- RIL.iccInfoPrivate.mwis = mwis; //Keep raw MWIS for updateMWIS()
-
- let mwi = {};
- // b8 b7 B6 b5 b4 b3 b2 b1 4.2.63, TS 31.102 version 11.6.0
- // | | | | | | | |__ Voicemail
- // | | | | | | |_____ Fax
- // | | | | | |________ Electronic Mail
- // | | | | |___________ Other
- // | | | |______________ Videomail
- // |__|__|_________________ RFU
- mwi.active = ((mwis[0] & 0x01) != 0);
-
- if (mwi.active) {
- // In TS 23.040 msgCount is in the range from 0 to 255.
- // The value 255 shall be taken to mean 255 or greater.
- //
- // However, There is no definition about 0 when MWI is active.
- //
- // Normally, when mwi is active, the msgCount must be larger than 0.
- // Refer to other reference phone,
- // 0 is usually treated as UNKNOWN for storing 2nd level MWI status (DCS).
- mwi.msgCount = (mwis[1] === 0) ? GECKO_VOICEMAIL_MESSAGE_COUNT_UNKNOWN
- : mwis[1];
- } else {
- mwi.msgCount = 0;
- }
-
- RIL.sendChromeMessage({ rilMessageType: "iccmwis",
- mwi: mwi });
- }
-
- this.context.ICCIOHelper.loadLinearFixedEF({
- fileId: ICC_EF_MWIS,
- recordNumber: 1, // Get 1st Subscriber Profile.
- callback: callback.bind(this)
- });
- },
-
- /**
- * Update ICC MWIS. (Message Waiting Indication Status)
- *
- * @see TS 31.102, clause 4.2.63 for USIM and TS 51.011, clause 10.3.45 for SIM.
- */
- updateMWIS: function(mwi) {
- let RIL = this.context.RIL;
- if (!RIL.iccInfoPrivate.mwis) {
- return;
- }
-
- function dataWriter(recordSize) {
- let mwis = RIL.iccInfoPrivate.mwis;
-
- let msgCount =
- (mwi.msgCount === GECKO_VOICEMAIL_MESSAGE_COUNT_UNKNOWN) ? 0 : mwi.msgCount;
-
- [mwis[0], mwis[1]] = (mwi.active) ? [(mwis[0] | 0x01), msgCount]
- : [(mwis[0] & 0xFE), 0];
-
- let strLen = recordSize * 2;
- let Buf = this.context.Buf;
- Buf.writeInt32(strLen);
-
- let GsmPDUHelper = this.context.GsmPDUHelper;
- for (let i = 0; i < mwis.length; i++) {
- GsmPDUHelper.writeHexOctet(mwis[i]);
- }
-
- Buf.writeStringDelimiter(strLen);
- }
-
- this.context.ICCIOHelper.updateLinearFixedEF({
- fileId: ICC_EF_MWIS,
- recordNumber: 1, // Update 1st Subscriber Profile.
- dataWriter: dataWriter.bind(this)
- });
- },
-
- /**
- * Read the SPDI (Service Provider Display Information) from the (U)SIM.
- *
- * See TS 131.102 section 4.2.66 for USIM and TS 51.011 section 10.3.50
- * for SIM.
- */
- readSPDI: function() {
- function callback() {
- let Buf = this.context.Buf;
- let strLen = Buf.readInt32();
- let octetLen = strLen / 2;
- let readLen = 0;
- let endLoop = false;
-
- let RIL = this.context.RIL;
- RIL.iccInfoPrivate.SPDI = null;
-
- let GsmPDUHelper = this.context.GsmPDUHelper;
- while ((readLen < octetLen) && !endLoop) {
- let tlvTag = GsmPDUHelper.readHexOctet();
- let tlvLen = GsmPDUHelper.readHexOctet();
- readLen += 2; // For tag and length fields.
- switch (tlvTag) {
- case SPDI_TAG_SPDI:
- // The value part itself is a TLV.
- continue;
- case SPDI_TAG_PLMN_LIST:
- // This PLMN list is what we want.
- RIL.iccInfoPrivate.SPDI = this.readPLMNEntries(tlvLen / 3);
- readLen += tlvLen;
- endLoop = true;
- break;
- default:
- // We don't care about its content if its tag is not SPDI nor
- // PLMN_LIST.
- endLoop = true;
- break;
- }
- }
-
- // Consume unread octets.
- Buf.seekIncoming((octetLen - readLen) * Buf.PDU_HEX_OCTET_SIZE);
- Buf.readStringDelimiter(strLen);
-
- if (DEBUG) {
- this.context.debug("SPDI: " + JSON.stringify(RIL.iccInfoPrivate.SPDI));
- }
- let ICCUtilsHelper = this.context.ICCUtilsHelper;
- if (ICCUtilsHelper.updateDisplayCondition()) {
- ICCUtilsHelper.handleICCInfoChange();
- }
- }
-
- // PLMN List is Servive 51 in USIM, EF_SPDI
- this.context.ICCIOHelper.loadTransparentEF({
- fileId: ICC_EF_SPDI,
- callback: callback.bind(this)
- });
- },
-
- _readCbmiHelper: function(which) {
- let RIL = this.context.RIL;
-
- function callback() {
- let Buf = this.context.Buf;
- let strLength = Buf.readInt32();
-
- // Each Message Identifier takes two octets and each octet is encoded
- // into two chars.
- let numIds = strLength / 4, list = null;
- if (numIds) {
- list = [];
- let GsmPDUHelper = this.context.GsmPDUHelper;
- for (let i = 0, id; i < numIds; i++) {
- id = GsmPDUHelper.readHexOctet() << 8 | GsmPDUHelper.readHexOctet();
- // `Unused entries shall be set to 'FF FF'.`
- if (id != 0xFFFF) {
- list.push(id);
- list.push(id + 1);
- }
- }
- }
- if (DEBUG) {
- this.context.debug(which + ": " + JSON.stringify(list));
- }
-
- Buf.readStringDelimiter(strLength);
-
- RIL.cellBroadcastConfigs[which] = list;
- RIL._mergeAllCellBroadcastConfigs();
- }
-
- function onerror() {
- RIL.cellBroadcastConfigs[which] = null;
- RIL._mergeAllCellBroadcastConfigs();
- }
-
- let fileId = GLOBAL["ICC_EF_" + which];
- this.context.ICCIOHelper.loadTransparentEF({
- fileId: fileId,
- callback: callback.bind(this),
- onerror: onerror.bind(this)
- });
- },
-
- /**
- * Read EFcbmi (Cell Broadcast Message Identifier selection)
- *
- * @see 3GPP TS 31.102 v110.02.0 section 4.2.14 EFcbmi
- * @see 3GPP TS 51.011 v5.0.0 section 10.3.13 EFcbmi
- */
- readCBMI: function() {
- this._readCbmiHelper("CBMI");
- },
-
- /**
- * Read EFcbmid (Cell Broadcast Message Identifier for Data Download)
- *
- * @see 3GPP TS 31.102 v110.02.0 section 4.2.20 EFcbmid
- * @see 3GPP TS 51.011 v5.0.0 section 10.3.26 EFcbmid
- */
- readCBMID: function() {
- this._readCbmiHelper("CBMID");
- },
-
- /**
- * Read EFcbmir (Cell Broadcast Message Identifier Range selection)
- *
- * @see 3GPP TS 31.102 v110.02.0 section 4.2.22 EFcbmir
- * @see 3GPP TS 51.011 v5.0.0 section 10.3.28 EFcbmir
- */
- readCBMIR: function() {
- let RIL = this.context.RIL;
-
- function callback() {
- let Buf = this.context.Buf;
- let strLength = Buf.readInt32();
-
- // Each Message Identifier range takes four octets and each octet is
- // encoded into two chars.
- let numIds = strLength / 8, list = null;
- if (numIds) {
- list = [];
- let GsmPDUHelper = this.context.GsmPDUHelper;
- for (let i = 0, from, to; i < numIds; i++) {
- // `Bytes one and two of each range identifier equal the lower value
- // of a cell broadcast range, bytes three and four equal the upper
- // value of a cell broadcast range.`
- from = GsmPDUHelper.readHexOctet() << 8 | GsmPDUHelper.readHexOctet();
- to = GsmPDUHelper.readHexOctet() << 8 | GsmPDUHelper.readHexOctet();
- // `Unused entries shall be set to 'FF FF'.`
- if ((from != 0xFFFF) && (to != 0xFFFF)) {
- list.push(from);
- list.push(to + 1);
- }
- }
- }
- if (DEBUG) {
- this.context.debug("CBMIR: " + JSON.stringify(list));
- }
-
- Buf.readStringDelimiter(strLength);
-
- RIL.cellBroadcastConfigs.CBMIR = list;
- RIL._mergeAllCellBroadcastConfigs();
- }
-
- function onerror() {
- RIL.cellBroadcastConfigs.CBMIR = null;
- RIL._mergeAllCellBroadcastConfigs();
- }
-
- this.context.ICCIOHelper.loadTransparentEF({
- fileId: ICC_EF_CBMIR,
- callback: callback.bind(this),
- onerror: onerror.bind(this)
- });
- },
-
- /**
- * Read OPL (Operator PLMN List) from (U)SIM.
- *
- * See 3GPP TS 31.102 Sec. 4.2.59 for USIM
- * 3GPP TS 51.011 Sec. 10.3.42 for SIM.
- */
- readOPL: function() {
- let ICCIOHelper = this.context.ICCIOHelper;
- let opl = [];
- function callback(options) {
- let Buf = this.context.Buf;
- let GsmPDUHelper = this.context.GsmPDUHelper;
-
- let strLen = Buf.readInt32();
- // The first 7 bytes are LAI (for UMTS) and the format of LAI is defined
- // in 3GPP TS 23.003, Sec 4.1
- // +-------------+---------+
- // | Octet 1 - 3 | MCC/MNC |
- // +-------------+---------+
- // | Octet 4 - 7 | LAC |
- // +-------------+---------+
- let mccMnc = [GsmPDUHelper.readHexOctet(),
- GsmPDUHelper.readHexOctet(),
- GsmPDUHelper.readHexOctet()];
- if (mccMnc[0] != 0xFF || mccMnc[1] != 0xFF || mccMnc[2] != 0xFF) {
- let oplElement = {};
- let semiOctets = [];
- for (let i = 0; i < mccMnc.length; i++) {
- semiOctets.push((mccMnc[i] & 0xf0) >> 4);
- semiOctets.push(mccMnc[i] & 0x0f);
- }
- let reformat = [semiOctets[1], semiOctets[0], semiOctets[3],
- semiOctets[5], semiOctets[4], semiOctets[2]];
- let buf = "";
- for (let i = 0; i < reformat.length; i++) {
- if (reformat[i] != 0xF) {
- buf += GsmPDUHelper.semiOctetToExtendedBcdChar(reformat[i]);
- }
- if (i === 2) {
- // 0-2: MCC
- oplElement.mcc = buf;
- buf = "";
- } else if (i === 5) {
- // 3-5: MNC
- oplElement.mnc = buf;
- }
- }
- // LAC/TAC
- oplElement.lacTacStart =
- (GsmPDUHelper.readHexOctet() << 8) | GsmPDUHelper.readHexOctet();
- oplElement.lacTacEnd =
- (GsmPDUHelper.readHexOctet() << 8) | GsmPDUHelper.readHexOctet();
- // PLMN Network Name Record Identifier
- oplElement.pnnRecordId = GsmPDUHelper.readHexOctet();
- if (DEBUG) {
- this.context.debug("OPL: [" + (opl.length + 1) + "]: " +
- JSON.stringify(oplElement));
- }
- opl.push(oplElement);
- } else {
- Buf.seekIncoming(5 * Buf.PDU_HEX_OCTET_SIZE);
- }
- Buf.readStringDelimiter(strLen);
-
- let RIL = this.context.RIL;
- if (options.p1 < options.totalRecords) {
- ICCIOHelper.loadNextRecord(options);
- } else {
- RIL.iccInfoPrivate.OPL = opl;
- RIL.overrideICCNetworkName();
- }
- }
-
- ICCIOHelper.loadLinearFixedEF({fileId: ICC_EF_OPL,
- callback: callback.bind(this)});
- },
-
- /**
- * Read PNN (PLMN Network Name) from (U)SIM.
- *
- * See 3GPP TS 31.102 Sec. 4.2.58 for USIM
- * 3GPP TS 51.011 Sec. 10.3.41 for SIM.
- */
- readPNN: function() {
- let ICCIOHelper = this.context.ICCIOHelper;
- function callback(options) {
- let pnnElement;
- let Buf = this.context.Buf;
- let strLen = Buf.readInt32();
- let octetLen = strLen / 2;
- let readLen = 0;
-
- let GsmPDUHelper = this.context.GsmPDUHelper;
- while (readLen < octetLen) {
- let tlvTag = GsmPDUHelper.readHexOctet();
-
- if (tlvTag == 0xFF) {
- // Unused byte
- readLen++;
- Buf.seekIncoming((octetLen - readLen) * Buf.PDU_HEX_OCTET_SIZE);
- break;
- }
-
- // Needs this check to avoid initializing twice.
- pnnElement = pnnElement || {};
-
- let tlvLen = GsmPDUHelper.readHexOctet();
-
- switch (tlvTag) {
- case PNN_IEI_FULL_NETWORK_NAME:
- pnnElement.fullName = GsmPDUHelper.readNetworkName(tlvLen);
- break;
- case PNN_IEI_SHORT_NETWORK_NAME:
- pnnElement.shortName = GsmPDUHelper.readNetworkName(tlvLen);
- break;
- default:
- Buf.seekIncoming(tlvLen * Buf.PDU_HEX_OCTET_SIZE);
- break;
- }
-
- readLen += (tlvLen + 2); // +2 for tlvTag and tlvLen
- }
- Buf.readStringDelimiter(strLen);
-
- pnn.push(pnnElement);
-
- let RIL = this.context.RIL;
- if (options.p1 < options.totalRecords) {
- ICCIOHelper.loadNextRecord(options);
- } else {
- if (DEBUG) {
- for (let i = 0; i < pnn.length; i++) {
- this.context.debug("PNN: [" + i + "]: " + JSON.stringify(pnn[i]));
- }
- }
- RIL.iccInfoPrivate.PNN = pnn;
- RIL.overrideICCNetworkName();
- }
- }
-
- let pnn = [];
- ICCIOHelper.loadLinearFixedEF({fileId: ICC_EF_PNN,
- callback: callback.bind(this)});
- },
-
- /**
- * Read the list of PLMN (Public Land Mobile Network) entries
- * We cannot directly rely on readSwappedNibbleBcdToString(),
- * since it will no correctly handle some corner-cases that are
- * not a problem in our case (0xFF 0xFF 0xFF).
- *
- * @param length The number of PLMN records.
- * @return An array of string corresponding to the PLMNs.
- */
- readPLMNEntries: function(length) {
- let plmnList = [];
- // Each PLMN entry has 3 bytes.
- if (DEBUG) {
- this.context.debug("PLMN entries length = " + length);
- }
- let GsmPDUHelper = this.context.GsmPDUHelper;
- let index = 0;
- while (index < length) {
- // Unused entries will be 0xFFFFFF, according to EF_SPDI
- // specs (TS 131 102, section 4.2.66)
- try {
- let plmn = [GsmPDUHelper.readHexOctet(),
- GsmPDUHelper.readHexOctet(),
- GsmPDUHelper.readHexOctet()];
- if (DEBUG) {
- this.context.debug("Reading PLMN entry: [" + index + "]: '" + plmn + "'");
- }
- if (plmn[0] != 0xFF &&
- plmn[1] != 0xFF &&
- plmn[2] != 0xFF) {
- let semiOctets = [];
- for (let idx = 0; idx < plmn.length; idx++) {
- semiOctets.push((plmn[idx] & 0xF0) >> 4);
- semiOctets.push(plmn[idx] & 0x0F);
- }
-
- // According to TS 24.301, 9.9.3.12, the semi octets is arranged
- // in format:
- // Byte 1: MCC[2] | MCC[1]
- // Byte 2: MNC[3] | MCC[3]
- // Byte 3: MNC[2] | MNC[1]
- // Therefore, we need to rearrange them.
- let reformat = [semiOctets[1], semiOctets[0], semiOctets[3],
- semiOctets[5], semiOctets[4], semiOctets[2]];
- let buf = "";
- let plmnEntry = {};
- for (let i = 0; i < reformat.length; i++) {
- if (reformat[i] != 0xF) {
- buf += GsmPDUHelper.semiOctetToExtendedBcdChar(reformat[i]);
- }
- if (i === 2) {
- // 0-2: MCC
- plmnEntry.mcc = buf;
- buf = "";
- } else if (i === 5) {
- // 3-5: MNC
- plmnEntry.mnc = buf;
- }
- }
- if (DEBUG) {
- this.context.debug("PLMN = " + plmnEntry.mcc + ", " + plmnEntry.mnc);
- }
- plmnList.push(plmnEntry);
- }
- } catch (e) {
- if (DEBUG) {
- this.context.debug("PLMN entry " + index + " is invalid.");
- }
- break;
- }
- index ++;
- }
- return plmnList;
- },
-
- /**
- * Read the SMS from the ICC.
- *
- * @param recordNumber The number of the record shall be loaded.
- * @param onsuccess Callback to be called when success.
- * @param onerror Callback to be called when error.
- */
- readSMS: function(recordNumber, onsuccess, onerror) {
- function callback(options) {
- let Buf = this.context.Buf;
- let strLen = Buf.readInt32();
-
- // TS 51.011, 10.5.3 EF_SMS
- // b3 b2 b1
- // 0 0 1 message received by MS from network; message read
- // 0 1 1 message received by MS from network; message to be read
- // 1 1 1 MS originating message; message to be sent
- // 1 0 1 MS originating message; message sent to the network:
- let GsmPDUHelper = this.context.GsmPDUHelper;
- let status = GsmPDUHelper.readHexOctet();
-
- let message = GsmPDUHelper.readMessage();
- message.simStatus = status;
-
- // Consumes the remaining buffer
- Buf.seekIncoming(Buf.getReadAvailable() - Buf.PDU_HEX_OCTET_SIZE);
-
- Buf.readStringDelimiter(strLen);
-
- if (message) {
- onsuccess(message);
- } else {
- onerror("Failed to decode SMS on SIM #" + recordNumber);
- }
- }
-
- this.context.ICCIOHelper.loadLinearFixedEF({
- fileId: ICC_EF_SMS,
- recordNumber: recordNumber,
- callback: callback.bind(this),
- onerror: onerror
- });
- },
-
- readGID1: function() {
- function callback() {
- let Buf = this.context.Buf;
- let RIL = this.context.RIL;
-
- RIL.iccInfoPrivate.gid1 = Buf.readString();
- if (DEBUG) {
- this.context.debug("GID1: " + RIL.iccInfoPrivate.gid1);
- }
- }
-
- this.context.ICCIOHelper.loadTransparentEF({
- fileId: ICC_EF_GID1,
- callback: callback.bind(this)
- });
- },
-
- /**
- * Read CPHS Phase & Service Table from CPHS Info.
- *
- * @See B.3.1.1 CPHS Information in CPHS Phase 2.
- *
- * @param onsuccess Callback to be called when success.
- * @param onerror Callback to be called when error.
- */
- readCphsInfo: function(onsuccess, onerror) {
- function callback() {
- try {
- let Buf = this.context.Buf;
- let RIL = this.context.RIL;
-
- let strLen = Buf.readInt32();
- // Each octet is encoded into two chars.
- let octetLen = strLen / 2;
- let cphsInfo = this.context.GsmPDUHelper.readHexOctetArray(octetLen);
- Buf.readStringDelimiter(strLen);
- if (DEBUG) {
- let str = "";
- for (let i = 0; i < cphsInfo.length; i++) {
- str += cphsInfo[i] + ", ";
- }
- this.context.debug("CPHS INFO: " + str);
- }
-
- /**
- * CPHS INFORMATION
- *
- * Byte 1: CPHS Phase
- * 01 phase 1
- * 02 phase 2
- * etc.
- *
- * Byte 2: CPHS Service Table
- * +----+----+----+----+----+----+----+----+
- * | b8 | b7 | b6 | b5 | b4 | b3 | b2 | b1 |
- * +----+----+----+----+----+----+----+----+
- * | ONSF | MBN | SST | CSP |
- * | Phase 2 | ALL | Phase 1 | All |
- * +----+----+----+----+----+----+----+----+
- *
- * Byte 3: CPHS Service Table continued
- * +----+----+----+----+----+----+----+----+
- * | b8 | b7 | b6 | b5 | b4 | b3 | b2 | b1 |
- * +----+----+----+----+----+----+----+----+
- * | RFU | RFU | RFU | INFO_NUM|
- * | | | | Phase 2 |
- * +----+----+----+----+----+----+----+----+
- */
- let cphsPhase = cphsInfo[0];
- if (cphsPhase == 1) {
- // Clear 'Phase 2 only' services.
- cphsInfo[1] &= 0x3F;
- // We don't know whether Byte 3 is available in CPHS phase 1 or not.
- // Add boundary check before accessing it.
- if (cphsInfo.length > 2) {
- cphsInfo[2] = 0x00;
- }
- } else if (cphsPhase == 2) {
- // Clear 'Phase 1 only' services.
- cphsInfo[1] &= 0xF3;
- } else {
- throw new Error("Unknown CPHS phase: " + cphsPhase);
- }
-
- RIL.iccInfoPrivate.cphsSt = cphsInfo.subarray(1);
- onsuccess();
- } catch(e) {
- onerror(e.toString());
- }
- }
-
- this.context.ICCIOHelper.loadTransparentEF({
- fileId: ICC_EF_CPHS_INFO,
- callback: callback.bind(this),
- onerror: onerror
- });
- },
-
- /**
- * Read CPHS MBN. (Mailbox Numbers)
- *
- * @See B.4.2.2 Voice Message Retrieval and Indicator Clearing
- */
- readCphsMBN: function() {
- function callback(options) {
- let RIL = this.context.RIL;
- let contact =
- this.context.ICCPDUHelper.readAlphaIdDiallingNumber(options.recordSize);
- if (!contact ||
- (RIL.iccInfoPrivate.mbdn !== undefined &&
- RIL.iccInfoPrivate.mbdn === contact.number)) {
- return;
- }
- RIL.iccInfoPrivate.mbdn = contact.number;
- if (DEBUG) {
- this.context.debug("CPHS_MDN, alphaId=" + contact.alphaId +
- " number=" + contact.number);
- }
- contact.rilMessageType = "iccmbdn";
- RIL.sendChromeMessage(contact);
- }
-
- this.context.ICCIOHelper.loadLinearFixedEF({
- fileId: ICC_EF_CPHS_MBN,
- callback: callback.bind(this)
- });
- }
-};
-
-function RuimRecordHelperObject(aContext) {
- this.context = aContext;
-}
-RuimRecordHelperObject.prototype = {
- context: null,
-
- fetchRuimRecords: function() {
- this.getIMSI_M();
- this.readCST();
- this.readCDMAHome();
- this.context.RIL.getCdmaSubscription();
- },
-
- /**
- * Get IMSI_M from CSIM/RUIM.
- * See 3GPP2 C.S0065 Sec. 5.2.2
- */
- getIMSI_M: function() {
- function callback() {
- let Buf = this.context.Buf;
- let strLen = Buf.readInt32();
- let encodedImsi = this.context.GsmPDUHelper.readHexOctetArray(strLen / 2);
- Buf.readStringDelimiter(strLen);
-
- if ((encodedImsi[CSIM_IMSI_M_PROGRAMMED_BYTE] & 0x80)) { // IMSI_M programmed
- let RIL = this.context.RIL;
- RIL.iccInfoPrivate.imsi = this.decodeIMSI(encodedImsi);
- RIL.sendChromeMessage({rilMessageType: "iccimsi",
- imsi: RIL.iccInfoPrivate.imsi});
-
- let ICCUtilsHelper = this.context.ICCUtilsHelper;
- let mccMnc = ICCUtilsHelper.parseMccMncFromImsi(RIL.iccInfoPrivate.imsi);
- if (mccMnc) {
- RIL.iccInfo.mcc = mccMnc.mcc;
- RIL.iccInfo.mnc = mccMnc.mnc;
- ICCUtilsHelper.handleICCInfoChange();
- }
- }
- }
-
- this.context.ICCIOHelper.loadTransparentEF({
- fileId: ICC_EF_CSIM_IMSI_M,
- callback: callback.bind(this)
- });
- },
-
- /**
- * Decode IMSI from IMSI_M
- * See 3GPP2 C.S0005 Sec. 2.3.1
- * +---+---------+------------+---+--------+---------+---+---------+--------+
- * |RFU| MCC | programmed |RFU| MNC | MIN1 |RFU| MIN2 | CLASS |
- * +---+---------+------------+---+--------+---------+---+---------+--------+
- * | 6 | 10 bits | 8 bits | 1 | 7 bits | 24 bits | 6 | 10 bits | 8 bits |
- * +---+---------+------------+---+--------+---------+---+---------+--------+
- */
- decodeIMSI: function(encodedImsi) {
- // MCC: 10 bits, 3 digits
- let encodedMCC = ((encodedImsi[CSIM_IMSI_M_MCC_BYTE + 1] & 0x03) << 8) +
- (encodedImsi[CSIM_IMSI_M_MCC_BYTE] & 0xff);
- let mcc = this.decodeIMSIValue(encodedMCC, 3);
-
- // MNC: 7 bits, 2 digits
- let encodedMNC = encodedImsi[CSIM_IMSI_M_MNC_BYTE] & 0x7f;
- let mnc = this.decodeIMSIValue(encodedMNC, 2);
-
- // MIN2: 10 bits, 3 digits
- let encodedMIN2 = ((encodedImsi[CSIM_IMSI_M_MIN2_BYTE + 1] & 0x03) << 8) +
- (encodedImsi[CSIM_IMSI_M_MIN2_BYTE] & 0xff);
- let min2 = this.decodeIMSIValue(encodedMIN2, 3);
-
- // MIN1: 10+4+10 bits, 3+1+3 digits
- let encodedMIN1First3 = ((encodedImsi[CSIM_IMSI_M_MIN1_BYTE + 2] & 0xff) << 2) +
- ((encodedImsi[CSIM_IMSI_M_MIN1_BYTE + 1] & 0xc0) >> 6);
- let min1First3 = this.decodeIMSIValue(encodedMIN1First3, 3);
-
- let encodedFourthDigit = (encodedImsi[CSIM_IMSI_M_MIN1_BYTE + 1] & 0x3c) >> 2;
- if (encodedFourthDigit > 9) {
- encodedFourthDigit = 0;
- }
- let fourthDigit = encodedFourthDigit.toString();
-
- let encodedMIN1Last3 = ((encodedImsi[CSIM_IMSI_M_MIN1_BYTE + 1] & 0x03) << 8) +
- (encodedImsi[CSIM_IMSI_M_MIN1_BYTE] & 0xff);
- let min1Last3 = this.decodeIMSIValue(encodedMIN1Last3, 3);
-
- return mcc + mnc + min2 + min1First3 + fourthDigit + min1Last3;
- },
-
- /**
- * Decode IMSI Helper function
- * See 3GPP2 C.S0005 section 2.3.1.1
- */
- decodeIMSIValue: function(encoded, length) {
- let offset = length === 3 ? 111 : 11;
- let value = encoded + offset;
-
- for (let base = 10, temp = value, i = 0; i < length; i++) {
- if (temp % 10 === 0) {
- value -= base;
- }
- temp = Math.floor(value / base);
- base = base * 10;
- }
-
- let s = value.toString();
- while (s.length < length) {
- s = "0" + s;
- }
-
- return s;
- },
-
- /**
- * Read CDMAHOME for CSIM.
- * See 3GPP2 C.S0023 Sec. 3.4.8.
- */
- readCDMAHome: function() {
- let ICCIOHelper = this.context.ICCIOHelper;
-
- function callback(options) {
- let Buf = this.context.Buf;
- let GsmPDUHelper = this.context.GsmPDUHelper;
-
- let strLen = Buf.readInt32();
- let tempOctet = GsmPDUHelper.readHexOctet();
- cdmaHomeSystemId.push(((GsmPDUHelper.readHexOctet() & 0x7f) << 8) | tempOctet);
- tempOctet = GsmPDUHelper.readHexOctet();
- cdmaHomeNetworkId.push(((GsmPDUHelper.readHexOctet() & 0xff) << 8) | tempOctet);
-
- // Consuming the last octet: band class.
- Buf.seekIncoming(Buf.PDU_HEX_OCTET_SIZE);
-
- Buf.readStringDelimiter(strLen);
- if (options.p1 < options.totalRecords) {
- ICCIOHelper.loadNextRecord(options);
- } else {
- if (DEBUG) {
- this.context.debug("CDMAHome system id: " +
- JSON.stringify(cdmaHomeSystemId));
- this.context.debug("CDMAHome network id: " +
- JSON.stringify(cdmaHomeNetworkId));
- }
- this.context.RIL.cdmaHome = {
- systemId: cdmaHomeSystemId,
- networkId: cdmaHomeNetworkId
- };
- }
- }
-
- let cdmaHomeSystemId = [], cdmaHomeNetworkId = [];
- ICCIOHelper.loadLinearFixedEF({fileId: ICC_EF_CSIM_CDMAHOME,
- callback: callback.bind(this)});
- },
-
- /**
- * Read CDMA Service Table.
- * See 3GPP2 C.S0023 Sec. 3.4.18
- */
- readCST: function() {
- function callback() {
- let Buf = this.context.Buf;
- let RIL = this.context.RIL;
-
- let strLen = Buf.readInt32();
- // Each octet is encoded into two chars.
- RIL.iccInfoPrivate.cst =
- this.context.GsmPDUHelper.readHexOctetArray(strLen / 2);
- Buf.readStringDelimiter(strLen);
-
- if (DEBUG) {
- let str = "";
- for (let i = 0; i < RIL.iccInfoPrivate.cst.length; i++) {
- str += RIL.iccInfoPrivate.cst[i] + ", ";
- }
- this.context.debug("CST: " + str);
- }
-
- if (this.context.ICCUtilsHelper.isICCServiceAvailable("SPN")) {
- if (DEBUG) this.context.debug("SPN: SPN is available");
- this.readSPN();
- }
- }
- this.context.ICCIOHelper.loadTransparentEF({
- fileId: ICC_EF_CSIM_CST,
- callback: callback.bind(this)
- });
- },
-
- readSPN: function() {
- function callback() {
- let Buf = this.context.Buf;
- let strLen = Buf.readInt32();
- let octetLen = strLen / 2;
-
- let GsmPDUHelper = this.context.GsmPDUHelper;
- let displayCondition = GsmPDUHelper.readHexOctet();
- let codingScheme = GsmPDUHelper.readHexOctet();
- // Skip one octet: language indicator.
- Buf.seekIncoming(Buf.PDU_HEX_OCTET_SIZE);
- let readLen = 3;
-
- // SPN String ends up with 0xff.
- let userDataBuffer = [];
-
- while (readLen < octetLen) {
- let octet = GsmPDUHelper.readHexOctet();
- readLen++;
- if (octet == 0xff) {
- break;
- }
- userDataBuffer.push(octet);
- }
-
- this.context.BitBufferHelper.startRead(userDataBuffer);
-
- let CdmaPDUHelper = this.context.CdmaPDUHelper;
- let msgLen;
- switch (CdmaPDUHelper.getCdmaMsgEncoding(codingScheme)) {
- case PDU_DCS_MSG_CODING_7BITS_ALPHABET:
- msgLen = Math.floor(userDataBuffer.length * 8 / 7);
- break;
- case PDU_DCS_MSG_CODING_8BITS_ALPHABET:
- msgLen = userDataBuffer.length;
- break;
- case PDU_DCS_MSG_CODING_16BITS_ALPHABET:
- msgLen = Math.floor(userDataBuffer.length / 2);
- break;
- }
-
- let RIL = this.context.RIL;
- RIL.iccInfo.spn = CdmaPDUHelper.decodeCdmaPDUMsg(codingScheme, null, msgLen);
- if (DEBUG) {
- this.context.debug("CDMA SPN: " + RIL.iccInfo.spn +
- ", Display condition: " + displayCondition);
- }
- RIL.iccInfoPrivate.spnDisplayCondition = displayCondition;
- Buf.seekIncoming((octetLen - readLen) * Buf.PDU_HEX_OCTET_SIZE);
- Buf.readStringDelimiter(strLen);
- }
-
- this.context.ICCIOHelper.loadTransparentEF({
- fileId: ICC_EF_CSIM_SPN,
- callback: callback.bind(this)
- });
- }
-};
-
-/**
- * Helper functions for ICC utilities.
- */
-function ICCUtilsHelperObject(aContext) {
- this.context = aContext;
-}
-ICCUtilsHelperObject.prototype = {
- context: null,
-
- /**
- * Get network names by using EF_OPL and EF_PNN
- *
- * @See 3GPP TS 31.102 sec. 4.2.58 and sec. 4.2.59 for USIM,
- * 3GPP TS 51.011 sec. 10.3.41 and sec. 10.3.42 for SIM.
- *
- * @param mcc The mobile country code of the network.
- * @param mnc The mobile network code of the network.
- * @param lac The location area code of the network.
- */
- getNetworkNameFromICC: function(mcc, mnc, lac) {
- let RIL = this.context.RIL;
- let iccInfoPriv = RIL.iccInfoPrivate;
- let iccInfo = RIL.iccInfo;
- let pnnEntry;
-
- if (!mcc || !mnc || lac == null || lac < 0) {
- return null;
- }
-
- // We won't get network name if there is no PNN file.
- if (!iccInfoPriv.PNN) {
- return null;
- }
-
- if (!this.isICCServiceAvailable("OPL")) {
- // When OPL is not present:
- // According to 3GPP TS 31.102 Sec. 4.2.58 and 3GPP TS 51.011 Sec. 10.3.41,
- // If EF_OPL is not present, the first record in this EF is used for the
- // default network name when registered to the HPLMN.
- // If we haven't get pnnEntry assigned, we should try to assign default
- // value to it.
- if (mcc == iccInfo.mcc && mnc == iccInfo.mnc) {
- pnnEntry = iccInfoPriv.PNN[0];
- }
- } else {
- let GsmPDUHelper = this.context.GsmPDUHelper;
- let wildChar = GsmPDUHelper.extendedBcdChars.charAt(0x0d);
- // According to 3GPP TS 31.102 Sec. 4.2.59 and 3GPP TS 51.011 Sec. 10.3.42,
- // the ME shall use this EF_OPL in association with the EF_PNN in place
- // of any network name stored within the ME's internal list and any network
- // name received when registered to the PLMN.
- let length = iccInfoPriv.OPL ? iccInfoPriv.OPL.length : 0;
- for (let i = 0; i < length; i++) {
- let unmatch = false;
- let opl = iccInfoPriv.OPL[i];
- // Try to match the MCC/MNC. Besides, A BCD value of 'D' in any of the
- // MCC and/or MNC digits shall be used to indicate a "wild" value for
- // that corresponding MCC/MNC digit.
- if (opl.mcc.indexOf(wildChar) !== -1) {
- for (let j = 0; j < opl.mcc.length; j++) {
- if (opl.mcc[j] !== wildChar && opl.mcc[j] !== mcc[j]) {
- unmatch = true;
- break;
- }
- }
- if (unmatch) {
- continue;
- }
- } else {
- if (mcc !== opl.mcc) {
- continue;
- }
- }
-
- if (mnc.length !== opl.mnc.length) {
- continue;
- }
-
- if (opl.mnc.indexOf(wildChar) !== -1) {
- for (let j = 0; j < opl.mnc.length; j++) {
- if (opl.mnc[j] !== wildChar && opl.mnc[j] !== mnc[j]) {
- unmatch = true;
- break;
- }
- }
- if (unmatch) {
- continue;
- }
- } else {
- if (mnc !== opl.mnc) {
- continue;
- }
- }
-
- // Try to match the location area code. If current local area code is
- // covered by lac range that specified in the OPL entry, use the PNN
- // that specified in the OPL entry.
- if ((opl.lacTacStart === 0x0 && opl.lacTacEnd == 0xFFFE) ||
- (opl.lacTacStart <= lac && opl.lacTacEnd >= lac)) {
- if (opl.pnnRecordId === 0) {
- // See 3GPP TS 31.102 Sec. 4.2.59 and 3GPP TS 51.011 Sec. 10.3.42,
- // A value of '00' indicates that the name is to be taken from other
- // sources.
- return null;
- }
- pnnEntry = iccInfoPriv.PNN[opl.pnnRecordId - 1];
- break;
- }
- }
- }
-
- if (!pnnEntry) {
- return null;
- }
-
- // Return a new object to avoid global variable, PNN, be modified by accident.
- return { fullName: pnnEntry.fullName || "",
- shortName: pnnEntry.shortName || "" };
- },
-
- /**
- * This will compute the spnDisplay field of the network.
- * See TS 22.101 Annex A and TS 51.011 10.3.11 for details.
- *
- * @return True if some of iccInfo is changed in by this function.
- */
- updateDisplayCondition: function() {
- let RIL = this.context.RIL;
-
- // If EFspn isn't existed in SIM or it haven't been read yet, we should
- // just set isDisplayNetworkNameRequired = true and
- // isDisplaySpnRequired = false
- let iccInfo = RIL.iccInfo;
- let iccInfoPriv = RIL.iccInfoPrivate;
- let displayCondition = iccInfoPriv.spnDisplayCondition;
- let origIsDisplayNetworkNameRequired = iccInfo.isDisplayNetworkNameRequired;
- let origIsDisplaySPNRequired = iccInfo.isDisplaySpnRequired;
-
- if (displayCondition === undefined) {
- iccInfo.isDisplayNetworkNameRequired = true;
- iccInfo.isDisplaySpnRequired = false;
- } else if (RIL._isCdma) {
- // CDMA family display rule.
- let cdmaHome = RIL.cdmaHome;
- let cell = RIL.voiceRegistrationState.cell;
- let sid = cell && cell.cdmaSystemId;
- let nid = cell && cell.cdmaNetworkId;
-
- iccInfo.isDisplayNetworkNameRequired = false;
-
- // If display condition is 0x0, we don't even need to check network id
- // or system id.
- if (displayCondition === 0x0) {
- iccInfo.isDisplaySpnRequired = false;
- } else {
- // CDMA SPN Display condition dosen't specify whenever network name is
- // reqired.
- if (!cdmaHome ||
- !cdmaHome.systemId ||
- cdmaHome.systemId.length === 0 ||
- cdmaHome.systemId.length != cdmaHome.networkId.length ||
- !sid || !nid) {
- // CDMA Home haven't been ready, or we haven't got the system id and
- // network id of the network we register to, assuming we are in home
- // network.
- iccInfo.isDisplaySpnRequired = true;
- } else {
- // Determine if we are registered in the home service area.
- // System ID and Network ID are described in 3GPP2 C.S0005 Sec. 2.6.5.2.
- let inHomeArea = false;
- for (let i = 0; i < cdmaHome.systemId.length; i++) {
- let homeSid = cdmaHome.systemId[i],
- homeNid = cdmaHome.networkId[i];
- if (homeSid === 0 || homeNid === 0 // Reserved system id/network id
- || homeSid != sid) {
- continue;
- }
- // According to 3GPP2 C.S0005 Sec. 2.6.5.2, NID number 65535 means
- // all networks in the system should be considered as home.
- if (homeNid == 65535 || homeNid == nid) {
- inHomeArea = true;
- break;
- }
- }
- iccInfo.isDisplaySpnRequired = inHomeArea;
- }
- }
- } else {
- // GSM family display rule.
- let operatorMnc = RIL.operator ? RIL.operator.mnc : -1;
- let operatorMcc = RIL.operator ? RIL.operator.mcc : -1;
-
- // First detect if we are on HPLMN or one of the PLMN
- // specified by the SIM card.
- let isOnMatchingPlmn = false;
-
- // If the current network is the one defined as mcc/mnc
- // in SIM card, it's okay.
- if (iccInfo.mcc == operatorMcc && iccInfo.mnc == operatorMnc) {
- isOnMatchingPlmn = true;
- }
-
- // Test to see if operator's mcc/mnc match mcc/mnc of PLMN.
- if (!isOnMatchingPlmn && iccInfoPriv.SPDI) {
- let iccSpdi = iccInfoPriv.SPDI; // PLMN list
- for (let plmn in iccSpdi) {
- let plmnMcc = iccSpdi[plmn].mcc;
- let plmnMnc = iccSpdi[plmn].mnc;
- isOnMatchingPlmn = (plmnMcc == operatorMcc) && (plmnMnc == operatorMnc);
- if (isOnMatchingPlmn) {
- break;
- }
- }
- }
-
- // See 3GPP TS 22.101 A.4 Service Provider Name indication, and TS 31.102
- // clause 4.2.12 EF_SPN for detail.
- if (isOnMatchingPlmn) {
- // The first bit of display condition tells us if we should display
- // registered PLMN.
- if (DEBUG) {
- this.context.debug("PLMN is HPLMN or PLMN " + "is in PLMN list");
- }
-
- // TS 31.102 Sec. 4.2.66 and TS 51.011 Sec. 10.3.50
- // EF_SPDI contains a list of PLMNs in which the Service Provider Name
- // shall be displayed.
- iccInfo.isDisplaySpnRequired = true;
- iccInfo.isDisplayNetworkNameRequired = (displayCondition & 0x01) !== 0;
- } else {
- // The second bit of display condition tells us if we should display
- // registered PLMN.
- if (DEBUG) {
- this.context.debug("PLMN isn't HPLMN and PLMN isn't in PLMN list");
- }
-
- iccInfo.isDisplayNetworkNameRequired = true;
- iccInfo.isDisplaySpnRequired = (displayCondition & 0x02) === 0;
- }
- }
-
- if (DEBUG) {
- this.context.debug("isDisplayNetworkNameRequired = " +
- iccInfo.isDisplayNetworkNameRequired);
- this.context.debug("isDisplaySpnRequired = " + iccInfo.isDisplaySpnRequired);
- }
-
- return ((origIsDisplayNetworkNameRequired !== iccInfo.isDisplayNetworkNameRequired) ||
- (origIsDisplaySPNRequired !== iccInfo.isDisplaySpnRequired));
- },
-
- decodeSimTlvs: function(tlvsLen) {
- let GsmPDUHelper = this.context.GsmPDUHelper;
-
- let index = 0;
- let tlvs = [];
- while (index < tlvsLen) {
- let simTlv = {
- tag : GsmPDUHelper.readHexOctet(),
- length : GsmPDUHelper.readHexOctet(),
- };
- simTlv.value = GsmPDUHelper.readHexOctetArray(simTlv.length);
- tlvs.push(simTlv);
- index += simTlv.length + 2; // The length of 'tag' and 'length' field.
- }
- return tlvs;
- },
-
- /**
- * Parse those TLVs and convert it to an object.
- */
- parsePbrTlvs: function(pbrTlvs) {
- let pbr = {};
- for (let i = 0; i < pbrTlvs.length; i++) {
- let pbrTlv = pbrTlvs[i];
- let anrIndex = 0;
- for (let j = 0; j < pbrTlv.value.length; j++) {
- let tlv = pbrTlv.value[j];
- let tagName = USIM_TAG_NAME[tlv.tag];
-
- // ANR could have multiple files. We save it as anr0, anr1,...etc.
- if (tlv.tag == ICC_USIM_EFANR_TAG) {
- tagName += anrIndex;
- anrIndex++;
- }
- pbr[tagName] = tlv;
- pbr[tagName].fileType = pbrTlv.tag;
- pbr[tagName].fileId = (tlv.value[0] << 8) | tlv.value[1];
- pbr[tagName].sfi = tlv.value[2];
-
- // For Type 2, the order of files is in the same order in IAP.
- if (pbrTlv.tag == ICC_USIM_TYPE2_TAG) {
- pbr[tagName].indexInIAP = j;
- }
- }
- }
-
- return pbr;
- },
-
- /**
- * Update the ICC information to RadioInterfaceLayer.
- */
- handleICCInfoChange: function() {
- let RIL = this.context.RIL;
- RIL.iccInfo.rilMessageType = "iccinfochange";
- RIL.sendChromeMessage(RIL.iccInfo);
- },
-
- /**
- * Get whether specificed (U)SIM service is available.
- *
- * @param geckoService
- * Service name like "ADN", "BDN", etc.
- *
- * @return true if the service is enabled, false otherwise.
- */
- isICCServiceAvailable: function(geckoService) {
- let RIL = this.context.RIL;
- let serviceTable = RIL._isCdma ? RIL.iccInfoPrivate.cst:
- RIL.iccInfoPrivate.sst;
- let index, bitmask;
- if (RIL.appType == CARD_APPTYPE_SIM || RIL.appType == CARD_APPTYPE_RUIM) {
- /**
- * Service id is valid in 1..N, and 2 bits are used to code each service.
- *
- * +----+-- --+----+----+
- * | b8 | ... | b2 | b1 |
- * +----+-- --+----+----+
- *
- * b1 = 0, service not allocated.
- * 1, service allocated.
- * b2 = 0, service not activated.
- * 1, service activated.
- *
- * @see 3GPP TS 51.011 10.3.7.
- */
- let simService;
- if (RIL.appType == CARD_APPTYPE_SIM) {
- simService = GECKO_ICC_SERVICES.sim[geckoService];
- } else {
- simService = GECKO_ICC_SERVICES.ruim[geckoService];
- }
- if (!simService) {
- return false;
- }
- simService -= 1;
- index = Math.floor(simService / 4);
- bitmask = 2 << ((simService % 4) << 1);
- } else if (RIL.appType == CARD_APPTYPE_USIM) {
- /**
- * Service id is valid in 1..N, and 1 bit is used to code each service.
- *
- * +----+-- --+----+----+
- * | b8 | ... | b2 | b1 |
- * +----+-- --+----+----+
- *
- * b1 = 0, service not avaiable.
- * 1, service available.
- *
- * @see 3GPP TS 31.102 4.2.8.
- */
- let usimService = GECKO_ICC_SERVICES.usim[geckoService];
- if (!usimService) {
- return false;
- }
- usimService -= 1;
- index = Math.floor(usimService / 8);
- bitmask = 1 << ((usimService % 8) << 0);
- }
-
- return (serviceTable !== null) &&
- (index < serviceTable.length) &&
- ((serviceTable[index] & bitmask) !== 0);
- },
-
- /**
- * Get whether specificed CPHS service is available.
- *
- * @param geckoService
- * Service name like "MDN", etc.
- *
- * @return true if the service is enabled, false otherwise.
- */
- isCphsServiceAvailable: function(geckoService) {
- let RIL = this.context.RIL;
- let serviceTable = RIL.iccInfoPrivate.cphsSt;
-
- if (!(serviceTable instanceof Uint8Array)) {
- return false;
- }
-
- /**
- * Service id is valid in 1..N, and 2 bits are used to code each service.
- *
- * +----+-- --+----+----+
- * | b8 | ... | b2 | b1 |
- * +----+-- --+----+----+
- *
- * b1 = 0, service not allocated.
- * 1, service allocated.
- * b2 = 0, service not activated.
- * 1, service activated.
- *
- * @See B.3.1.1 CPHS Information in CPHS Phase 2.
- */
- let cphsService = GECKO_ICC_SERVICES.cphs[geckoService];
-
- if (!cphsService) {
- return false;
- }
- cphsService -= 1;
- let index = Math.floor(cphsService / 4);
- let bitmask = 2 << ((cphsService % 4) << 1);
-
- return (index < serviceTable.length) &&
- ((serviceTable[index] & bitmask) !== 0);
- },
-
- /**
- * Check if the string is of GSM default 7-bit coded alphabets with bit 8
- * set to 0.
- *
- * @param str String to be checked.
- */
- isGsm8BitAlphabet: function(str) {
- if (!str) {
- return false;
- }
-
- const langTable = PDU_NL_LOCKING_SHIFT_TABLES[PDU_NL_IDENTIFIER_DEFAULT];
- const langShiftTable = PDU_NL_SINGLE_SHIFT_TABLES[PDU_NL_IDENTIFIER_DEFAULT];
-
- for (let i = 0; i < str.length; i++) {
- let c = str.charAt(i);
- let octet = langTable.indexOf(c);
- if (octet == -1) {
- octet = langShiftTable.indexOf(c);
- if (octet == -1) {
- return false;
- }
- }
- }
-
- return true;
- },
-
- /**
- * Parse MCC/MNC from IMSI. If there is no available value for the length of
- * mnc, it will use the data in MCC table to parse.
- *
- * @param imsi
- * The imsi of icc.
- * @param mncLength [optional]
- * The length of mnc.
- * Zero indicates we haven't got a valid mnc length.
- *
- * @return An object contains the parsing result of mcc and mnc.
- * Or null if any error occurred.
- */
- parseMccMncFromImsi: function(imsi, mncLength) {
- if (!imsi) {
- return null;
- }
-
- // MCC is the first 3 digits of IMSI.
- let mcc = imsi.substr(0,3);
- if (!mncLength) {
- // Check the MCC/MNC table for MNC length = 3 first for the case we don't
- // have the 4th byte data from EF_AD.
- if (PLMN_HAVING_3DIGITS_MNC[mcc] &&
- PLMN_HAVING_3DIGITS_MNC[mcc].indexOf(imsi.substr(3, 3)) !== -1) {
- mncLength = 3;
- } else {
- // Check the MCC table to decide the length of MNC.
- let index = MCC_TABLE_FOR_MNC_LENGTH_IS_3.indexOf(mcc);
- mncLength = (index !== -1) ? 3 : 2;
- }
- }
- let mnc = imsi.substr(3, mncLength);
- if (DEBUG) {
- this.context.debug("IMSI: " + imsi + " MCC: " + mcc + " MNC: " + mnc);
- }
-
- return { mcc: mcc, mnc: mnc};
- },
-};
-
-/**
- * Helper for ICC Contacts.
- */
-function ICCContactHelperObject(aContext) {
- this.context = aContext;
-}
-ICCContactHelperObject.prototype = {
- context: null,
-
- /**
- * Helper function to check DF_PHONEBOOK.
- */
- hasDfPhoneBook: function(appType) {
- switch (appType) {
- case CARD_APPTYPE_SIM:
- return false;
- case CARD_APPTYPE_USIM:
- return true;
- case CARD_APPTYPE_RUIM:
- let ICCUtilsHelper = this.context.ICCUtilsHelper;
- return ICCUtilsHelper.isICCServiceAvailable("ENHANCED_PHONEBOOK");
- default:
- return false;
- }
- },
-
- /**
- * Helper function to read ICC contacts.
- *
- * @param appType One of CARD_APPTYPE_*.
- * @param contactType One of GECKO_CARDCONTACT_TYPE_*.
- * @param onsuccess Callback to be called when success.
- * @param onerror Callback to be called when error.
- */
- readICCContacts: function(appType, contactType, onsuccess, onerror) {
- let ICCRecordHelper = this.context.ICCRecordHelper;
- let ICCUtilsHelper = this.context.ICCUtilsHelper;
-
- switch (contactType) {
- case GECKO_CARDCONTACT_TYPE_ADN:
- if (!this.hasDfPhoneBook(appType)) {
- ICCRecordHelper.readADNLike(ICC_EF_ADN,
- (ICCUtilsHelper.isICCServiceAvailable("EXT1")) ? ICC_EF_EXT1 : null,
- onsuccess, onerror);
- } else {
- this.readUSimContacts(onsuccess, onerror);
- }
- break;
- case GECKO_CARDCONTACT_TYPE_FDN:
- if (!ICCUtilsHelper.isICCServiceAvailable("FDN")) {
- onerror(CONTACT_ERR_CONTACT_TYPE_NOT_SUPPORTED);
- break;
- }
- ICCRecordHelper.readADNLike(ICC_EF_FDN,
- (ICCUtilsHelper.isICCServiceAvailable("EXT2")) ? ICC_EF_EXT2 : null,
- onsuccess, onerror);
- break;
- case GECKO_CARDCONTACT_TYPE_SDN:
- if (!ICCUtilsHelper.isICCServiceAvailable("SDN")) {
- onerror(CONTACT_ERR_CONTACT_TYPE_NOT_SUPPORTED);
- break;
- }
-
- ICCRecordHelper.readADNLike(ICC_EF_SDN,
- (ICCUtilsHelper.isICCServiceAvailable("EXT3")) ? ICC_EF_EXT3 : null,
- onsuccess, onerror);
- break;
- default:
- if (DEBUG) {
- this.context.debug("Unsupported contactType :" + contactType);
- }
- onerror(CONTACT_ERR_CONTACT_TYPE_NOT_SUPPORTED);
- break;
- }
- },
-
- /**
- * Helper function to find free contact record.
- *
- * @param appType One of CARD_APPTYPE_*.
- * @param contactType One of GECKO_CARDCONTACT_TYPE_*.
- * @param onsuccess Callback to be called when success.
- * @param onerror Callback to be called when error.
- */
- findFreeICCContact: function(appType, contactType, onsuccess, onerror) {
- let ICCRecordHelper = this.context.ICCRecordHelper;
-
- switch (contactType) {
- case GECKO_CARDCONTACT_TYPE_ADN:
- if (!this.hasDfPhoneBook(appType)) {
- ICCRecordHelper.findFreeRecordId(ICC_EF_ADN, onsuccess.bind(null, 0), onerror);
- } else {
- let gotPbrCb = function gotPbrCb(pbrs) {
- this.findUSimFreeADNRecordId(pbrs, onsuccess, onerror);
- }.bind(this);
-
- ICCRecordHelper.readPBR(gotPbrCb, onerror);
- }
- break;
- case GECKO_CARDCONTACT_TYPE_FDN:
- ICCRecordHelper.findFreeRecordId(ICC_EF_FDN, onsuccess.bind(null, 0), onerror);
- break;
- default:
- if (DEBUG) {
- this.context.debug("Unsupported contactType :" + contactType);
- }
- onerror(CONTACT_ERR_CONTACT_TYPE_NOT_SUPPORTED);
- break;
- }
- },
-
- /**
- * Cache the pbr index of the possible free record.
- */
- _freePbrIndex: 0,
-
- /**
- * Find free ADN record id in USIM.
- *
- * @param pbrs All Phonebook Reference Files read.
- * @param onsuccess Callback to be called when success.
- * @param onerror Callback to be called when error.
- */
- findUSimFreeADNRecordId: function(pbrs, onsuccess, onerror) {
- let ICCRecordHelper = this.context.ICCRecordHelper;
-
- function callback(pbrIndex, recordId) {
- // Assume other free records are probably in the same phonebook set.
- this._freePbrIndex = pbrIndex;
- onsuccess(pbrIndex, recordId);
- }
-
- let nextPbrIndex = -1;
- (function findFreeRecordId(pbrIndex) {
- if (nextPbrIndex === this._freePbrIndex) {
- // No free record found, reset the pbr index of free record.
- this._freePbrIndex = 0;
- if (DEBUG) {
- this.context.debug(CONTACT_ERR_NO_FREE_RECORD_FOUND);
- }
- onerror(CONTACT_ERR_NO_FREE_RECORD_FOUND);
- return;
- }
-
- let pbr = pbrs[pbrIndex];
- nextPbrIndex = (pbrIndex + 1) % pbrs.length;
- ICCRecordHelper.findFreeRecordId(
- pbr.adn.fileId,
- callback.bind(this, pbrIndex),
- findFreeRecordId.bind(this, nextPbrIndex));
- }).call(this, this._freePbrIndex);
- },
-
- /**
- * Helper function to add a new ICC contact.
- *
- * @param appType One of CARD_APPTYPE_*.
- * @param contactType One of GECKO_CARDCONTACT_TYPE_*.
- * @param contact The contact will be added.
- * @param pin2 PIN2 is required for FDN.
- * @param onsuccess Callback to be called when success.
- * @param onerror Callback to be called when error.
- */
- addICCContact: function(appType, contactType, contact, pin2, onsuccess, onerror) {
- let foundFreeCb = (function foundFreeCb(pbrIndex, recordId) {
- contact.pbrIndex = pbrIndex;
- contact.recordId = recordId;
- this.updateICCContact(appType, contactType, contact, pin2, onsuccess, onerror);
- }).bind(this);
-
- // Find free record first.
- this.findFreeICCContact(appType, contactType, foundFreeCb, onerror);
- },
-
- /**
- * Helper function to update ICC contact.
- *
- * @param appType One of CARD_APPTYPE_*.
- * @param contactType One of GECKO_CARDCONTACT_TYPE_*.
- * @param contact The contact will be updated.
- * @param pin2 PIN2 is required for FDN.
- * @param onsuccess Callback to be called when success.
- * @param onerror Callback to be called when error.
- */
- updateICCContact: function(appType, contactType, contact, pin2, onsuccess, onerror) {
- let ICCRecordHelper = this.context.ICCRecordHelper;
- let ICCUtilsHelper = this.context.ICCUtilsHelper;
-
- let updateContactCb = (updatedContact) => {
- updatedContact.pbrIndex = contact.pbrIndex;
- updatedContact.recordId = contact.recordId;
- onsuccess(updatedContact);
- }
-
- switch (contactType) {
- case GECKO_CARDCONTACT_TYPE_ADN:
- if (!this.hasDfPhoneBook(appType)) {
- if (ICCUtilsHelper.isICCServiceAvailable("EXT1")) {
- this.updateADNLikeWithExtension(ICC_EF_ADN, ICC_EF_EXT1,
- contact, null,
- updateContactCb, onerror);
- } else {
- ICCRecordHelper.updateADNLike(ICC_EF_ADN, 0xff,
- contact, null,
- updateContactCb, onerror);
- }
- } else {
- this.updateUSimContact(contact, updateContactCb, onerror);
- }
- break;
- case GECKO_CARDCONTACT_TYPE_FDN:
- if (!pin2) {
- onerror(GECKO_ERROR_SIM_PIN2);
- return;
- }
- if (!ICCUtilsHelper.isICCServiceAvailable("FDN")) {
- onerror(CONTACT_ERR_CONTACT_TYPE_NOT_SUPPORTED);
- break;
- }
- if (ICCUtilsHelper.isICCServiceAvailable("EXT2")) {
- this.updateADNLikeWithExtension(ICC_EF_FDN, ICC_EF_EXT2,
- contact, pin2,
- updateContactCb, onerror);
- } else {
- ICCRecordHelper.updateADNLike(ICC_EF_FDN,
- 0xff,
- contact, pin2,
- updateContactCb, onerror);
- }
- break;
- default:
- if (DEBUG) {
- this.context.debug("Unsupported contactType :" + contactType);
- }
- onerror(CONTACT_ERR_CONTACT_TYPE_NOT_SUPPORTED);
- break;
- }
- },
-
- /**
- * Read contacts from USIM.
- *
- * @param onsuccess Callback to be called when success.
- * @param onerror Callback to be called when error.
- */
- readUSimContacts: function(onsuccess, onerror) {
- let gotPbrCb = function gotPbrCb(pbrs) {
- this.readAllPhonebookSets(pbrs, onsuccess, onerror);
- }.bind(this);
-
- this.context.ICCRecordHelper.readPBR(gotPbrCb, onerror);
- },
-
- /**
- * Read all Phonebook sets.
- *
- * @param pbrs All Phonebook Reference Files read.
- * @param onsuccess Callback to be called when success.
- * @param onerror Callback to be called when error.
- */
- readAllPhonebookSets: function(pbrs, onsuccess, onerror) {
- let allContacts = [], pbrIndex = 0;
- let readPhonebook = function(contacts) {
- if (contacts) {
- allContacts = allContacts.concat(contacts);
- }
-
- let cLen = contacts ? contacts.length : 0;
- for (let i = 0; i < cLen; i++) {
- contacts[i].pbrIndex = pbrIndex;
- }
-
- pbrIndex++;
- if (pbrIndex >= pbrs.length) {
- if (onsuccess) {
- onsuccess(allContacts);
- }
- return;
- }
-
- this.readPhonebookSet(pbrs[pbrIndex], readPhonebook, onerror);
- }.bind(this);
-
- this.readPhonebookSet(pbrs[pbrIndex], readPhonebook, onerror);
- },
-
- /**
- * Read from Phonebook Reference File.
- *
- * @param pbr Phonebook Reference File to be read.
- * @param onsuccess Callback to be called when success.
- * @param onerror Callback to be called when error.
- */
- readPhonebookSet: function(pbr, onsuccess, onerror) {
- let ICCRecordHelper = this.context.ICCRecordHelper;
- let gotAdnCb = function gotAdnCb(contacts) {
- this.readSupportedPBRFields(pbr, contacts, onsuccess, onerror);
- }.bind(this);
-
- ICCRecordHelper.readADNLike(pbr.adn.fileId,
- (pbr.ext1) ? pbr.ext1.fileId : null, gotAdnCb, onerror);
- },
-
- /**
- * Read supported Phonebook fields.
- *
- * @param pbr Phone Book Reference file.
- * @param contacts Contacts stored on ICC.
- * @param onsuccess Callback to be called when success.
- * @param onerror Callback to be called when error.
- */
- readSupportedPBRFields: function(pbr, contacts, onsuccess, onerror) {
- let fieldIndex = 0;
- (function readField() {
- let field = USIM_PBR_FIELDS[fieldIndex];
- fieldIndex += 1;
- if (!field) {
- if (onsuccess) {
- onsuccess(contacts);
- }
- return;
- }
-
- this.readPhonebookField(pbr, contacts, field, readField.bind(this), onerror);
- }).call(this);
- },
-
- /**
- * Read Phonebook field.
- *
- * @param pbr The phonebook reference file.
- * @param contacts Contacts stored on ICC.
- * @param field Phonebook field to be retrieved.
- * @param onsuccess Callback to be called when success.
- * @param onerror Callback to be called when error.
- */
- readPhonebookField: function(pbr, contacts, field, onsuccess, onerror) {
- if (!pbr[field]) {
- if (onsuccess) {
- onsuccess(contacts);
- }
- return;
- }
-
- (function doReadContactField(n) {
- if (n >= contacts.length) {
- // All contact's fields are read.
- if (onsuccess) {
- onsuccess(contacts);
- }
- return;
- }
-
- // get n-th contact's field.
- this.readContactField(pbr, contacts[n], field,
- doReadContactField.bind(this, n + 1), onerror);
- }).call(this, 0);
- },
-
- /**
- * Read contact's field from USIM.
- *
- * @param pbr The phonebook reference file.
- * @param contact The contact needs to get field.
- * @param field Phonebook field to be retrieved.
- * @param onsuccess Callback to be called when success.
- * @param onerror Callback to be called when error.
- */
- readContactField: function(pbr, contact, field, onsuccess, onerror) {
- let gotRecordIdCb = function gotRecordIdCb(recordId) {
- if (recordId == 0xff) {
- if (onsuccess) {
- onsuccess();
- }
- return;
- }
-
- let fileId = pbr[field].fileId;
- let fileType = pbr[field].fileType;
- let gotFieldCb = function gotFieldCb(value) {
- if (value) {
- // Move anr0 anr1,.. into anr[].
- if (field.startsWith(USIM_PBR_ANR)) {
- if (!contact[USIM_PBR_ANR]) {
- contact[USIM_PBR_ANR] = [];
- }
- contact[USIM_PBR_ANR].push(value);
- } else {
- contact[field] = value;
- }
- }
-
- if (onsuccess) {
- onsuccess();
- }
- }.bind(this);
-
- let ICCRecordHelper = this.context.ICCRecordHelper;
- // Detect EF to be read, for anr, it could have anr0, anr1,...
- let ef = field.startsWith(USIM_PBR_ANR) ? USIM_PBR_ANR : field;
- switch (ef) {
- case USIM_PBR_EMAIL:
- ICCRecordHelper.readEmail(fileId, fileType, recordId, gotFieldCb, onerror);
- break;
- case USIM_PBR_ANR:
- ICCRecordHelper.readANR(fileId, fileType, recordId, gotFieldCb, onerror);
- break;
- default:
- if (DEBUG) {
- this.context.debug("Unsupported field :" + field);
- }
- onerror(CONTACT_ERR_FIELD_NOT_SUPPORTED);
- break;
- }
- }.bind(this);
-
- this.getContactFieldRecordId(pbr, contact, field, gotRecordIdCb, onerror);
- },
-
- /**
- * Get the recordId.
- *
- * If the fileType of field is ICC_USIM_TYPE1_TAG, use corresponding ADN recordId.
- * otherwise get the recordId from IAP.
- *
- * @see TS 131.102, clause 4.4.2.2
- *
- * @param pbr The phonebook reference file.
- * @param contact The contact will be updated.
- * @param onsuccess Callback to be called when success.
- * @param onerror Callback to be called when error.
- */
- getContactFieldRecordId: function(pbr, contact, field, onsuccess, onerror) {
- if (pbr[field].fileType == ICC_USIM_TYPE1_TAG) {
- // If the file type is ICC_USIM_TYPE1_TAG, use corresponding ADN recordId.
- if (onsuccess) {
- onsuccess(contact.recordId);
- }
- } else if (pbr[field].fileType == ICC_USIM_TYPE2_TAG) {
- // If the file type is ICC_USIM_TYPE2_TAG, the recordId shall be got from IAP.
- let gotIapCb = function gotIapCb(iap) {
- let indexInIAP = pbr[field].indexInIAP;
- let recordId = iap[indexInIAP];
-
- if (onsuccess) {
- onsuccess(recordId);
- }
- }.bind(this);
-
- this.context.ICCRecordHelper.readIAP(pbr.iap.fileId, contact.recordId,
- gotIapCb, onerror);
- } else {
- if (DEBUG) {
- this.context.debug("USIM PBR files in Type 3 format are not supported.");
- }
- onerror(CONTACT_ERR_REQUEST_NOT_SUPPORTED);
- }
- },
-
- /**
- * Update USIM contact.
- *
- * @param contact The contact will be updated.
- * @param onsuccess Callback to be called when success.
- * @param onerror Callback to be called when error.
- */
- updateUSimContact: function(contact, onsuccess, onerror) {
- let gotPbrCb = function gotPbrCb(pbrs) {
- let pbr = pbrs[contact.pbrIndex];
- if (!pbr) {
- if (DEBUG) {
- this.context.debug(CONTACT_ERR_CANNOT_ACCESS_PHONEBOOK);
- }
- onerror(CONTACT_ERR_CANNOT_ACCESS_PHONEBOOK);
- return;
- }
- this.updatePhonebookSet(pbr, contact, onsuccess, onerror);
- }.bind(this);
-
- this.context.ICCRecordHelper.readPBR(gotPbrCb, onerror);
- },
-
- /**
- * Update fields in Phonebook Reference File.
- *
- * @param pbr Phonebook Reference File to be read.
- * @param onsuccess Callback to be called when success.
- * @param onerror Callback to be called when error.
- */
- updatePhonebookSet: function(pbr, contact, onsuccess, onerror) {
- let updateAdnCb = function(updatedContact) {
- this.updateSupportedPBRFields(pbr, contact, (updatedContactField) => {
- onsuccess(Object.assign(updatedContact, updatedContactField));
- }, onerror);
- }.bind(this);
-
- if (pbr.ext1) {
- this.updateADNLikeWithExtension(pbr.adn.fileId, pbr.ext1.fileId,
- contact, null, updateAdnCb, onerror);
- } else {
- this.context.ICCRecordHelper.updateADNLike(pbr.adn.fileId, 0xff, contact,
- null, updateAdnCb, onerror);
- }
- },
-
- /**
- * Update supported Phonebook fields.
- *
- * @param pbr Phone Book Reference file.
- * @param contact Contact to be updated.
- * @param onsuccess Callback to be called when success.
- * @param onerror Callback to be called when error.
- */
- updateSupportedPBRFields: function(pbr, contact, onsuccess, onerror) {
- let fieldIndex = 0;
- let contactField = {};
-
- (function updateField() {
- let field = USIM_PBR_FIELDS[fieldIndex];
- fieldIndex += 1;
-
- if (!field) {
- if (onsuccess) {
- onsuccess(contactField);
- }
- return;
- }
-
- // Check if PBR has this field.
- if (!pbr[field]) {
- updateField.call(this);
- return;
- }
-
- this.updateContactField(pbr, contact, field, (fieldEntry) => {
- contactField = Object.assign(contactField, fieldEntry);
- updateField.call(this);
- }, (errorMsg) => {
- // Bug 1194149, there are some sim cards without sufficient
- // Type 2 USIM contact fields record. We allow user continue
- // importing contacts.
- if (errorMsg === CONTACT_ERR_NO_FREE_RECORD_FOUND) {
- updateField.call(this);
- return;
- }
- onerror(errorMsg);
- });
- }).call(this);
- },
-
- /**
- * Update contact's field from USIM.
- *
- * @param pbr The phonebook reference file.
- * @param contact The contact needs to be updated.
- * @param field Phonebook field to be updated.
- * @param onsuccess Callback to be called when success.
- * @param onerror Callback to be called when error.
- */
- updateContactField: function(pbr, contact, field, onsuccess, onerror) {
- if (pbr[field].fileType === ICC_USIM_TYPE1_TAG) {
- this.updateContactFieldType1(pbr, contact, field, onsuccess, onerror);
- } else if (pbr[field].fileType === ICC_USIM_TYPE2_TAG) {
- this.updateContactFieldType2(pbr, contact, field, onsuccess, onerror);
- } else {
- if (DEBUG) {
- this.context.debug("USIM PBR files in Type 3 format are not supported.");
- }
- onerror(CONTACT_ERR_REQUEST_NOT_SUPPORTED);
- }
- },
-
- /**
- * Update Type 1 USIM contact fields.
- *
- * @param pbr The phonebook reference file.
- * @param contact The contact needs to be updated.
- * @param field Phonebook field to be updated.
- * @param onsuccess Callback to be called when success.
- * @param onerror Callback to be called when error.
- */
- updateContactFieldType1: function(pbr, contact, field, onsuccess, onerror) {
- let ICCRecordHelper = this.context.ICCRecordHelper;
-
- if (field === USIM_PBR_EMAIL) {
- ICCRecordHelper.updateEmail(pbr, contact.recordId, contact.email, null,
- (updatedEmail) => {
- onsuccess({email: updatedEmail});
- }, onerror);
- } else if (field === USIM_PBR_ANR0) {
- let anr = Array.isArray(contact.anr) ? contact.anr[0] : null;
- ICCRecordHelper.updateANR(pbr, contact.recordId, anr, null,
- (updatedANR) => {
- // ANR could have multiple files. If we support more than one anr,
- // we will save it as anr0, anr1,...etc.
- onsuccess((updatedANR) ? {anr: [updatedANR]} : null);
- }, onerror);
- } else {
- if (DEBUG) {
- this.context.debug("Unsupported field :" + field);
- }
- onerror(CONTACT_ERR_FIELD_NOT_SUPPORTED);
- }
- },
-
- /**
- * Update Type 2 USIM contact fields.
- *
- * @param pbr The phonebook reference file.
- * @param contact The contact needs to be updated.
- * @param field Phonebook field to be updated.
- * @param onsuccess Callback to be called when success.
- * @param onerror Callback to be called when error.
- */
- updateContactFieldType2: function(pbr, contact, field, onsuccess, onerror) {
- let ICCRecordHelper = this.context.ICCRecordHelper;
-
- // Case 1 : EF_IAP[adnRecordId] doesn't have a value(0xff)
- // Find a free recordId for EF_field
- // Update field with that free recordId.
- // Update IAP.
- //
- // Case 2: EF_IAP[adnRecordId] has a value
- // update EF_field[iap[field.indexInIAP]]
-
- let gotIapCb = function gotIapCb(iap) {
- let recordId = iap[pbr[field].indexInIAP];
- if (recordId === 0xff) {
- // If the value in IAP[index] is 0xff, which means the contact stored on
- // the SIM doesn't have the additional attribute (email or anr).
- // So if the contact to be updated doesn't have the attribute either,
- // we don't have to update it.
- if ((field === USIM_PBR_EMAIL && contact.email) ||
- (field === USIM_PBR_ANR0 &&
- (Array.isArray(contact.anr) && contact.anr[0]))) {
- // Case 1.
- this.addContactFieldType2(pbr, contact, field, onsuccess, onerror);
- } else {
- if (onsuccess) {
- onsuccess();
- }
- }
- return;
- }
-
- // Case 2.
- if (field === USIM_PBR_EMAIL) {
- ICCRecordHelper.updateEmail(pbr, recordId, contact.email, contact.recordId,
- (updatedEmail) => {
- onsuccess({email: updatedEmail});
- }, onerror);
- } else if (field === USIM_PBR_ANR0) {
- let anr = Array.isArray(contact.anr) ? contact.anr[0] : null;
- ICCRecordHelper.updateANR(pbr, recordId, anr, contact.recordId,
- (updatedANR) => {
- // ANR could have multiple files. If we support more than one anr,
- // we will save it as anr0, anr1,...etc.
- onsuccess((updatedANR) ? {anr: [updatedANR]} : null);
- }, onerror);
- } else {
- if (DEBUG) {
- this.context.debug("Unsupported field :" + field);
- }
- onerror(CONTACT_ERR_FIELD_NOT_SUPPORTED);
- }
-
- }.bind(this);
-
- ICCRecordHelper.readIAP(pbr.iap.fileId, contact.recordId, gotIapCb, onerror);
- },
-
- /**
- * Add Type 2 USIM contact fields.
- *
- * @param pbr The phonebook reference file.
- * @param contact The contact needs to be updated.
- * @param field Phonebook field to be updated.
- * @param onsuccess Callback to be called when success.
- * @param onerror Callback to be called when error.
- */
- addContactFieldType2: function(pbr, contact, field, onsuccess, onerror) {
- let ICCRecordHelper = this.context.ICCRecordHelper;
- let successCb = function successCb(recordId) {
-
- let updateCb = function updateCb(contactField) {
- this.updateContactFieldIndexInIAP(pbr, contact.recordId, field, recordId, () => {
- onsuccess(contactField);
- }, onerror);
- }.bind(this);
-
- if (field === USIM_PBR_EMAIL) {
- ICCRecordHelper.updateEmail(pbr, recordId, contact.email, contact.recordId,
- (updatedEmail) => {
- updateCb({email: updatedEmail});
- }, onerror);
- } else if (field === USIM_PBR_ANR0) {
- ICCRecordHelper.updateANR(pbr, recordId, contact.anr[0], contact.recordId,
- (updatedANR) => {
- // ANR could have multiple files. If we support more than one anr,
- // we will save it as anr0, anr1,...etc.
- updateCb((updatedANR) ? {anr: [updatedANR]} : null);
- }, onerror);
- }
- }.bind(this);
-
- let errorCb = function errorCb(errorMsg) {
- if (DEBUG) {
- this.context.debug(errorMsg + " USIM field " + field);
- }
- onerror(errorMsg);
- }.bind(this);
-
- ICCRecordHelper.findFreeRecordId(pbr[field].fileId, successCb, errorCb);
- },
-
- /**
- * Update IAP value.
- *
- * @param pbr The phonebook reference file.
- * @param recordNumber The record identifier of EF_IAP.
- * @param field Phonebook field.
- * @param value The value of 'field' in IAP.
- * @param onsuccess Callback to be called when success.
- * @param onerror Callback to be called when error.
- *
- */
- updateContactFieldIndexInIAP: function(pbr, recordNumber, field, value, onsuccess, onerror) {
- let ICCRecordHelper = this.context.ICCRecordHelper;
-
- let gotIAPCb = function gotIAPCb(iap) {
- iap[pbr[field].indexInIAP] = value;
- ICCRecordHelper.updateIAP(pbr.iap.fileId, recordNumber, iap, onsuccess, onerror);
- }.bind(this);
- ICCRecordHelper.readIAP(pbr.iap.fileId, recordNumber, gotIAPCb, onerror);
- },
-
- /**
- * Update ICC ADN like EFs with Extension, like EF_ADN, EF_FDN.
- *
- * @param fileId EF id of the ADN or FDN.
- * @param extFileId EF id of the EXT.
- * @param contact The contact will be updated. (Shall have recordId property)
- * @param pin2 PIN2 is required when updating ICC_EF_FDN.
- * @param onsuccess Callback to be called when success.
- * @param onerror Callback to be called when error.
- */
- updateADNLikeWithExtension: function(fileId, extFileId, contact, pin2, onsuccess, onerror) {
- let ICCRecordHelper = this.context.ICCRecordHelper;
- let extNumber;
-
- if (contact.number) {
- let numStart = contact.number[0] == "+" ? 1 : 0;
- let number = contact.number.substring(0, numStart) +
- this.context.GsmPDUHelper.stringToExtendedBcd(
- contact.number.substring(numStart));
- extNumber = number.substr(numStart + ADN_MAX_NUMBER_DIGITS,
- EXT_MAX_NUMBER_DIGITS);
- }
-
- ICCRecordHelper.getADNLikeExtensionRecordNumber(fileId, contact.recordId,
- (extRecordNumber) => {
- let updateADNLike = (extRecordNumber) => {
- ICCRecordHelper.updateADNLike(fileId, extRecordNumber, contact,
- pin2, (updatedContact) => {
- if (extNumber && extRecordNumber != 0xff) {
- updatedContact.number = updatedContact.number.concat(extNumber);
- }
- onsuccess(updatedContact);
- }, onerror);
- };
-
- let updateExtension = (extRecordNumber) => {
- ICCRecordHelper.updateExtension(extFileId, extRecordNumber, extNumber,
- () => updateADNLike(extRecordNumber),
- () => updateADNLike(0xff));
- };
-
- if (extNumber) {
- if (extRecordNumber != 0xff) {
- updateExtension(extRecordNumber);
- return;
- }
-
- ICCRecordHelper.findFreeRecordId(extFileId,
- (extRecordNumber) => updateExtension(extRecordNumber),
- (errorMsg) => {
- if (DEBUG) {
- this.context.debug("Couldn't find free extension record Id for " + extFileId + ": " + errorMsg);
- }
- updateADNLike(0xff);
- });
- return;
- }
-
- if (extRecordNumber != 0xff) {
- ICCRecordHelper.cleanEFRecord(extFileId, extRecordNumber,
- () => updateADNLike(0xff), onerror);
- return;
- }
-
- updateADNLike(0xff);
- }, onerror);
- },
-};
-
-function IconLoaderObject(aContext) {
- this.context = aContext;
-}
-IconLoaderObject.prototype = {
- context: null,
-
- /**
- * Load icons.
- *
- * @param recordNumbers Array of the record identifiers of EF_IMG.
- * @param onsuccess Callback to be called when success.
- * @param onerror Callback to be called when error.
- */
- loadIcons: function(recordNumbers, onsuccess, onerror) {
- if (!recordNumbers || !recordNumbers.length) {
- if (onerror) {
- onerror();
- }
- return;
- }
-
- this._start({
- recordNumbers: recordNumbers,
- onsuccess: onsuccess,
- onerror: onerror});
- },
-
- _start: function(options) {
- let callback = (function(icons) {
- if (!options.icons) {
- options.icons = [];
- }
- for (let i = 0; i < icons.length; i++) {
- icons[i] = this._parseRawData(icons[i]);
- }
- options.icons[options.currentRecordIndex] = icons;
- options.currentRecordIndex++;
-
- let recordNumbers = options.recordNumbers;
- if (options.currentRecordIndex < recordNumbers.length) {
- let recordNumber = recordNumbers[options.currentRecordIndex];
- this.context.SimRecordHelper.readIMG(recordNumber,
- callback,
- options.onerror);
- } else {
- if (options.onsuccess) {
- options.onsuccess(options.icons);
- }
- }
- }).bind(this);
-
- options.currentRecordIndex = 0;
- this.context.SimRecordHelper.readIMG(options.recordNumbers[0],
- callback,
- options.onerror);
- },
-
- _parseRawData: function(rawData) {
- let codingScheme = rawData.codingScheme;
-
- switch (codingScheme) {
- case ICC_IMG_CODING_SCHEME_BASIC:
- return this._decodeBasicImage(rawData.width, rawData.height, rawData.body);
-
- case ICC_IMG_CODING_SCHEME_COLOR:
- case ICC_IMG_CODING_SCHEME_COLOR_TRANSPARENCY:
- return this._decodeColorImage(codingScheme,
- rawData.width, rawData.height,
- rawData.bitsPerImgPoint,
- rawData.numOfClutEntries,
- rawData.clut, rawData.body);
- }
-
- return null;
- },
-
- _decodeBasicImage: function(width, height, body) {
- let numOfPixels = width * height;
- let pixelIndex = 0;
- let currentByteIndex = 0;
- let currentByte = 0x00;
-
- const BLACK = 0x000000FF;
- const WHITE = 0xFFFFFFFF;
-
- let pixels = [];
- while (pixelIndex < numOfPixels) {
- // Reassign data and index for every byte (8 bits).
- if (pixelIndex % 8 == 0) {
- currentByte = body[currentByteIndex++];
- }
- let bit = (currentByte >> (7 - (pixelIndex % 8))) & 0x01;
- pixels[pixelIndex++] = bit ? WHITE : BLACK;
- }
-
- return {pixels: pixels,
- codingScheme: GECKO_IMG_CODING_SCHEME_BASIC,
- width: width,
- height: height};
- },
-
- _decodeColorImage: function(codingScheme, width, height, bitsPerImgPoint,
- numOfClutEntries, clut, body) {
- let mask = 0xff >> (8 - bitsPerImgPoint);
- let bitsStartOffset = 8 - bitsPerImgPoint;
- let bitIndex = bitsStartOffset;
- let numOfPixels = width * height;
- let pixelIndex = 0;
- let currentByteIndex = 0;
- let currentByte = body[currentByteIndex++];
-
- let pixels = [];
- while (pixelIndex < numOfPixels) {
- // Reassign data and index for every byte (8 bits).
- if (bitIndex < 0) {
- currentByte = body[currentByteIndex++];
- bitIndex = bitsStartOffset;
- }
- let clutEntry = ((currentByte >> bitIndex) & mask);
- let clutIndex = clutEntry * ICC_CLUT_ENTRY_SIZE;
- let alpha = codingScheme == ICC_IMG_CODING_SCHEME_COLOR_TRANSPARENCY &&
- clutEntry == numOfClutEntries - 1;
- pixels[pixelIndex++] = alpha ? 0x00
- : (clut[clutIndex] << 24 |
- clut[clutIndex + 1] << 16 |
- clut[clutIndex + 2] << 8 |
- 0xFF) >>> 0;
- bitIndex -= bitsPerImgPoint;
- }
-
- return {pixels: pixels,
- codingScheme: ICC_IMG_CODING_SCHEME_TO_GECKO[codingScheme],
- width: width,
- height: height};
- },
-};
-
-/**
- * Global stuff.
- */
-
-function Context(aClientId) {
- this.clientId = aClientId;
-
- this.Buf = new BufObject(this);
- this.RIL = new RilObject(this);
- this.RIL.initRILState();
-}
-Context.prototype = {
- clientId: null,
- Buf: null,
- RIL: null,
-
- debug: function(aMessage) {
- GLOBAL.debug("[" + this.clientId + "] " + aMessage);
- }
-};
-
-(function() {
- let lazySymbols = [
- "BerTlvHelper", "BitBufferHelper", "CdmaPDUHelper",
- "ComprehensionTlvHelper", "GsmPDUHelper", "ICCContactHelper",
- "ICCFileHelper", "ICCIOHelper", "ICCPDUHelper", "ICCRecordHelper",
- "ICCUtilsHelper", "RuimRecordHelper", "SimRecordHelper",
- "StkCommandParamsFactory", "StkProactiveCmdHelper", "IconLoader",
- ];
-
- for (let i = 0; i < lazySymbols.length; i++) {
- let symbol = lazySymbols[i];
- Object.defineProperty(Context.prototype, symbol, {
- get: function() {
- let real = new GLOBAL[symbol + "Object"](this);
- Object.defineProperty(this, symbol, {
- value: real,
- enumerable: true
- });
- return real;
- },
- configurable: true,
- enumerable: true
- });
- }
-})();
-
-var ContextPool = {
- _contexts: [],
-
- handleRilMessage: function(aClientId, aUint8Array) {
- let context = this._contexts[aClientId];
- context.Buf.processIncoming(aUint8Array);
- },
-
- handleChromeMessage: function(aMessage) {
- let clientId = aMessage.rilMessageClientId;
- if (clientId != null) {
- let context = this._contexts[clientId];
- context.RIL.handleChromeMessage(aMessage);
- return;
- }
-
- if (DEBUG) debug("Received global chrome message " + JSON.stringify(aMessage));
- let method = this[aMessage.rilMessageType];
- if (typeof method != "function") {
- if (DEBUG) {
- debug("Don't know what to do");
- }
- return;
- }
- method.call(this, aMessage);
- },
-
- setInitialOptions: function(aOptions) {
- DEBUG = DEBUG_WORKER || aOptions.debug;
-
- let quirks = aOptions.quirks;
- RILQUIRKS_CALLSTATE_EXTRA_UINT32 = quirks.callstateExtraUint32;
- RILQUIRKS_REQUEST_USE_DIAL_EMERGENCY_CALL = quirks.requestUseDialEmergencyCall;
- RILQUIRKS_SIM_APP_STATE_EXTRA_FIELDS = quirks.simAppStateExtraFields;
- RILQUIRKS_EXTRA_UINT32_2ND_CALL = quirks.extraUint2ndCall;
- RILQUIRKS_HAVE_QUERY_ICC_LOCK_RETRY_COUNT = quirks.haveQueryIccLockRetryCount;
- RILQUIRKS_SEND_STK_PROFILE_DOWNLOAD = quirks.sendStkProfileDownload;
- RILQUIRKS_DATA_REGISTRATION_ON_DEMAND = quirks.dataRegistrationOnDemand;
- RILQUIRKS_SUBSCRIPTION_CONTROL = quirks.subscriptionControl;
- RILQUIRKS_SIGNAL_EXTRA_INT32 = quirks.signalExtraInt;
- RILQUIRKS_AVAILABLE_NETWORKS_EXTRA_STRING = quirks.availableNetworkExtraStr;
- RILQUIRKS_SMSC_ADDRESS_FORMAT = quirks.smscAddressFormat;
- },
-
- setDebugFlag: function(aOptions) {
- DEBUG = DEBUG_WORKER || aOptions.debug;
- },
-
- registerClient: function(aOptions) {
- let clientId = aOptions.clientId;
- this._contexts[clientId] = new Context(clientId);
- },
-};
-
-function onRILMessage(aClientId, aUint8Array) {
- ContextPool.handleRilMessage(aClientId, aUint8Array);
-}
-
-onmessage = function onmessage(event) {
- ContextPool.handleChromeMessage(event.data);
-};
-
-onerror = function onerror(event) {
- if (DEBUG) debug("onerror" + event.message + "\n");
-};
diff --git a/dom/system/gonk/ril_worker_buf_object.js b/dom/system/gonk/ril_worker_buf_object.js
deleted file mode 100644
index 70018c5b2a..0000000000
--- a/dom/system/gonk/ril_worker_buf_object.js
+++ /dev/null
@@ -1,168 +0,0 @@
-/* global require */
-/* global DEBUG, DEBUG_WORKER */
-/* global RESPONSE_TYPE_SOLICITED */
-/* global RESPONSE_TYPE_UNSOLICITED */
-
-"use strict";
-
-/**
- * This is a specialized worker buffer for the Parcel protocol.
- *
- * NOTE: To prevent including/importing twice, this file should be included
- * in a file which already includes 'ril_consts.js' and 'require.js'.
- */
-(function(exports) {
-
- // Set to true in ril_consts.js to see debug messages
- let DEBUG = DEBUG_WORKER;
- // Need to inherit it.
- let Buf = require("resource://gre/modules/workers/worker_buf.js").Buf;
-
- let BufObject = function(aContext) {
- this.context = aContext;
- // This gets incremented each time we send out a parcel.
- this.mToken = 1;
- // Maps tokens we send out with requests to the request type, so that
- // when we get a response parcel back, we know what request it was for.
- this.mTokenRequestMap = new Map();
- // This is because the underlying 'Buf' is still using the 'init' pattern, so
- // this derived one needs to invoke it.
- // Using 'apply' style to mark it's a parent method calling explicitly.
- Buf._init.apply(this);
-
- // Remapping the request type to different values based on RIL version.
- // We only have to do this for SUBSCRIPTION right now, so I just make it
- // simple. A generic logic or structure could be discussed if we have more
- // use cases, especially the cases from different partners.
- this._requestMap = {};
- // RIL version 8.
- // For the CAF's proprietary parcels. Please see
- // https://www.codeaurora.org/cgit/quic/la/platform/hardware/ril/tree/include/telephony/ril.h?h=b2g_jb_3.2
- let map = {};
- map[REQUEST_SET_UICC_SUBSCRIPTION] = 114;
- map[REQUEST_SET_DATA_SUBSCRIPTION] = 115;
- this._requestMap[8] = map;
- // RIL version 9.
- // For the CAF's proprietary parcels. Please see
- // https://www.codeaurora.org/cgit/quic/la/platform/hardware/ril/tree/include/telephony/ril.h?h=b2g_kk_3.5
- map = {};
- map[REQUEST_SET_UICC_SUBSCRIPTION] = 115;
- map[REQUEST_SET_DATA_SUBSCRIPTION] = 116;
- this._requestMap[9] = map;
- };
-
- /**
- * "inherit" the basic worker buffer.
- */
- BufObject.prototype = Object.create(Buf);
-
- /**
- * Process one parcel.
- */
- BufObject.prototype.processParcel = function() {
- let responseType = this.readInt32();
-
- let requestType, options;
- if (responseType == RESPONSE_TYPE_SOLICITED) {
- let token = this.readInt32();
- let error = this.readInt32();
-
- options = this.mTokenRequestMap.get(token);
- if (!options) {
- if (DEBUG) {
- this.context.debug("Suspicious uninvited request found: " +
- token + ". Ignored!");
- }
- return;
- }
-
- this.mTokenRequestMap.delete(token);
- requestType = options.rilRequestType;
-
- if (error !== ERROR_SUCCESS) {
- options.errorMsg = RIL_ERROR_TO_GECKO_ERROR[error] ||
- GECKO_ERROR_UNSPECIFIED_ERROR;
- }
- if (DEBUG) {
- this.context.debug("Solicited response for request type " + requestType +
- ", token " + token + ", error " + error);
- }
- } else if (responseType == RESPONSE_TYPE_UNSOLICITED) {
- requestType = this.readInt32();
- if (DEBUG) {
- this.context.debug("Unsolicited response for request type " + requestType);
- }
- } else {
- if (DEBUG) {
- this.context.debug("Unknown response type: " + responseType);
- }
- return;
- }
-
- this.context.RIL.handleParcel(requestType, this.readAvailable, options);
- };
-
- /**
- * Start a new outgoing parcel.
- *
- * @param type
- * Integer specifying the request type.
- * @param options [optional]
- * Object containing information about the request, e.g. the
- * original main thread message object that led to the RIL request.
- */
- BufObject.prototype.newParcel = function(type, options) {
- if (DEBUG) {
- this.context.debug("New outgoing parcel of type " + type);
- }
-
- // We're going to leave room for the parcel size at the beginning.
- this.outgoingIndex = this.PARCEL_SIZE_SIZE;
- this.writeInt32(this._reMapRequestType(type));
- this.writeInt32(this.mToken);
-
- if (!options) {
- options = {};
- }
- options.rilRequestType = type;
- this.mTokenRequestMap.set(this.mToken, options);
- this.mToken++;
- return this.mToken;
- };
-
- BufObject.prototype.simpleRequest = function(type, options) {
- this.newParcel(type, options);
- this.sendParcel();
- };
-
- BufObject.prototype.onSendParcel = function(parcel) {
- self.postRILMessage(this.context.clientId, parcel);
- };
-
- /**
- * Remapping the request type to different values based on RIL version.
- * We only have to do this for SUBSCRIPTION right now, so I just make it
- * simple. A generic logic or structure could be discussed if we have more
- * use cases, especially the cases from different partners.
- */
- BufObject.prototype._reMapRequestType = function(type) {
- for (let version in this._requestMap) {
- if (this.context.RIL.version <= version) {
- let newType = this._requestMap[version][type];
- if (newType) {
- if (DEBUG) {
- this.context.debug("Remap request type to " + newType);
- }
- return newType;
- }
- }
- }
- return type;
- };
-
- // Before we make sure to form it as a module would not add extra
- // overhead of module loading, we need to define it in this way
- // rather than 'module.exports' it as a module component.
- exports.BufObject = BufObject;
-})(self); // in worker self is the global
-
diff --git a/dom/system/gonk/ril_worker_telephony_request_queue.js b/dom/system/gonk/ril_worker_telephony_request_queue.js
deleted file mode 100644
index 4dba7a42fb..0000000000
--- a/dom/system/gonk/ril_worker_telephony_request_queue.js
+++ /dev/null
@@ -1,157 +0,0 @@
-/* global DEBUG, DEBUG_WORKER */
-/* global REQUEST_GET_CURRENT_CALLS */
-/* global REQUEST_ANSWER, REQUEST_CONFERENCE, REQUEST_DIAL */
-/* global REQUEST_DIAL_EMERGENCY_CALL, REQUEST_HANGUP */
-/* global REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND */
-/* global REQUEST_HANGUP_WAITING_OR_BACKGROUND */
-/* global REQUEST_SEPARATE_CONNECTION */
-/* global REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE, REQUEST_UDUB */
-
-"use strict";
-
-(function(exports) {
-
- const TELEPHONY_REQUESTS = [
- REQUEST_GET_CURRENT_CALLS,
- REQUEST_ANSWER,
- REQUEST_CONFERENCE,
- REQUEST_DIAL,
- REQUEST_DIAL_EMERGENCY_CALL,
- REQUEST_HANGUP,
- REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND,
- REQUEST_HANGUP_WAITING_OR_BACKGROUND,
- REQUEST_SEPARATE_CONNECTION,
- REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE,
- REQUEST_UDUB
- ];
-
- // Set to true in ril_consts.js to see debug messages
- let DEBUG = DEBUG_WORKER;
-
- /**
- * Queue entry; only used in the queue.
- */
- let TelephonyRequestEntry = function(request, callback) {
- this.request = request;
- this.callback = callback;
- };
-
- let TelephonyRequestQueue = function(ril) {
- this.ril = ril;
- this.currentQueue = null; // Point to the current running queue.
-
- this.queryQueue = [];
- this.controlQueue = [];
- };
-
- TelephonyRequestQueue.prototype._getQueue = function(request) {
- return (request === REQUEST_GET_CURRENT_CALLS) ? this.queryQueue
- : this.controlQueue;
- };
-
- TelephonyRequestQueue.prototype._getAnotherQueue = function(queue) {
- return (this.queryQueue === queue) ? this.controlQueue : this.queryQueue;
- };
-
- TelephonyRequestQueue.prototype._find = function(queue, request) {
- for (let i = 0; i < queue.length; ++i) {
- if (queue[i].request === request) {
- return i;
- }
- }
- return -1;
- };
-
- TelephonyRequestQueue.prototype._startQueue = function(queue) {
- if (queue.length === 0) {
- return;
- }
-
- // We only need to keep one entry for queryQueue.
- if (queue === this.queryQueue) {
- queue.splice(1, queue.length - 1);
- }
-
- this.currentQueue = queue;
- for (let entry of queue) {
- this._executeEntry(entry);
- }
- };
-
- TelephonyRequestQueue.prototype._executeEntry = function(entry) {
- if (DEBUG) {
- this.debug("execute " + this._getRequestName(entry.request));
- }
- entry.callback();
- };
-
- TelephonyRequestQueue.prototype._getRequestName = function(request) {
- let method = this.ril[request];
- return (typeof method === 'function') ? method.name : "";
- };
-
- TelephonyRequestQueue.prototype.debug = function(msg) {
- this.ril.context.debug("[TeleQ] " + msg);
- };
-
- TelephonyRequestQueue.prototype.isValidRequest = function(request) {
- return TELEPHONY_REQUESTS.indexOf(request) !== -1;
- };
-
- TelephonyRequestQueue.prototype.push = function(request, callback) {
- if (!this.isValidRequest(request)) {
- if (DEBUG) {
- this.debug("Error: " + this._getRequestName(request) +
- " is not a telephony request");
- }
- return;
- }
-
- if (DEBUG) {
- this.debug("push " + this._getRequestName(request));
- }
- let entry = new TelephonyRequestEntry(request, callback);
- let queue = this._getQueue(request);
- queue.push(entry);
-
- // Try to run the request.
- if (this.currentQueue === queue) {
- this._executeEntry(entry);
- } else if (!this.currentQueue) {
- this._startQueue(queue);
- }
- };
-
- TelephonyRequestQueue.prototype.pop = function(request) {
- if (!this.isValidRequest(request)) {
- if (DEBUG) {
- this.debug("Error: " + this._getRequestName(request) +
- " is not a telephony request");
- }
- return;
- }
-
- if (DEBUG) {
- this.debug("pop " + this._getRequestName(request));
- }
- let queue = this._getQueue(request);
- let index = this._find(queue, request);
- if (index === -1) {
- throw new Error("Cannot find the request in telephonyRequestQueue.");
- } else {
- queue.splice(index, 1);
- }
-
- if (queue.length === 0) {
- this.currentQueue = null;
- this._startQueue(this._getAnotherQueue(queue));
- }
- };
-
-
- // Before we make sure to form it as a module would not add extra
- // overhead of module loading, we need to define it in this way
- // rather than 'module.exports' it as a module component.
- exports.TelephonyRequestQueue = TelephonyRequestQueue;
-})(self); // in worker self is the global
-
diff --git a/dom/system/gonk/systemlibs.js b/dom/system/gonk/systemlibs.js
deleted file mode 100644
index a27b30e20d..0000000000
--- a/dom/system/gonk/systemlibs.js
+++ /dev/null
@@ -1,201 +0,0 @@
-/* Copyright 2012 Mozilla Foundation and Mozilla contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-if (!this.ctypes) {
- // We're likely being loaded as a JSM.
- this.EXPORTED_SYMBOLS = [ "libcutils", "netHelpers" ];
- Components.utils.import("resource://gre/modules/ctypes.jsm");
-}
-
-const SYSTEM_PROPERTY_KEY_MAX = 32;
-const SYSTEM_PROPERTY_VALUE_MAX = 92;
-
-// We leave this as 'undefined' instead of setting it to 'false'. That
-// way a file that includes us can have it defined already without us
-// overriding the value here.
-var DEBUG;
-
-/**
- * Expose some system-level functions.
- */
-this.libcutils = (function() {
- let lib;
- try {
- lib = ctypes.open("libcutils.so");
- } catch(ex) {
- // Return a fallback option in case libcutils.so isn't present (e.g.
- // when building Firefox with MOZ_B2G_RIL.
- if (DEBUG) {
- dump("Could not load libcutils.so. Using fake propdb.\n");
- }
- let fake_propdb = Object.create(null);
- return {
- property_get: function(key, defaultValue) {
- if (key in fake_propdb) {
- return fake_propdb[key];
- }
- return defaultValue === undefined ? null : defaultValue;
- },
- property_set: function(key, value) {
- fake_propdb[key] = value;
- }
- };
- }
-
- let c_property_get = lib.declare("property_get", ctypes.default_abi,
- ctypes.int, // return value: length
- ctypes.char.ptr, // key
- ctypes.char.ptr, // value
- ctypes.char.ptr); // default
- let c_property_set = lib.declare("property_set", ctypes.default_abi,
- ctypes.int, // return value: success
- ctypes.char.ptr, // key
- ctypes.char.ptr); // value
- let c_value_buf = ctypes.char.array(SYSTEM_PROPERTY_VALUE_MAX)();
-
- return {
-
- /**
- * Get a system property.
- *
- * @param key
- * Name of the property
- * @param defaultValue [optional]
- * Default value to return if the property isn't set (default: null)
- */
- property_get: function(key, defaultValue) {
- if (defaultValue === undefined) {
- defaultValue = null;
- }
- c_property_get(key, c_value_buf, defaultValue);
- return c_value_buf.readString();
- },
-
- /**
- * Set a system property
- *
- * @param key
- * Name of the property
- * @param value
- * Value to set the property to.
- */
- property_set: function(key, value) {
- let rv = c_property_set(key, value);
- if (rv) {
- throw Error('libcutils.property_set("' + key + '", "' + value +
- '") failed with error ' + rv);
- }
- }
-
- };
-})();
-
-/**
- * Helpers for conversions.
- */
-this.netHelpers = {
-
- /**
- * Swap byte orders for 32-bit value
- */
- swap32: function(n) {
- return (((n >> 24) & 0xFF) << 0) |
- (((n >> 16) & 0xFF) << 8) |
- (((n >> 8) & 0xFF) << 16) |
- (((n >> 0) & 0xFF) << 24);
- },
-
- /**
- * Convert network byte order to host byte order
- * Note: Assume that the system is little endian
- */
- ntohl: function(n) {
- return this.swap32(n);
- },
-
- /**
- * Convert host byte order to network byte order
- * Note: Assume that the system is little endian
- */
- htonl: function(n) {
- return this.swap32(n);
- },
-
- /**
- * Convert integer representation of an IP address to the string
- * representation.
- *
- * @param ip
- * IP address in number format.
- */
- ipToString: function(ip) {
- return ((ip >> 0) & 0xFF) + "." +
- ((ip >> 8) & 0xFF) + "." +
- ((ip >> 16) & 0xFF) + "." +
- ((ip >> 24) & 0xFF);
- },
-
- /**
- * Convert string representation of an IP address to the integer
- * representation (network byte order).
- *
- * @param string
- * String containing the IP address.
- */
- stringToIP: function(string) {
- if (!string) {
- return null;
- }
- let ip = 0;
- let start, end = -1;
- for (let i = 0; i < 4; i++) {
- start = end + 1;
- end = string.indexOf(".", start);
- if (end == -1) {
- end = string.length;
- }
- let num = parseInt(string.slice(start, end), 10);
- if (isNaN(num)) {
- return null;
- }
- ip |= num << (i * 8);
- }
- return ip;
- },
-
- /**
- * Make a subnet mask.
- */
- makeMask: function(len) {
- let mask = 0;
- for (let i = 0; i < len; ++i) {
- mask |= (0x80000000 >> i);
- }
- return this.ntohl(mask);
- },
-
- /**
- * Get Mask length from given mask address
- */
- getMaskLength: function(mask) {
- let len = 0;
- let netmask = this.ntohl(mask);
- while (netmask & 0x80000000) {
- len++;
- netmask = netmask << 1;
- }
- return len;
- }
-};
diff --git a/dom/system/gonk/tests/header_helpers.js b/dom/system/gonk/tests/header_helpers.js
deleted file mode 100644
index 8d1144f75b..0000000000
--- a/dom/system/gonk/tests/header_helpers.js
+++ /dev/null
@@ -1,217 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-var {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
-
-
-var subscriptLoader = Cc["@mozilla.org/moz/jssubscript-loader;1"]
- .getService(Ci.mozIJSSubScriptLoader);
-
-/**
- * Start a new RIL worker.
- *
- * @param custom_ns
- * Namespace with symbols to be injected into the new worker
- * namespace.
- *
- * @return an object that represents the worker's namespace.
- *
- * @note that this does not start an actual worker thread. The worker
- * is executed on the main thread, within a separate namespace object.
- */
-function newWorker(custom_ns) {
- let worker_ns = {
- importScripts: function() {
- Array.slice(arguments).forEach(function(script) {
- if (!script.startsWith("resource:")) {
- script = "resource://gre/modules/" + script;
- }
- subscriptLoader.loadSubScript(script, this);
- }, this);
- },
-
- postRILMessage: function(message) {
- },
-
- postMessage: function(message) {
- },
-
- // Define these variables inside the worker scope so ES5 strict mode
- // doesn't flip out.
- onmessage: undefined,
- onerror: undefined,
-
- DEBUG: true
- };
- // The 'self' variable in a worker points to the worker's own namespace.
- worker_ns.self = worker_ns;
-
- // Copy the custom definitions over.
- for (let key in custom_ns) {
- worker_ns[key] = custom_ns[key];
- }
-
- // fake require() for toolkit/components/workerloader/require.js
- let require = (function() {
- return function require(script) {
- worker_ns.module = {};
- worker_ns.importScripts(script);
- return worker_ns;
- }
- })();
-
- Object.freeze(require);
- Object.defineProperty(worker_ns, "require", {
- value: require,
- enumerable: true,
- configurable: false
- });
-
- // Load the RIL worker itself.
- worker_ns.importScripts("ril_worker.js");
-
- // Register at least one client.
- worker_ns.ContextPool.registerClient({ clientId: 0 });
-
- return worker_ns;
-}
-
-/**
- * Create a buffered RIL worker.
- *
- * @return A worker object that stores sending octets in a internal buffer.
- */
-function newUint8Worker() {
- let worker = newWorker();
- let index = 0; // index for read
- let buf = [];
-
- let context = worker.ContextPool._contexts[0];
- context.Buf.writeUint8 = function(value) {
- buf.push(value);
- };
-
- context.Buf.readUint8 = function() {
- return buf[index++];
- };
-
- context.Buf.seekIncoming = function(offset) {
- index += offset;
- };
-
- context.Buf.getReadAvailable = function() {
- return buf.length - index;
- };
-
- worker.debug = do_print;
-
- return worker;
-}
-
-/**
- * Create a worker that keeps posted chrome message.
- */
-function newInterceptWorker() {
- let postedMessage;
- let worker = newWorker({
- postRILMessage: function(data) {
- },
- postMessage: function(message) {
- postedMessage = message;
- }
- });
- return {
- get postedMessage() {
- return postedMessage;
- },
- get worker() {
- return worker;
- }
- };
-}
-
-/**
- * Create a parcel suitable for postRILMessage().
- *
- * @param fakeParcelSize
- * Value to be written to parcel size field for testing
- * incorrect/incomplete parcel reading. Replaced with correct
- * one determined length of data if negative.
- * @param response
- * Response code of the incoming parcel.
- * @param request
- * Request code of the incoming parcel.
- * @param data
- * Extra data to be appended.
- *
- * @return an Uint8Array carrying all parcel data.
- */
-function newIncomingParcel(fakeParcelSize, response, request, data) {
- const UINT32_SIZE = 4;
- const PARCEL_SIZE_SIZE = 4;
-
- let realParcelSize = data.length + 2 * UINT32_SIZE;
- let buffer = new ArrayBuffer(realParcelSize + PARCEL_SIZE_SIZE);
- let bytes = new Uint8Array(buffer);
-
- let writeIndex = 0;
- function writeUint8(value) {
- bytes[writeIndex] = value;
- ++writeIndex;
- }
-
- function writeInt32(value) {
- writeUint8(value & 0xff);
- writeUint8((value >> 8) & 0xff);
- writeUint8((value >> 16) & 0xff);
- writeUint8((value >> 24) & 0xff);
- }
-
- function writeParcelSize(value) {
- writeUint8((value >> 24) & 0xff);
- writeUint8((value >> 16) & 0xff);
- writeUint8((value >> 8) & 0xff);
- writeUint8(value & 0xff);
- }
-
- if (fakeParcelSize < 0) {
- fakeParcelSize = realParcelSize;
- }
- writeParcelSize(fakeParcelSize);
-
- writeInt32(response);
- writeInt32(request);
-
- // write parcel data
- for (let ii = 0; ii < data.length; ++ii) {
- writeUint8(data[ii]);
- }
-
- return bytes;
-}
-
-/**
- * Create a parcel buffer which represents the hex string.
- *
- * @param hexString
- * The HEX string to be converted.
- *
- * @return an Uint8Array carrying all parcel data.
- */
-function hexStringToParcelByteArrayData(hexString) {
- let length = Math.ceil((hexString.length / 2));
- let bytes = new Uint8Array(4 + length);
-
- bytes[0] = length & 0xFF;
- bytes[1] = (length >> 8) & 0xFF;
- bytes[2] = (length >> 16) & 0xFF;
- bytes[3] = (length >> 24) & 0xFF;
-
- for (let i = 0; i < length; i ++) {
- bytes[i + 4] = Number.parseInt(hexString.substr(i * 2, 2), 16);
- }
-
- return bytes;
-}
diff --git a/dom/system/gonk/tests/marionette/head.js b/dom/system/gonk/tests/marionette/head.js
deleted file mode 100644
index 5a6ee1272d..0000000000
--- a/dom/system/gonk/tests/marionette/head.js
+++ /dev/null
@@ -1,345 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-MARIONETTE_CONTEXT = "chrome";
-
-const SETTINGS_KEY_DATA_ENABLED = "ril.data.enabled";
-const SETTINGS_KEY_DATA_APN_SETTINGS = "ril.data.apnSettings";
-const SETTINGS_KEY_WIFI_ENABLED = "wifi.enabled";
-
-const TOPIC_CONNECTION_STATE_CHANGED = "network-connection-state-changed";
-const TOPIC_NETWORK_ACTIVE_CHANGED = "network-active-changed";
-
-const NETWORK_STATE_UNKNOWN = Ci.nsINetworkInfo.NETWORK_STATE_UNKNOWN;
-const NETWORK_STATE_CONNECTING = Ci.nsINetworkInfo.NETWORK_STATE_CONNECTING;
-const NETWORK_STATE_CONNECTED = Ci.nsINetworkInfo.NETWORK_STATE_CONNECTED;
-const NETWORK_STATE_DISCONNECTING = Ci.nsINetworkInfo.NETWORK_STATE_DISCONNECTING;
-const NETWORK_STATE_DISCONNECTED = Ci.nsINetworkInfo.NETWORK_STATE_DISCONNECTED;
-
-const NETWORK_TYPE_MOBILE = Ci.nsINetworkInfo.NETWORK_TYPE_MOBILE;
-const NETWORK_TYPE_MOBILE_MMS = Ci.nsINetworkInfo.NETWORK_TYPE_MOBILE_MMS;
-const NETWORK_TYPE_MOBILE_SUPL = Ci.nsINetworkInfo.NETWORK_TYPE_MOBILE_SUPL;
-const NETWORK_TYPE_MOBILE_IMS = Ci.nsINetworkInfo.NETWORK_TYPE_MOBILE_IMS;
-const NETWORK_TYPE_MOBILE_DUN = Ci.nsINetworkInfo.NETWORK_TYPE_MOBILE_DUN;
-const NETWORK_TYPE_MOBILE_FOTA = Ci.nsINetworkInfo.NETWORK_TYPE_MOBILE_FOTA;
-
-const networkTypes = [
- NETWORK_TYPE_MOBILE,
- NETWORK_TYPE_MOBILE_MMS,
- NETWORK_TYPE_MOBILE_SUPL,
- NETWORK_TYPE_MOBILE_IMS,
- NETWORK_TYPE_MOBILE_DUN,
- NETWORK_TYPE_MOBILE_FOTA
-];
-
-var Promise = Cu.import("resource://gre/modules/Promise.jsm").Promise;
-
-var ril = Cc["@mozilla.org/ril;1"].getService(Ci.nsIRadioInterfaceLayer);
-ok(ril, "ril.constructor is " + ril.constructor);
-
-var radioInterface = ril.getRadioInterface(0);
-ok(radioInterface, "radioInterface.constructor is " + radioInterface.constrctor);
-
-var _pendingEmulatorShellCmdCount = 0;
-var _pendingEmulatorCmdCount = 0;
-
-/**
- * Send emulator shell command with safe guard.
- *
- * We should only call |finish()| after all emulator shell command transactions
- * end, so here comes with the pending counter. Resolve when the emulator
- * shell gives response. Never reject.
- *
- * Fulfill params:
- * result -- an array of emulator shell response lines.
- *
- * @param aCommands
- * A string array commands to be passed to emulator through adb shell.
- *
- * @return A deferred promise.
- */
-function runEmulatorShellCmdSafe(aCommands) {
- return new Promise(function(aResolve, aReject) {
- ++_pendingEmulatorShellCmdCount;
- runEmulatorShell(aCommands, function(aResult) {
- --_pendingEmulatorShellCmdCount;
-
- log("Emulator shell response: " + JSON.stringify(aResult));
- aResolve(aResult);
- });
- });
-}
-
-/**
- * Send emulator 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 runEmulatorCmdSafe(aCommand) {
- log(aCommand);
- return new Promise(function(aResolve, aReject) {
- ++_pendingEmulatorCmdCount;
- runEmulatorCmd(aCommand, function(aResult) {
- --_pendingEmulatorCmdCount;
-
- log("Emulator console response: " + JSON.stringify(aResult));
- if (Array.isArray(aResult) &&
- aResult[aResult.length - 1] === "OK") {
- aResolve(aResult);
- } else {
- aReject(aResult);
- }
- });
- });
-}
-
-/**
- * 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 = window.navigator.mozSettings.createLock().get(aKey);
- return request.then(function resolve(aValue) {
- log("getSettings(" + aKey + ") - success");
- return aValue[aKey];
- }, function reject(aError) {
- ok(aAllowError, "getSettings(" + aKey + ") - error");
- });
-}
-
-/**
- * Set mozSettings values.
- *
- * 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 setSettings(aKey, aValue, aAllowError) {
- let settings = {};
- settings[aKey] = aValue;
- let lock = window.navigator.mozSettings.createLock();
- let request = lock.set(settings);
- let deferred = Promise.defer();
- lock.onsettingstransactionsuccess = function () {
- log("setSettings(" + JSON.stringify(settings) + ") - success");
- deferred.resolve();
- };
- lock.onsettingstransactionfailure = function () {
- ok(aAllowError, "setSettings(" + JSON.stringify(settings) + ") - error");
- // We resolve even though we've thrown an error, since the ok()
- // will do that.
- deferred.resolve();
- };
- return deferred.promise;
-}
-
-/**
- * Wait for observer event.
- *
- * Resolve if that topic event occurs. Never reject.
- *
- * Fulfill params: the subject passed.
- *
- * @param aTopic
- * A string topic name.
- *
- * @return A deferred promise.
- */
-function waitForObserverEvent(aTopic) {
- let obs = Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService);
- let deferred = Promise.defer();
-
- obs.addObserver(function observer(subject, topic, data) {
- if (topic === aTopic) {
- obs.removeObserver(observer, aTopic);
- deferred.resolve(subject);
- }
- }, aTopic, false);
-
- return deferred.promise;
-}
-
-/**
- * Wait for one named event.
- *
- * Resolve if that named event occurs. Never reject.
- *
- * Fulfill params: the DOMEvent passed.
- *
- * @param aEventTarget
- * An EventTarget object.
- * @param aEventName
- * A string event name.
- * @param aMatchFun [optional]
- * A matching function returns true or false to filter the event.
- *
- * @return A deferred promise.
- */
-function waitForTargetEvent(aEventTarget, aEventName, aMatchFun) {
- return new Promise(function(aResolve, aReject) {
- aEventTarget.addEventListener(aEventName, function onevent(aEvent) {
- if (!aMatchFun || aMatchFun(aEvent)) {
- aEventTarget.removeEventListener(aEventName, onevent);
- ok(true, "Event '" + aEventName + "' got.");
- aResolve(aEvent);
- }
- });
- });
-}
-
-/**
- * Set the default data connection enabling state, wait for
- * "network-connection-state-changed" event and verify state.
- *
- * Fulfill params: instance of nsIRilNetworkInfo of the network connected.
- *
- * @param aEnabled
- * A boolean state.
- *
- * @return A deferred promise.
- */
-function setDataEnabledAndWait(aEnabled) {
- let promises = [];
- promises.push(waitForObserverEvent(TOPIC_CONNECTION_STATE_CHANGED)
- .then(function(aSubject) {
- ok(aSubject instanceof Ci.nsIRilNetworkInfo,
- "subject should be an instance of nsIRilNetworkInfo");
- is(aSubject.type, NETWORK_TYPE_MOBILE,
- "subject.type should be " + NETWORK_TYPE_MOBILE);
- is(aSubject.state,
- aEnabled ? Ci.nsINetworkInfo.NETWORK_STATE_CONNECTED
- : Ci.nsINetworkInfo.NETWORK_STATE_DISCONNECTED,
- "subject.state should be " + aEnabled ? "CONNECTED" : "DISCONNECTED");
-
- return aSubject;
- }));
- promises.push(setSettings(SETTINGS_KEY_DATA_ENABLED, aEnabled));
-
- return Promise.all(promises).then(aValues => aValues[0]);
-}
-
-/**
- * Setup a certain type of data connection, wait for
- * "network-connection-state-changed" event and verify state.
- *
- * Fulfill params: instance of nsIRilNetworkInfo of the network connected.
- *
- * @param aNetworkType
- * The mobile network type to setup.
- *
- * @return A deferred promise.
- */
-function setupDataCallAndWait(aNetworkType) {
- log("setupDataCallAndWait: " + aNetworkType);
-
- let promises = [];
- promises.push(waitForObserverEvent(TOPIC_CONNECTION_STATE_CHANGED)
- .then(function(aSubject) {
- ok(aSubject instanceof Ci.nsIRilNetworkInfo,
- "subject should be an instance of nsIRilNetworkInfo");
- is(aSubject.type, aNetworkType,
- "subject.type should be " + aNetworkType);
- is(aSubject.state, Ci.nsINetworkInfo.NETWORK_STATE_CONNECTED,
- "subject.state should be CONNECTED");
-
- return aSubject;
- }));
- promises.push(radioInterface.setupDataCallByType(aNetworkType));
-
- return Promise.all(promises).then(aValues => aValues[0]);
-}
-
-/**
- * Deactivate a certain type of data connection, wait for
- * "network-connection-state-changed" event and verify state.
- *
- * Fulfill params: (none)
- *
- * @param aNetworkType
- * The mobile network type to deactivate.
- *
- * @return A deferred promise.
- */
-function deactivateDataCallAndWait(aNetworkType) {
- log("deactivateDataCallAndWait: " + aNetworkType);
-
- let promises = [];
- promises.push(waitForObserverEvent(TOPIC_CONNECTION_STATE_CHANGED)
- .then(function(aSubject) {
- ok(aSubject instanceof Ci.nsIRilNetworkInfo,
- "subject should be an instance of nsIRilNetworkInfo");
- is(aSubject.type, aNetworkType,
- "subject.type should be " + aNetworkType);
- is(aSubject.state, Ci.nsINetworkInfo.NETWORK_STATE_DISCONNECTED,
- "subject.state should be DISCONNECTED");
- }));
- promises.push(radioInterface.deactivateDataCallByType(aNetworkType));
-
- return Promise.all(promises);
-}
-
-/**
- * Wait for pending emulator transactions and call |finish()|.
- */
-function cleanUp() {
- // Use ok here so that we have at least one test run.
- ok(true, ":: CLEANING UP ::");
-
- waitFor(finish, function() {
- return _pendingEmulatorShellCmdCount === 0 &&
- _pendingEmulatorCmdCount === 0;
- });
-}
-
-/**
- * Basic test routine helper.
- *
- * This helper does nothing but clean-ups.
- *
- * @param aTestCaseMain
- * A function that takes no parameter.
- */
-function startTestBase(aTestCaseMain) {
- Promise.resolve()
- .then(aTestCaseMain)
- .then(cleanUp, function(aException) {
- ok(false, "promise rejects during test: " + aException);
- cleanUp();
- });
-}
diff --git a/dom/system/gonk/tests/marionette/manifest.ini b/dom/system/gonk/tests/marionette/manifest.ini
deleted file mode 100644
index 528fe3baff..0000000000
--- a/dom/system/gonk/tests/marionette/manifest.ini
+++ /dev/null
@@ -1,19 +0,0 @@
-[DEFAULT]
-run-if = buildapp == 'b2g'
-
-[test_geolocation.js]
-skip-if = true # Bug 808783
-[test_fakevolume.js]
-[test_ril_code_quality.py]
-[test_screen_state.js]
-[test_dsds_numRadioInterfaces.js]
-[test_data_connection.js]
-[test_network_active_changed.js]
-[test_multiple_data_connection.js]
-[test_data_connection_proxy.js]
-[test_network_interface_list_service.js]
-[test_all_network_info.js]
-[test_network_interface_mtu.js]
-skip-if = android_version < '19'
-[test_timezone_changes.js]
-skip-if = android_version < '19'
diff --git a/dom/system/gonk/tests/marionette/ril_jshint/README.md b/dom/system/gonk/tests/marionette/ril_jshint/README.md
deleted file mode 100644
index a63967d633..0000000000
--- a/dom/system/gonk/tests/marionette/ril_jshint/README.md
+++ /dev/null
@@ -1,9 +0,0 @@
-Test RIL Code Quality
-=====================
-
-For more information, please refer to
-
-* Bug 880643 - B2G RIL: Add a code quality test on try server for RIL javascript code in gecko
-* Slide: https://speakerdeck.com/aknow/improve-code-quality-of-ril-code-by-jshint
-* Document: https://hackpad.com/Code-Quality-Test-For-RIL-Javascript-Code-In-Gecko-cz5j7YIGiw8
-
diff --git a/dom/system/gonk/tests/marionette/ril_jshint/jshint.js b/dom/system/gonk/tests/marionette/ril_jshint/jshint.js
deleted file mode 100644
index ec5263a5b9..0000000000
--- a/dom/system/gonk/tests/marionette/ril_jshint/jshint.js
+++ /dev/null
@@ -1,11096 +0,0 @@
-//2.1.3
-var JSHINT;
-(function () {
-var require;
-require=(function(e,t,n){function i(n,s){if(!t[n]){if(!e[n]){var o=typeof require=="function"&&require;if(!s&&o)return o(n,!0);if(r)return r(n,!0);throw new Error("Cannot find module '"+n+"'")}var u=t[n]={exports:{}};e[n][0].call(u.exports,function(t){var r=e[n][1][t];return i(r?r:t)},u,u.exports)}return t[n].exports}var r=typeof require=="function"&&require;for(var s=0;s<n.length;s++)i(n[s]);return i})({1:[function(require,module,exports){
-// shim for using process in browser
-
-var process = module.exports = {};
-
-process.nextTick = (function () {
- var canSetImmediate = typeof window !== 'undefined'
- && window.setImmediate;
- var canPost = typeof window !== 'undefined'
- && window.postMessage && window.addEventListener
- ;
-
- if (canSetImmediate) {
- return function (f) { return window.setImmediate(f) };
- }
-
- if (canPost) {
- var queue = [];
- window.addEventListener('message', function (ev) {
- if (ev.source === window && ev.data === 'process-tick') {
- ev.stopPropagation();
- if (queue.length > 0) {
- var fn = queue.shift();
- fn();
- }
- }
- }, true);
-
- return function nextTick(fn) {
- queue.push(fn);
- window.postMessage('process-tick', '*');
- };
- }
-
- return function nextTick(fn) {
- setTimeout(fn, 0);
- };
-})();
-
-process.title = 'browser';
-process.browser = true;
-process.env = {};
-process.argv = [];
-
-process.binding = function (name) {
- throw new Error('process.binding is not supported');
-}
-
-// TODO(shtylman)
-process.cwd = function () { return '/' };
-process.chdir = function (dir) {
- throw new Error('process.chdir is not supported');
-};
-
-},{}],2:[function(require,module,exports){
-(function(process){if (!process.EventEmitter) process.EventEmitter = function () {};
-
-var EventEmitter = exports.EventEmitter = process.EventEmitter;
-var isArray = typeof Array.isArray === 'function'
- ? Array.isArray
- : function (xs) {
- return Object.prototype.toString.call(xs) === '[object Array]'
- }
-;
-function indexOf (xs, x) {
- if (xs.indexOf) return xs.indexOf(x);
- for (var i = 0; i < xs.length; i++) {
- if (x === xs[i]) return i;
- }
- return -1;
-}
-
-// By default EventEmitters will print a warning if more than
-// 10 listeners are added to it. This is a useful default which
-// helps finding memory leaks.
-//
-// Obviously not all Emitters should be limited to 10. This function allows
-// that to be increased. Set to zero for unlimited.
-var defaultMaxListeners = 10;
-EventEmitter.prototype.setMaxListeners = function(n) {
- if (!this._events) this._events = {};
- this._events.maxListeners = n;
-};
-
-
-EventEmitter.prototype.emit = function(type) {
- // If there is no 'error' event listener then throw.
- if (type === 'error') {
- if (!this._events || !this._events.error ||
- (isArray(this._events.error) && !this._events.error.length))
- {
- if (arguments[1] instanceof Error) {
- throw arguments[1]; // Unhandled 'error' event
- } else {
- throw new Error("Uncaught, unspecified 'error' event.");
- }
- return false;
- }
- }
-
- if (!this._events) return false;
- var handler = this._events[type];
- if (!handler) return false;
-
- if (typeof handler == 'function') {
- switch (arguments.length) {
- // fast cases
- case 1:
- handler.call(this);
- break;
- case 2:
- handler.call(this, arguments[1]);
- break;
- case 3:
- handler.call(this, arguments[1], arguments[2]);
- break;
- // slower
- default:
- var args = Array.prototype.slice.call(arguments, 1);
- handler.apply(this, args);
- }
- return true;
-
- } else if (isArray(handler)) {
- var args = Array.prototype.slice.call(arguments, 1);
-
- var listeners = handler.slice();
- for (var i = 0, l = listeners.length; i < l; i++) {
- listeners[i].apply(this, args);
- }
- return true;
-
- } else {
- return false;
- }
-};
-
-// EventEmitter is defined in src/node_events.cc
-// EventEmitter.prototype.emit() is also defined there.
-EventEmitter.prototype.addListener = function(type, listener) {
- if ('function' !== typeof listener) {
- throw new Error('addListener only takes instances of Function');
- }
-
- if (!this._events) this._events = {};
-
- // To avoid recursion in the case that type == "newListeners"! Before
- // adding it to the listeners, first emit "newListeners".
- this.emit('newListener', type, listener);
-
- if (!this._events[type]) {
- // Optimize the case of one listener. Don't need the extra array object.
- this._events[type] = listener;
- } else if (isArray(this._events[type])) {
-
- // Check for listener leak
- if (!this._events[type].warned) {
- var m;
- if (this._events.maxListeners !== undefined) {
- m = this._events.maxListeners;
- } else {
- m = defaultMaxListeners;
- }
-
- if (m && m > 0 && this._events[type].length > m) {
- this._events[type].warned = true;
- console.error('(node) warning: possible EventEmitter memory ' +
- 'leak detected. %d listeners added. ' +
- 'Use emitter.setMaxListeners() to increase limit.',
- this._events[type].length);
- console.trace();
- }
- }
-
- // If we've already got an array, just append.
- this._events[type].push(listener);
- } else {
- // Adding the second element, need to change to array.
- this._events[type] = [this._events[type], listener];
- }
-
- return this;
-};
-
-EventEmitter.prototype.on = EventEmitter.prototype.addListener;
-
-EventEmitter.prototype.once = function(type, listener) {
- var self = this;
- self.on(type, function g() {
- self.removeListener(type, g);
- listener.apply(this, arguments);
- });
-
- return this;
-};
-
-EventEmitter.prototype.removeListener = function(type, listener) {
- if ('function' !== typeof listener) {
- throw new Error('removeListener only takes instances of Function');
- }
-
- // does not use listeners(), so no side effect of creating _events[type]
- if (!this._events || !this._events[type]) return this;
-
- var list = this._events[type];
-
- if (isArray(list)) {
- var i = indexOf(list, listener);
- if (i < 0) return this;
- list.splice(i, 1);
- if (list.length == 0)
- delete this._events[type];
- } else if (this._events[type] === listener) {
- delete this._events[type];
- }
-
- return this;
-};
-
-EventEmitter.prototype.removeAllListeners = function(type) {
- if (arguments.length === 0) {
- this._events = {};
- return this;
- }
-
- // does not use listeners(), so no side effect of creating _events[type]
- if (type && this._events && this._events[type]) this._events[type] = null;
- return this;
-};
-
-EventEmitter.prototype.listeners = function(type) {
- if (!this._events) this._events = {};
- if (!this._events[type]) this._events[type] = [];
- if (!isArray(this._events[type])) {
- this._events[type] = [this._events[type]];
- }
- return this._events[type];
-};
-
-})(require("__browserify_process"))
-},{"__browserify_process":1}],3:[function(require,module,exports){
-(function(){// jshint -W001
-
-"use strict";
-
-// Identifiers provided by the ECMAScript standard.
-
-exports.reservedVars = {
- arguments : false,
- NaN : false
-};
-
-exports.ecmaIdentifiers = {
- Array : false,
- Boolean : false,
- Date : false,
- decodeURI : false,
- decodeURIComponent : false,
- encodeURI : false,
- encodeURIComponent : false,
- Error : false,
- "eval" : false,
- EvalError : false,
- Function : false,
- hasOwnProperty : false,
- isFinite : false,
- isNaN : false,
- JSON : false,
- Math : false,
- Map : false,
- Number : false,
- Object : false,
- parseInt : false,
- parseFloat : false,
- RangeError : false,
- ReferenceError : false,
- RegExp : false,
- Set : false,
- String : false,
- SyntaxError : false,
- TypeError : false,
- URIError : false,
- WeakMap : false
-};
-
-// Global variables commonly provided by a web browser environment.
-
-exports.browser = {
- ArrayBuffer : false,
- ArrayBufferView : false,
- Audio : false,
- Blob : false,
- addEventListener : false,
- applicationCache : false,
- atob : false,
- blur : false,
- btoa : false,
- clearInterval : false,
- clearTimeout : false,
- close : false,
- closed : false,
- DataView : false,
- DOMParser : false,
- defaultStatus : false,
- document : false,
- Element : false,
- ElementTimeControl : false,
- event : false,
- FileReader : false,
- Float32Array : false,
- Float64Array : false,
- FormData : false,
- focus : false,
- frames : false,
- getComputedStyle : false,
- HTMLElement : false,
- HTMLAnchorElement : false,
- HTMLBaseElement : false,
- HTMLBlockquoteElement: false,
- HTMLBodyElement : false,
- HTMLBRElement : false,
- HTMLButtonElement : false,
- HTMLCanvasElement : false,
- HTMLDirectoryElement : false,
- HTMLDivElement : false,
- HTMLDListElement : false,
- HTMLFieldSetElement : false,
- HTMLFontElement : false,
- HTMLFormElement : false,
- HTMLFrameElement : false,
- HTMLFrameSetElement : false,
- HTMLHeadElement : false,
- HTMLHeadingElement : false,
- HTMLHRElement : false,
- HTMLHtmlElement : false,
- HTMLIFrameElement : false,
- HTMLImageElement : false,
- HTMLInputElement : false,
- HTMLIsIndexElement : false,
- HTMLLabelElement : false,
- HTMLLayerElement : false,
- HTMLLegendElement : false,
- HTMLLIElement : false,
- HTMLLinkElement : false,
- HTMLMapElement : false,
- HTMLMenuElement : false,
- HTMLMetaElement : false,
- HTMLModElement : false,
- HTMLObjectElement : false,
- HTMLOListElement : false,
- HTMLOptGroupElement : false,
- HTMLOptionElement : false,
- HTMLParagraphElement : false,
- HTMLParamElement : false,
- HTMLPreElement : false,
- HTMLQuoteElement : false,
- HTMLScriptElement : false,
- HTMLSelectElement : false,
- HTMLStyleElement : false,
- HTMLTableCaptionElement: false,
- HTMLTableCellElement : false,
- HTMLTableColElement : false,
- HTMLTableElement : false,
- HTMLTableRowElement : false,
- HTMLTableSectionElement: false,
- HTMLTextAreaElement : false,
- HTMLTitleElement : false,
- HTMLUListElement : false,
- HTMLVideoElement : false,
- history : false,
- Int16Array : false,
- Int32Array : false,
- Int8Array : false,
- Image : false,
- length : false,
- localStorage : false,
- location : false,
- MessageChannel : false,
- MessageEvent : false,
- MessagePort : false,
- moveBy : false,
- moveTo : false,
- MutationObserver : false,
- name : false,
- Node : false,
- NodeFilter : false,
- navigator : false,
- onbeforeunload : true,
- onblur : true,
- onerror : true,
- onfocus : true,
- onload : true,
- onresize : true,
- onunload : true,
- open : false,
- openDatabase : false,
- opener : false,
- Option : false,
- parent : false,
- print : false,
- removeEventListener : false,
- resizeBy : false,
- resizeTo : false,
- screen : false,
- scroll : false,
- scrollBy : false,
- scrollTo : false,
- sessionStorage : false,
- setInterval : false,
- setTimeout : false,
- SharedWorker : false,
- status : false,
- SVGAElement : false,
- SVGAltGlyphDefElement: false,
- SVGAltGlyphElement : false,
- SVGAltGlyphItemElement: false,
- SVGAngle : false,
- SVGAnimateColorElement: false,
- SVGAnimateElement : false,
- SVGAnimateMotionElement: false,
- SVGAnimateTransformElement: false,
- SVGAnimatedAngle : false,
- SVGAnimatedBoolean : false,
- SVGAnimatedEnumeration: false,
- SVGAnimatedInteger : false,
- SVGAnimatedLength : false,
- SVGAnimatedLengthList: false,
- SVGAnimatedNumber : false,
- SVGAnimatedNumberList: false,
- SVGAnimatedPathData : false,
- SVGAnimatedPoints : false,
- SVGAnimatedPreserveAspectRatio: false,
- SVGAnimatedRect : false,
- SVGAnimatedString : false,
- SVGAnimatedTransformList: false,
- SVGAnimationElement : false,
- SVGCSSRule : false,
- SVGCircleElement : false,
- SVGClipPathElement : false,
- SVGColor : false,
- SVGColorProfileElement: false,
- SVGColorProfileRule : false,
- SVGComponentTransferFunctionElement: false,
- SVGCursorElement : false,
- SVGDefsElement : false,
- SVGDescElement : false,
- SVGDocument : false,
- SVGElement : false,
- SVGElementInstance : false,
- SVGElementInstanceList: false,
- SVGEllipseElement : false,
- SVGExternalResourcesRequired: false,
- SVGFEBlendElement : false,
- SVGFEColorMatrixElement: false,
- SVGFEComponentTransferElement: false,
- SVGFECompositeElement: false,
- SVGFEConvolveMatrixElement: false,
- SVGFEDiffuseLightingElement: false,
- SVGFEDisplacementMapElement: false,
- SVGFEDistantLightElement: false,
- SVGFEDropShadowElement: false,
- SVGFEFloodElement : false,
- SVGFEFuncAElement : false,
- SVGFEFuncBElement : false,
- SVGFEFuncGElement : false,
- SVGFEFuncRElement : false,
- SVGFEGaussianBlurElement: false,
- SVGFEImageElement : false,
- SVGFEMergeElement : false,
- SVGFEMergeNodeElement: false,
- SVGFEMorphologyElement: false,
- SVGFEOffsetElement : false,
- SVGFEPointLightElement: false,
- SVGFESpecularLightingElement: false,
- SVGFESpotLightElement: false,
- SVGFETileElement : false,
- SVGFETurbulenceElement: false,
- SVGFilterElement : false,
- SVGFilterPrimitiveStandardAttributes: false,
- SVGFitToViewBox : false,
- SVGFontElement : false,
- SVGFontFaceElement : false,
- SVGFontFaceFormatElement: false,
- SVGFontFaceNameElement: false,
- SVGFontFaceSrcElement: false,
- SVGFontFaceUriElement: false,
- SVGForeignObjectElement: false,
- SVGGElement : false,
- SVGGlyphElement : false,
- SVGGlyphRefElement : false,
- SVGGradientElement : false,
- SVGHKernElement : false,
- SVGICCColor : false,
- SVGImageElement : false,
- SVGLangSpace : false,
- SVGLength : false,
- SVGLengthList : false,
- SVGLineElement : false,
- SVGLinearGradientElement: false,
- SVGLocatable : false,
- SVGMPathElement : false,
- SVGMarkerElement : false,
- SVGMaskElement : false,
- SVGMatrix : false,
- SVGMetadataElement : false,
- SVGMissingGlyphElement: false,
- SVGNumber : false,
- SVGNumberList : false,
- SVGPaint : false,
- SVGPathElement : false,
- SVGPathSeg : false,
- SVGPathSegArcAbs : false,
- SVGPathSegArcRel : false,
- SVGPathSegClosePath : false,
- SVGPathSegCurvetoCubicAbs: false,
- SVGPathSegCurvetoCubicRel: false,
- SVGPathSegCurvetoCubicSmoothAbs: false,
- SVGPathSegCurvetoCubicSmoothRel: false,
- SVGPathSegCurvetoQuadraticAbs: false,
- SVGPathSegCurvetoQuadraticRel: false,
- SVGPathSegCurvetoQuadraticSmoothAbs: false,
- SVGPathSegCurvetoQuadraticSmoothRel: false,
- SVGPathSegLinetoAbs : false,
- SVGPathSegLinetoHorizontalAbs: false,
- SVGPathSegLinetoHorizontalRel: false,
- SVGPathSegLinetoRel : false,
- SVGPathSegLinetoVerticalAbs: false,
- SVGPathSegLinetoVerticalRel: false,
- SVGPathSegList : false,
- SVGPathSegMovetoAbs : false,
- SVGPathSegMovetoRel : false,
- SVGPatternElement : false,
- SVGPoint : false,
- SVGPointList : false,
- SVGPolygonElement : false,
- SVGPolylineElement : false,
- SVGPreserveAspectRatio: false,
- SVGRadialGradientElement: false,
- SVGRect : false,
- SVGRectElement : false,
- SVGRenderingIntent : false,
- SVGSVGElement : false,
- SVGScriptElement : false,
- SVGSetElement : false,
- SVGStopElement : false,
- SVGStringList : false,
- SVGStylable : false,
- SVGStyleElement : false,
- SVGSwitchElement : false,
- SVGSymbolElement : false,
- SVGTRefElement : false,
- SVGTSpanElement : false,
- SVGTests : false,
- SVGTextContentElement: false,
- SVGTextElement : false,
- SVGTextPathElement : false,
- SVGTextPositioningElement: false,
- SVGTitleElement : false,
- SVGTransform : false,
- SVGTransformList : false,
- SVGTransformable : false,
- SVGURIReference : false,
- SVGUnitTypes : false,
- SVGUseElement : false,
- SVGVKernElement : false,
- SVGViewElement : false,
- SVGViewSpec : false,
- SVGZoomAndPan : false,
- TimeEvent : false,
- top : false,
- Uint16Array : false,
- Uint32Array : false,
- Uint8Array : false,
- Uint8ClampedArray : false,
- WebSocket : false,
- window : false,
- Worker : false,
- XMLHttpRequest : false,
- XMLSerializer : false,
- XPathEvaluator : false,
- XPathException : false,
- XPathExpression : false,
- XPathNSResolver : false,
- XPathResult : false
-};
-
-exports.devel = {
- alert : false,
- confirm: false,
- console: false,
- Debug : false,
- opera : false,
- prompt : false
-};
-
-exports.worker = {
- importScripts: true,
- postMessage : true,
- self : true
-};
-
-// Widely adopted global names that are not part of ECMAScript standard
-exports.nonstandard = {
- escape : false,
- unescape: false
-};
-
-// Globals provided by popular JavaScript environments.
-
-exports.couch = {
- "require" : false,
- respond : false,
- getRow : false,
- emit : false,
- send : false,
- start : false,
- sum : false,
- log : false,
- exports : false,
- module : false,
- provides : false
-};
-
-exports.node = {
- __filename : false,
- __dirname : false,
- Buffer : false,
- DataView : false,
- console : false,
- exports : true, // In Node it is ok to exports = module.exports = foo();
- GLOBAL : false,
- global : false,
- module : false,
- process : false,
- require : false,
- setTimeout : false,
- clearTimeout : false,
- setInterval : false,
- clearInterval : false,
- setImmediate : false, // v0.9.1+
- clearImmediate: false // v0.9.1+
-};
-
-exports.phantom = {
- phantom : true,
- require : true,
- WebPage : true
-};
-
-exports.rhino = {
- defineClass : false,
- deserialize : false,
- gc : false,
- help : false,
- importPackage: false,
- "java" : false,
- load : false,
- loadClass : false,
- print : false,
- quit : false,
- readFile : false,
- readUrl : false,
- runCommand : false,
- seal : false,
- serialize : false,
- spawn : false,
- sync : false,
- toint32 : false,
- version : false
-};
-
-exports.wsh = {
- ActiveXObject : true,
- Enumerator : true,
- GetObject : true,
- ScriptEngine : true,
- ScriptEngineBuildVersion : true,
- ScriptEngineMajorVersion : true,
- ScriptEngineMinorVersion : true,
- VBArray : true,
- WSH : true,
- WScript : true,
- XDomainRequest : true
-};
-
-// Globals provided by popular JavaScript libraries.
-
-exports.dojo = {
- dojo : false,
- dijit : false,
- dojox : false,
- define : false,
- "require": false
-};
-
-exports.jquery = {
- "$" : false,
- jQuery : false
-};
-
-exports.mootools = {
- "$" : false,
- "$$" : false,
- Asset : false,
- Browser : false,
- Chain : false,
- Class : false,
- Color : false,
- Cookie : false,
- Core : false,
- Document : false,
- DomReady : false,
- DOMEvent : false,
- DOMReady : false,
- Drag : false,
- Element : false,
- Elements : false,
- Event : false,
- Events : false,
- Fx : false,
- Group : false,
- Hash : false,
- HtmlTable : false,
- Iframe : false,
- IframeShim : false,
- InputValidator: false,
- instanceOf : false,
- Keyboard : false,
- Locale : false,
- Mask : false,
- MooTools : false,
- Native : false,
- Options : false,
- OverText : false,
- Request : false,
- Scroller : false,
- Slick : false,
- Slider : false,
- Sortables : false,
- Spinner : false,
- Swiff : false,
- Tips : false,
- Type : false,
- typeOf : false,
- URI : false,
- Window : false
-};
-
-exports.prototypejs = {
- "$" : false,
- "$$" : false,
- "$A" : false,
- "$F" : false,
- "$H" : false,
- "$R" : false,
- "$break" : false,
- "$continue" : false,
- "$w" : false,
- Abstract : false,
- Ajax : false,
- Class : false,
- Enumerable : false,
- Element : false,
- Event : false,
- Field : false,
- Form : false,
- Hash : false,
- Insertion : false,
- ObjectRange : false,
- PeriodicalExecuter: false,
- Position : false,
- Prototype : false,
- Selector : false,
- Template : false,
- Toggle : false,
- Try : false,
- Autocompleter : false,
- Builder : false,
- Control : false,
- Draggable : false,
- Draggables : false,
- Droppables : false,
- Effect : false,
- Sortable : false,
- SortableObserver : false,
- Sound : false,
- Scriptaculous : false
-};
-
-exports.yui = {
- YUI : false,
- Y : false,
- YUI_config: false
-};
-
-
-})()
-},{}],4:[function(require,module,exports){
-"use strict";
-
-var state = {
- syntax: {},
-
- reset: function () {
- this.tokens = {
- prev: null,
- next: null,
- curr: null
- };
-
- this.option = {};
- this.ignored = {};
- this.directive = {};
- this.jsonMode = false;
- this.jsonWarnings = [];
- this.lines = [];
- this.tab = "";
- this.cache = {}; // Node.JS doesn't have Map. Sniff.
- }
-};
-
-exports.state = state;
-
-},{}],5:[function(require,module,exports){
-(function(){"use strict";
-
-exports.register = function (linter) {
- // Check for properties named __proto__. This special property was
- // deprecated and then re-introduced for ES6.
-
- linter.on("Identifier", function style_scanProto(data) {
- if (linter.getOption("proto")) {
- return;
- }
-
- if (data.name === "__proto__") {
- linter.warn("W103", {
- line: data.line,
- char: data.char,
- data: [ data.name ]
- });
- }
- });
-
- // Check for properties named __iterator__. This is a special property
- // available only in browsers with JavaScript 1.7 implementation.
-
- linter.on("Identifier", function style_scanIterator(data) {
- if (linter.getOption("iterator")) {
- return;
- }
-
- if (data.name === "__iterator__") {
- linter.warn("W104", {
- line: data.line,
- char: data.char,
- data: [ data.name ]
- });
- }
- });
-
- // Check for dangling underscores.
-
- linter.on("Identifier", function style_scanDangling(data) {
- if (!linter.getOption("nomen")) {
- return;
- }
-
- // Underscore.js
- if (data.name === "_") {
- return;
- }
-
- // In Node, __dirname and __filename should be ignored.
- if (linter.getOption("node")) {
- if (/^(__dirname|__filename)$/.test(data.name) && !data.isProperty) {
- return;
- }
- }
-
- if (/^(_+.*|.*_+)$/.test(data.name)) {
- linter.warn("W105", {
- line: data.line,
- char: data.from,
- data: [ "dangling '_'", data.name ]
- });
- }
- });
-
- // Check that all identifiers are using camelCase notation.
- // Exceptions: names like MY_VAR and _myVar.
-
- linter.on("Identifier", function style_scanCamelCase(data) {
- if (!linter.getOption("camelcase")) {
- return;
- }
-
- if (data.name.replace(/^_+/, "").indexOf("_") > -1 && !data.name.match(/^[A-Z0-9_]*$/)) {
- linter.warn("W106", {
- line: data.line,
- char: data.from,
- data: [ data.name ]
- });
- }
- });
-
- // Enforce consistency in style of quoting.
-
- linter.on("String", function style_scanQuotes(data) {
- var quotmark = linter.getOption("quotmark");
- var code;
-
- if (!quotmark) {
- return;
- }
-
- // If quotmark is set to 'single' warn about all double-quotes.
-
- if (quotmark === "single" && data.quote !== "'") {
- code = "W109";
- }
-
- // If quotmark is set to 'double' warn about all single-quotes.
-
- if (quotmark === "double" && data.quote !== "\"") {
- code = "W108";
- }
-
- // If quotmark is set to true, remember the first quotation style
- // and then warn about all others.
-
- if (quotmark === true) {
- if (!linter.getCache("quotmark")) {
- linter.setCache("quotmark", data.quote);
- }
-
- if (linter.getCache("quotmark") !== data.quote) {
- code = "W110";
- }
- }
-
- if (code) {
- linter.warn(code, {
- line: data.line,
- char: data.char,
- });
- }
- });
-
- linter.on("Number", function style_scanNumbers(data) {
- if (data.value.charAt(0) === ".") {
- // Warn about a leading decimal point.
- linter.warn("W008", {
- line: data.line,
- char: data.char,
- data: [ data.value ]
- });
- }
-
- if (data.value.substr(data.value.length - 1) === ".") {
- // Warn about a trailing decimal point.
- linter.warn("W047", {
- line: data.line,
- char: data.char,
- data: [ data.value ]
- });
- }
-
- if (/^00+/.test(data.value)) {
- // Multiple leading zeroes.
- linter.warn("W046", {
- line: data.line,
- char: data.char,
- data: [ data.value ]
- });
- }
- });
-
- // Warn about script URLs.
-
- linter.on("String", function style_scanJavaScriptURLs(data) {
- var re = /^(?:javascript|jscript|ecmascript|vbscript|mocha|livescript)\s*:/i;
-
- if (linter.getOption("scripturl")) {
- return;
- }
-
- if (re.test(data.value)) {
- linter.warn("W107", {
- line: data.line,
- char: data.char
- });
- }
- });
-};
-})()
-},{}],6:[function(require,module,exports){
-/*
- * Regular expressions. Some of these are stupidly long.
- */
-
-/*jshint maxlen:1000 */
-
-"use string";
-
-// Unsafe comment or string (ax)
-exports.unsafeString =
- /@cc|<\/?|script|\]\s*\]|<\s*!|&lt/i;
-
-// Unsafe characters that are silently deleted by one or more browsers (cx)
-exports.unsafeChars =
- /[\u0000-\u001f\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/;
-
-// Characters in strings that need escaping (nx and nxg)
-exports.needEsc =
- /[\u0000-\u001f&<"\/\\\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/;
-
-exports.needEscGlobal =
- /[\u0000-\u001f&<"\/\\\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;
-
-// Star slash (lx)
-exports.starSlash = /\*\//;
-
-// Identifier (ix)
-exports.identifier = /^([a-zA-Z_$][a-zA-Z0-9_$]*)$/;
-
-// JavaScript URL (jx)
-exports.javascriptURL = /^(?:javascript|jscript|ecmascript|vbscript|mocha|livescript)\s*:/i;
-
-// Catches /* falls through */ comments (ft)
-//exports.fallsThrough = /^\s*\/\*\s*falls?\sthrough\s*\*\/\s*$/;
-exports.fallsThrough = /^\s*\/\/\s*Falls?\sthrough.*\s*$/;
-
-},{}],7:[function(require,module,exports){
-(function(global){/*global window, global*/
-var util = require("util")
-var assert = require("assert")
-
-var slice = Array.prototype.slice
-var console
-var times = {}
-
-if (typeof global !== "undefined" && global.console) {
- console = global.console
-} else if (typeof window !== "undefined" && window.console) {
- console = window.console
-} else {
- console = window.console = {}
-}
-
-var functions = [
- [log, "log"]
- , [info, "info"]
- , [warn, "warn"]
- , [error, "error"]
- , [time, "time"]
- , [timeEnd, "timeEnd"]
- , [trace, "trace"]
- , [dir, "dir"]
- , [assert, "assert"]
-]
-
-for (var i = 0; i < functions.length; i++) {
- var tuple = functions[i]
- var f = tuple[0]
- var name = tuple[1]
-
- if (!console[name]) {
- console[name] = f
- }
-}
-
-module.exports = console
-
-function log() {}
-
-function info() {
- console.log.apply(console, arguments)
-}
-
-function warn() {
- console.log.apply(console, arguments)
-}
-
-function error() {
- console.warn.apply(console, arguments)
-}
-
-function time(label) {
- times[label] = Date.now()
-}
-
-function timeEnd(label) {
- var time = times[label]
- if (!time) {
- throw new Error("No such label: " + label)
- }
-
- var duration = Date.now() - time
- console.log(label + ": " + duration + "ms")
-}
-
-function trace() {
- var err = new Error()
- err.name = "Trace"
- err.message = util.format.apply(null, arguments)
- console.error(err.stack)
-}
-
-function dir(object) {
- console.log(util.inspect(object) + "\n")
-}
-
-function assert(expression) {
- if (!expression) {
- var arr = slice.call(arguments, 1)
- assert.ok(false, util.format.apply(null, arr))
- }
-}
-
-})(window)
-},{"util":8,"assert":9}],10:[function(require,module,exports){
-(function(){/*
- * Lexical analysis and token construction.
- */
-
-"use strict";
-
-var _ = require("underscore");
-var events = require("events");
-var reg = require("./reg.js");
-var state = require("./state.js").state;
-
-// Some of these token types are from JavaScript Parser API
-// while others are specific to JSHint parser.
-// JS Parser API: https://developer.mozilla.org/en-US/docs/SpiderMonkey/Parser_API
-
-var Token = {
- Identifier: 1,
- Punctuator: 2,
- NumericLiteral: 3,
- StringLiteral: 4,
- Comment: 5,
- Keyword: 6,
- NullLiteral: 7,
- BooleanLiteral: 8,
- RegExp: 9
-};
-
-// This is auto generated from the unicode tables.
-// The tables are at:
-// http://www.fileformat.info/info/unicode/category/Lu/list.htm
-// http://www.fileformat.info/info/unicode/category/Ll/list.htm
-// http://www.fileformat.info/info/unicode/category/Lt/list.htm
-// http://www.fileformat.info/info/unicode/category/Lm/list.htm
-// http://www.fileformat.info/info/unicode/category/Lo/list.htm
-// http://www.fileformat.info/info/unicode/category/Nl/list.htm
-
-var unicodeLetterTable = [
- 170, 170, 181, 181, 186, 186, 192, 214,
- 216, 246, 248, 705, 710, 721, 736, 740, 748, 748, 750, 750,
- 880, 884, 886, 887, 890, 893, 902, 902, 904, 906, 908, 908,
- 910, 929, 931, 1013, 1015, 1153, 1162, 1319, 1329, 1366,
- 1369, 1369, 1377, 1415, 1488, 1514, 1520, 1522, 1568, 1610,
- 1646, 1647, 1649, 1747, 1749, 1749, 1765, 1766, 1774, 1775,
- 1786, 1788, 1791, 1791, 1808, 1808, 1810, 1839, 1869, 1957,
- 1969, 1969, 1994, 2026, 2036, 2037, 2042, 2042, 2048, 2069,
- 2074, 2074, 2084, 2084, 2088, 2088, 2112, 2136, 2308, 2361,
- 2365, 2365, 2384, 2384, 2392, 2401, 2417, 2423, 2425, 2431,
- 2437, 2444, 2447, 2448, 2451, 2472, 2474, 2480, 2482, 2482,
- 2486, 2489, 2493, 2493, 2510, 2510, 2524, 2525, 2527, 2529,
- 2544, 2545, 2565, 2570, 2575, 2576, 2579, 2600, 2602, 2608,
- 2610, 2611, 2613, 2614, 2616, 2617, 2649, 2652, 2654, 2654,
- 2674, 2676, 2693, 2701, 2703, 2705, 2707, 2728, 2730, 2736,
- 2738, 2739, 2741, 2745, 2749, 2749, 2768, 2768, 2784, 2785,
- 2821, 2828, 2831, 2832, 2835, 2856, 2858, 2864, 2866, 2867,
- 2869, 2873, 2877, 2877, 2908, 2909, 2911, 2913, 2929, 2929,
- 2947, 2947, 2949, 2954, 2958, 2960, 2962, 2965, 2969, 2970,
- 2972, 2972, 2974, 2975, 2979, 2980, 2984, 2986, 2990, 3001,
- 3024, 3024, 3077, 3084, 3086, 3088, 3090, 3112, 3114, 3123,
- 3125, 3129, 3133, 3133, 3160, 3161, 3168, 3169, 3205, 3212,
- 3214, 3216, 3218, 3240, 3242, 3251, 3253, 3257, 3261, 3261,
- 3294, 3294, 3296, 3297, 3313, 3314, 3333, 3340, 3342, 3344,
- 3346, 3386, 3389, 3389, 3406, 3406, 3424, 3425, 3450, 3455,
- 3461, 3478, 3482, 3505, 3507, 3515, 3517, 3517, 3520, 3526,
- 3585, 3632, 3634, 3635, 3648, 3654, 3713, 3714, 3716, 3716,
- 3719, 3720, 3722, 3722, 3725, 3725, 3732, 3735, 3737, 3743,
- 3745, 3747, 3749, 3749, 3751, 3751, 3754, 3755, 3757, 3760,
- 3762, 3763, 3773, 3773, 3776, 3780, 3782, 3782, 3804, 3805,
- 3840, 3840, 3904, 3911, 3913, 3948, 3976, 3980, 4096, 4138,
- 4159, 4159, 4176, 4181, 4186, 4189, 4193, 4193, 4197, 4198,
- 4206, 4208, 4213, 4225, 4238, 4238, 4256, 4293, 4304, 4346,
- 4348, 4348, 4352, 4680, 4682, 4685, 4688, 4694, 4696, 4696,
- 4698, 4701, 4704, 4744, 4746, 4749, 4752, 4784, 4786, 4789,
- 4792, 4798, 4800, 4800, 4802, 4805, 4808, 4822, 4824, 4880,
- 4882, 4885, 4888, 4954, 4992, 5007, 5024, 5108, 5121, 5740,
- 5743, 5759, 5761, 5786, 5792, 5866, 5870, 5872, 5888, 5900,
- 5902, 5905, 5920, 5937, 5952, 5969, 5984, 5996, 5998, 6000,
- 6016, 6067, 6103, 6103, 6108, 6108, 6176, 6263, 6272, 6312,
- 6314, 6314, 6320, 6389, 6400, 6428, 6480, 6509, 6512, 6516,
- 6528, 6571, 6593, 6599, 6656, 6678, 6688, 6740, 6823, 6823,
- 6917, 6963, 6981, 6987, 7043, 7072, 7086, 7087, 7104, 7141,
- 7168, 7203, 7245, 7247, 7258, 7293, 7401, 7404, 7406, 7409,
- 7424, 7615, 7680, 7957, 7960, 7965, 7968, 8005, 8008, 8013,
- 8016, 8023, 8025, 8025, 8027, 8027, 8029, 8029, 8031, 8061,
- 8064, 8116, 8118, 8124, 8126, 8126, 8130, 8132, 8134, 8140,
- 8144, 8147, 8150, 8155, 8160, 8172, 8178, 8180, 8182, 8188,
- 8305, 8305, 8319, 8319, 8336, 8348, 8450, 8450, 8455, 8455,
- 8458, 8467, 8469, 8469, 8473, 8477, 8484, 8484, 8486, 8486,
- 8488, 8488, 8490, 8493, 8495, 8505, 8508, 8511, 8517, 8521,
- 8526, 8526, 8544, 8584, 11264, 11310, 11312, 11358,
- 11360, 11492, 11499, 11502, 11520, 11557, 11568, 11621,
- 11631, 11631, 11648, 11670, 11680, 11686, 11688, 11694,
- 11696, 11702, 11704, 11710, 11712, 11718, 11720, 11726,
- 11728, 11734, 11736, 11742, 11823, 11823, 12293, 12295,
- 12321, 12329, 12337, 12341, 12344, 12348, 12353, 12438,
- 12445, 12447, 12449, 12538, 12540, 12543, 12549, 12589,
- 12593, 12686, 12704, 12730, 12784, 12799, 13312, 13312,
- 19893, 19893, 19968, 19968, 40907, 40907, 40960, 42124,
- 42192, 42237, 42240, 42508, 42512, 42527, 42538, 42539,
- 42560, 42606, 42623, 42647, 42656, 42735, 42775, 42783,
- 42786, 42888, 42891, 42894, 42896, 42897, 42912, 42921,
- 43002, 43009, 43011, 43013, 43015, 43018, 43020, 43042,
- 43072, 43123, 43138, 43187, 43250, 43255, 43259, 43259,
- 43274, 43301, 43312, 43334, 43360, 43388, 43396, 43442,
- 43471, 43471, 43520, 43560, 43584, 43586, 43588, 43595,
- 43616, 43638, 43642, 43642, 43648, 43695, 43697, 43697,
- 43701, 43702, 43705, 43709, 43712, 43712, 43714, 43714,
- 43739, 43741, 43777, 43782, 43785, 43790, 43793, 43798,
- 43808, 43814, 43816, 43822, 43968, 44002, 44032, 44032,
- 55203, 55203, 55216, 55238, 55243, 55291, 63744, 64045,
- 64048, 64109, 64112, 64217, 64256, 64262, 64275, 64279,
- 64285, 64285, 64287, 64296, 64298, 64310, 64312, 64316,
- 64318, 64318, 64320, 64321, 64323, 64324, 64326, 64433,
- 64467, 64829, 64848, 64911, 64914, 64967, 65008, 65019,
- 65136, 65140, 65142, 65276, 65313, 65338, 65345, 65370,
- 65382, 65470, 65474, 65479, 65482, 65487, 65490, 65495,
- 65498, 65500, 65536, 65547, 65549, 65574, 65576, 65594,
- 65596, 65597, 65599, 65613, 65616, 65629, 65664, 65786,
- 65856, 65908, 66176, 66204, 66208, 66256, 66304, 66334,
- 66352, 66378, 66432, 66461, 66464, 66499, 66504, 66511,
- 66513, 66517, 66560, 66717, 67584, 67589, 67592, 67592,
- 67594, 67637, 67639, 67640, 67644, 67644, 67647, 67669,
- 67840, 67861, 67872, 67897, 68096, 68096, 68112, 68115,
- 68117, 68119, 68121, 68147, 68192, 68220, 68352, 68405,
- 68416, 68437, 68448, 68466, 68608, 68680, 69635, 69687,
- 69763, 69807, 73728, 74606, 74752, 74850, 77824, 78894,
- 92160, 92728, 110592, 110593, 119808, 119892, 119894, 119964,
- 119966, 119967, 119970, 119970, 119973, 119974, 119977, 119980,
- 119982, 119993, 119995, 119995, 119997, 120003, 120005, 120069,
- 120071, 120074, 120077, 120084, 120086, 120092, 120094, 120121,
- 120123, 120126, 120128, 120132, 120134, 120134, 120138, 120144,
- 120146, 120485, 120488, 120512, 120514, 120538, 120540, 120570,
- 120572, 120596, 120598, 120628, 120630, 120654, 120656, 120686,
- 120688, 120712, 120714, 120744, 120746, 120770, 120772, 120779,
- 131072, 131072, 173782, 173782, 173824, 173824, 177972, 177972,
- 177984, 177984, 178205, 178205, 194560, 195101
-];
-
-var identifierStartTable = [];
-
-for (var i = 0; i < 128; i++) {
- identifierStartTable[i] =
- i === 36 || // $
- i >= 65 && i <= 90 || // A-Z
- i === 95 || // _
- i >= 97 && i <= 122; // a-z
-}
-
-var identifierPartTable = [];
-
-for (var i = 0; i < 128; i++) {
- identifierPartTable[i] =
- identifierStartTable[i] || // $, _, A-Z, a-z
- i >= 48 && i <= 57; // 0-9
-}
-
-// Object that handles postponed lexing verifications that checks the parsed
-// environment state.
-
-function asyncTrigger() {
- var _checks = [];
-
- return {
- push: function (fn) {
- _checks.push(fn);
- },
-
- check: function () {
- for (var check in _checks) {
- _checks[check]();
- }
-
- _checks.splice(0, _checks.length);
- }
- };
-}
-
-/*
- * Lexer for JSHint.
- *
- * This object does a char-by-char scan of the provided source code
- * and produces a sequence of tokens.
- *
- * var lex = new Lexer("var i = 0;");
- * lex.start();
- * lex.token(); // returns the next token
- *
- * You have to use the token() method to move the lexer forward
- * but you don't have to use its return value to get tokens. In addition
- * to token() method returning the next token, the Lexer object also
- * emits events.
- *
- * lex.on("Identifier", function (data) {
- * if (data.name.indexOf("_") >= 0) {
- * // Produce a warning.
- * }
- * });
- *
- * Note that the token() method returns tokens in a JSLint-compatible
- * format while the event emitter uses a slightly modified version of
- * Mozilla's JavaScript Parser API. Eventually, we will move away from
- * JSLint format.
- */
-function Lexer(source) {
- var lines = source;
-
- if (typeof lines === "string") {
- lines = lines
- .replace(/\r\n/g, "\n")
- .replace(/\r/g, "\n")
- .split("\n");
- }
-
- // If the first line is a shebang (#!), make it a blank and move on.
- // Shebangs are used by Node scripts.
-
- if (lines[0] && lines[0].substr(0, 2) === "#!") {
- lines[0] = "";
- }
-
- this.emitter = new events.EventEmitter();
- this.source = source;
- this.lines = lines;
- this.prereg = true;
-
- this.line = 0;
- this.char = 1;
- this.from = 1;
- this.input = "";
-
- for (var i = 0; i < state.option.indent; i += 1) {
- state.tab += " ";
- }
-}
-
-Lexer.prototype = {
- _lines: [],
-
- get lines() {
- this._lines = state.lines;
- return this._lines;
- },
-
- set lines(val) {
- this._lines = val;
- state.lines = this._lines;
- },
-
- /*
- * Return the next i character without actually moving the
- * char pointer.
- */
- peek: function (i) {
- return this.input.charAt(i || 0);
- },
-
- /*
- * Move the char pointer forward i times.
- */
- skip: function (i) {
- i = i || 1;
- this.char += i;
- this.input = this.input.slice(i);
- },
-
- /*
- * Subscribe to a token event. The API for this method is similar
- * Underscore.js i.e. you can subscribe to multiple events with
- * one call:
- *
- * lex.on("Identifier Number", function (data) {
- * // ...
- * });
- */
- on: function (names, listener) {
- names.split(" ").forEach(function (name) {
- this.emitter.on(name, listener);
- }.bind(this));
- },
-
- /*
- * Trigger a token event. All arguments will be passed to each
- * listener.
- */
- trigger: function () {
- this.emitter.emit.apply(this.emitter, Array.prototype.slice.call(arguments));
- },
-
- /*
- * Postpone a token event. the checking condition is set as
- * last parameter, and the trigger function is called in a
- * stored callback. To be later called using the check() function
- * by the parser. This avoids parser's peek() to give the lexer
- * a false context.
- */
- triggerAsync: function (type, args, checks, fn) {
- checks.push(function () {
- if (fn()) {
- this.trigger(type, args);
- }
- }.bind(this));
- },
-
- /*
- * Extract a punctuator out of the next sequence of characters
- * or return 'null' if its not possible.
- *
- * This method's implementation was heavily influenced by the
- * scanPunctuator function in the Esprima parser's source code.
- */
- scanPunctuator: function () {
- var ch1 = this.peek();
- var ch2, ch3, ch4;
-
- switch (ch1) {
- // Most common single-character punctuators
- case ".":
- if ((/^[0-9]$/).test(this.peek(1))) {
- return null;
- }
- if (this.peek(1) === "." && this.peek(2) === ".") {
- return {
- type: Token.Punctuator,
- value: "..."
- };
- }
- /* falls through */
- case "(":
- case ")":
- case ";":
- case ",":
- case "{":
- case "}":
- case "[":
- case "]":
- case ":":
- case "~":
- case "?":
- return {
- type: Token.Punctuator,
- value: ch1
- };
-
- // A pound sign (for Node shebangs)
- case "#":
- return {
- type: Token.Punctuator,
- value: ch1
- };
-
- // We're at the end of input
- case "":
- return null;
- }
-
- // Peek more characters
-
- ch2 = this.peek(1);
- ch3 = this.peek(2);
- ch4 = this.peek(3);
-
- // 4-character punctuator: >>>=
-
- if (ch1 === ">" && ch2 === ">" && ch3 === ">" && ch4 === "=") {
- return {
- type: Token.Punctuator,
- value: ">>>="
- };
- }
-
- // 3-character punctuators: === !== >>> <<= >>=
-
- if (ch1 === "=" && ch2 === "=" && ch3 === "=") {
- return {
- type: Token.Punctuator,
- value: "==="
- };
- }
-
- if (ch1 === "!" && ch2 === "=" && ch3 === "=") {
- return {
- type: Token.Punctuator,
- value: "!=="
- };
- }
-
- if (ch1 === ">" && ch2 === ">" && ch3 === ">") {
- return {
- type: Token.Punctuator,
- value: ">>>"
- };
- }
-
- if (ch1 === "<" && ch2 === "<" && ch3 === "=") {
- return {
- type: Token.Punctuator,
- value: "<<="
- };
- }
-
- if (ch1 === ">" && ch2 === ">" && ch3 === "=") {
- return {
- type: Token.Punctuator,
- value: ">>="
- };
- }
-
- // Fat arrow punctuator
- if (ch1 === "=" && ch2 === ">") {
- return {
- type: Token.Punctuator,
- value: ch1 + ch2
- };
- }
-
- // 2-character punctuators: <= >= == != ++ -- << >> && ||
- // += -= *= %= &= |= ^= (but not /=, see below)
- if (ch1 === ch2 && ("+-<>&|".indexOf(ch1) >= 0)) {
- return {
- type: Token.Punctuator,
- value: ch1 + ch2
- };
- }
-
- if ("<>=!+-*%&|^".indexOf(ch1) >= 0) {
- if (ch2 === "=") {
- return {
- type: Token.Punctuator,
- value: ch1 + ch2
- };
- }
-
- return {
- type: Token.Punctuator,
- value: ch1
- };
- }
-
- // Special case: /=. We need to make sure that this is an
- // operator and not a regular expression.
-
- if (ch1 === "/") {
- if (ch2 === "=" && /\/=(?!(\S*\/[gim]?))/.test(this.input)) {
- // /= is not a part of a regular expression, return it as a
- // punctuator.
- return {
- type: Token.Punctuator,
- value: "/="
- };
- }
-
- return {
- type: Token.Punctuator,
- value: "/"
- };
- }
-
- return null;
- },
-
- /*
- * Extract a comment out of the next sequence of characters and/or
- * lines or return 'null' if its not possible. Since comments can
- * span across multiple lines this method has to move the char
- * pointer.
- *
- * In addition to normal JavaScript comments (// and /*) this method
- * also recognizes JSHint- and JSLint-specific comments such as
- * /*jshint, /*jslint, /*globals and so on.
- */
- scanComments: function () {
- var ch1 = this.peek();
- var ch2 = this.peek(1);
- var rest = this.input.substr(2);
- var startLine = this.line;
- var startChar = this.char;
-
- // Create a comment token object and make sure it
- // has all the data JSHint needs to work with special
- // comments.
-
- function commentToken(label, body, opt) {
- var special = ["jshint", "jslint", "members", "member", "globals", "global", "exported"];
- var isSpecial = false;
- var value = label + body;
- var commentType = "plain";
- opt = opt || {};
-
- if (opt.isMultiline) {
- value += "*/";
- }
-
- special.forEach(function (str) {
- if (isSpecial) {
- return;
- }
-
- // Don't recognize any special comments other than jshint for single-line
- // comments. This introduced many problems with legit comments.
- if (label === "//" && str !== "jshint") {
- return;
- }
-
- if (body.substr(0, str.length) === str) {
- isSpecial = true;
- label = label + str;
- body = body.substr(str.length);
- }
-
- if (!isSpecial && body.charAt(0) === " " && body.substr(1, str.length) === str) {
- isSpecial = true;
- label = label + " " + str;
- body = body.substr(str.length + 1);
- }
-
- if (!isSpecial) {
- return;
- }
-
- switch (str) {
- case "member":
- commentType = "members";
- break;
- case "global":
- commentType = "globals";
- break;
- default:
- commentType = str;
- }
- });
-
- return {
- type: Token.Comment,
- commentType: commentType,
- value: value,
- body: body,
- isSpecial: isSpecial,
- isMultiline: opt.isMultiline || false,
- isMalformed: opt.isMalformed || false
- };
- }
-
- // End of unbegun comment. Raise an error and skip that input.
- if (ch1 === "*" && ch2 === "/") {
- this.trigger("error", {
- code: "E018",
- line: startLine,
- character: startChar
- });
-
- this.skip(2);
- return null;
- }
-
- // Comments must start either with // or /*
- if (ch1 !== "/" || (ch2 !== "*" && ch2 !== "/")) {
- return null;
- }
-
- // One-line comment
- if (ch2 === "/") {
- this.skip(this.input.length); // Skip to the EOL.
- return commentToken("//", rest);
- }
-
- var body = "";
-
- /* Multi-line comment */
- if (ch2 === "*") {
- this.skip(2);
-
- while (this.peek() !== "*" || this.peek(1) !== "/") {
- if (this.peek() === "") { // End of Line
- body += "\n";
-
- // If we hit EOF and our comment is still unclosed,
- // trigger an error and end the comment implicitly.
- if (!this.nextLine()) {
- this.trigger("error", {
- code: "E017",
- line: startLine,
- character: startChar
- });
-
- return commentToken("/*", body, {
- isMultiline: true,
- isMalformed: true
- });
- }
- } else {
- body += this.peek();
- this.skip();
- }
- }
-
- this.skip(2);
- return commentToken("/*", body, { isMultiline: true });
- }
- },
-
- /*
- * Extract a keyword out of the next sequence of characters or
- * return 'null' if its not possible.
- */
- scanKeyword: function () {
- var result = /^[a-zA-Z_$][a-zA-Z0-9_$]*/.exec(this.input);
- var keywords = [
- "if", "in", "do", "var", "for", "new",
- "try", "let", "this", "else", "case",
- "void", "with", "enum", "while", "break",
- "catch", "throw", "const", "yield", "class",
- "super", "return", "typeof", "delete",
- "switch", "export", "import", "default",
- "finally", "extends", "function", "continue",
- "debugger", "instanceof"
- ];
-
- if (result && keywords.indexOf(result[0]) >= 0) {
- return {
- type: Token.Keyword,
- value: result[0]
- };
- }
-
- return null;
- },
-
- /*
- * Extract a JavaScript identifier out of the next sequence of
- * characters or return 'null' if its not possible. In addition,
- * to Identifier this method can also produce BooleanLiteral
- * (true/false) and NullLiteral (null).
- */
- scanIdentifier: function () {
- var id = "";
- var index = 0;
- var type, char;
-
- // Detects any character in the Unicode categories "Uppercase
- // letter (Lu)", "Lowercase letter (Ll)", "Titlecase letter
- // (Lt)", "Modifier letter (Lm)", "Other letter (Lo)", or
- // "Letter number (Nl)".
- //
- // Both approach and unicodeLetterTable were borrowed from
- // Google's Traceur.
-
- function isUnicodeLetter(code) {
- for (var i = 0; i < unicodeLetterTable.length;) {
- if (code < unicodeLetterTable[i++]) {
- return false;
- }
-
- if (code <= unicodeLetterTable[i++]) {
- return true;
- }
- }
-
- return false;
- }
-
- function isHexDigit(str) {
- return (/^[0-9a-fA-F]$/).test(str);
- }
-
- var readUnicodeEscapeSequence = function () {
- /*jshint validthis:true */
- index += 1;
-
- if (this.peek(index) !== "u") {
- return null;
- }
-
- var ch1 = this.peek(index + 1);
- var ch2 = this.peek(index + 2);
- var ch3 = this.peek(index + 3);
- var ch4 = this.peek(index + 4);
- var code;
-
- if (isHexDigit(ch1) && isHexDigit(ch2) && isHexDigit(ch3) && isHexDigit(ch4)) {
- code = parseInt(ch1 + ch2 + ch3 + ch4, 16);
-
- if (isUnicodeLetter(code)) {
- index += 5;
- return "\\u" + ch1 + ch2 + ch3 + ch4;
- }
-
- return null;
- }
-
- return null;
- }.bind(this);
-
- var getIdentifierStart = function () {
- /*jshint validthis:true */
- var chr = this.peek(index);
- var code = chr.charCodeAt(0);
-
- if (code === 92) {
- return readUnicodeEscapeSequence();
- }
-
- if (code < 128) {
- if (identifierStartTable[code]) {
- index += 1;
- return chr;
- }
-
- return null;
- }
-
- if (isUnicodeLetter(code)) {
- index += 1;
- return chr;
- }
-
- return null;
- }.bind(this);
-
- var getIdentifierPart = function () {
- /*jshint validthis:true */
- var chr = this.peek(index);
- var code = chr.charCodeAt(0);
-
- if (code === 92) {
- return readUnicodeEscapeSequence();
- }
-
- if (code < 128) {
- if (identifierPartTable[code]) {
- index += 1;
- return chr;
- }
-
- return null;
- }
-
- if (isUnicodeLetter(code)) {
- index += 1;
- return chr;
- }
-
- return null;
- }.bind(this);
-
- char = getIdentifierStart();
- if (char === null) {
- return null;
- }
-
- id = char;
- for (;;) {
- char = getIdentifierPart();
-
- if (char === null) {
- break;
- }
-
- id += char;
- }
-
- switch (id) {
- case "true":
- case "false":
- type = Token.BooleanLiteral;
- break;
- case "null":
- type = Token.NullLiteral;
- break;
- default:
- type = Token.Identifier;
- }
-
- return {
- type: type,
- value: id
- };
- },
-
- /*
- * Extract a numeric literal out of the next sequence of
- * characters or return 'null' if its not possible. This method
- * supports all numeric literals described in section 7.8.3
- * of the EcmaScript 5 specification.
- *
- * This method's implementation was heavily influenced by the
- * scanNumericLiteral function in the Esprima parser's source code.
- */
- scanNumericLiteral: function () {
- var index = 0;
- var value = "";
- var length = this.input.length;
- var char = this.peek(index);
- var bad;
-
- function isDecimalDigit(str) {
- return (/^[0-9]$/).test(str);
- }
-
- function isOctalDigit(str) {
- return (/^[0-7]$/).test(str);
- }
-
- function isHexDigit(str) {
- return (/^[0-9a-fA-F]$/).test(str);
- }
-
- function isIdentifierStart(ch) {
- return (ch === "$") || (ch === "_") || (ch === "\\") ||
- (ch >= "a" && ch <= "z") || (ch >= "A" && ch <= "Z");
- }
-
- // Numbers must start either with a decimal digit or a point.
-
- if (char !== "." && !isDecimalDigit(char)) {
- return null;
- }
-
- if (char !== ".") {
- value = this.peek(index);
- index += 1;
- char = this.peek(index);
-
- if (value === "0") {
- // Base-16 numbers.
- if (char === "x" || char === "X") {
- index += 1;
- value += char;
-
- while (index < length) {
- char = this.peek(index);
- if (!isHexDigit(char)) {
- break;
- }
- value += char;
- index += 1;
- }
-
- if (value.length <= 2) { // 0x
- return {
- type: Token.NumericLiteral,
- value: value,
- isMalformed: true
- };
- }
-
- if (index < length) {
- char = this.peek(index);
- if (isIdentifierStart(char)) {
- return null;
- }
- }
-
- return {
- type: Token.NumericLiteral,
- value: value,
- base: 16,
- isMalformed: false
- };
- }
-
- // Base-8 numbers.
- if (isOctalDigit(char)) {
- index += 1;
- value += char;
- bad = false;
-
- while (index < length) {
- char = this.peek(index);
-
- // Numbers like '019' (note the 9) are not valid octals
- // but we still parse them and mark as malformed.
-
- if (isDecimalDigit(char)) {
- bad = true;
- } else if (!isOctalDigit(char)) {
- break;
- }
- value += char;
- index += 1;
- }
-
- if (index < length) {
- char = this.peek(index);
- if (isIdentifierStart(char)) {
- return null;
- }
- }
-
- return {
- type: Token.NumericLiteral,
- value: value,
- base: 8,
- isMalformed: false
- };
- }
-
- // Decimal numbers that start with '0' such as '09' are illegal
- // but we still parse them and return as malformed.
-
- if (isDecimalDigit(char)) {
- index += 1;
- value += char;
- }
- }
-
- while (index < length) {
- char = this.peek(index);
- if (!isDecimalDigit(char)) {
- break;
- }
- value += char;
- index += 1;
- }
- }
-
- // Decimal digits.
-
- if (char === ".") {
- value += char;
- index += 1;
-
- while (index < length) {
- char = this.peek(index);
- if (!isDecimalDigit(char)) {
- break;
- }
- value += char;
- index += 1;
- }
- }
-
- // Exponent part.
-
- if (char === "e" || char === "E") {
- value += char;
- index += 1;
- char = this.peek(index);
-
- if (char === "+" || char === "-") {
- value += this.peek(index);
- index += 1;
- }
-
- char = this.peek(index);
- if (isDecimalDigit(char)) {
- value += char;
- index += 1;
-
- while (index < length) {
- char = this.peek(index);
- if (!isDecimalDigit(char)) {
- break;
- }
- value += char;
- index += 1;
- }
- } else {
- return null;
- }
- }
-
- if (index < length) {
- char = this.peek(index);
- if (isIdentifierStart(char)) {
- return null;
- }
- }
-
- return {
- type: Token.NumericLiteral,
- value: value,
- base: 10,
- isMalformed: !isFinite(value)
- };
- },
-
- /*
- * Extract a string out of the next sequence of characters and/or
- * lines or return 'null' if its not possible. Since strings can
- * span across multiple lines this method has to move the char
- * pointer.
- *
- * This method recognizes pseudo-multiline JavaScript strings:
- *
- * var str = "hello\
- * world";
- */
- scanStringLiteral: function (checks) {
- /*jshint loopfunc:true */
- var quote = this.peek();
-
- // String must start with a quote.
- if (quote !== "\"" && quote !== "'") {
- return null;
- }
-
- // In JSON strings must always use double quotes.
- this.triggerAsync("warning", {
- code: "W108",
- line: this.line,
- character: this.char // +1?
- }, checks, function () { return state.jsonMode && quote !== "\""; });
-
- var value = "";
- var startLine = this.line;
- var startChar = this.char;
- var allowNewLine = false;
-
- this.skip();
-
- while (this.peek() !== quote) {
- while (this.peek() === "") { // End Of Line
-
- // If an EOL is not preceded by a backslash, show a warning
- // and proceed like it was a legit multi-line string where
- // author simply forgot to escape the newline symbol.
- //
- // Another approach is to implicitly close a string on EOL
- // but it generates too many false positives.
-
- if (!allowNewLine) {
- this.trigger("warning", {
- code: "W112",
- line: this.line,
- character: this.char
- });
- } else {
- allowNewLine = false;
-
- // Otherwise show a warning if multistr option was not set.
- // For JSON, show warning no matter what.
-
- this.triggerAsync("warning", {
- code: "W043",
- line: this.line,
- character: this.char
- }, checks, function () { return !state.option.multistr; });
-
- this.triggerAsync("warning", {
- code: "W042",
- line: this.line,
- character: this.char
- }, checks, function () { return state.jsonMode && state.option.multistr; });
- }
-
- // If we get an EOF inside of an unclosed string, show an
- // error and implicitly close it at the EOF point.
-
- if (!this.nextLine()) {
- this.trigger("error", {
- code: "E029",
- line: startLine,
- character: startChar
- });
-
- return {
- type: Token.StringLiteral,
- value: value,
- isUnclosed: true,
- quote: quote
- };
- }
- }
-
- allowNewLine = false;
- var char = this.peek();
- var jump = 1; // A length of a jump, after we're done
- // parsing this character.
-
- if (char < " ") {
- // Warn about a control character in a string.
- this.trigger("warning", {
- code: "W113",
- line: this.line,
- character: this.char,
- data: [ "<non-printable>" ]
- });
- }
-
- // Special treatment for some escaped characters.
-
- if (char === "\\") {
- this.skip();
- char = this.peek();
-
- switch (char) {
- case "'":
- this.triggerAsync("warning", {
- code: "W114",
- line: this.line,
- character: this.char,
- data: [ "\\'" ]
- }, checks, function () {return state.jsonMode; });
- break;
- case "b":
- char = "\b";
- break;
- case "f":
- char = "\f";
- break;
- case "n":
- char = "\n";
- break;
- case "r":
- char = "\r";
- break;
- case "t":
- char = "\t";
- break;
- case "0":
- char = "\0";
-
- // Octal literals fail in strict mode.
- // Check if the number is between 00 and 07.
- var n = parseInt(this.peek(1), 10);
- this.triggerAsync("warning", {
- code: "W115",
- line: this.line,
- character: this.char
- }, checks,
- function () { return n >= 0 && n <= 7 && state.directive["use strict"]; });
- break;
- case "u":
- char = String.fromCharCode(parseInt(this.input.substr(1, 4), 16));
- jump = 5;
- break;
- case "v":
- this.triggerAsync("warning", {
- code: "W114",
- line: this.line,
- character: this.char,
- data: [ "\\v" ]
- }, checks, function () { return state.jsonMode; });
-
- char = "\v";
- break;
- case "x":
- var x = parseInt(this.input.substr(1, 2), 16);
-
- this.triggerAsync("warning", {
- code: "W114",
- line: this.line,
- character: this.char,
- data: [ "\\x-" ]
- }, checks, function () { return state.jsonMode; });
-
- char = String.fromCharCode(x);
- jump = 3;
- break;
- case "\\":
- case "\"":
- case "/":
- break;
- case "":
- allowNewLine = true;
- char = "";
- break;
- case "!":
- if (value.slice(value.length - 2) === "<") {
- break;
- }
-
- /*falls through */
- default:
- // Weird escaping.
- this.trigger("warning", {
- code: "W044",
- line: this.line,
- character: this.char
- });
- }
- }
-
- value += char;
- this.skip(jump);
- }
-
- this.skip();
- return {
- type: Token.StringLiteral,
- value: value,
- isUnclosed: false,
- quote: quote
- };
- },
-
- /*
- * Extract a regular expression out of the next sequence of
- * characters and/or lines or return 'null' if its not possible.
- *
- * This method is platform dependent: it accepts almost any
- * regular expression values but then tries to compile and run
- * them using system's RegExp object. This means that there are
- * rare edge cases where one JavaScript engine complains about
- * your regular expression while others don't.
- */
- scanRegExp: function () {
- var index = 0;
- var length = this.input.length;
- var char = this.peek();
- var value = char;
- var body = "";
- var flags = [];
- var malformed = false;
- var isCharSet = false;
- var terminated;
-
- var scanUnexpectedChars = function () {
- // Unexpected control character
- if (char < " ") {
- malformed = true;
- this.trigger("warning", {
- code: "W048",
- line: this.line,
- character: this.char
- });
- }
-
- // Unexpected escaped character
- if (char === "<") {
- malformed = true;
- this.trigger("warning", {
- code: "W049",
- line: this.line,
- character: this.char,
- data: [ char ]
- });
- }
- }.bind(this);
-
- // Regular expressions must start with '/'
- if (!this.prereg || char !== "/") {
- return null;
- }
-
- index += 1;
- terminated = false;
-
- // Try to get everything in between slashes. A couple of
- // cases aside (see scanUnexpectedChars) we don't really
- // care whether the resulting expression is valid or not.
- // We will check that later using the RegExp object.
-
- while (index < length) {
- char = this.peek(index);
- value += char;
- body += char;
-
- if (isCharSet) {
- if (char === "]") {
- if (this.peek(index - 1) !== "\\" || this.peek(index - 2) === "\\") {
- isCharSet = false;
- }
- }
-
- if (char === "\\") {
- index += 1;
- char = this.peek(index);
- body += char;
- value += char;
-
- scanUnexpectedChars();
- }
-
- index += 1;
- continue;
- }
-
- if (char === "\\") {
- index += 1;
- char = this.peek(index);
- body += char;
- value += char;
-
- scanUnexpectedChars();
-
- if (char === "/") {
- index += 1;
- continue;
- }
-
- if (char === "[") {
- index += 1;
- continue;
- }
- }
-
- if (char === "[") {
- isCharSet = true;
- index += 1;
- continue;
- }
-
- if (char === "/") {
- body = body.substr(0, body.length - 1);
- terminated = true;
- index += 1;
- break;
- }
-
- index += 1;
- }
-
- // A regular expression that was never closed is an
- // error from which we cannot recover.
-
- if (!terminated) {
- this.trigger("error", {
- code: "E015",
- line: this.line,
- character: this.from
- });
-
- return void this.trigger("fatal", {
- line: this.line,
- from: this.from
- });
- }
-
- // Parse flags (if any).
-
- while (index < length) {
- char = this.peek(index);
- if (!/[gim]/.test(char)) {
- break;
- }
- flags.push(char);
- value += char;
- index += 1;
- }
-
- // Check regular expression for correctness.
-
- try {
- new RegExp(body, flags.join(""));
- } catch (err) {
- malformed = true;
- this.trigger("error", {
- code: "E016",
- line: this.line,
- character: this.char,
- data: [ err.message ] // Platform dependent!
- });
- }
-
- return {
- type: Token.RegExp,
- value: value,
- flags: flags,
- isMalformed: malformed
- };
- },
-
- /*
- * Scan for any occurence of mixed tabs and spaces. If smarttabs option
- * is on, ignore tabs followed by spaces.
- *
- * Tabs followed by one space followed by a block comment are allowed.
- */
- scanMixedSpacesAndTabs: function () {
- var at, match;
-
- if (state.option.smarttabs) {
- // Negative look-behind for "//"
- match = this.input.match(/(\/\/|^\s?\*)? \t/);
- at = match && !match[1] ? 0 : -1;
- } else {
- at = this.input.search(/ \t|\t [^\*]/);
- }
-
- return at;
- },
-
- /*
- * Scan for characters that get silently deleted by one or more browsers.
- */
- scanUnsafeChars: function () {
- return this.input.search(reg.unsafeChars);
- },
-
- /*
- * Produce the next raw token or return 'null' if no tokens can be matched.
- * This method skips over all space characters.
- */
- next: function (checks) {
- this.from = this.char;
-
- // Move to the next non-space character.
- var start;
- if (/\s/.test(this.peek())) {
- start = this.char;
-
- while (/\s/.test(this.peek())) {
- this.from += 1;
- this.skip();
- }
-
- if (this.peek() === "") { // EOL
- if (!/^\s*$/.test(this.lines[this.line - 1]) && state.option.trailing) {
- this.trigger("warning", { code: "W102", line: this.line, character: start });
- }
- }
- }
-
- // Methods that work with multi-line structures and move the
- // character pointer.
-
- var match = this.scanComments() ||
- this.scanStringLiteral(checks);
-
- if (match) {
- return match;
- }
-
- // Methods that don't move the character pointer.
-
- match =
- this.scanRegExp() ||
- this.scanPunctuator() ||
- this.scanKeyword() ||
- this.scanIdentifier() ||
- this.scanNumericLiteral();
-
- if (match) {
- this.skip(match.value.length);
- return match;
- }
-
- // No token could be matched, give up.
-
- return null;
- },
-
- /*
- * Switch to the next line and reset all char pointers. Once
- * switched, this method also checks for mixed spaces and tabs
- * and other minor warnings.
- */
- nextLine: function () {
- var char;
-
- if (this.line >= this.lines.length) {
- return false;
- }
-
- this.input = this.lines[this.line];
- this.line += 1;
- this.char = 1;
- this.from = 1;
-
- char = this.scanMixedSpacesAndTabs();
- if (char >= 0) {
- this.trigger("warning", { code: "W099", line: this.line, character: char + 1 });
- }
-
- this.input = this.input.replace(/\t/g, state.tab);
- char = this.scanUnsafeChars();
-
- if (char >= 0) {
- this.trigger("warning", { code: "W100", line: this.line, character: char });
- }
-
- // If there is a limit on line length, warn when lines get too
- // long.
-
- if (state.option.maxlen && state.option.maxlen < this.input.length) {
- this.trigger("warning", { code: "W101", line: this.line, character: this.input.length });
- }
-
- return true;
- },
-
- /*
- * This is simply a synonym for nextLine() method with a friendlier
- * public name.
- */
- start: function () {
- this.nextLine();
- },
-
- /*
- * Produce the next token. This function is called by advance() to get
- * the next token. It retuns a token in a JSLint-compatible format.
- */
- token: function () {
- /*jshint loopfunc:true */
- var checks = asyncTrigger();
- var token;
-
-
- function isReserved(token, isProperty) {
- if (!token.reserved) {
- return false;
- }
-
- if (token.meta && token.meta.isFutureReservedWord) {
- // ES3 FutureReservedWord in an ES5 environment.
- if (state.option.inES5(true) && !token.meta.es5) {
- return false;
- }
-
- // Some ES5 FutureReservedWord identifiers are active only
- // within a strict mode environment.
- if (token.meta.strictOnly) {
- if (!state.option.strict && !state.directive["use strict"]) {
- return false;
- }
- }
-
- if (isProperty) {
- return false;
- }
- }
-
- return true;
- }
-
- // Produce a token object.
- var create = function (type, value, isProperty) {
- /*jshint validthis:true */
- var obj;
-
- if (type !== "(endline)" && type !== "(end)") {
- this.prereg = false;
- }
-
- if (type === "(punctuator)") {
- switch (value) {
- case ".":
- case ")":
- case "~":
- case "#":
- case "]":
- this.prereg = false;
- break;
- default:
- this.prereg = true;
- }
-
- obj = Object.create(state.syntax[value] || state.syntax["(error)"]);
- }
-
- if (type === "(identifier)") {
- if (value === "return" || value === "case" || value === "typeof") {
- this.prereg = true;
- }
-
- if (_.has(state.syntax, value)) {
- obj = Object.create(state.syntax[value] || state.syntax["(error)"]);
-
- // If this can't be a reserved keyword, reset the object.
- if (!isReserved(obj, isProperty && type === "(identifier)")) {
- obj = null;
- }
- }
- }
-
- if (!obj) {
- obj = Object.create(state.syntax[type]);
- }
-
- obj.identifier = (type === "(identifier)");
- obj.type = obj.type || type;
- obj.value = value;
- obj.line = this.line;
- obj.character = this.char;
- obj.from = this.from;
-
- if (isProperty && obj.identifier) {
- obj.isProperty = isProperty;
- }
-
- obj.check = checks.check;
-
- return obj;
- }.bind(this);
-
- for (;;) {
- if (!this.input.length) {
- return create(this.nextLine() ? "(endline)" : "(end)", "");
- }
-
- token = this.next(checks);
-
- if (!token) {
- if (this.input.length) {
- // Unexpected character.
- this.trigger("error", {
- code: "E024",
- line: this.line,
- character: this.char,
- data: [ this.peek() ]
- });
-
- this.input = "";
- }
-
- continue;
- }
-
- switch (token.type) {
- case Token.StringLiteral:
- this.triggerAsync("String", {
- line: this.line,
- char: this.char,
- from: this.from,
- value: token.value,
- quote: token.quote
- }, checks, function () { return true; });
-
- return create("(string)", token.value);
- case Token.Identifier:
- this.trigger("Identifier", {
- line: this.line,
- char: this.char,
- from: this.form,
- name: token.value,
- isProperty: state.tokens.curr.id === "."
- });
-
- /* falls through */
- case Token.Keyword:
- case Token.NullLiteral:
- case Token.BooleanLiteral:
- return create("(identifier)", token.value, state.tokens.curr.id === ".");
-
- case Token.NumericLiteral:
- if (token.isMalformed) {
- this.trigger("warning", {
- code: "W045",
- line: this.line,
- character: this.char,
- data: [ token.value ]
- });
- }
-
- this.triggerAsync("warning", {
- code: "W114",
- line: this.line,
- character: this.char,
- data: [ "0x-" ]
- }, checks, function () { return token.base === 16 && state.jsonMode; });
-
- this.triggerAsync("warning", {
- code: "W115",
- line: this.line,
- character: this.char
- }, checks, function () {
- return state.directive["use strict"] && token.base === 8;
- });
-
- this.trigger("Number", {
- line: this.line,
- char: this.char,
- from: this.from,
- value: token.value,
- base: token.base,
- isMalformed: token.malformed
- });
-
- return create("(number)", token.value);
-
- case Token.RegExp:
- return create("(regexp)", token.value);
-
- case Token.Comment:
- state.tokens.curr.comment = true;
-
- if (token.isSpecial) {
- return {
- value: token.value,
- body: token.body,
- type: token.commentType,
- isSpecial: token.isSpecial,
- line: this.line,
- character: this.char,
- from: this.from
- };
- }
-
- break;
-
- case "":
- break;
-
- default:
- return create("(punctuator)", token.value);
- }
- }
- }
-};
-
-exports.Lexer = Lexer;
-
-})()
-},{"events":2,"./reg.js":6,"./state.js":4,"underscore":11}],"jshint":[function(require,module,exports){
-module.exports=require('E/GbHF');
-},{}],"E/GbHF":[function(require,module,exports){
-(function(){/*!
- * JSHint, by JSHint Community.
- *
- * This file (and this file only) is licensed under the same slightly modified
- * MIT license that JSLint is. It stops evil-doers everywhere:
- *
- * Copyright (c) 2002 Douglas Crockford (www.JSLint.com)
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom
- * the Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * The Software shall be used for Good, not Evil.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- */
-
-/*jshint quotmark:double */
-/*global console:true */
-/*exported console */
-
-var _ = require("underscore");
-var events = require("events");
-var vars = require("../shared/vars.js");
-var messages = require("../shared/messages.js");
-var Lexer = require("./lex.js").Lexer;
-var reg = require("./reg.js");
-var state = require("./state.js").state;
-var style = require("./style.js");
-
-// We need this module here because environments such as IE and Rhino
-// don't necessarilly expose the 'console' API and browserify uses
-// it to log things. It's a sad state of affair, really.
-var console = require("console-browserify");
-
-// We build the application inside a function so that we produce only a singleton
-// variable. That function will be invoked immediately, and its return value is
-// the JSHINT function itself.
-
-var JSHINT = (function () {
- "use strict";
-
- var anonname, // The guessed name for anonymous functions.
- api, // Extension API
-
- // These are operators that should not be used with the ! operator.
- bang = {
- "<" : true,
- "<=" : true,
- "==" : true,
- "===": true,
- "!==": true,
- "!=" : true,
- ">" : true,
- ">=" : true,
- "+" : true,
- "-" : true,
- "*" : true,
- "/" : true,
- "%" : true
- },
-
- // These are the JSHint boolean options.
- boolOptions = {
- asi : true, // if automatic semicolon insertion should be tolerated
- bitwise : true, // if bitwise operators should not be allowed
- boss : true, // if advanced usage of assignments should be allowed
- browser : true, // if the standard browser globals should be predefined
- camelcase : true, // if identifiers should be required in camel case
- couch : true, // if CouchDB globals should be predefined
- curly : true, // if curly braces around all blocks should be required
- debug : true, // if debugger statements should be allowed
- devel : true, // if logging globals should be predefined (console, alert, etc.)
- dojo : true, // if Dojo Toolkit globals should be predefined
- eqeqeq : true, // if === should be required
- eqnull : true, // if == null comparisons should be tolerated
- es3 : true, // if ES3 syntax should be allowed
- es5 : true, // if ES5 syntax should be allowed (is now set per default)
- esnext : true, // if es.next specific syntax should be allowed
- moz : true, // if mozilla specific syntax should be allowed
- evil : true, // if eval should be allowed
- expr : true, // if ExpressionStatement should be allowed as Programs
- forin : true, // if for in statements must filter
- funcscope : true, // if only function scope should be used for scope tests
- gcl : true, // if JSHint should be compatible with Google Closure Linter
- globalstrict: true, // if global "use strict"; should be allowed (also enables 'strict')
- immed : true, // if immediate invocations must be wrapped in parens
- iterator : true, // if the `__iterator__` property should be allowed
- jquery : true, // if jQuery globals should be predefined
- lastsemic : true, // if semicolons may be ommitted for the trailing
- // statements inside of a one-line blocks.
- laxbreak : true, // if line breaks should not be checked
- laxcomma : true, // if line breaks should not be checked around commas
- loopfunc : true, // if functions should be allowed to be defined within
- // loops
- mootools : true, // if MooTools globals should be predefined
- multistr : true, // allow multiline strings
- newcap : true, // if constructor names must be capitalized
- noarg : true, // if arguments.caller and arguments.callee should be
- // disallowed
- node : true, // if the Node.js environment globals should be
- // predefined
- noempty : true, // if empty blocks should be disallowed
- nonew : true, // if using `new` for side-effects should be disallowed
- nonstandard : true, // if non-standard (but widely adopted) globals should
- // be predefined
- nomen : true, // if names should be checked
- onevar : true, // if only one var statement per function should be
- // allowed
- passfail : true, // if the scan should stop on first error
- phantom : true, // if PhantomJS symbols should be allowed
- plusplus : true, // if increment/decrement should not be allowed
- proto : true, // if the `__proto__` property should be allowed
- prototypejs : true, // if Prototype and Scriptaculous globals should be
- // predefined
- rhino : true, // if the Rhino environment globals should be predefined
- undef : true, // if variables should be declared before used
- scripturl : true, // if script-targeted URLs should be tolerated
- shadow : true, // if variable shadowing should be tolerated
- smarttabs : true, // if smarttabs should be tolerated
- // (http://www.emacswiki.org/emacs/SmartTabs)
- strict : true, // require the "use strict"; pragma
- sub : true, // if all forms of subscript notation are tolerated
- supernew : true, // if `new function () { ... };` and `new Object;`
- // should be tolerated
- trailing : true, // if trailing whitespace rules apply
- validthis : true, // if 'this' inside a non-constructor function is valid.
- // This is a function scoped option only.
- withstmt : true, // if with statements should be allowed
- white : true, // if strict whitespace rules apply
- worker : true, // if Web Worker script symbols should be allowed
- wsh : true, // if the Windows Scripting Host environment globals
- // should be predefined
- yui : true, // YUI variables should be predefined
-
- // Obsolete options
- onecase : true, // if one case switch statements should be allowed
- regexp : true, // if the . should not be allowed in regexp literals
- regexdash : true // if unescaped first/last dash (-) inside brackets
- // should be tolerated
- },
-
- // These are the JSHint options that can take any value
- // (we use this object to detect invalid options)
- valOptions = {
- maxlen : false,
- indent : false,
- maxerr : false,
- predef : false,
- quotmark : false, //'single'|'double'|true
- scope : false,
- maxstatements: false, // {int} max statements per function
- maxdepth : false, // {int} max nested block depth per function
- maxparams : false, // {int} max params per function
- maxcomplexity: false, // {int} max cyclomatic complexity per function
- unused : true, // warn if variables are unused. Available options:
- // false - don't check for unused variables
- // true - "vars" + check last function param
- // "vars" - skip checking unused function params
- // "strict" - "vars" + check all function params
- latedef : false // warn if the variable is used before its definition
- // false - don't emit any warnings
- // true - warn if any variable is used before its definition
- // "nofunc" - warn for any variable but function declarations
- },
-
- // These are JSHint boolean options which are shared with JSLint
- // where the definition in JSHint is opposite JSLint
- invertedOptions = {
- bitwise : true,
- forin : true,
- newcap : true,
- nomen : true,
- plusplus: true,
- regexp : true,
- undef : true,
- white : true,
-
- // Inverted and renamed, use JSHint name here
- eqeqeq : true,
- onevar : true,
- strict : true
- },
-
- // These are JSHint boolean options which are shared with JSLint
- // where the name has been changed but the effect is unchanged
- renamedOptions = {
- eqeq : "eqeqeq",
- vars : "onevar",
- windows: "wsh",
- sloppy : "strict"
- },
-
- declared, // Globals that were declared using /*global ... */ syntax.
- exported, // Variables that are used outside of the current file.
-
- functionicity = [
- "closure", "exception", "global", "label",
- "outer", "unused", "var"
- ],
-
- funct, // The current function
- functions, // All of the functions
-
- global, // The global scope
- implied, // Implied globals
- inblock,
- indent,
- lookahead,
- lex,
- member,
- membersOnly,
- noreach,
- predefined, // Global variables defined by option
-
- scope, // The current scope
- stack,
- unuseds,
- urls,
- warnings,
-
- extraModules = [],
- emitter = new events.EventEmitter();
-
- function checkOption(name, t) {
- name = name.trim();
-
- if (/^[+-]W\d{3}$/g.test(name)) {
- return true;
- }
-
- if (valOptions[name] === undefined && boolOptions[name] === undefined) {
- if (t.type !== "jslint") {
- error("E001", t, name);
- return false;
- }
- }
-
- return true;
- }
-
- function isString(obj) {
- return Object.prototype.toString.call(obj) === "[object String]";
- }
-
- function isIdentifier(tkn, value) {
- if (!tkn)
- return false;
-
- if (!tkn.identifier || tkn.value !== value)
- return false;
-
- return true;
- }
-
- function isReserved(token) {
- if (!token.reserved) {
- return false;
- }
-
- if (token.meta && token.meta.isFutureReservedWord) {
- // ES3 FutureReservedWord in an ES5 environment.
- if (state.option.inES5(true) && !token.meta.es5) {
- return false;
- }
-
- // Some ES5 FutureReservedWord identifiers are active only
- // within a strict mode environment.
- if (token.meta.strictOnly) {
- if (!state.option.strict && !state.directive["use strict"]) {
- return false;
- }
- }
-
- if (token.isProperty) {
- return false;
- }
- }
-
- return true;
- }
-
- function supplant(str, data) {
- return str.replace(/\{([^{}]*)\}/g, function (a, b) {
- var r = data[b];
- return typeof r === "string" || typeof r === "number" ? r : a;
- });
- }
-
- function combine(t, o) {
- var n;
- for (n in o) {
- if (_.has(o, n) && !_.has(JSHINT.blacklist, n)) {
- t[n] = o[n];
- }
- }
- }
-
- function updatePredefined() {
- Object.keys(JSHINT.blacklist).forEach(function (key) {
- delete predefined[key];
- });
- }
-
- function assume() {
- if (state.option.es5) {
- warning("I003");
- }
- if (state.option.couch) {
- combine(predefined, vars.couch);
- }
-
- if (state.option.rhino) {
- combine(predefined, vars.rhino);
- }
-
- if (state.option.phantom) {
- combine(predefined, vars.phantom);
- }
-
- if (state.option.prototypejs) {
- combine(predefined, vars.prototypejs);
- }
-
- if (state.option.node) {
- combine(predefined, vars.node);
- }
-
- if (state.option.devel) {
- combine(predefined, vars.devel);
- }
-
- if (state.option.dojo) {
- combine(predefined, vars.dojo);
- }
-
- if (state.option.browser) {
- combine(predefined, vars.browser);
- }
-
- if (state.option.nonstandard) {
- combine(predefined, vars.nonstandard);
- }
-
- if (state.option.jquery) {
- combine(predefined, vars.jquery);
- }
-
- if (state.option.mootools) {
- combine(predefined, vars.mootools);
- }
-
- if (state.option.worker) {
- combine(predefined, vars.worker);
- }
-
- if (state.option.wsh) {
- combine(predefined, vars.wsh);
- }
-
- if (state.option.globalstrict && state.option.strict !== false) {
- state.option.strict = true;
- }
-
- if (state.option.yui) {
- combine(predefined, vars.yui);
- }
-
- // Let's assume that chronologically ES3 < ES5 < ES6/ESNext < Moz
-
- state.option.inMoz = function (strict) {
- if (strict) {
- return state.option.moz && !state.option.esnext;
- }
- return state.option.moz;
- };
-
- state.option.inESNext = function (strict) {
- if (strict) {
- return !state.option.moz && state.option.esnext;
- }
- return state.option.moz || state.option.esnext;
- };
-
- state.option.inES5 = function (/* strict */) {
- return !state.option.es3;
- };
-
- state.option.inES3 = function (strict) {
- if (strict) {
- return !state.option.moz && !state.option.esnext && state.option.es3;
- }
- return state.option.es3;
- };
- }
-
- // Produce an error warning.
- function quit(code, line, chr) {
- var percentage = Math.floor((line / state.lines.length) * 100);
- var message = messages.errors[code].desc;
-
- throw {
- name: "JSHintError",
- line: line,
- character: chr,
- message: message + " (" + percentage + "% scanned).",
- raw: message
- };
- }
-
- function isundef(scope, code, token, a) {
- return JSHINT.undefs.push([scope, code, token, a]);
- }
-
- function warning(code, t, a, b, c, d) {
- var ch, l, w, msg;
-
- if (/^W\d{3}$/.test(code)) {
- if (state.ignored[code])
- return;
-
- msg = messages.warnings[code];
- } else if (/E\d{3}/.test(code)) {
- msg = messages.errors[code];
- } else if (/I\d{3}/.test(code)) {
- msg = messages.info[code];
- }
-
- t = t || state.tokens.next;
- if (t.id === "(end)") { // `~
- t = state.tokens.curr;
- }
-
- l = t.line || 0;
- ch = t.from || 0;
-
- w = {
- id: "(error)",
- raw: msg.desc,
- code: msg.code,
- evidence: state.lines[l - 1] || "",
- line: l,
- character: ch,
- scope: JSHINT.scope,
- a: a,
- b: b,
- c: c,
- d: d
- };
-
- w.reason = supplant(msg.desc, w);
- JSHINT.errors.push(w);
-
- if (state.option.passfail) {
- quit("E042", l, ch);
- }
-
- warnings += 1;
- if (warnings >= state.option.maxerr) {
- quit("E043", l, ch);
- }
-
- return w;
- }
-
- function warningAt(m, l, ch, a, b, c, d) {
- return warning(m, {
- line: l,
- from: ch
- }, a, b, c, d);
- }
-
- function error(m, t, a, b, c, d) {
- warning(m, t, a, b, c, d);
- }
-
- function errorAt(m, l, ch, a, b, c, d) {
- return error(m, {
- line: l,
- from: ch
- }, a, b, c, d);
- }
-
- // Tracking of "internal" scripts, like eval containing a static string
- function addInternalSrc(elem, src) {
- var i;
- i = {
- id: "(internal)",
- elem: elem,
- value: src
- };
- JSHINT.internals.push(i);
- return i;
- }
-
- function addlabel(t, type, tkn, islet) {
- // Define t in the current function in the current scope.
- if (type === "exception") {
- if (_.has(funct["(context)"], t)) {
- if (funct[t] !== true && !state.option.node) {
- warning("W002", state.tokens.next, t);
- }
- }
- }
-
- if (_.has(funct, t) && !funct["(global)"]) {
- if (funct[t] === true) {
- if (state.option.latedef) {
- if ((state.option.latedef === true && _.contains([funct[t], type], "unction")) ||
- !_.contains([funct[t], type], "unction")) {
- warning("W003", state.tokens.next, t);
- }
- }
- } else {
- if (!state.option.shadow && type !== "exception" ||
- (funct["(blockscope)"].getlabel(t))) {
- warning("W004", state.tokens.next, t);
- }
- }
- }
-
- // a double definition of a let variable in same block throws a TypeError
- //if (funct["(blockscope)"] && funct["(blockscope)"].current.has(t)) {
- // error("E044", state.tokens.next, t);
- //}
-
- // if the identifier is from a let, adds it only to the current blockscope
- if (islet) {
- funct["(blockscope)"].current.add(t, type, state.tokens.curr);
- } else {
-
- funct[t] = type;
-
- if (tkn) {
- funct["(tokens)"][t] = tkn;
- }
-
- if (funct["(global)"]) {
- global[t] = funct;
- if (_.has(implied, t)) {
- if (state.option.latedef) {
- if ((state.option.latedef === true && _.contains([funct[t], type], "unction")) ||
- !_.contains([funct[t], type], "unction")) {
- warning("W003", state.tokens.next, t);
- }
- }
-
- delete implied[t];
- }
- } else {
- scope[t] = funct;
- }
- }
- }
-
- function doOption() {
- var nt = state.tokens.next;
- var body = nt.body.split(",").map(function (s) { return s.trim(); });
- var predef = {};
-
- if (nt.type === "globals") {
- body.forEach(function (g) {
- g = g.split(":");
- var key = g[0];
- var val = g[1];
-
- if (key.charAt(0) === "-") {
- key = key.slice(1);
- val = false;
-
- JSHINT.blacklist[key] = key;
- updatePredefined();
- } else {
- predef[key] = (val === "true");
- }
- });
-
- combine(predefined, predef);
-
- for (var key in predef) {
- if (_.has(predef, key)) {
- declared[key] = nt;
- }
- }
- }
-
- if (nt.type === "exported") {
- body.forEach(function (e) {
- exported[e] = true;
- });
- }
-
- if (nt.type === "members") {
- membersOnly = membersOnly || {};
-
- body.forEach(function (m) {
- var ch1 = m.charAt(0);
- var ch2 = m.charAt(m.length - 1);
-
- if (ch1 === ch2 && (ch1 === "\"" || ch1 === "'")) {
- m = m
- .substr(1, m.length - 2)
- .replace("\\b", "\b")
- .replace("\\t", "\t")
- .replace("\\n", "\n")
- .replace("\\v", "\v")
- .replace("\\f", "\f")
- .replace("\\r", "\r")
- .replace("\\\\", "\\")
- .replace("\\\"", "\"");
- }
-
- membersOnly[m] = false;
- });
- }
-
- var numvals = [
- "maxstatements",
- "maxparams",
- "maxdepth",
- "maxcomplexity",
- "maxerr",
- "maxlen",
- "indent"
- ];
-
- if (nt.type === "jshint" || nt.type === "jslint") {
- body.forEach(function (g) {
- g = g.split(":");
- var key = (g[0] || "").trim();
- var val = (g[1] || "").trim();
-
- if (!checkOption(key, nt)) {
- return;
- }
-
- if (numvals.indexOf(key) >= 0) {
-
- // GH988 - numeric options can be disabled by setting them to `false`
- if (val !== "false") {
- val = +val;
-
- if (typeof val !== "number" || !isFinite(val) || val <= 0 || Math.floor(val) !== val) {
- error("E032", nt, g[1].trim());
- return;
- }
-
- if (key === "indent") {
- state.option["(explicitIndent)"] = true;
- }
- state.option[key] = val;
- } else {
- if (key === "indent") {
- state.option["(explicitIndent)"] = false;
- } else {
- state.option[key] = false;
- }
- }
-
- return;
- }
-
- if (key === "validthis") {
- // `validthis` is valid only within a function scope.
- if (funct["(global)"]) {
- error("E009");
- } else {
- if (val === "true" || val === "false") {
- state.option.validthis = (val === "true");
- } else {
- error("E002", nt);
- }
- }
- return;
- }
-
- if (key === "quotmark") {
- switch (val) {
- case "true":
- case "false":
- state.option.quotmark = (val === "true");
- break;
- case "double":
- case "single":
- state.option.quotmark = val;
- break;
- default:
- error("E002", nt);
- }
- return;
- }
-
- if (key === "unused") {
- switch (val) {
- case "true":
- state.option.unused = true;
- break;
- case "false":
- state.option.unused = false;
- break;
- case "vars":
- case "strict":
- state.option.unused = val;
- break;
- default:
- error("E002", nt);
- }
- return;
- }
-
- if (key === "latedef") {
- switch (val) {
- case "true":
- state.option.latedef = true;
- break;
- case "false":
- state.option.latedef = false;
- break;
- case "nofunc":
- state.option.latedef = "nofunc";
- break;
- default:
- error("E002", nt);
- }
- return;
- }
-
- var match = /^([+-])(W\d{3})$/g.exec(key);
- if (match) {
- // ignore for -W..., unignore for +W...
- state.ignored[match[2]] = (match[1] === "-");
- return;
- }
-
- var tn;
- if (val === "true" || val === "false") {
- if (nt.type === "jslint") {
- tn = renamedOptions[key] || key;
- state.option[tn] = (val === "true");
-
- if (invertedOptions[tn] !== undefined) {
- state.option[tn] = !state.option[tn];
- }
- } else {
- state.option[key] = (val === "true");
- }
-
- if (key === "newcap") {
- state.option["(explicitNewcap)"] = true;
- }
- return;
- }
-
- error("E002", nt);
- });
-
- assume();
- }
- }
-
- // We need a peek function. If it has an argument, it peeks that much farther
- // ahead. It is used to distinguish
- // for ( var i in ...
- // from
- // for ( var i = ...
-
- function peek(p) {
- var i = p || 0, j = 0, t;
-
- while (j <= i) {
- t = lookahead[j];
- if (!t) {
- t = lookahead[j] = lex.token();
- }
- j += 1;
- }
- return t;
- }
-
- // Produce the next token. It looks for programming errors.
-
- function advance(id, t) {
- switch (state.tokens.curr.id) {
- case "(number)":
- if (state.tokens.next.id === ".") {
- warning("W005", state.tokens.curr);
- }
- break;
- case "-":
- if (state.tokens.next.id === "-" || state.tokens.next.id === "--") {
- warning("W006");
- }
- break;
- case "+":
- if (state.tokens.next.id === "+" || state.tokens.next.id === "++") {
- warning("W007");
- }
- break;
- }
-
- if (state.tokens.curr.type === "(string)" || state.tokens.curr.identifier) {
- anonname = state.tokens.curr.value;
- }
-
- if (id && state.tokens.next.id !== id) {
- if (t) {
- if (state.tokens.next.id === "(end)") {
- error("E019", t, t.id);
- } else {
- error("E020", state.tokens.next, id, t.id, t.line, state.tokens.next.value);
- }
- } else if (state.tokens.next.type !== "(identifier)" || state.tokens.next.value !== id) {
- warning("W116", state.tokens.next, id, state.tokens.next.value);
- }
- }
-
- state.tokens.prev = state.tokens.curr;
- state.tokens.curr = state.tokens.next;
- for (;;) {
- state.tokens.next = lookahead.shift() || lex.token();
-
- if (!state.tokens.next) { // No more tokens left, give up
- quit("E041", state.tokens.curr.line);
- }
-
- if (state.tokens.next.id === "(end)" || state.tokens.next.id === "(error)") {
- return;
- }
-
- if (state.tokens.next.check) {
- state.tokens.next.check();
- }
-
- if (state.tokens.next.isSpecial) {
- doOption();
- } else {
- if (state.tokens.next.id !== "(endline)") {
- break;
- }
- }
- }
- }
-
- // This is the heart of JSHINT, the Pratt parser. In addition to parsing, it
- // is looking for ad hoc lint patterns. We add .fud to Pratt's model, which is
- // like .nud except that it is only used on the first token of a statement.
- // Having .fud makes it much easier to define statement-oriented languages like
- // JavaScript. I retained Pratt's nomenclature.
-
- // .nud Null denotation
- // .fud First null denotation
- // .led Left denotation
- // lbp Left binding power
- // rbp Right binding power
-
- // They are elements of the parsing method called Top Down Operator Precedence.
-
- function expression(rbp, initial) {
- var left, isArray = false, isObject = false, isLetExpr = false;
-
- // if current expression is a let expression
- if (!initial && state.tokens.next.value === "let" && peek(0).value === "(") {
- if (!state.option.inMoz(true)) {
- warning("W118", state.tokens.next, "let expressions");
- }
- isLetExpr = true;
- // create a new block scope we use only for the current expression
- funct["(blockscope)"].stack();
- advance("let");
- advance("(");
- state.syntax["let"].fud.call(state.syntax["let"].fud, false);
- advance(")");
- }
-
- if (state.tokens.next.id === "(end)")
- error("E006", state.tokens.curr);
-
- advance();
-
- if (initial) {
- anonname = "anonymous";
- funct["(verb)"] = state.tokens.curr.value;
- }
-
- if (initial === true && state.tokens.curr.fud) {
- left = state.tokens.curr.fud();
- } else {
- if (state.tokens.curr.nud) {
- left = state.tokens.curr.nud();
- } else {
- error("E030", state.tokens.curr, state.tokens.curr.id);
- }
-
- var end_of_expr = state.tokens.next.identifier &&
- !state.tokens.curr.led &&
- state.tokens.curr.line !== state.tokens.next.line;
- while (rbp < state.tokens.next.lbp && !end_of_expr) {
- isArray = state.tokens.curr.value === "Array";
- isObject = state.tokens.curr.value === "Object";
-
- // #527, new Foo.Array(), Foo.Array(), new Foo.Object(), Foo.Object()
- // Line breaks in IfStatement heads exist to satisfy the checkJSHint
- // "Line too long." error.
- if (left && (left.value || (left.first && left.first.value))) {
- // If the left.value is not "new", or the left.first.value is a "."
- // then safely assume that this is not "new Array()" and possibly
- // not "new Object()"...
- if (left.value !== "new" ||
- (left.first && left.first.value && left.first.value === ".")) {
- isArray = false;
- // ...In the case of Object, if the left.value and state.tokens.curr.value
- // are not equal, then safely assume that this not "new Object()"
- if (left.value !== state.tokens.curr.value) {
- isObject = false;
- }
- }
- }
-
- advance();
-
- if (isArray && state.tokens.curr.id === "(" && state.tokens.next.id === ")") {
- warning("W009", state.tokens.curr);
- }
-
- if (isObject && state.tokens.curr.id === "(" && state.tokens.next.id === ")") {
- warning("W010", state.tokens.curr);
- }
-
- if (left && state.tokens.curr.led) {
- left = state.tokens.curr.led(left);
- } else {
- error("E033", state.tokens.curr, state.tokens.curr.id);
- }
- }
- }
- if (isLetExpr) {
- funct["(blockscope)"].unstack();
- }
- return left;
- }
-
-
-// Functions for conformance of style.
-
- function adjacent(left, right) {
- left = left || state.tokens.curr;
- right = right || state.tokens.next;
- if (state.option.white) {
- if (left.character !== right.from && left.line === right.line) {
- left.from += (left.character - left.from);
- warning("W011", left, left.value);
- }
- }
- }
-
- function nobreak(left, right) {
- left = left || state.tokens.curr;
- right = right || state.tokens.next;
- if (state.option.white && (left.character !== right.from || left.line !== right.line)) {
- warning("W012", right, right.value);
- }
- }
-
- function nospace(left, right) {
- left = left || state.tokens.curr;
- right = right || state.tokens.next;
- if (state.option.white && !left.comment) {
- if (left.line === right.line) {
- adjacent(left, right);
- }
- }
- }
-
- function nonadjacent(left, right) {
- if (state.option.white) {
- left = left || state.tokens.curr;
- right = right || state.tokens.next;
-
- if (left.value === ";" && right.value === ";") {
- return;
- }
-
- if (left.line === right.line && left.character === right.from) {
- left.from += (left.character - left.from);
- warning("W013", left, left.value);
- }
- }
- }
-
- function nobreaknonadjacent(left, right) {
- left = left || state.tokens.curr;
- right = right || state.tokens.next;
- if (!state.option.laxbreak && left.line !== right.line) {
- warning("W014", right, right.id);
- } else if (state.option.white) {
- left = left || state.tokens.curr;
- right = right || state.tokens.next;
- if (left.character === right.from) {
- left.from += (left.character - left.from);
- warning("W013", left, left.value);
- }
- }
- }
-
- function indentation(bias) {
- if (!state.option.white && !state.option["(explicitIndent)"]) {
- return;
- }
-
- if (state.tokens.next.id === "(end)") {
- return;
- }
-
- var i = indent + (bias || 0);
- if (state.tokens.next.from !== i) {
- warning("W015", state.tokens.next, state.tokens.next.value, i, state.tokens.next.from);
- }
- }
-
- function nolinebreak(t) {
- t = t || state.tokens.curr;
- if (t.line !== state.tokens.next.line) {
- warning("E022", t, t.value);
- }
- }
-
-
- function comma(opts) {
- opts = opts || {};
-
- if (!opts.peek) {
- if (state.tokens.curr.line !== state.tokens.next.line) {
- if (!state.option.laxcomma) {
- if (comma.first) {
- warning("I001");
- comma.first = false;
- }
- warning("W014", state.tokens.curr, state.tokens.next.value);
- }
- } else if (!state.tokens.curr.comment &&
- state.tokens.curr.character !== state.tokens.next.from && state.option.white) {
- state.tokens.curr.from += (state.tokens.curr.character - state.tokens.curr.from);
- warning("W011", state.tokens.curr, state.tokens.curr.value);
- }
-
- advance(",");
- }
-
- // TODO: This is a temporary solution to fight against false-positives in
- // arrays and objects with trailing commas (see GH-363). The best solution
- // would be to extract all whitespace rules out of parser.
-
- if (state.tokens.next.value !== "]" && state.tokens.next.value !== "}") {
- nonadjacent(state.tokens.curr, state.tokens.next);
- }
-
- if (state.tokens.next.identifier && !(opts.property && state.option.inES5())) {
- // Keywords that cannot follow a comma operator.
- switch (state.tokens.next.value) {
- case "break":
- case "case":
- case "catch":
- case "continue":
- case "default":
- case "do":
- case "else":
- case "finally":
- case "for":
- case "if":
- case "in":
- case "instanceof":
- case "return":
- case "yield":
- case "switch":
- case "throw":
- case "try":
- case "var":
- case "let":
- case "while":
- case "with":
- error("E024", state.tokens.next, state.tokens.next.value);
- return false;
- }
- }
-
- if (state.tokens.next.type === "(punctuator)") {
- switch (state.tokens.next.value) {
- case "}":
- case "]":
- case ",":
- if (opts.allowTrailing) {
- return true;
- }
-
- /* falls through */
- case ")":
- error("E024", state.tokens.next, state.tokens.next.value);
- return false;
- }
- }
- return true;
- }
-
- // Functional constructors for making the symbols that will be inherited by
- // tokens.
-
- function symbol(s, p) {
- var x = state.syntax[s];
- if (!x || typeof x !== "object") {
- state.syntax[s] = x = {
- id: s,
- lbp: p,
- value: s
- };
- }
- return x;
- }
-
- function delim(s) {
- return symbol(s, 0);
- }
-
- function stmt(s, f) {
- var x = delim(s);
- x.identifier = x.reserved = true;
- x.fud = f;
- return x;
- }
-
- function blockstmt(s, f) {
- var x = stmt(s, f);
- x.block = true;
- return x;
- }
-
- function reserveName(x) {
- var c = x.id.charAt(0);
- if ((c >= "a" && c <= "z") || (c >= "A" && c <= "Z")) {
- x.identifier = x.reserved = true;
- }
- return x;
- }
-
- function prefix(s, f) {
- var x = symbol(s, 150);
- reserveName(x);
- x.nud = (typeof f === "function") ? f : function () {
- this.right = expression(150);
- this.arity = "unary";
- if (this.id === "++" || this.id === "--") {
- if (state.option.plusplus) {
- warning("W016", this, this.id);
- } else if ((!this.right.identifier || isReserved(this.right)) &&
- this.right.id !== "." && this.right.id !== "[") {
- warning("W017", this);
- }
- }
- return this;
- };
- return x;
- }
-
- function type(s, f) {
- var x = delim(s);
- x.type = s;
- x.nud = f;
- return x;
- }
-
- function reserve(name, func) {
- var x = type(name, func);
- x.identifier = true;
- x.reserved = true;
- return x;
- }
-
- function FutureReservedWord(name, meta) {
- var x = type(name, (meta && meta.nud) || function () {
- return this;
- });
-
- meta = meta || {};
- meta.isFutureReservedWord = true;
-
- x.value = name;
- x.identifier = true;
- x.reserved = true;
- x.meta = meta;
-
- return x;
- }
-
- function reservevar(s, v) {
- return reserve(s, function () {
- if (typeof v === "function") {
- v(this);
- }
- return this;
- });
- }
-
- function infix(s, f, p, w) {
- var x = symbol(s, p);
- reserveName(x);
- x.led = function (left) {
- if (!w) {
- nobreaknonadjacent(state.tokens.prev, state.tokens.curr);
- nonadjacent(state.tokens.curr, state.tokens.next);
- }
- if (s === "in" && left.id === "!") {
- warning("W018", left, "!");
- }
- if (typeof f === "function") {
- return f(left, this);
- } else {
- this.left = left;
- this.right = expression(p);
- return this;
- }
- };
- return x;
- }
-
-
- function application(s) {
- var x = symbol(s, 42);
-
- x.led = function (left) {
- if (!state.option.inESNext()) {
- warning("W104", state.tokens.curr, "arrow function syntax (=>)");
- }
-
- nobreaknonadjacent(state.tokens.prev, state.tokens.curr);
- nonadjacent(state.tokens.curr, state.tokens.next);
-
- this.left = left;
- this.right = doFunction(undefined, undefined, false, left);
- return this;
- };
- return x;
- }
-
- function relation(s, f) {
- var x = symbol(s, 100);
-
- x.led = function (left) {
- nobreaknonadjacent(state.tokens.prev, state.tokens.curr);
- nonadjacent(state.tokens.curr, state.tokens.next);
- var right = expression(100);
-
- if (isIdentifier(left, "NaN") || isIdentifier(right, "NaN")) {
- warning("W019", this);
- } else if (f) {
- f.apply(this, [left, right]);
- }
-
- if (!left || !right) {
- quit("E041", state.tokens.curr.line);
- }
-
- if (left.id === "!") {
- warning("W018", left, "!");
- }
-
- if (right.id === "!") {
- warning("W018", right, "!");
- }
-
- this.left = left;
- this.right = right;
- return this;
- };
- return x;
- }
-
- function isPoorRelation(node) {
- return node &&
- ((node.type === "(number)" && +node.value === 0) ||
- (node.type === "(string)" && node.value === "") ||
- (node.type === "null" && !state.option.eqnull) ||
- node.type === "true" ||
- node.type === "false" ||
- node.type === "undefined");
- }
-
- function assignop(s) {
- symbol(s, 20).exps = true;
-
- return infix(s, function (left, that) {
- that.left = left;
-
- if (left) {
- if (predefined[left.value] === false &&
- scope[left.value]["(global)"] === true) {
- warning("W020", left);
- } else if (left["function"]) {
- warning("W021", left, left.value);
- }
-
- if (funct[left.value] === "const") {
- error("E013", left, left.value);
- }
-
- if (left.id === ".") {
- if (!left.left) {
- warning("E031", that);
- } else if (left.left.value === "arguments" && !state.directive["use strict"]) {
- warning("E031", that);
- }
-
- that.right = expression(19);
- return that;
- } else if (left.id === "[") {
- if (state.tokens.curr.left.first) {
- state.tokens.curr.left.first.forEach(function (t) {
- if (funct[t.value] === "const") {
- error("E013", t, t.value);
- }
- });
- } else if (!left.left) {
- warning("E031", that);
- } else if (left.left.value === "arguments" && !state.directive["use strict"]) {
- warning("E031", that);
- }
- that.right = expression(19);
- return that;
- } else if (left.identifier && !isReserved(left)) {
- if (funct[left.value] === "exception") {
- warning("W022", left);
- }
- that.right = expression(19);
- return that;
- }
-
- if (left === state.syntax["function"]) {
- warning("W023", state.tokens.curr);
- }
- }
-
- error("E031", that);
- }, 20);
- }
-
-
- function bitwise(s, f, p) {
- var x = symbol(s, p);
- reserveName(x);
- x.led = (typeof f === "function") ? f : function (left) {
- if (state.option.bitwise) {
- warning("W016", this, this.id);
- }
- this.left = left;
- this.right = expression(p);
- return this;
- };
- return x;
- }
-
-
- function bitwiseassignop(s) {
- symbol(s, 20).exps = true;
- return infix(s, function (left, that) {
- if (state.option.bitwise) {
- warning("W016", that, that.id);
- }
- nonadjacent(state.tokens.prev, state.tokens.curr);
- nonadjacent(state.tokens.curr, state.tokens.next);
- if (left) {
- if (left.id === "." || left.id === "[" ||
- (left.identifier && !isReserved(left))) {
- expression(19);
- return that;
- }
- if (left === state.syntax["function"]) {
- warning("W023", state.tokens.curr);
- }
- return that;
- }
- error("E031", that);
- }, 20);
- }
-
-
- function suffix(s) {
- var x = symbol(s, 150);
-
- x.led = function (left) {
- if (state.option.plusplus) {
- warning("W016", this, this.id);
- } else if ((!left.identifier || isReserved(left)) && left.id !== "." && left.id !== "[") {
- warning("W017", this);
- }
-
- this.left = left;
- return this;
- };
- return x;
- }
-
- // fnparam means that this identifier is being defined as a function
- // argument (see identifier())
- // prop means that this identifier is that of an object property
-
- function optionalidentifier(fnparam, prop) {
- if (!state.tokens.next.identifier) {
- return;
- }
-
- advance();
-
- var curr = state.tokens.curr;
- var meta = curr.meta || {};
- var val = state.tokens.curr.value;
-
- if (!isReserved(curr)) {
- return val;
- }
-
- if (prop) {
- if (state.option.inES5() || meta.isFutureReservedWord) {
- return val;
- }
- }
-
- if (fnparam && val === "undefined") {
- return val;
- }
-
- // Display an info message about reserved words as properties
- // and ES5 but do it only once.
- if (prop && !api.getCache("displayed:I002")) {
- api.setCache("displayed:I002", true);
- warning("I002");
- }
-
- warning("W024", state.tokens.curr, state.tokens.curr.id);
- return val;
- }
-
- // fnparam means that this identifier is being defined as a function
- // argument
- // prop means that this identifier is that of an object property
- function identifier(fnparam, prop) {
- var i = optionalidentifier(fnparam, prop);
- if (i) {
- return i;
- }
- if (state.tokens.curr.id === "function" && state.tokens.next.id === "(") {
- warning("W025");
- } else {
- error("E030", state.tokens.next, state.tokens.next.value);
- }
- }
-
-
- function reachable(s) {
- var i = 0, t;
- if (state.tokens.next.id !== ";" || noreach) {
- return;
- }
- for (;;) {
- t = peek(i);
- if (t.reach) {
- return;
- }
- if (t.id !== "(endline)") {
- if (t.id === "function") {
- if (!state.option.latedef) {
- break;
- }
-
- warning("W026", t);
- break;
- }
-
- warning("W027", t, t.value, s);
- break;
- }
- i += 1;
- }
- }
-
-
- function statement(noindent) {
- var values;
- var i = indent, r, s = scope, t = state.tokens.next;
-
- if (t.id === ";") {
- advance(";");
- return;
- }
-
- // Is this a labelled statement?
- var res = isReserved(t);
-
- // We're being more tolerant here: if someone uses
- // a FutureReservedWord as a label, we warn but proceed
- // anyway.
-
- if (res && t.meta && t.meta.isFutureReservedWord && peek().id === ":") {
- warning("W024", t, t.id);
- res = false;
- }
-
- // detect a destructuring assignment
- if (_.has(["[", "{"], t.value)) {
- if (lookupBlockType().isDestAssign) {
- if (!state.option.inESNext()) {
- warning("W104", state.tokens.curr, "destructuring expression");
- }
- values = destructuringExpression();
- values.forEach(function (tok) {
- isundef(funct, "W117", tok.token, tok.id);
- });
- advance("=");
- destructuringExpressionMatch(values, expression(5, true));
- advance(";");
- return;
- }
- }
- if (t.identifier && !res && peek().id === ":") {
- advance();
- advance(":");
- scope = Object.create(s);
- addlabel(t.value, "label");
-
- if (!state.tokens.next.labelled && state.tokens.next.value !== "{") {
- warning("W028", state.tokens.next, t.value, state.tokens.next.value);
- }
-
- state.tokens.next.label = t.value;
- t = state.tokens.next;
- }
-
- // Is it a lonely block?
-
- if (t.id === "{") {
- // Is it a switch case block?
- //
- // switch (foo) {
- // case bar: { <= here.
- // ...
- // }
- // }
- var iscase = (funct["(verb)"] === "case" && state.tokens.curr.value === ":");
- block(true, true, false, false, iscase);
- return;
- }
-
- // Parse the statement.
-
- if (!noindent) {
- indentation();
- }
- r = expression(0, true);
-
- // Look for the final semicolon.
-
- if (!t.block) {
- if (!state.option.expr && (!r || !r.exps)) {
- warning("W030", state.tokens.curr);
- } else if (state.option.nonew && r && r.left && r.id === "(" && r.left.id === "new") {
- warning("W031", t);
- }
-
- if (state.tokens.next.id !== ";") {
- if (!state.option.asi) {
- // If this is the last statement in a block that ends on
- // the same line *and* option lastsemic is on, ignore the warning.
- // Otherwise, complain about missing semicolon.
- if (!state.option.lastsemic || state.tokens.next.id !== "}" ||
- state.tokens.next.line !== state.tokens.curr.line) {
- warningAt("W033", state.tokens.curr.line, state.tokens.curr.character);
- }
- }
- } else {
- adjacent(state.tokens.curr, state.tokens.next);
- advance(";");
- nonadjacent(state.tokens.curr, state.tokens.next);
- }
- }
-
- // Restore the indentation.
-
- indent = i;
- scope = s;
- return r;
- }
-
-
- function statements(startLine) {
- var a = [], p;
-
- while (!state.tokens.next.reach && state.tokens.next.id !== "(end)") {
- if (state.tokens.next.id === ";") {
- p = peek();
-
- if (!p || (p.id !== "(" && p.id !== "[")) {
- warning("W032");
- }
-
- advance(";");
- } else {
- a.push(statement(startLine === state.tokens.next.line));
- }
- }
- return a;
- }
-
-
- /*
- * read all directives
- * recognizes a simple form of asi, but always
- * warns, if it is used
- */
- function directives() {
- var i, p, pn;
-
- for (;;) {
- if (state.tokens.next.id === "(string)") {
- p = peek(0);
- if (p.id === "(endline)") {
- i = 1;
- do {
- pn = peek(i);
- i = i + 1;
- } while (pn.id === "(endline)");
-
- if (pn.id !== ";") {
- if (pn.id !== "(string)" && pn.id !== "(number)" &&
- pn.id !== "(regexp)" && pn.identifier !== true &&
- pn.id !== "}") {
- break;
- }
- warning("W033", state.tokens.next);
- } else {
- p = pn;
- }
- } else if (p.id === "}") {
- // Directive with no other statements, warn about missing semicolon
- warning("W033", p);
- } else if (p.id !== ";") {
- break;
- }
-
- indentation();
- advance();
- if (state.directive[state.tokens.curr.value]) {
- warning("W034", state.tokens.curr, state.tokens.curr.value);
- }
-
- if (state.tokens.curr.value === "use strict") {
- if (!state.option["(explicitNewcap)"])
- state.option.newcap = true;
- state.option.undef = true;
- }
-
- // there's no directive negation, so always set to true
- state.directive[state.tokens.curr.value] = true;
-
- if (p.id === ";") {
- advance(";");
- }
- continue;
- }
- break;
- }
- }
-
-
- /*
- * Parses a single block. A block is a sequence of statements wrapped in
- * braces.
- *
- * ordinary - true for everything but function bodies and try blocks.
- * stmt - true if block can be a single statement (e.g. in if/for/while).
- * isfunc - true if block is a function body
- * isfatarrow -
- * iscase - true if block is a switch case block
- */
- function block(ordinary, stmt, isfunc, isfatarrow, iscase) {
- var a,
- b = inblock,
- old_indent = indent,
- m,
- s = scope,
- t,
- line,
- d;
-
- inblock = ordinary;
-
- if (!ordinary || !state.option.funcscope)
- scope = Object.create(scope);
-
- nonadjacent(state.tokens.curr, state.tokens.next);
- t = state.tokens.next;
-
- var metrics = funct["(metrics)"];
- metrics.nestedBlockDepth += 1;
- metrics.verifyMaxNestedBlockDepthPerFunction();
-
- if (state.tokens.next.id === "{") {
- advance("{");
-
- // create a new block scope
- funct["(blockscope)"].stack();
-
- line = state.tokens.curr.line;
- if (state.tokens.next.id !== "}") {
- indent += state.option.indent;
- while (!ordinary && state.tokens.next.from > indent) {
- indent += state.option.indent;
- }
-
- if (isfunc) {
- m = {};
- for (d in state.directive) {
- if (_.has(state.directive, d)) {
- m[d] = state.directive[d];
- }
- }
- directives();
-
- if (state.option.strict && funct["(context)"]["(global)"]) {
- if (!m["use strict"] && !state.directive["use strict"]) {
- warning("E007");
- }
- }
- }
-
- a = statements(line);
-
- metrics.statementCount += a.length;
-
- if (isfunc) {
- state.directive = m;
- }
-
- indent -= state.option.indent;
- if (line !== state.tokens.next.line) {
- indentation();
- }
- } else if (line !== state.tokens.next.line) {
- indentation();
- }
- advance("}", t);
-
- funct["(blockscope)"].unstack();
-
- indent = old_indent;
- } else if (!ordinary) {
- if (isfunc) {
- m = {};
- if (stmt && !isfatarrow && !state.option.inMoz(true)) {
- error("W118", state.tokens.curr, "function closure expressions");
- }
-
- if (!stmt) {
- for (d in state.directive) {
- if (_.has(state.directive, d)) {
- m[d] = state.directive[d];
- }
- }
- }
- expression(5);
-
- if (state.option.strict && funct["(context)"]["(global)"]) {
- if (!m["use strict"] && !state.directive["use strict"]) {
- warning("E007");
- }
- }
- } else {
- error("E021", state.tokens.next, "{", state.tokens.next.value);
- }
- } else {
-
- // check to avoid let declaration not within a block
- funct["(nolet)"] = true;
-
- if (!stmt || state.option.curly) {
- warning("W116", state.tokens.next, "{", state.tokens.next.value);
- }
-
- noreach = true;
- indent += state.option.indent;
- // test indentation only if statement is in new line
- a = [statement(state.tokens.next.line === state.tokens.curr.line)];
- indent -= state.option.indent;
- noreach = false;
-
- delete funct["(nolet)"];
- }
- // If it is a "break" in switch case, don't clear and let it propagate out.
- if (!(iscase && funct["(verb)"] === "break")) funct["(verb)"] = null;
-
- if (!ordinary || !state.option.funcscope) scope = s;
- inblock = b;
- if (ordinary && state.option.noempty && (!a || a.length === 0)) {
- warning("W035");
- }
- metrics.nestedBlockDepth -= 1;
- return a;
- }
-
-
- function countMember(m) {
- if (membersOnly && typeof membersOnly[m] !== "boolean") {
- warning("W036", state.tokens.curr, m);
- }
- if (typeof member[m] === "number") {
- member[m] += 1;
- } else {
- member[m] = 1;
- }
- }
-
-
- function note_implied(tkn) {
- var name = tkn.value, line = tkn.line, a = implied[name];
- if (typeof a === "function") {
- a = false;
- }
-
- if (!a) {
- a = [line];
- implied[name] = a;
- } else if (a[a.length - 1] !== line) {
- a.push(line);
- }
- }
-
-
- // Build the syntax table by declaring the syntactic elements of the language.
-
- type("(number)", function () {
- return this;
- });
-
- type("(string)", function () {
- return this;
- });
-
- state.syntax["(identifier)"] = {
- type: "(identifier)",
- lbp: 0,
- identifier: true,
- nud: function () {
- var v = this.value,
- s = scope[v],
- f;
-
- if (typeof s === "function") {
- // Protection against accidental inheritance.
- s = undefined;
- } else if (typeof s === "boolean") {
- f = funct;
- funct = functions[0];
- addlabel(v, "var");
- s = funct;
- funct = f;
- }
- var block;
- if (_.has(funct, "(blockscope)")) {
- block = funct["(blockscope)"].getlabel(v);
- }
-
- // The name is in scope and defined in the current function.
- if (funct === s || block) {
- // Change 'unused' to 'var', and reject labels.
- // the name is in a block scope
- switch (block ? block[v]["(type)"] : funct[v]) {
- case "unused":
- if (block) block[v]["(type)"] = "var";
- else funct[v] = "var";
- break;
- case "unction":
- if (block) block[v]["(type)"] = "function";
- else funct[v] = "function";
- this["function"] = true;
- break;
- case "function":
- this["function"] = true;
- break;
- case "label":
- warning("W037", state.tokens.curr, v);
- break;
- }
- } else if (funct["(global)"]) {
- // The name is not defined in the function. If we are in the global
- // scope, then we have an undefined variable.
- //
- // Operators typeof and delete do not raise runtime errors even if
- // the base object of a reference is null so no need to display warning
- // if we're inside of typeof or delete.
-
- if (typeof predefined[v] !== "boolean") {
- // Attempting to subscript a null reference will throw an
- // error, even within the typeof and delete operators
- if (!(anonname === "typeof" || anonname === "delete") ||
- (state.tokens.next && (state.tokens.next.value === "." ||
- state.tokens.next.value === "["))) {
-
- // if we're in a list comprehension, variables are declared
- // locally and used before being defined. So we check
- // the presence of the given variable in the comp array
- // before declaring it undefined.
-
- if (!funct["(comparray)"].check(v)) {
- isundef(funct, "W117", state.tokens.curr, v);
- }
- }
- }
-
- note_implied(state.tokens.curr);
- } else {
- // If the name is already defined in the current
- // function, but not as outer, then there is a scope error.
-
- switch (funct[v]) {
- case "closure":
- case "function":
- case "var":
- case "unused":
- warning("W038", state.tokens.curr, v);
- break;
- case "label":
- warning("W037", state.tokens.curr, v);
- break;
- case "outer":
- case "global":
- break;
- default:
- // If the name is defined in an outer function, make an outer entry,
- // and if it was unused, make it var.
- if (s === true) {
- funct[v] = true;
- } else if (s === null) {
- warning("W039", state.tokens.curr, v);
- note_implied(state.tokens.curr);
- } else if (typeof s !== "object") {
- // Operators typeof and delete do not raise runtime errors even
- // if the base object of a reference is null so no need to
- //
- // display warning if we're inside of typeof or delete.
- // Attempting to subscript a null reference will throw an
- // error, even within the typeof and delete operators
- if (!(anonname === "typeof" || anonname === "delete") ||
- (state.tokens.next &&
- (state.tokens.next.value === "." || state.tokens.next.value === "["))) {
-
- isundef(funct, "W117", state.tokens.curr, v);
- }
- funct[v] = true;
- note_implied(state.tokens.curr);
- } else {
- switch (s[v]) {
- case "function":
- case "unction":
- this["function"] = true;
- s[v] = "closure";
- funct[v] = s["(global)"] ? "global" : "outer";
- break;
- case "var":
- case "unused":
- s[v] = "closure";
- funct[v] = s["(global)"] ? "global" : "outer";
- break;
- case "closure":
- funct[v] = s["(global)"] ? "global" : "outer";
- break;
- case "label":
- warning("W037", state.tokens.curr, v);
- }
- }
- }
- }
- return this;
- },
- led: function () {
- error("E033", state.tokens.next, state.tokens.next.value);
- }
- };
-
- type("(regexp)", function () {
- return this;
- });
-
- // ECMAScript parser
-
- delim("(endline)");
- delim("(begin)");
- delim("(end)").reach = true;
- delim("(error)").reach = true;
- delim("}").reach = true;
- delim(")");
- delim("]");
- delim("\"").reach = true;
- delim("'").reach = true;
- delim(";");
- delim(":").reach = true;
- delim("#");
-
- reserve("else");
- reserve("case").reach = true;
- reserve("catch");
- reserve("default").reach = true;
- reserve("finally");
- reservevar("arguments", function (x) {
- if (state.directive["use strict"] && funct["(global)"]) {
- warning("E008", x);
- }
- });
- reservevar("eval");
- reservevar("false");
- reservevar("Infinity");
- reservevar("null");
- reservevar("this", function (x) {
- if (state.directive["use strict"] && !state.option.validthis && ((funct["(statement)"] &&
- funct["(name)"].charAt(0) > "Z") || funct["(global)"])) {
- warning("W040", x);
- }
- });
- reservevar("true");
- reservevar("undefined");
-
- assignop("=", "assign", 20);
- assignop("+=", "assignadd", 20);
- assignop("-=", "assignsub", 20);
- assignop("*=", "assignmult", 20);
- assignop("/=", "assigndiv", 20).nud = function () {
- error("E014");
- };
- assignop("%=", "assignmod", 20);
-
- bitwiseassignop("&=", "assignbitand", 20);
- bitwiseassignop("|=", "assignbitor", 20);
- bitwiseassignop("^=", "assignbitxor", 20);
- bitwiseassignop("<<=", "assignshiftleft", 20);
- bitwiseassignop(">>=", "assignshiftright", 20);
- bitwiseassignop(">>>=", "assignshiftrightunsigned", 20);
- infix(",", function (left, that) {
- var expr;
- that.exprs = [left];
- if (!comma({peek: true})) {
- return that;
- }
- while (true) {
- if (!(expr = expression(5))) {
- break;
- }
- that.exprs.push(expr);
- if (state.tokens.next.value !== "," || !comma()) {
- break;
- }
- }
- return that;
- }, 5, true);
- infix("?", function (left, that) {
- that.left = left;
- that.right = expression(10);
- advance(":");
- that["else"] = expression(10);
- return that;
- }, 30);
-
- infix("||", "or", 40);
- infix("&&", "and", 50);
- bitwise("|", "bitor", 70);
- bitwise("^", "bitxor", 80);
- bitwise("&", "bitand", 90);
- relation("==", function (left, right) {
- var eqnull = state.option.eqnull && (left.value === "null" || right.value === "null");
-
- if (!eqnull && state.option.eqeqeq)
- warning("W116", this, "===", "==");
- else if (isPoorRelation(left))
- warning("W041", this, "===", left.value);
- else if (isPoorRelation(right))
- warning("W041", this, "===", right.value);
-
- return this;
- });
- relation("===");
- relation("!=", function (left, right) {
- var eqnull = state.option.eqnull &&
- (left.value === "null" || right.value === "null");
-
- if (!eqnull && state.option.eqeqeq) {
- warning("W116", this, "!==", "!=");
- } else if (isPoorRelation(left)) {
- warning("W041", this, "!==", left.value);
- } else if (isPoorRelation(right)) {
- warning("W041", this, "!==", right.value);
- }
- return this;
- });
- relation("!==");
- relation("<");
- relation(">");
- relation("<=");
- relation(">=");
- bitwise("<<", "shiftleft", 120);
- bitwise(">>", "shiftright", 120);
- bitwise(">>>", "shiftrightunsigned", 120);
- infix("in", "in", 120);
- infix("instanceof", "instanceof", 120);
- infix("+", function (left, that) {
- var right = expression(130);
- if (left && right && left.id === "(string)" && right.id === "(string)") {
- left.value += right.value;
- left.character = right.character;
- if (!state.option.scripturl && reg.javascriptURL.test(left.value)) {
- warning("W050", left);
- }
- return left;
- }
- that.left = left;
- that.right = right;
- return that;
- }, 130);
- prefix("+", "num");
- prefix("+++", function () {
- warning("W007");
- this.right = expression(150);
- this.arity = "unary";
- return this;
- });
- infix("+++", function (left) {
- warning("W007");
- this.left = left;
- this.right = expression(130);
- return this;
- }, 130);
- infix("-", "sub", 130);
- prefix("-", "neg");
- prefix("---", function () {
- warning("W006");
- this.right = expression(150);
- this.arity = "unary";
- return this;
- });
- infix("---", function (left) {
- warning("W006");
- this.left = left;
- this.right = expression(130);
- return this;
- }, 130);
- infix("*", "mult", 140);
- infix("/", "div", 140);
- infix("%", "mod", 140);
-
- suffix("++", "postinc");
- prefix("++", "preinc");
- state.syntax["++"].exps = true;
-
- suffix("--", "postdec");
- prefix("--", "predec");
- state.syntax["--"].exps = true;
- prefix("delete", function () {
- var p = expression(5);
- if (!p || (p.id !== "." && p.id !== "[")) {
- warning("W051");
- }
- this.first = p;
- return this;
- }).exps = true;
-
- prefix("~", function () {
- if (state.option.bitwise) {
- warning("W052", this, "~");
- }
- expression(150);
- return this;
- });
-
- prefix("...", function () {
- if (!state.option.inESNext()) {
- warning("W104", this, "spread/rest operator");
- }
- if (!state.tokens.next.identifier) {
- error("E030", state.tokens.next, state.tokens.next.value);
- }
- expression(150);
- return this;
- });
-
- prefix("!", function () {
- this.right = expression(150);
- this.arity = "unary";
-
- if (!this.right) { // '!' followed by nothing? Give up.
- quit("E041", this.line || 0);
- }
-
- if (bang[this.right.id] === true) {
- warning("W018", this, "!");
- }
- return this;
- });
-
- prefix("typeof", "typeof");
- prefix("new", function () {
- var c = expression(155), i;
- if (c && c.id !== "function") {
- if (c.identifier) {
- c["new"] = true;
- switch (c.value) {
- case "Number":
- case "String":
- case "Boolean":
- case "Math":
- case "JSON":
- warning("W053", state.tokens.prev, c.value);
- break;
- case "Function":
- if (!state.option.evil) {
- warning("W054");
- }
- break;
- case "Date":
- case "RegExp":
- break;
- default:
- if (c.id !== "function") {
- i = c.value.substr(0, 1);
- if (state.option.newcap && (i < "A" || i > "Z") && !_.has(global, c.value)) {
- warning("W055", state.tokens.curr);
- }
- }
- }
- } else {
- if (c.id !== "." && c.id !== "[" && c.id !== "(") {
- warning("W056", state.tokens.curr);
- }
- }
- } else {
- if (!state.option.supernew)
- warning("W057", this);
- }
- adjacent(state.tokens.curr, state.tokens.next);
- if (state.tokens.next.id !== "(" && !state.option.supernew) {
- warning("W058", state.tokens.curr, state.tokens.curr.value);
- }
- this.first = c;
- return this;
- });
- state.syntax["new"].exps = true;
-
- prefix("void").exps = true;
-
- infix(".", function (left, that) {
- adjacent(state.tokens.prev, state.tokens.curr);
- nobreak();
- var m = identifier(false, true);
-
- if (typeof m === "string") {
- countMember(m);
- }
-
- that.left = left;
- that.right = m;
-
- if (m && m === "hasOwnProperty" && state.tokens.next.value === "=") {
- warning("W001");
- }
-
- if (left && left.value === "arguments" && (m === "callee" || m === "caller")) {
- if (state.option.noarg)
- warning("W059", left, m);
- else if (state.directive["use strict"])
- error("E008");
- } else if (!state.option.evil && left && left.value === "document" &&
- (m === "write" || m === "writeln")) {
- warning("W060", left);
- }
-
- if (!state.option.evil && (m === "eval" || m === "execScript")) {
- warning("W061");
- }
-
- return that;
- }, 160, true);
-
- infix("(", function (left, that) {
- if (state.tokens.prev.id !== "}" && state.tokens.prev.id !== ")") {
- nobreak(state.tokens.prev, state.tokens.curr);
- }
-
- nospace();
- if (state.option.immed && left && !left.immed && left.id === "function") {
- warning("W062");
- }
-
- var n = 0;
- var p = [];
-
- if (left) {
- if (left.type === "(identifier)") {
- if (left.value.match(/^[A-Z]([A-Z0-9_$]*[a-z][A-Za-z0-9_$]*)?$/)) {
- if ("Number String Boolean Date Object".indexOf(left.value) === -1) {
- if (left.value === "Math") {
- warning("W063", left);
- } else if (state.option.newcap) {
- warning("W064", left);
- }
- }
- }
- }
- }
-
- if (state.tokens.next.id !== ")") {
- for (;;) {
- p[p.length] = expression(10);
- n += 1;
- if (state.tokens.next.id !== ",") {
- break;
- }
- comma();
- }
- }
-
- advance(")");
- nospace(state.tokens.prev, state.tokens.curr);
-
- if (typeof left === "object") {
- if (left.value === "parseInt" && n === 1) {
- warning("W065", state.tokens.curr);
- }
- if (!state.option.evil) {
- if (left.value === "eval" || left.value === "Function" ||
- left.value === "execScript") {
- warning("W061", left);
-
- if (p[0] && [0].id === "(string)") {
- addInternalSrc(left, p[0].value);
- }
- } else if (p[0] && p[0].id === "(string)" &&
- (left.value === "setTimeout" ||
- left.value === "setInterval")) {
- warning("W066", left);
- addInternalSrc(left, p[0].value);
-
- // window.setTimeout/setInterval
- } else if (p[0] && p[0].id === "(string)" &&
- left.value === "." &&
- left.left.value === "window" &&
- (left.right === "setTimeout" ||
- left.right === "setInterval")) {
- warning("W066", left);
- addInternalSrc(left, p[0].value);
- }
- }
- if (!left.identifier && left.id !== "." && left.id !== "[" &&
- left.id !== "(" && left.id !== "&&" && left.id !== "||" &&
- left.id !== "?") {
- warning("W067", left);
- }
- }
-
- that.left = left;
- return that;
- }, 155, true).exps = true;
-
- prefix("(", function () {
- nospace();
- var bracket, brackets = [];
- var pn, pn1, i = 0;
-
- do {
- pn = peek(i);
- i += 1;
- pn1 = peek(i);
- i += 1;
- } while (pn.value !== ")" && pn1.value !== "=>" && pn1.value !== ";" && pn1.type !== "(end)");
-
- if (state.tokens.next.id === "function") {
- state.tokens.next.immed = true;
- }
-
- var exprs = [];
-
- if (state.tokens.next.id !== ")") {
- for (;;) {
- if (pn1.value === "=>" && state.tokens.next.value === "{") {
- bracket = state.tokens.next;
- bracket.left = destructuringExpression();
- brackets.push(bracket);
- for (var t in bracket.left) {
- exprs.push(bracket.left[t].token);
- }
- } else {
- exprs.push(expression(5));
- }
- if (state.tokens.next.id !== ",") {
- break;
- }
- comma();
- }
- }
-
- advance(")", this);
- nospace(state.tokens.prev, state.tokens.curr);
- if (state.option.immed && exprs[0] && exprs[0].id === "function") {
- if (state.tokens.next.id !== "(" &&
- (state.tokens.next.id !== "." || (peek().value !== "call" && peek().value !== "apply"))) {
- warning("W068", this);
- }
- }
-
- if (state.tokens.next.value === "=>") {
- return exprs;
- }
- if (!exprs.length) {
- return;
- }
- exprs[exprs.length - 1].paren = true;
- if (exprs.length > 1) {
- return Object.create(state.syntax[","], { exprs: { value: exprs } });
- }
- return exprs[0];
- });
-
- application("=>");
-
- infix("[", function (left, that) {
- nobreak(state.tokens.prev, state.tokens.curr);
- nospace();
- var e = expression(5), s;
- if (e && e.type === "(string)") {
- if (!state.option.evil && (e.value === "eval" || e.value === "execScript")) {
- warning("W061", that);
- }
-
- countMember(e.value);
- if (!state.option.sub && reg.identifier.test(e.value)) {
- s = state.syntax[e.value];
- if (!s || !isReserved(s)) {
- warning("W069", state.tokens.prev, e.value);
- }
- }
- }
- advance("]", that);
-
- if (e && e.value === "hasOwnProperty" && state.tokens.next.value === "=") {
- warning("W001");
- }
-
- nospace(state.tokens.prev, state.tokens.curr);
- that.left = left;
- that.right = e;
- return that;
- }, 160, true);
-
- function comprehensiveArrayExpression() {
- var res = {};
- res.exps = true;
- funct["(comparray)"].stack();
-
- res.right = expression(5);
- advance("for");
- if (state.tokens.next.value === "each") {
- advance("each");
- if (!state.option.inMoz(true)) {
- warning("W118", state.tokens.curr, "for each");
- }
- }
- advance("(");
- funct["(comparray)"].setState("define");
- res.left = expression(5);
- advance(")");
- if (state.tokens.next.value === "if") {
- advance("if");
- advance("(");
- funct["(comparray)"].setState("filter");
- res.filter = expression(5);
- advance(")");
- }
- advance("]");
- funct["(comparray)"].unstack();
- return res;
- }
-
- prefix("[", function () {
- var blocktype = lookupBlockType(true);
- if (blocktype.isCompArray) {
- if (!state.option.inMoz(true)) {
- warning("W118", state.tokens.curr, "array comprehension");
- }
- return comprehensiveArrayExpression();
- } else if (blocktype.isDestAssign && !state.option.inESNext()) {
- warning("W104", state.tokens.curr, "destructuring assignment");
- }
- var b = state.tokens.curr.line !== state.tokens.next.line;
- this.first = [];
- if (b) {
- indent += state.option.indent;
- if (state.tokens.next.from === indent + state.option.indent) {
- indent += state.option.indent;
- }
- }
- while (state.tokens.next.id !== "(end)") {
- while (state.tokens.next.id === ",") {
- if (!state.option.inES5())
- warning("W070");
- advance(",");
- }
- if (state.tokens.next.id === "]") {
- break;
- }
- if (b && state.tokens.curr.line !== state.tokens.next.line) {
- indentation();
- }
- this.first.push(expression(10));
- if (state.tokens.next.id === ",") {
- comma({ allowTrailing: true });
- if (state.tokens.next.id === "]" && !state.option.inES5(true)) {
- warning("W070", state.tokens.curr);
- break;
- }
- } else {
- break;
- }
- }
- if (b) {
- indent -= state.option.indent;
- indentation();
- }
- advance("]", this);
- return this;
- }, 160);
-
-
- function property_name() {
- var id = optionalidentifier(false, true);
-
- if (!id) {
- if (state.tokens.next.id === "(string)") {
- id = state.tokens.next.value;
- advance();
- } else if (state.tokens.next.id === "(number)") {
- id = state.tokens.next.value.toString();
- advance();
- }
- }
-
- if (id === "hasOwnProperty") {
- warning("W001");
- }
-
- return id;
- }
-
-
- function functionparams(parsed) {
- var curr, next;
- var params = [];
- var ident;
- var tokens = [];
- var t;
-
- if (parsed) {
- if (parsed instanceof Array) {
- for (var i in parsed) {
- curr = parsed[i];
- if (_.contains(["{", "["], curr.id)) {
- for (t in curr.left) {
- t = tokens[t];
- if (t.id) {
- params.push(t.id);
- addlabel(t.id, "unused", t.token);
- }
- }
- } else if (curr.value === "...") {
- if (!state.option.inESNext()) {
- warning("W104", curr, "spread/rest operator");
- }
- continue;
- } else {
- addlabel(curr.value, "unused", curr);
- }
- }
- return params;
- } else {
- if (parsed.identifier === true) {
- addlabel(parsed.value, "unused", parsed);
- return [parsed];
- }
- }
- }
-
- next = state.tokens.next;
-
- advance("(");
- nospace();
-
- if (state.tokens.next.id === ")") {
- advance(")");
- return;
- }
-
- for (;;) {
- if (_.contains(["{", "["], state.tokens.next.id)) {
- tokens = destructuringExpression();
- for (t in tokens) {
- t = tokens[t];
- if (t.id) {
- params.push(t.id);
- addlabel(t.id, "unused", t.token);
- }
- }
- } else if (state.tokens.next.value === "...") {
- if (!state.option.inESNext()) {
- warning("W104", state.tokens.next, "spread/rest operator");
- }
- advance("...");
- nospace();
- ident = identifier(true);
- params.push(ident);
- addlabel(ident, "unused", state.tokens.curr);
- } else {
- ident = identifier(true);
- params.push(ident);
- addlabel(ident, "unused", state.tokens.curr);
- }
- if (state.tokens.next.id === ",") {
- comma();
- } else {
- advance(")", next);
- nospace(state.tokens.prev, state.tokens.curr);
- return params;
- }
- }
- }
-
-
- function doFunction(name, statement, generator, fatarrowparams) {
- var f;
- var oldOption = state.option;
- var oldIgnored = state.ignored;
- var oldScope = scope;
-
- state.option = Object.create(state.option);
- state.ignored = Object.create(state.ignored);
- scope = Object.create(scope);
-
- funct = {
- "(name)" : name || "\"" + anonname + "\"",
- "(line)" : state.tokens.next.line,
- "(character)" : state.tokens.next.character,
- "(context)" : funct,
- "(breakage)" : 0,
- "(loopage)" : 0,
- "(metrics)" : createMetrics(state.tokens.next),
- "(scope)" : scope,
- "(statement)" : statement,
- "(tokens)" : {},
- "(blockscope)": funct["(blockscope)"],
- "(comparray)" : funct["(comparray)"]
- };
-
- if (generator) {
- funct["(generator)"] = true;
- }
-
- f = funct;
- state.tokens.curr.funct = funct;
-
- functions.push(funct);
-
- if (name) {
- addlabel(name, "function");
- }
-
- funct["(params)"] = functionparams(fatarrowparams);
-
- funct["(metrics)"].verifyMaxParametersPerFunction(funct["(params)"]);
-
- block(false, true, true, fatarrowparams ? true:false);
-
- if (generator && funct["(generator)"] !== "yielded") {
- error("E047", state.tokens.curr);
- }
-
- funct["(metrics)"].verifyMaxStatementsPerFunction();
- funct["(metrics)"].verifyMaxComplexityPerFunction();
- funct["(unusedOption)"] = state.option.unused;
-
- scope = oldScope;
- state.option = oldOption;
- state.ignored = oldIgnored;
- funct["(last)"] = state.tokens.curr.line;
- funct["(lastcharacter)"] = state.tokens.curr.character;
- funct = funct["(context)"];
-
- return f;
- }
-
- function createMetrics(functionStartToken) {
- return {
- statementCount: 0,
- nestedBlockDepth: -1,
- ComplexityCount: 1,
- verifyMaxStatementsPerFunction: function () {
- if (state.option.maxstatements &&
- this.statementCount > state.option.maxstatements) {
- warning("W071", functionStartToken, this.statementCount);
- }
- },
-
- verifyMaxParametersPerFunction: function (params) {
- params = params || [];
-
- if (state.option.maxparams && params.length > state.option.maxparams) {
- warning("W072", functionStartToken, params.length);
- }
- },
-
- verifyMaxNestedBlockDepthPerFunction: function () {
- if (state.option.maxdepth &&
- this.nestedBlockDepth > 0 &&
- this.nestedBlockDepth === state.option.maxdepth + 1) {
- warning("W073", null, this.nestedBlockDepth);
- }
- },
-
- verifyMaxComplexityPerFunction: function () {
- var max = state.option.maxcomplexity;
- var cc = this.ComplexityCount;
- if (max && cc > max) {
- warning("W074", functionStartToken, cc);
- }
- }
- };
- }
-
- function increaseComplexityCount() {
- funct["(metrics)"].ComplexityCount += 1;
- }
-
- // Parse assignments that were found instead of conditionals.
- // For example: if (a = 1) { ... }
-
- function checkCondAssignment(expr) {
- var id = expr.id;
- if (id === ",") {
- expr = expr.exprs[expr.exprs.length - 1];
- id = expr.id;
- }
- switch (id) {
- case "=":
- case "+=":
- case "-=":
- case "*=":
- case "%=":
- case "&=":
- case "|=":
- case "^=":
- case "/=":
- if (!expr.paren && !state.option.boss) {
- warning("W084");
- }
- }
- }
-
-
- (function (x) {
- x.nud = function (isclassdef) {
- var b, f, i, p, t, g;
- var props = {}; // All properties, including accessors
- var tag = "";
-
- function saveProperty(name, tkn) {
- if (props[name] && _.has(props, name))
- warning("W075", state.tokens.next, i);
- else
- props[name] = {};
-
- props[name].basic = true;
- props[name].basictkn = tkn;
- }
-
- function saveSetter(name, tkn) {
- if (props[name] && _.has(props, name)) {
- if (props[name].basic || props[name].setter)
- warning("W075", state.tokens.next, i);
- } else {
- props[name] = {};
- }
-
- props[name].setter = true;
- props[name].setterToken = tkn;
- }
-
- function saveGetter(name) {
- if (props[name] && _.has(props, name)) {
- if (props[name].basic || props[name].getter)
- warning("W075", state.tokens.next, i);
- } else {
- props[name] = {};
- }
-
- props[name].getter = true;
- props[name].getterToken = state.tokens.curr;
- }
-
- b = state.tokens.curr.line !== state.tokens.next.line;
- if (b) {
- indent += state.option.indent;
- if (state.tokens.next.from === indent + state.option.indent) {
- indent += state.option.indent;
- }
- }
-
- for (;;) {
- if (state.tokens.next.id === "}") {
- break;
- }
-
- if (b) {
- indentation();
- }
-
- if (isclassdef && state.tokens.next.value === "static") {
- advance("static");
- tag = "static ";
- }
-
- if (state.tokens.next.value === "get" && peek().id !== ":") {
- advance("get");
-
- if (!state.option.inES5(!isclassdef)) {
- error("E034");
- }
-
- i = property_name();
- if (!i) {
- error("E035");
- }
-
- // It is a Syntax Error if PropName of MethodDefinition is
- // "constructor" and SpecialMethod of MethodDefinition is true.
- if (isclassdef && i === "constructor") {
- error("E049", state.tokens.next, "class getter method", i);
- }
-
- saveGetter(tag + i);
- t = state.tokens.next;
- adjacent(state.tokens.curr, state.tokens.next);
- f = doFunction();
- p = f["(params)"];
-
- if (p) {
- warning("W076", t, p[0], i);
- }
-
- adjacent(state.tokens.curr, state.tokens.next);
- } else if (state.tokens.next.value === "set" && peek().id !== ":") {
- advance("set");
-
- if (!state.option.inES5(!isclassdef)) {
- error("E034");
- }
-
- i = property_name();
- if (!i) {
- error("E035");
- }
-
- // It is a Syntax Error if PropName of MethodDefinition is
- // "constructor" and SpecialMethod of MethodDefinition is true.
- if (isclassdef && i === "constructor") {
- error("E049", state.tokens.next, "class setter method", i);
- }
-
- saveSetter(tag + i, state.tokens.next);
- t = state.tokens.next;
- adjacent(state.tokens.curr, state.tokens.next);
- f = doFunction();
- p = f["(params)"];
-
- if (!p || p.length !== 1) {
- warning("W077", t, i);
- }
- } else {
- g = false;
- if (state.tokens.next.value === "*" && state.tokens.next.type === "(punctuator)") {
- if (!state.option.inESNext()) {
- warning("W104", state.tokens.next, "generator functions");
- }
- advance("*");
- g = true;
- }
- i = property_name();
- saveProperty(tag + i, state.tokens.next);
-
- if (typeof i !== "string") {
- break;
- }
-
- if (state.tokens.next.value === "(") {
- if (!state.option.inESNext()) {
- warning("W104", state.tokens.curr, "concise methods");
- }
- doFunction(i, undefined, g);
- } else if (!isclassdef) {
- advance(":");
- nonadjacent(state.tokens.curr, state.tokens.next);
- expression(10);
- }
- }
- // It is a Syntax Error if PropName of MethodDefinition is "prototype".
- if (isclassdef && i === "prototype") {
- error("E049", state.tokens.next, "class method", i);
- }
-
- countMember(i);
- if (isclassdef) {
- tag = "";
- continue;
- }
- if (state.tokens.next.id === ",") {
- comma({ allowTrailing: true, property: true });
- if (state.tokens.next.id === ",") {
- warning("W070", state.tokens.curr);
- } else if (state.tokens.next.id === "}" && !state.option.inES5(true)) {
- warning("W070", state.tokens.curr);
- }
- } else {
- break;
- }
- }
- if (b) {
- indent -= state.option.indent;
- indentation();
- }
- advance("}", this);
-
- // Check for lonely setters if in the ES5 mode.
- if (state.option.inES5()) {
- for (var name in props) {
- if (_.has(props, name) && props[name].setter && !props[name].getter) {
- warning("W078", props[name].setterToken);
- }
- }
- }
- return this;
- };
- x.fud = function () {
- error("E036", state.tokens.curr);
- };
- }(delim("{")));
-
- function destructuringExpression() {
- var id, ids;
- var identifiers = [];
- if (!state.option.inESNext()) {
- warning("W104", state.tokens.curr, "destructuring expression");
- }
- var nextInnerDE = function () {
- var ident;
- if (_.contains(["[", "{"], state.tokens.next.value)) {
- ids = destructuringExpression();
- for (var id in ids) {
- id = ids[id];
- identifiers.push({ id: id.id, token: id.token });
- }
- } else if (state.tokens.next.value === ",") {
- identifiers.push({ id: null, token: state.tokens.curr });
- } else {
- ident = identifier();
- if (ident)
- identifiers.push({ id: ident, token: state.tokens.curr });
- }
- };
- if (state.tokens.next.value === "[") {
- advance("[");
- nextInnerDE();
- while (state.tokens.next.value !== "]") {
- advance(",");
- nextInnerDE();
- }
- advance("]");
- } else if (state.tokens.next.value === "{") {
- advance("{");
- id = identifier();
- if (state.tokens.next.value === ":") {
- advance(":");
- nextInnerDE();
- } else {
- identifiers.push({ id: id, token: state.tokens.curr });
- }
- while (state.tokens.next.value !== "}") {
- advance(",");
- id = identifier();
- if (state.tokens.next.value === ":") {
- advance(":");
- nextInnerDE();
- } else {
- identifiers.push({ id: id, token: state.tokens.curr });
- }
- }
- advance("}");
- }
- return identifiers;
- }
- function destructuringExpressionMatch(tokens, value) {
- if (value.first) {
- _.zip(tokens, value.first).forEach(function (val) {
- var token = val[0];
- var value = val[1];
- if (token && value) {
- token.first = value;
- } else if (token && token.first && !value) {
- warning("W080", token.first, token.first.value);
- } /* else {
- XXX value is discarded: wouldn't it need a warning ?
- } */
- });
- }
- }
-
- var conststatement = stmt("const", function (prefix) {
- var tokens, value;
- // state variable to know if it is a lone identifier, or a destructuring statement.
- var lone;
-
- if (!state.option.inESNext()) {
- warning("W104", state.tokens.curr, "const");
- }
-
- this.first = [];
- for (;;) {
- var names = [];
- nonadjacent(state.tokens.curr, state.tokens.next);
- if (_.contains(["{", "["], state.tokens.next.value)) {
- tokens = destructuringExpression();
- lone = false;
- } else {
- tokens = [ { id: identifier(), token: state.tokens.curr } ];
- lone = true;
- }
- for (var t in tokens) {
- t = tokens[t];
- if (funct[t.id] === "const") {
- warning("E011", null, t.id);
- }
- if (funct["(global)"] && predefined[t.id] === false) {
- warning("W079", t.token, t.id);
- }
- if (t.id) {
- addlabel(t.id, "const");
- names.push(t.token);
- }
- }
- if (prefix) {
- break;
- }
-
- this.first = this.first.concat(names);
-
- if (state.tokens.next.id !== "=") {
- warning("E012", state.tokens.curr, state.tokens.curr.value);
- }
-
- if (state.tokens.next.id === "=") {
- nonadjacent(state.tokens.curr, state.tokens.next);
- advance("=");
- nonadjacent(state.tokens.curr, state.tokens.next);
- if (state.tokens.next.id === "undefined") {
- warning("W080", state.tokens.prev, state.tokens.prev.value);
- }
- if (peek(0).id === "=" && state.tokens.next.identifier) {
- error("E037", state.tokens.next, state.tokens.next.value);
- }
- value = expression(5);
- if (lone) {
- tokens[0].first = value;
- } else {
- destructuringExpressionMatch(names, value);
- }
- }
-
- if (state.tokens.next.id !== ",") {
- break;
- }
- comma();
- }
- return this;
- });
- conststatement.exps = true;
- var varstatement = stmt("var", function (prefix) {
- // JavaScript does not have block scope. It only has function scope. So,
- // declaring a variable in a block can have unexpected consequences.
- var tokens, lone, value;
-
- if (funct["(onevar)"] && state.option.onevar) {
- warning("W081");
- } else if (!funct["(global)"]) {
- funct["(onevar)"] = true;
- }
-
- this.first = [];
- for (;;) {
- var names = [];
- nonadjacent(state.tokens.curr, state.tokens.next);
- if (_.contains(["{", "["], state.tokens.next.value)) {
- tokens = destructuringExpression();
- lone = false;
- } else {
- tokens = [ { id: identifier(), token: state.tokens.curr } ];
- lone = true;
- }
- for (var t in tokens) {
- t = tokens[t];
- if (state.option.inESNext() && funct[t.id] === "const") {
- warning("E011", null, t.id);
- }
- if (funct["(global)"] && predefined[t.id] === false) {
- warning("W079", t.token, t.id);
- }
- if (t.id) {
- addlabel(t.id, "unused", t.token);
- names.push(t.token);
- }
- }
- if (prefix) {
- break;
- }
-
- this.first = this.first.concat(names);
-
- if (state.tokens.next.id === "=") {
- nonadjacent(state.tokens.curr, state.tokens.next);
- advance("=");
- nonadjacent(state.tokens.curr, state.tokens.next);
- if (state.tokens.next.id === "undefined") {
- warning("W080", state.tokens.prev, state.tokens.prev.value);
- }
- if (peek(0).id === "=" && state.tokens.next.identifier) {
- error("E038", state.tokens.next, state.tokens.next.value);
- }
- value = expression(5);
- if (lone) {
- tokens[0].first = value;
- } else {
- destructuringExpressionMatch(names, value);
- }
- }
-
- if (state.tokens.next.id !== ",") {
- break;
- }
- comma();
- }
- return this;
- });
- varstatement.exps = true;
- var letstatement = stmt("let", function (prefix) {
- var tokens, lone, value, letblock;
-
- if (!state.option.inESNext()) {
- warning("W104", state.tokens.curr, "let");
- }
-
- if (state.tokens.next.value === "(") {
- if (!state.option.inMoz(true)) {
- warning("W118", state.tokens.next, "let block");
- }
- advance("(");
- funct["(blockscope)"].stack();
- letblock = true;
- } else if (funct["(nolet)"]) {
- error("E048", state.tokens.curr);
- }
-
- if (funct["(onevar)"] && state.option.onevar) {
- warning("W081");
- } else if (!funct["(global)"]) {
- funct["(onevar)"] = true;
- }
-
- this.first = [];
- for (;;) {
- var names = [];
- nonadjacent(state.tokens.curr, state.tokens.next);
- if (_.contains(["{", "["], state.tokens.next.value)) {
- tokens = destructuringExpression();
- lone = false;
- } else {
- tokens = [ { id: identifier(), token: state.tokens.curr.value } ];
- lone = true;
- }
- for (var t in tokens) {
- t = tokens[t];
- if (state.option.inESNext() && funct[t.id] === "const") {
- warning("E011", null, t.id);
- }
- if (funct["(global)"] && predefined[t.id] === false) {
- warning("W079", t.token, t.id);
- }
- if (t.id && !funct["(nolet)"]) {
- addlabel(t.id, "unused", t.token, true);
- names.push(t.token);
- }
- }
- if (prefix) {
- break;
- }
-
- this.first = this.first.concat(names);
-
- if (state.tokens.next.id === "=") {
- nonadjacent(state.tokens.curr, state.tokens.next);
- advance("=");
- nonadjacent(state.tokens.curr, state.tokens.next);
- if (state.tokens.next.id === "undefined") {
- warning("W080", state.tokens.prev, state.tokens.prev.value);
- }
- if (peek(0).id === "=" && state.tokens.next.identifier) {
- error("E037", state.tokens.next, state.tokens.next.value);
- }
- value = expression(5);
- if (lone) {
- tokens[0].first = value;
- } else {
- destructuringExpressionMatch(names, value);
- }
- }
-
- if (state.tokens.next.id !== ",") {
- break;
- }
- comma();
- }
- if (letblock) {
- advance(")");
- block(true, true);
- this.block = true;
- funct["(blockscope)"].unstack();
- }
-
- return this;
- });
- letstatement.exps = true;
-
- blockstmt("class", function () {
- return classdef.call(this, true);
- });
-
- function classdef(stmt) {
- /*jshint validthis:true */
- if (!state.option.inESNext()) {
- warning("W104", state.tokens.curr, "class");
- }
- if (stmt) {
- // BindingIdentifier
- this.name = identifier();
- addlabel(this.name, "unused", state.tokens.curr);
- } else if (state.tokens.next.identifier && state.tokens.next.value !== "extends") {
- // BindingIdentifier(opt)
- this.name = identifier();
- }
- classtail(this);
- return this;
- }
-
- function classtail(c) {
- var strictness = state.directive["use strict"];
-
- // ClassHeritage(opt)
- if (state.tokens.next.value === "extends") {
- advance("extends");
- c.heritage = expression(10);
- }
-
- // A ClassBody is always strict code.
- state.directive["use strict"] = true;
- advance("{");
- // ClassBody(opt)
- c.body = state.syntax["{"].nud(true);
- state.directive["use strict"] = strictness;
- }
-
- blockstmt("function", function () {
- var generator = false;
- if (state.tokens.next.value === "*") {
- advance("*");
- if (state.option.inESNext(true)) {
- generator = true;
- } else {
- warning("W119", state.tokens.curr, "function*");
- }
- }
- if (inblock) {
- warning("W082", state.tokens.curr);
-
- }
- var i = identifier();
- if (funct[i] === "const") {
- warning("E011", null, i);
- }
- adjacent(state.tokens.curr, state.tokens.next);
- addlabel(i, "unction", state.tokens.curr);
-
- doFunction(i, { statement: true }, generator);
- if (state.tokens.next.id === "(" && state.tokens.next.line === state.tokens.curr.line) {
- error("E039");
- }
- return this;
- });
-
- prefix("function", function () {
- var generator = false;
- if (state.tokens.next.value === "*") {
- if (!state.option.inESNext()) {
- warning("W119", state.tokens.curr, "function*");
- }
- advance("*");
- generator = true;
- }
- var i = optionalidentifier();
- if (i || state.option.gcl) {
- adjacent(state.tokens.curr, state.tokens.next);
- } else {
- nonadjacent(state.tokens.curr, state.tokens.next);
- }
- doFunction(i, undefined, generator);
- if (!state.option.loopfunc && funct["(loopage)"]) {
- warning("W083");
- }
- return this;
- });
-
- blockstmt("if", function () {
- var t = state.tokens.next;
- increaseComplexityCount();
- state.condition = true;
- advance("(");
- nonadjacent(this, t);
- nospace();
- checkCondAssignment(expression(0));
- advance(")", t);
- state.condition = false;
- nospace(state.tokens.prev, state.tokens.curr);
- block(true, true);
- if (state.tokens.next.id === "else") {
- nonadjacent(state.tokens.curr, state.tokens.next);
- advance("else");
- if (state.tokens.next.id === "if" || state.tokens.next.id === "switch") {
- statement(true);
- } else {
- block(true, true);
- }
- }
- return this;
- });
-
- blockstmt("try", function () {
- var b;
-
- function doCatch() {
- var oldScope = scope;
- var e;
-
- advance("catch");
- nonadjacent(state.tokens.curr, state.tokens.next);
- advance("(");
-
- scope = Object.create(oldScope);
-
- e = state.tokens.next.value;
- if (state.tokens.next.type !== "(identifier)") {
- e = null;
- warning("E030", state.tokens.next, e);
- }
-
- advance();
-
- funct = {
- "(name)" : "(catch)",
- "(line)" : state.tokens.next.line,
- "(character)": state.tokens.next.character,
- "(context)" : funct,
- "(breakage)" : funct["(breakage)"],
- "(loopage)" : funct["(loopage)"],
- "(scope)" : scope,
- "(statement)": false,
- "(metrics)" : createMetrics(state.tokens.next),
- "(catch)" : true,
- "(tokens)" : {},
- "(blockscope)": funct["(blockscope)"],
- "(comparray)": funct["(comparray)"]
- };
-
- if (e) {
- addlabel(e, "exception");
- }
-
- if (state.tokens.next.value === "if") {
- if (!state.option.inMoz(true)) {
- warning("W118", state.tokens.curr, "catch filter");
- }
- advance("if");
- expression(0);
- }
-
- advance(")");
-
- state.tokens.curr.funct = funct;
- functions.push(funct);
-
- block(false);
-
- scope = oldScope;
-
- funct["(last)"] = state.tokens.curr.line;
- funct["(lastcharacter)"] = state.tokens.curr.character;
- funct = funct["(context)"];
- }
-
- block(false);
-
- while (state.tokens.next.id === "catch") {
- increaseComplexityCount();
- if (b && (!state.option.inMoz(true))) {
- warning("W118", state.tokens.next, "multiple catch blocks");
- }
- doCatch();
- b = true;
- }
-
- if (state.tokens.next.id === "finally") {
- advance("finally");
- block(false);
- return;
- }
-
- if (!b) {
- error("E021", state.tokens.next, "catch", state.tokens.next.value);
- }
-
- return this;
- });
-
- blockstmt("while", function () {
- var t = state.tokens.next;
- funct["(breakage)"] += 1;
- funct["(loopage)"] += 1;
- increaseComplexityCount();
- advance("(");
- nonadjacent(this, t);
- nospace();
- checkCondAssignment(expression(0));
- advance(")", t);
- nospace(state.tokens.prev, state.tokens.curr);
- block(true, true);
- funct["(breakage)"] -= 1;
- funct["(loopage)"] -= 1;
- return this;
- }).labelled = true;
-
- blockstmt("with", function () {
- var t = state.tokens.next;
- if (state.directive["use strict"]) {
- error("E010", state.tokens.curr);
- } else if (!state.option.withstmt) {
- warning("W085", state.tokens.curr);
- }
-
- advance("(");
- nonadjacent(this, t);
- nospace();
- expression(0);
- advance(")", t);
- nospace(state.tokens.prev, state.tokens.curr);
- block(true, true);
-
- return this;
- });
-
- blockstmt("switch", function () {
- var t = state.tokens.next,
- g = false;
- funct["(breakage)"] += 1;
- advance("(");
- nonadjacent(this, t);
- nospace();
- checkCondAssignment(expression(0));
- advance(")", t);
- nospace(state.tokens.prev, state.tokens.curr);
- nonadjacent(state.tokens.curr, state.tokens.next);
- t = state.tokens.next;
- advance("{");
- nonadjacent(state.tokens.curr, state.tokens.next);
- indent += state.option.indent;
- this.cases = [];
-
- for (;;) {
- switch (state.tokens.next.id) {
- case "case":
- switch (funct["(verb)"]) {
- case "yield":
- case "break":
- case "case":
- case "continue":
- case "return":
- case "switch":
- case "throw":
- break;
- default:
- // You can tell JSHint that you don't use break intentionally by
- // adding a comment /* falls through */ on a line just before
- // the next `case`.
- if (!reg.fallsThrough.test(state.lines[state.tokens.next.line - 2])) {
- warning("W086", state.tokens.curr, "case");
- }
- }
- indentation(-state.option.indent);
- advance("case");
- this.cases.push(expression(20));
- increaseComplexityCount();
- g = true;
- advance(":");
- funct["(verb)"] = "case";
- break;
- case "default":
- switch (funct["(verb)"]) {
- case "yield":
- case "break":
- case "continue":
- case "return":
- case "throw":
- break;
- default:
- // Do not display a warning if 'default' is the first statement or if
- // there is a special /* falls through */ comment.
- if (this.cases.length) {
- if (!reg.fallsThrough.test(state.lines[state.tokens.next.line - 2])) {
- warning("W086", state.tokens.curr, "default");
- }
- }
- }
- indentation(-state.option.indent);
- advance("default");
- g = true;
- advance(":");
- break;
- case "}":
- indent -= state.option.indent;
- indentation();
- advance("}", t);
- funct["(breakage)"] -= 1;
- funct["(verb)"] = undefined;
- return;
- case "(end)":
- error("E023", state.tokens.next, "}");
- return;
- default:
- if (g) {
- switch (state.tokens.curr.id) {
- case ",":
- error("E040");
- return;
- case ":":
- g = false;
- statements();
- break;
- default:
- error("E025", state.tokens.curr);
- return;
- }
- } else {
- if (state.tokens.curr.id === ":") {
- advance(":");
- error("E024", state.tokens.curr, ":");
- statements();
- } else {
- error("E021", state.tokens.next, "case", state.tokens.next.value);
- return;
- }
- }
- }
- }
- }).labelled = true;
-
- stmt("debugger", function () {
- if (!state.option.debug) {
- warning("W087");
- }
- return this;
- }).exps = true;
-
- (function () {
- var x = stmt("do", function () {
- funct["(breakage)"] += 1;
- funct["(loopage)"] += 1;
- increaseComplexityCount();
-
- this.first = block(true, true);
- advance("while");
- var t = state.tokens.next;
- nonadjacent(state.tokens.curr, t);
- advance("(");
- nospace();
- checkCondAssignment(expression(0));
- advance(")", t);
- nospace(state.tokens.prev, state.tokens.curr);
- funct["(breakage)"] -= 1;
- funct["(loopage)"] -= 1;
- return this;
- });
- x.labelled = true;
- x.exps = true;
- }());
-
- blockstmt("for", function () {
- var s, t = state.tokens.next;
- var letscope = false;
- var foreachtok = null;
-
- if (t.value === "each") {
- foreachtok = t;
- advance("each");
- if (!state.option.inMoz(true)) {
- warning("W118", state.tokens.curr, "for each");
- }
- }
-
- funct["(breakage)"] += 1;
- funct["(loopage)"] += 1;
- increaseComplexityCount();
- advance("(");
- nonadjacent(this, t);
- nospace();
-
- // what kind of for(…) statement it is? for(…of…)? for(…in…)? for(…;…;…)?
- var nextop; // contains the token of the "in" or "of" operator
- var i = 0;
- var inof = ["in", "of"];
- do {
- nextop = peek(i);
- ++i;
- } while (!_.contains(inof, nextop.value) && nextop.value !== ";" &&
- nextop.type !== "(end)");
-
- // if we're in a for (… in|of …) statement
- if (_.contains(inof, nextop.value)) {
- if (!state.option.inESNext() && nextop.value === "of") {
- error("W104", nextop, "for of");
- }
- if (state.tokens.next.id === "var") {
- advance("var");
- state.syntax["var"].fud.call(state.syntax["var"].fud, true);
- } else if (state.tokens.next.id === "let") {
- advance("let");
- // create a new block scope
- letscope = true;
- funct["(blockscope)"].stack();
- state.syntax["let"].fud.call(state.syntax["let"].fud, true);
- } else {
- switch (funct[state.tokens.next.value]) {
- case "unused":
- funct[state.tokens.next.value] = "var";
- break;
- case "var":
- break;
- default:
- if (!funct["(blockscope)"].getlabel(state.tokens.next.value))
- warning("W088", state.tokens.next, state.tokens.next.value);
- }
- advance();
- }
- advance(nextop.value);
- expression(20);
- advance(")", t);
- s = block(true, true);
- if (state.option.forin && s && (s.length > 1 || typeof s[0] !== "object" ||
- s[0].value !== "if")) {
- warning("W089", this);
- }
- funct["(breakage)"] -= 1;
- funct["(loopage)"] -= 1;
- } else {
- if (foreachtok) {
- error("E045", foreachtok);
- }
- if (state.tokens.next.id !== ";") {
- if (state.tokens.next.id === "var") {
- advance("var");
- state.syntax["var"].fud.call(state.syntax["var"].fud);
- } else if (state.tokens.next.id === "let") {
- advance("let");
- // create a new block scope
- letscope = true;
- funct["(blockscope)"].stack();
- state.syntax["let"].fud.call(state.syntax["let"].fud);
- } else {
- for (;;) {
- expression(0, "for");
- if (state.tokens.next.id !== ",") {
- break;
- }
- comma();
- }
- }
- }
- nolinebreak(state.tokens.curr);
- advance(";");
- if (state.tokens.next.id !== ";") {
- checkCondAssignment(expression(0));
- }
- nolinebreak(state.tokens.curr);
- advance(";");
- if (state.tokens.next.id === ";") {
- error("E021", state.tokens.next, ")", ";");
- }
- if (state.tokens.next.id !== ")") {
- for (;;) {
- expression(0, "for");
- if (state.tokens.next.id !== ",") {
- break;
- }
- comma();
- }
- }
- advance(")", t);
- nospace(state.tokens.prev, state.tokens.curr);
- block(true, true);
- funct["(breakage)"] -= 1;
- funct["(loopage)"] -= 1;
-
- }
- // unstack loop blockscope
- if (letscope) {
- funct["(blockscope)"].unstack();
- }
- return this;
- }).labelled = true;
-
-
- stmt("break", function () {
- var v = state.tokens.next.value;
-
- if (funct["(breakage)"] === 0)
- warning("W052", state.tokens.next, this.value);
-
- if (!state.option.asi)
- nolinebreak(this);
-
- if (state.tokens.next.id !== ";") {
- if (state.tokens.curr.line === state.tokens.next.line) {
- if (funct[v] !== "label") {
- warning("W090", state.tokens.next, v);
- } else if (scope[v] !== funct) {
- warning("W091", state.tokens.next, v);
- }
- this.first = state.tokens.next;
- advance();
- }
- }
- reachable("break");
- return this;
- }).exps = true;
-
-
- stmt("continue", function () {
- var v = state.tokens.next.value;
-
- if (funct["(breakage)"] === 0)
- warning("W052", state.tokens.next, this.value);
-
- if (!state.option.asi)
- nolinebreak(this);
-
- if (state.tokens.next.id !== ";") {
- if (state.tokens.curr.line === state.tokens.next.line) {
- if (funct[v] !== "label") {
- warning("W090", state.tokens.next, v);
- } else if (scope[v] !== funct) {
- warning("W091", state.tokens.next, v);
- }
- this.first = state.tokens.next;
- advance();
- }
- } else if (!funct["(loopage)"]) {
- warning("W052", state.tokens.next, this.value);
- }
- reachable("continue");
- return this;
- }).exps = true;
-
-
- stmt("return", function () {
- if (this.line === state.tokens.next.line) {
- if (state.tokens.next.id === "(regexp)")
- warning("W092");
-
- if (state.tokens.next.id !== ";" && !state.tokens.next.reach) {
- nonadjacent(state.tokens.curr, state.tokens.next);
- this.first = expression(0);
-
- if (this.first &&
- this.first.type === "(punctuator)" && this.first.value === "=" && !state.option.boss) {
- warningAt("W093", this.first.line, this.first.character);
- }
- }
- } else {
- if (state.tokens.next.type === "(punctuator)" &&
- ["[", "{", "+", "-"].indexOf(state.tokens.next.value) > -1) {
- nolinebreak(this); // always warn (Line breaking error)
- }
- }
- reachable("return");
- return this;
- }).exps = true;
-
- stmt("yield", function () {
- if (state.option.inESNext(true) && funct["(generator)"] !== true) {
- error("E046", state.tokens.curr, "yield");
- } else if (!state.option.inESNext()) {
- warning("W104", state.tokens.curr, "yield");
- }
- funct["(generator)"] = "yielded";
- if (this.line === state.tokens.next.line) {
- if (state.tokens.next.id === "(regexp)")
- warning("W092");
-
- if (state.tokens.next.id !== ";" && !state.tokens.next.reach) {
- nonadjacent(state.tokens.curr, state.tokens.next);
- this.first = expression(0);
-
- if (this.first.type === "(punctuator)" && this.first.value === "=" && !state.option.boss) {
- warningAt("W093", this.first.line, this.first.character);
- }
- }
- } else if (!state.option.asi) {
- nolinebreak(this); // always warn (Line breaking error)
- }
- return this;
- }).exps = true;
-
-
- stmt("throw", function () {
- nolinebreak(this);
- nonadjacent(state.tokens.curr, state.tokens.next);
- this.first = expression(20);
- reachable("throw");
- return this;
- }).exps = true;
-
- // Future Reserved Words
-
- FutureReservedWord("abstract");
- FutureReservedWord("boolean");
- FutureReservedWord("byte");
- FutureReservedWord("char");
- FutureReservedWord("class", { es5: true, nud: classdef });
- FutureReservedWord("double");
- FutureReservedWord("enum", { es5: true });
- FutureReservedWord("export", { es5: true });
- FutureReservedWord("extends", { es5: true });
- FutureReservedWord("final");
- FutureReservedWord("float");
- FutureReservedWord("goto");
- FutureReservedWord("implements", { es5: true, strictOnly: true });
- FutureReservedWord("import", { es5: true });
- FutureReservedWord("int");
- FutureReservedWord("interface", { es5: true, strictOnly: true });
- FutureReservedWord("long");
- FutureReservedWord("native");
- FutureReservedWord("package", { es5: true, strictOnly: true });
- FutureReservedWord("private", { es5: true, strictOnly: true });
- FutureReservedWord("protected", { es5: true, strictOnly: true });
- FutureReservedWord("public", { es5: true, strictOnly: true });
- FutureReservedWord("short");
- FutureReservedWord("static", { es5: true, strictOnly: true });
- FutureReservedWord("super", { es5: true });
- FutureReservedWord("synchronized");
- FutureReservedWord("throws");
- FutureReservedWord("transient");
- FutureReservedWord("volatile");
-
- // this function is used to determine wether a squarebracket or a curlybracket
- // expression is a comprehension array, destructuring assignment or a json value.
-
- var lookupBlockType = function () {
- var pn, pn1;
- var i = 0;
- var bracketStack = 0;
- var ret = {};
- if (_.contains(["[", "{"], state.tokens.curr.value))
- bracketStack += 1;
- if (_.contains(["[", "{"], state.tokens.next.value))
- bracketStack += 1;
- if (_.contains(["]", "}"], state.tokens.next.value))
- bracketStack -= 1;
- do {
- pn = peek(i);
- pn1 = peek(i + 1);
- i = i + 1;
- if (_.contains(["[", "{"], pn.value)) {
- bracketStack += 1;
- } else if (_.contains(["]", "}"], pn.value)) {
- bracketStack -= 1;
- }
- if (pn.identifier && pn.value === "for" && bracketStack === 1) {
- ret.isCompArray = true;
- ret.notJson = true;
- break;
- }
- if (_.contains(["}", "]"], pn.value) && pn1.value === "=") {
- ret.isDestAssign = true;
- ret.notJson = true;
- break;
- }
- if (pn.value === ";") {
- ret.isBlock = true;
- ret.notJson = true;
- }
- } while (bracketStack > 0 && pn.id !== "(end)" && i < 15);
- return ret;
- };
-
- // Check whether this function has been reached for a destructuring assign with undeclared values
- function destructuringAssignOrJsonValue() {
- // lookup for the assignment (esnext only)
- // if it has semicolons, it is a block, so go parse it as a block
- // or it's not a block, but there are assignments, check for undeclared variables
-
- var block = lookupBlockType();
- if (block.notJson) {
- if (!state.option.inESNext() && block.isDestAssign) {
- warning("W104", state.tokens.curr, "destructuring assignment");
- }
- statements();
- // otherwise parse json value
- } else {
- state.option.laxbreak = true;
- state.jsonMode = true;
- jsonValue();
- }
- }
-
- // array comprehension parsing function
- // parses and defines the three states of the list comprehension in order
- // to avoid defining global variables, but keeping them to the list comprehension scope
- // only. The order of the states are as follows:
- // * "use" which will be the returned iterative part of the list comprehension
- // * "define" which will define the variables local to the list comprehension
- // * "filter" which will help filter out values
-
- var arrayComprehension = function () {
- var CompArray = function () {
- this.mode = "use";
- this.variables = [];
- };
- var _carrays = [];
- var _current;
- function declare(v) {
- var l = _current.variables.filter(function (elt) {
- // if it has, change its undef state
- if (elt.value === v) {
- elt.undef = false;
- return v;
- }
- }).length;
- return l !== 0;
- }
- function use(v) {
- var l = _current.variables.filter(function (elt) {
- // and if it has been defined
- if (elt.value === v && !elt.undef) {
- if (elt.unused === true) {
- elt.unused = false;
- }
- return v;
- }
- }).length;
- // otherwise we warn about it
- return (l === 0);
- }
- return {stack: function () {
- _current = new CompArray();
- _carrays.push(_current);
- },
- unstack: function () {
- _current.variables.filter(function (v) {
- if (v.unused)
- warning("W098", v.token, v.value);
- if (v.undef)
- isundef(v.funct, "W117", v.token, v.value);
- });
- _carrays.splice(_carrays[_carrays.length - 1], 1);
- _current = _carrays[_carrays.length - 1];
- },
- setState: function (s) {
- if (_.contains(["use", "define", "filter"], s))
- _current.mode = s;
- },
- check: function (v) {
- // When we are in "use" state of the list comp, we enqueue that var
- if (_current && _current.mode === "use") {
- _current.variables.push({funct: funct,
- token: state.tokens.curr,
- value: v,
- undef: true,
- unused: false});
- return true;
- // When we are in "define" state of the list comp,
- } else if (_current && _current.mode === "define") {
- // check if the variable has been used previously
- if (!declare(v)) {
- _current.variables.push({funct: funct,
- token: state.tokens.curr,
- value: v,
- undef: false,
- unused: true});
- }
- return true;
- // When we are in "filter" state,
- } else if (_current && _current.mode === "filter") {
- // we check whether current variable has been declared
- if (use(v)) {
- // if not we warn about it
- isundef(funct, "W117", state.tokens.curr, v);
- }
- return true;
- }
- return false;
- }
- };
- };
-
-
- // Parse JSON
-
- function jsonValue() {
-
- function jsonObject() {
- var o = {}, t = state.tokens.next;
- advance("{");
- if (state.tokens.next.id !== "}") {
- for (;;) {
- if (state.tokens.next.id === "(end)") {
- error("E026", state.tokens.next, t.line);
- } else if (state.tokens.next.id === "}") {
- warning("W094", state.tokens.curr);
- break;
- } else if (state.tokens.next.id === ",") {
- error("E028", state.tokens.next);
- } else if (state.tokens.next.id !== "(string)") {
- warning("W095", state.tokens.next, state.tokens.next.value);
- }
- if (o[state.tokens.next.value] === true) {
- warning("W075", state.tokens.next, state.tokens.next.value);
- } else if ((state.tokens.next.value === "__proto__" &&
- !state.option.proto) || (state.tokens.next.value === "__iterator__" &&
- !state.option.iterator)) {
- warning("W096", state.tokens.next, state.tokens.next.value);
- } else {
- o[state.tokens.next.value] = true;
- }
- advance();
- advance(":");
- jsonValue();
- if (state.tokens.next.id !== ",") {
- break;
- }
- advance(",");
- }
- }
- advance("}");
- }
-
- function jsonArray() {
- var t = state.tokens.next;
- advance("[");
- if (state.tokens.next.id !== "]") {
- for (;;) {
- if (state.tokens.next.id === "(end)") {
- error("E027", state.tokens.next, t.line);
- } else if (state.tokens.next.id === "]") {
- warning("W094", state.tokens.curr);
- break;
- } else if (state.tokens.next.id === ",") {
- error("E028", state.tokens.next);
- }
- jsonValue();
- if (state.tokens.next.id !== ",") {
- break;
- }
- advance(",");
- }
- }
- advance("]");
- }
-
- switch (state.tokens.next.id) {
- case "{":
- jsonObject();
- break;
- case "[":
- jsonArray();
- break;
- case "true":
- case "false":
- case "null":
- case "(number)":
- case "(string)":
- advance();
- break;
- case "-":
- advance("-");
- if (state.tokens.curr.character !== state.tokens.next.from) {
- warning("W011", state.tokens.curr);
- }
- adjacent(state.tokens.curr, state.tokens.next);
- advance("(number)");
- break;
- default:
- error("E003", state.tokens.next);
- }
- }
-
- var blockScope = function () {
- var _current = {};
- var _variables = [_current];
-
- function _checkBlockLabels() {
- for (var t in _current) {
- if (_current[t]["(type)"] === "unused") {
- if (state.option.unused) {
- var tkn = _current[t]["(token)"];
- var line = tkn.line;
- var chr = tkn.character;
- warningAt("W098", line, chr, t);
- }
- }
- }
- }
-
- return {
- stack: function () {
- _current = {};
- _variables.push(_current);
- },
-
- unstack: function () {
- _checkBlockLabels();
- _variables.splice(_variables.length - 1, 1);
- _current = _.last(_variables);
- },
-
- getlabel: function (l) {
- for (var i = _variables.length - 1 ; i >= 0; --i) {
- if (_.has(_variables[i], l)) {
- return _variables[i];
- }
- }
- },
-
- current: {
- has: function (t) {
- return _.has(_current, t);
- },
- add: function (t, type, tok) {
- _current[t] = { "(type)" : type,
- "(token)": tok };
- }
- }
- };
- };
-
- // The actual JSHINT function itself.
- var itself = function (s, o, g) {
- var a, i, k, x;
- var optionKeys;
- var newOptionObj = {};
- var newIgnoredObj = {};
-
- state.reset();
-
- if (o && o.scope) {
- JSHINT.scope = o.scope;
- } else {
- JSHINT.errors = [];
- JSHINT.undefs = [];
- JSHINT.internals = [];
- JSHINT.blacklist = {};
- JSHINT.scope = "(main)";
- }
-
- predefined = Object.create(null);
- combine(predefined, vars.ecmaIdentifiers);
- combine(predefined, vars.reservedVars);
-
- combine(predefined, g || {});
-
- declared = Object.create(null);
- exported = Object.create(null);
-
- if (o) {
- a = o.predef;
- if (a) {
- if (!Array.isArray(a) && typeof a === "object") {
- a = Object.keys(a);
- }
-
- a.forEach(function (item) {
- var slice, prop;
-
- if (item[0] === "-") {
- slice = item.slice(1);
- JSHINT.blacklist[slice] = slice;
- } else {
- prop = Object.getOwnPropertyDescriptor(o.predef, item);
- predefined[item] = prop ? prop.value : false;
- }
- });
- }
-
- optionKeys = Object.keys(o);
- for (x = 0; x < optionKeys.length; x++) {
- if (/^-W\d{3}$/g.test(optionKeys[x])) {
- newIgnoredObj[optionKeys[x].slice(1)] = true;
- } else {
- newOptionObj[optionKeys[x]] = o[optionKeys[x]];
-
- if (optionKeys[x] === "newcap" && o[optionKeys[x]] === false)
- newOptionObj["(explicitNewcap)"] = true;
-
- if (optionKeys[x] === "indent")
- newOptionObj["(explicitIndent)"] = o[optionKeys[x]] === false ? false : true;
- }
- }
- }
-
- state.option = newOptionObj;
- state.ignored = newIgnoredObj;
-
- state.option.indent = state.option.indent || 4;
- state.option.maxerr = state.option.maxerr || 50;
-
- indent = 1;
- global = Object.create(predefined);
- scope = global;
- funct = {
- "(global)": true,
- "(name)": "(global)",
- "(scope)": scope,
- "(breakage)": 0,
- "(loopage)": 0,
- "(tokens)": {},
- "(metrics)": createMetrics(state.tokens.next),
- "(blockscope)": blockScope(),
- "(comparray)": arrayComprehension()
- };
- functions = [funct];
- urls = [];
- stack = null;
- member = {};
- membersOnly = null;
- implied = {};
- inblock = false;
- lookahead = [];
- warnings = 0;
- unuseds = [];
-
- if (!isString(s) && !Array.isArray(s)) {
- errorAt("E004", 0);
- return false;
- }
-
- api = {
- get isJSON() {
- return state.jsonMode;
- },
-
- getOption: function (name) {
- return state.option[name] || null;
- },
-
- getCache: function (name) {
- return state.cache[name];
- },
-
- setCache: function (name, value) {
- state.cache[name] = value;
- },
-
- warn: function (code, data) {
- warningAt.apply(null, [ code, data.line, data.char ].concat(data.data));
- },
-
- on: function (names, listener) {
- names.split(" ").forEach(function (name) {
- emitter.on(name, listener);
- }.bind(this));
- }
- };
-
- emitter.removeAllListeners();
- (extraModules || []).forEach(function (func) {
- func(api);
- });
-
- state.tokens.prev = state.tokens.curr = state.tokens.next = state.syntax["(begin)"];
-
- lex = new Lexer(s);
-
- lex.on("warning", function (ev) {
- warningAt.apply(null, [ ev.code, ev.line, ev.character].concat(ev.data));
- });
-
- lex.on("error", function (ev) {
- errorAt.apply(null, [ ev.code, ev.line, ev.character ].concat(ev.data));
- });
-
- lex.on("fatal", function (ev) {
- quit("E041", ev.line, ev.from);
- });
-
- lex.on("Identifier", function (ev) {
- emitter.emit("Identifier", ev);
- });
-
- lex.on("String", function (ev) {
- emitter.emit("String", ev);
- });
-
- lex.on("Number", function (ev) {
- emitter.emit("Number", ev);
- });
-
- lex.start();
-
- // Check options
- for (var name in o) {
- if (_.has(o, name)) {
- checkOption(name, state.tokens.curr);
- }
- }
-
- assume();
-
- // combine the passed globals after we've assumed all our options
- combine(predefined, g || {});
-
- //reset values
- comma.first = true;
-
- try {
- advance();
- switch (state.tokens.next.id) {
- case "{":
- case "[":
- destructuringAssignOrJsonValue();
- break;
- default:
- directives();
-
- if (state.directive["use strict"]) {
- if (!state.option.globalstrict && !state.option.node) {
- warning("W097", state.tokens.prev);
- }
- }
-
- statements();
- }
- advance((state.tokens.next && state.tokens.next.value !== ".") ? "(end)" : undefined);
- funct["(blockscope)"].unstack();
-
- var markDefined = function (name, context) {
- do {
- if (typeof context[name] === "string") {
- // JSHINT marks unused variables as 'unused' and
- // unused function declaration as 'unction'. This
- // code changes such instances back 'var' and
- // 'closure' so that the code in JSHINT.data()
- // doesn't think they're unused.
-
- if (context[name] === "unused")
- context[name] = "var";
- else if (context[name] === "unction")
- context[name] = "closure";
-
- return true;
- }
-
- context = context["(context)"];
- } while (context);
-
- return false;
- };
-
- var clearImplied = function (name, line) {
- if (!implied[name])
- return;
-
- var newImplied = [];
- for (var i = 0; i < implied[name].length; i += 1) {
- if (implied[name][i] !== line)
- newImplied.push(implied[name][i]);
- }
-
- if (newImplied.length === 0)
- delete implied[name];
- else
- implied[name] = newImplied;
- };
-
- var warnUnused = function (name, tkn, type, unused_opt) {
- var line = tkn.line;
- var chr = tkn.character;
-
- if (unused_opt === undefined) {
- unused_opt = state.option.unused;
- }
-
- if (unused_opt === true) {
- unused_opt = "last-param";
- }
-
- var warnable_types = {
- "vars": ["var"],
- "last-param": ["var", "param"],
- "strict": ["var", "param", "last-param"]
- };
-
- if (unused_opt) {
- if (warnable_types[unused_opt] && warnable_types[unused_opt].indexOf(type) !== -1) {
- warningAt("W098", line, chr, name);
- }
- }
-
- unuseds.push({
- name: name,
- line: line,
- character: chr
- });
- };
-
- var checkUnused = function (func, key) {
- var type = func[key];
- var tkn = func["(tokens)"][key];
-
- if (key.charAt(0) === "(")
- return;
-
- if (type !== "unused" && type !== "unction")
- return;
-
- // Params are checked separately from other variables.
- if (func["(params)"] && func["(params)"].indexOf(key) !== -1)
- return;
-
- // Variable is in global scope and defined as exported.
- if (func["(global)"] && _.has(exported, key)) {
- return;
- }
-
- warnUnused(key, tkn, "var");
- };
-
- // Check queued 'x is not defined' instances to see if they're still undefined.
- for (i = 0; i < JSHINT.undefs.length; i += 1) {
- k = JSHINT.undefs[i].slice(0);
-
- if (markDefined(k[2].value, k[0])) {
- clearImplied(k[2].value, k[2].line);
- } else if (state.option.undef) {
- warning.apply(warning, k.slice(1));
- }
- }
-
- functions.forEach(function (func) {
- if (func["(unusedOption)"] === false) {
- return;
- }
-
- for (var key in func) {
- if (_.has(func, key)) {
- checkUnused(func, key);
- }
- }
-
- if (!func["(params)"])
- return;
-
- var params = func["(params)"].slice();
- var param = params.pop();
- var type, unused_opt;
-
- while (param) {
- type = func[param];
- unused_opt = func["(unusedOption)"] || state.option.unused;
- unused_opt = unused_opt === true ? "last-param" : unused_opt;
-
- // 'undefined' is a special case for (function (window, undefined) { ... })();
- // patterns.
-
- if (param === "undefined")
- return;
-
- if (type === "unused" || type === "unction") {
- warnUnused(param, func["(tokens)"][param], "param", func["(unusedOption)"]);
- } else if (unused_opt === "last-param") {
- return;
- }
-
- param = params.pop();
- }
- });
-
- for (var key in declared) {
- if (_.has(declared, key) && !_.has(global, key)) {
- warnUnused(key, declared[key], "var");
- }
- }
-
- } catch (err) {
- if (err && err.name === "JSHintError") {
- var nt = state.tokens.next || {};
- JSHINT.errors.push({
- scope : "(main)",
- raw : err.raw,
- reason : err.message,
- line : err.line || nt.line,
- character : err.character || nt.from
- }, null);
- } else {
- throw err;
- }
- }
-
- // Loop over the listed "internals", and check them as well.
-
- if (JSHINT.scope === "(main)") {
- o = o || {};
-
- for (i = 0; i < JSHINT.internals.length; i += 1) {
- k = JSHINT.internals[i];
- o.scope = k.elem;
- itself(k.value, o, g);
- }
- }
-
- return JSHINT.errors.length === 0;
- };
-
- // Modules.
- itself.addModule = function (func) {
- extraModules.push(func);
- };
-
- itself.addModule(style.register);
-
- // Data summary.
- itself.data = function () {
- var data = {
- functions: [],
- options: state.option
- };
- var implieds = [];
- var members = [];
- var fu, f, i, j, n, globals;
-
- if (itself.errors.length) {
- data.errors = itself.errors;
- }
-
- if (state.jsonMode) {
- data.json = true;
- }
-
- for (n in implied) {
- if (_.has(implied, n)) {
- implieds.push({
- name: n,
- line: implied[n]
- });
- }
- }
-
- if (implieds.length > 0) {
- data.implieds = implieds;
- }
-
- if (urls.length > 0) {
- data.urls = urls;
- }
-
- globals = Object.keys(scope);
- if (globals.length > 0) {
- data.globals = globals;
- }
-
- for (i = 1; i < functions.length; i += 1) {
- f = functions[i];
- fu = {};
-
- for (j = 0; j < functionicity.length; j += 1) {
- fu[functionicity[j]] = [];
- }
-
- for (j = 0; j < functionicity.length; j += 1) {
- if (fu[functionicity[j]].length === 0) {
- delete fu[functionicity[j]];
- }
- }
-
- fu.name = f["(name)"];
- fu.param = f["(params)"];
- fu.line = f["(line)"];
- fu.character = f["(character)"];
- fu.last = f["(last)"];
- fu.lastcharacter = f["(lastcharacter)"];
- data.functions.push(fu);
- }
-
- if (unuseds.length > 0) {
- data.unused = unuseds;
- }
-
- members = [];
- for (n in member) {
- if (typeof member[n] === "number") {
- data.member = member;
- break;
- }
- }
-
- return data;
- };
-
- itself.jshint = itself;
-
- return itself;
-}());
-
-// Make JSHINT a Node module, if possible.
-if (typeof exports === "object" && exports) {
- exports.JSHINT = JSHINT;
-}
-
-})()
-},{"events":2,"../shared/vars.js":3,"./lex.js":10,"./reg.js":6,"./state.js":4,"../shared/messages.js":12,"./style.js":5,"console-browserify":7,"underscore":11}],12:[function(require,module,exports){
-(function(){"use strict";
-
-var _ = require("underscore");
-
-var errors = {
- // JSHint options
- E001: "Bad option: '{a}'.",
- E002: "Bad option value.",
-
- // JSHint input
- E003: "Expected a JSON value.",
- E004: "Input is neither a string nor an array of strings.",
- E005: "Input is empty.",
- E006: "Unexpected early end of program.",
-
- // Strict mode
- E007: "Missing \"use strict\" statement.",
- E008: "Strict violation.",
- E009: "Option 'validthis' can't be used in a global scope.",
- E010: "'with' is not allowed in strict mode.",
-
- // Constants
- E011: "const '{a}' has already been declared.",
- E012: "const '{a}' is initialized to 'undefined'.",
- E013: "Attempting to override '{a}' which is a constant.",
-
- // Regular expressions
- E014: "A regular expression literal can be confused with '/='.",
- E015: "Unclosed regular expression.",
- E016: "Invalid regular expression.",
-
- // Tokens
- E017: "Unclosed comment.",
- E018: "Unbegun comment.",
- E019: "Unmatched '{a}'.",
- E020: "Expected '{a}' to match '{b}' from line {c} and instead saw '{d}'.",
- E021: "Expected '{a}' and instead saw '{b}'.",
- E022: "Line breaking error '{a}'.",
- E023: "Missing '{a}'.",
- E024: "Unexpected '{a}'.",
- E025: "Missing ':' on a case clause.",
- E026: "Missing '}' to match '{' from line {a}.",
- E027: "Missing ']' to match '[' form line {a}.",
- E028: "Illegal comma.",
- E029: "Unclosed string.",
-
- // Everything else
- E030: "Expected an identifier and instead saw '{a}'.",
- E031: "Bad assignment.", // FIXME: Rephrase
- E032: "Expected a small integer or 'false' and instead saw '{a}'.",
- E033: "Expected an operator and instead saw '{a}'.",
- E034: "get/set are ES5 features.",
- E035: "Missing property name.",
- E036: "Expected to see a statement and instead saw a block.",
- E037: "Constant {a} was not declared correctly.",
- E038: "Variable {a} was not declared correctly.",
- E039: "Function declarations are not invocable. Wrap the whole function invocation in parens.",
- E040: "Each value should have its own case label.",
- E041: "Unrecoverable syntax error.",
- E042: "Stopping.",
- E043: "Too many errors.",
- E044: "'{a}' is already defined and can't be redefined.",
- E045: "Invalid for each loop.",
- E046: "A yield statement shall be within a generator function (with syntax: `function*`)",
- E047: "A generator function shall contain a yield statement.",
- E048: "Let declaration not directly within block.",
- E049: "A {a} cannot be named '{b}'."
-};
-
-var warnings = {
- W001: "'hasOwnProperty' is a really bad name.",
- W002: "Value of '{a}' may be overwritten in IE.",
- W003: "'{a}' was used before it was defined.",
- W004: "'{a}' is already defined.",
- W005: "A dot following a number can be confused with a decimal point.",
- W006: "Confusing minuses.",
- W007: "Confusing pluses.",
- W008: "A leading decimal point can be confused with a dot: '{a}'.",
- W009: "The array literal notation [] is preferrable.",
- W010: "The object literal notation {} is preferrable.",
- W011: "Unexpected space after '{a}'.",
- W012: "Unexpected space before '{a}'.",
- W013: "Missing space after '{a}'.",
- W014: "Bad line breaking before '{a}'.",
- W015: "Expected '{a}' to have an indentation at {b} instead at {c}.",
- W016: "Unexpected use of '{a}'.",
- W017: "Bad operand.",
- W018: "Confusing use of '{a}'.",
- W019: "Use the isNaN function to compare with NaN.",
- W020: "Read only.",
- W021: "'{a}' is a function.",
- W022: "Do not assign to the exception parameter.",
- W023: "Expected an identifier in an assignment and instead saw a function invocation.",
- W024: "Expected an identifier and instead saw '{a}' (a reserved word).",
- W025: "Missing name in function declaration.",
- W026: "Inner functions should be listed at the top of the outer function.",
- W027: "Unreachable '{a}' after '{b}'.",
- W028: "Label '{a}' on {b} statement.",
- W030: "Expected an assignment or function call and instead saw an expression.",
- W031: "Do not use 'new' for side effects.",
- W032: "Unnecessary semicolon.",
- W033: "Missing semicolon.",
- W034: "Unnecessary directive \"{a}\".",
- W035: "Empty block.",
- W036: "Unexpected /*member '{a}'.",
- W037: "'{a}' is a statement label.",
- W038: "'{a}' used out of scope.",
- W039: "'{a}' is not allowed.",
- W040: "Possible strict violation.",
- W041: "Use '{a}' to compare with '{b}'.",
- W042: "Avoid EOL escaping.",
- W043: "Bad escaping of EOL. Use option multistr if needed.",
- W044: "Bad or unnecessary escaping.",
- W045: "Bad number '{a}'.",
- W046: "Don't use extra leading zeros '{a}'.",
- W047: "A trailing decimal point can be confused with a dot: '{a}'.",
- W048: "Unexpected control character in regular expression.",
- W049: "Unexpected escaped character '{a}' in regular expression.",
- W050: "JavaScript URL.",
- W051: "Variables should not be deleted.",
- W052: "Unexpected '{a}'.",
- W053: "Do not use {a} as a constructor.",
- W054: "The Function constructor is a form of eval.",
- W055: "A constructor name should start with an uppercase letter.",
- W056: "Bad constructor.",
- W057: "Weird construction. Is 'new' unnecessary?",
- W058: "Missing '()' invoking a constructor.",
- W059: "Avoid arguments.{a}.",
- W060: "document.write can be a form of eval.",
- W061: "eval can be harmful.",
- W062: "Wrap an immediate function invocation in parens " +
- "to assist the reader in understanding that the expression " +
- "is the result of a function, and not the function itself.",
- W063: "Math is not a function.",
- W064: "Missing 'new' prefix when invoking a constructor.",
- W065: "Missing radix parameter.",
- W066: "Implied eval. Consider passing a function instead of a string.",
- W067: "Bad invocation.",
- W068: "Wrapping non-IIFE function literals in parens is unnecessary.",
- W069: "['{a}'] is better written in dot notation.",
- W070: "Extra comma. (it breaks older versions of IE)",
- W071: "This function has too many statements. ({a})",
- W072: "This function has too many parameters. ({a})",
- W073: "Blocks are nested too deeply. ({a})",
- W074: "This function's cyclomatic complexity is too high. ({a})",
- W075: "Duplicate key '{a}'.",
- W076: "Unexpected parameter '{a}' in get {b} function.",
- W077: "Expected a single parameter in set {a} function.",
- W078: "Setter is defined without getter.",
- W079: "Redefinition of '{a}'.",
- W080: "It's not necessary to initialize '{a}' to 'undefined'.",
- W081: "Too many var statements.",
- W082: "Function declarations should not be placed in blocks. " +
- "Use a function expression or move the statement to the top of " +
- "the outer function.",
- W083: "Don't make functions within a loop.",
- W084: "Expected a conditional expression and instead saw an assignment.",
- W085: "Don't use 'with'.",
- W086: "Expected a 'break' statement before '{a}'.",
- W087: "Forgotten 'debugger' statement?",
- W088: "Creating global 'for' variable. Should be 'for (var {a} ...'.",
- W089: "The body of a for in should be wrapped in an if statement to filter " +
- "unwanted properties from the prototype.",
- W090: "'{a}' is not a statement label.",
- W091: "'{a}' is out of scope.",
- W092: "Wrap the /regexp/ literal in parens to disambiguate the slash operator.",
- W093: "Did you mean to return a conditional instead of an assignment?",
- W094: "Unexpected comma.",
- W095: "Expected a string and instead saw {a}.",
- W096: "The '{a}' key may produce unexpected results.",
- W097: "Use the function form of \"use strict\".",
- W098: "'{a}' is defined but never used.",
- W099: "Mixed spaces and tabs.",
- W100: "This character may get silently deleted by one or more browsers.",
- W101: "Line is too long.",
- W102: "Trailing whitespace.",
- W103: "The '{a}' property is deprecated.",
- W104: "'{a}' is only available in JavaScript 1.7.",
- W105: "Unexpected {a} in '{b}'.",
- W106: "Identifier '{a}' is not in camel case.",
- W107: "Script URL.",
- W108: "Strings must use doublequote.",
- W109: "Strings must use singlequote.",
- W110: "Mixed double and single quotes.",
- W112: "Unclosed string.",
- W113: "Control character in string: {a}.",
- W114: "Avoid {a}.",
- W115: "Octal literals are not allowed in strict mode.",
- W116: "Expected '{a}' and instead saw '{b}'.",
- W117: "'{a}' is not defined.",
- W118: "'{a}' is only available in Mozilla JavaScript extensions (use moz option).",
- W119: "'{a}' is only available in ES6 (use esnext option)."
-};
-
-var info = {
- I001: "Comma warnings can be turned off with 'laxcomma'.",
- I002: "Reserved words as properties can be used under the 'es5' option.",
- I003: "ES5 option is now set per default"
-};
-
-exports.errors = {};
-exports.warnings = {};
-exports.info = {};
-
-_.each(errors, function (desc, code) {
- exports.errors[code] = { code: code, desc: desc };
-});
-
-_.each(warnings, function (desc, code) {
- exports.warnings[code] = { code: code, desc: desc };
-});
-
-_.each(info, function (desc, code) {
- exports.info[code] = { code: code, desc: desc };
-});
-
-})()
-},{"underscore":11}],8:[function(require,module,exports){
-var events = require('events');
-
-exports.isArray = isArray;
-exports.isDate = function(obj){return Object.prototype.toString.call(obj) === '[object Date]'};
-exports.isRegExp = function(obj){return Object.prototype.toString.call(obj) === '[object RegExp]'};
-
-
-exports.print = function () {};
-exports.puts = function () {};
-exports.debug = function() {};
-
-exports.inspect = function(obj, showHidden, depth, colors) {
- var seen = [];
-
- var stylize = function(str, styleType) {
- // http://en.wikipedia.org/wiki/ANSI_escape_code#graphics
- var styles =
- { 'bold' : [1, 22],
- 'italic' : [3, 23],
- 'underline' : [4, 24],
- 'inverse' : [7, 27],
- 'white' : [37, 39],
- 'grey' : [90, 39],
- 'black' : [30, 39],
- 'blue' : [34, 39],
- 'cyan' : [36, 39],
- 'green' : [32, 39],
- 'magenta' : [35, 39],
- 'red' : [31, 39],
- 'yellow' : [33, 39] };
-
- var style =
- { 'special': 'cyan',
- 'number': 'blue',
- 'boolean': 'yellow',
- 'undefined': 'grey',
- 'null': 'bold',
- 'string': 'green',
- 'date': 'magenta',
- // "name": intentionally not styling
- 'regexp': 'red' }[styleType];
-
- if (style) {
- return '\033[' + styles[style][0] + 'm' + str +
- '\033[' + styles[style][1] + 'm';
- } else {
- return str;
- }
- };
- if (! colors) {
- stylize = function(str, styleType) { return str; };
- }
-
- function format(value, recurseTimes) {
- // Provide a hook for user-specified inspect functions.
- // Check that value is an object with an inspect function on it
- if (value && typeof value.inspect === 'function' &&
- // Filter out the util module, it's inspect function is special
- value !== exports &&
- // Also filter out any prototype objects using the circular check.
- !(value.constructor && value.constructor.prototype === value)) {
- return value.inspect(recurseTimes);
- }
-
- // Primitive types cannot have properties
- switch (typeof value) {
- case 'undefined':
- return stylize('undefined', 'undefined');
-
- case 'string':
- var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '')
- .replace(/'/g, "\\'")
- .replace(/\\"/g, '"') + '\'';
- return stylize(simple, 'string');
-
- case 'number':
- return stylize('' + value, 'number');
-
- case 'boolean':
- return stylize('' + value, 'boolean');
- }
- // For some reason typeof null is "object", so special case here.
- if (value === null) {
- return stylize('null', 'null');
- }
-
- // Look up the keys of the object.
- var visible_keys = Object_keys(value);
- var keys = showHidden ? Object_getOwnPropertyNames(value) : visible_keys;
-
- // Functions without properties can be shortcutted.
- if (typeof value === 'function' && keys.length === 0) {
- if (isRegExp(value)) {
- return stylize('' + value, 'regexp');
- } else {
- var name = value.name ? ': ' + value.name : '';
- return stylize('[Function' + name + ']', 'special');
- }
- }
-
- // Dates without properties can be shortcutted
- if (isDate(value) && keys.length === 0) {
- return stylize(value.toUTCString(), 'date');
- }
-
- var base, type, braces;
- // Determine the object type
- if (isArray(value)) {
- type = 'Array';
- braces = ['[', ']'];
- } else {
- type = 'Object';
- braces = ['{', '}'];
- }
-
- // Make functions say that they are functions
- if (typeof value === 'function') {
- var n = value.name ? ': ' + value.name : '';
- base = (isRegExp(value)) ? ' ' + value : ' [Function' + n + ']';
- } else {
- base = '';
- }
-
- // Make dates with properties first say the date
- if (isDate(value)) {
- base = ' ' + value.toUTCString();
- }
-
- if (keys.length === 0) {
- return braces[0] + base + braces[1];
- }
-
- if (recurseTimes < 0) {
- if (isRegExp(value)) {
- return stylize('' + value, 'regexp');
- } else {
- return stylize('[Object]', 'special');
- }
- }
-
- seen.push(value);
-
- var output = keys.map(function(key) {
- var name, str;
- if (value.__lookupGetter__) {
- if (value.__lookupGetter__(key)) {
- if (value.__lookupSetter__(key)) {
- str = stylize('[Getter/Setter]', 'special');
- } else {
- str = stylize('[Getter]', 'special');
- }
- } else {
- if (value.__lookupSetter__(key)) {
- str = stylize('[Setter]', 'special');
- }
- }
- }
- if (visible_keys.indexOf(key) < 0) {
- name = '[' + key + ']';
- }
- if (!str) {
- if (seen.indexOf(value[key]) < 0) {
- if (recurseTimes === null) {
- str = format(value[key]);
- } else {
- str = format(value[key], recurseTimes - 1);
- }
- if (str.indexOf('\n') > -1) {
- if (isArray(value)) {
- str = str.split('\n').map(function(line) {
- return ' ' + line;
- }).join('\n').substr(2);
- } else {
- str = '\n' + str.split('\n').map(function(line) {
- return ' ' + line;
- }).join('\n');
- }
- }
- } else {
- str = stylize('[Circular]', 'special');
- }
- }
- if (typeof name === 'undefined') {
- if (type === 'Array' && key.match(/^\d+$/)) {
- return str;
- }
- name = JSON.stringify('' + key);
- if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) {
- name = name.substr(1, name.length - 2);
- name = stylize(name, 'name');
- } else {
- name = name.replace(/'/g, "\\'")
- .replace(/\\"/g, '"')
- .replace(/(^"|"$)/g, "'");
- name = stylize(name, 'string');
- }
- }
-
- return name + ': ' + str;
- });
-
- seen.pop();
-
- var numLinesEst = 0;
- var length = output.reduce(function(prev, cur) {
- numLinesEst++;
- if (cur.indexOf('\n') >= 0) numLinesEst++;
- return prev + cur.length + 1;
- }, 0);
-
- if (length > 50) {
- output = braces[0] +
- (base === '' ? '' : base + '\n ') +
- ' ' +
- output.join(',\n ') +
- ' ' +
- braces[1];
-
- } else {
- output = braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1];
- }
-
- return output;
- }
- return format(obj, (typeof depth === 'undefined' ? 2 : depth));
-};
-
-
-function isArray(ar) {
- return ar instanceof Array ||
- Array.isArray(ar) ||
- (ar && ar !== Object.prototype && isArray(ar.__proto__));
-}
-
-
-function isRegExp(re) {
- return re instanceof RegExp ||
- (typeof re === 'object' && Object.prototype.toString.call(re) === '[object RegExp]');
-}
-
-
-function isDate(d) {
- if (d instanceof Date) return true;
- if (typeof d !== 'object') return false;
- var properties = Date.prototype && Object_getOwnPropertyNames(Date.prototype);
- var proto = d.__proto__ && Object_getOwnPropertyNames(d.__proto__);
- return JSON.stringify(proto) === JSON.stringify(properties);
-}
-
-function pad(n) {
- return n < 10 ? '0' + n.toString(10) : n.toString(10);
-}
-
-var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep',
- 'Oct', 'Nov', 'Dec'];
-
-// 26 Feb 16:19:34
-function timestamp() {
- var d = new Date();
- var time = [pad(d.getHours()),
- pad(d.getMinutes()),
- pad(d.getSeconds())].join(':');
- return [d.getDate(), months[d.getMonth()], time].join(' ');
-}
-
-exports.log = function (msg) {};
-
-exports.pump = null;
-
-var Object_keys = Object.keys || function (obj) {
- var res = [];
- for (var key in obj) res.push(key);
- return res;
-};
-
-var Object_getOwnPropertyNames = Object.getOwnPropertyNames || function (obj) {
- var res = [];
- for (var key in obj) {
- if (Object.hasOwnProperty.call(obj, key)) res.push(key);
- }
- return res;
-};
-
-var Object_create = Object.create || function (prototype, properties) {
- // from es5-shim
- var object;
- if (prototype === null) {
- object = { '__proto__' : null };
- }
- else {
- if (typeof prototype !== 'object') {
- throw new TypeError(
- 'typeof prototype[' + (typeof prototype) + '] != \'object\''
- );
- }
- var Type = function () {};
- Type.prototype = prototype;
- object = new Type();
- object.__proto__ = prototype;
- }
- if (typeof properties !== 'undefined' && Object.defineProperties) {
- Object.defineProperties(object, properties);
- }
- return object;
-};
-
-exports.inherits = function(ctor, superCtor) {
- ctor.super_ = superCtor;
- ctor.prototype = Object_create(superCtor.prototype, {
- constructor: {
- value: ctor,
- enumerable: false,
- writable: true,
- configurable: true
- }
- });
-};
-
-var formatRegExp = /%[sdj%]/g;
-exports.format = function(f) {
- if (typeof f !== 'string') {
- var objects = [];
- for (var i = 0; i < arguments.length; i++) {
- objects.push(exports.inspect(arguments[i]));
- }
- return objects.join(' ');
- }
-
- var i = 1;
- var args = arguments;
- var len = args.length;
- var str = String(f).replace(formatRegExp, function(x) {
- if (x === '%%') return '%';
- if (i >= len) return x;
- switch (x) {
- case '%s': return String(args[i++]);
- case '%d': return Number(args[i++]);
- case '%j': return JSON.stringify(args[i++]);
- default:
- return x;
- }
- });
- for(var x = args[i]; i < len; x = args[++i]){
- if (x === null || typeof x !== 'object') {
- str += ' ' + x;
- } else {
- str += ' ' + exports.inspect(x);
- }
- }
- return str;
-};
-
-},{"events":2}],9:[function(require,module,exports){
-(function(){// UTILITY
-var util = require('util');
-var Buffer = require("buffer").Buffer;
-var pSlice = Array.prototype.slice;
-
-function objectKeys(object) {
- if (Object.keys) return Object.keys(object);
- var result = [];
- for (var name in object) {
- if (Object.prototype.hasOwnProperty.call(object, name)) {
- result.push(name);
- }
- }
- return result;
-}
-
-// 1. The assert module provides functions that throw
-// AssertionError's when particular conditions are not met. The
-// assert module must conform to the following interface.
-
-var assert = module.exports = ok;
-
-// 2. The AssertionError is defined in assert.
-// new assert.AssertionError({ message: message,
-// actual: actual,
-// expected: expected })
-
-assert.AssertionError = function AssertionError(options) {
- this.name = 'AssertionError';
- this.message = options.message;
- this.actual = options.actual;
- this.expected = options.expected;
- this.operator = options.operator;
- var stackStartFunction = options.stackStartFunction || fail;
-
- if (Error.captureStackTrace) {
- Error.captureStackTrace(this, stackStartFunction);
- }
-};
-util.inherits(assert.AssertionError, Error);
-
-function replacer(key, value) {
- if (value === undefined) {
- return '' + value;
- }
- if (typeof value === 'number' && (isNaN(value) || !isFinite(value))) {
- return value.toString();
- }
- if (typeof value === 'function' || value instanceof RegExp) {
- return value.toString();
- }
- return value;
-}
-
-function truncate(s, n) {
- if (typeof s == 'string') {
- return s.length < n ? s : s.slice(0, n);
- } else {
- return s;
- }
-}
-
-assert.AssertionError.prototype.toString = function() {
- if (this.message) {
- return [this.name + ':', this.message].join(' ');
- } else {
- return [
- this.name + ':',
- truncate(JSON.stringify(this.actual, replacer), 128),
- this.operator,
- truncate(JSON.stringify(this.expected, replacer), 128)
- ].join(' ');
- }
-};
-
-// assert.AssertionError instanceof Error
-
-assert.AssertionError.__proto__ = Error.prototype;
-
-// At present only the three keys mentioned above are used and
-// understood by the spec. Implementations or sub modules can pass
-// other keys to the AssertionError's constructor - they will be
-// ignored.
-
-// 3. All of the following functions must throw an AssertionError
-// when a corresponding condition is not met, with a message that
-// may be undefined if not provided. All assertion methods provide
-// both the actual and expected values to the assertion error for
-// display purposes.
-
-function fail(actual, expected, message, operator, stackStartFunction) {
- throw new assert.AssertionError({
- message: message,
- actual: actual,
- expected: expected,
- operator: operator,
- stackStartFunction: stackStartFunction
- });
-}
-
-// EXTENSION! allows for well behaved errors defined elsewhere.
-assert.fail = fail;
-
-// 4. Pure assertion tests whether a value is truthy, as determined
-// by !!guard.
-// assert.ok(guard, message_opt);
-// This statement is equivalent to assert.equal(true, guard,
-// message_opt);. To test strictly for the value true, use
-// assert.strictEqual(true, guard, message_opt);.
-
-function ok(value, message) {
- if (!!!value) fail(value, true, message, '==', assert.ok);
-}
-assert.ok = ok;
-
-// 5. The equality assertion tests shallow, coercive equality with
-// ==.
-// assert.equal(actual, expected, message_opt);
-
-assert.equal = function equal(actual, expected, message) {
- if (actual != expected) fail(actual, expected, message, '==', assert.equal);
-};
-
-// 6. The non-equality assertion tests for whether two objects are not equal
-// with != assert.notEqual(actual, expected, message_opt);
-
-assert.notEqual = function notEqual(actual, expected, message) {
- if (actual == expected) {
- fail(actual, expected, message, '!=', assert.notEqual);
- }
-};
-
-// 7. The equivalence assertion tests a deep equality relation.
-// assert.deepEqual(actual, expected, message_opt);
-
-assert.deepEqual = function deepEqual(actual, expected, message) {
- if (!_deepEqual(actual, expected)) {
- fail(actual, expected, message, 'deepEqual', assert.deepEqual);
- }
-};
-
-function _deepEqual(actual, expected) {
- // 7.1. All identical values are equivalent, as determined by ===.
- if (actual === expected) {
- return true;
-
- } else if (Buffer.isBuffer(actual) && Buffer.isBuffer(expected)) {
- if (actual.length != expected.length) return false;
-
- for (var i = 0; i < actual.length; i++) {
- if (actual[i] !== expected[i]) return false;
- }
-
- return true;
-
- // 7.2. If the expected value is a Date object, the actual value is
- // equivalent if it is also a Date object that refers to the same time.
- } else if (actual instanceof Date && expected instanceof Date) {
- return actual.getTime() === expected.getTime();
-
- // 7.3. Other pairs that do not both pass typeof value == 'object',
- // equivalence is determined by ==.
- } else if (typeof actual != 'object' && typeof expected != 'object') {
- return actual == expected;
-
- // 7.4. For all other Object pairs, including Array objects, equivalence is
- // determined by having the same number of owned properties (as verified
- // with Object.prototype.hasOwnProperty.call), the same set of keys
- // (although not necessarily the same order), equivalent values for every
- // corresponding key, and an identical 'prototype' property. Note: this
- // accounts for both named and indexed properties on Arrays.
- } else {
- return objEquiv(actual, expected);
- }
-}
-
-function isUndefinedOrNull(value) {
- return value === null || value === undefined;
-}
-
-function isArguments(object) {
- return Object.prototype.toString.call(object) == '[object Arguments]';
-}
-
-function objEquiv(a, b) {
- if (isUndefinedOrNull(a) || isUndefinedOrNull(b))
- return false;
- // an identical 'prototype' property.
- if (a.prototype !== b.prototype) return false;
- //~~~I've managed to break Object.keys through screwy arguments passing.
- // Converting to array solves the problem.
- if (isArguments(a)) {
- if (!isArguments(b)) {
- return false;
- }
- a = pSlice.call(a);
- b = pSlice.call(b);
- return _deepEqual(a, b);
- }
- try {
- var ka = objectKeys(a),
- kb = objectKeys(b),
- key, i;
- } catch (e) {//happens when one is a string literal and the other isn't
- return false;
- }
- // having the same number of owned properties (keys incorporates
- // hasOwnProperty)
- if (ka.length != kb.length)
- return false;
- //the same set of keys (although not necessarily the same order),
- ka.sort();
- kb.sort();
- //~~~cheap key test
- for (i = ka.length - 1; i >= 0; i--) {
- if (ka[i] != kb[i])
- return false;
- }
- //equivalent values for every corresponding key, and
- //~~~possibly expensive deep test
- for (i = ka.length - 1; i >= 0; i--) {
- key = ka[i];
- if (!_deepEqual(a[key], b[key])) return false;
- }
- return true;
-}
-
-// 8. The non-equivalence assertion tests for any deep inequality.
-// assert.notDeepEqual(actual, expected, message_opt);
-
-assert.notDeepEqual = function notDeepEqual(actual, expected, message) {
- if (_deepEqual(actual, expected)) {
- fail(actual, expected, message, 'notDeepEqual', assert.notDeepEqual);
- }
-};
-
-// 9. The strict equality assertion tests strict equality, as determined by ===.
-// assert.strictEqual(actual, expected, message_opt);
-
-assert.strictEqual = function strictEqual(actual, expected, message) {
- if (actual !== expected) {
- fail(actual, expected, message, '===', assert.strictEqual);
- }
-};
-
-// 10. The strict non-equality assertion tests for strict inequality, as
-// determined by !==. assert.notStrictEqual(actual, expected, message_opt);
-
-assert.notStrictEqual = function notStrictEqual(actual, expected, message) {
- if (actual === expected) {
- fail(actual, expected, message, '!==', assert.notStrictEqual);
- }
-};
-
-function expectedException(actual, expected) {
- if (!actual || !expected) {
- return false;
- }
-
- if (expected instanceof RegExp) {
- return expected.test(actual);
- } else if (actual instanceof expected) {
- return true;
- } else if (expected.call({}, actual) === true) {
- return true;
- }
-
- return false;
-}
-
-function _throws(shouldThrow, block, expected, message) {
- var actual;
-
- if (typeof expected === 'string') {
- message = expected;
- expected = null;
- }
-
- try {
- block();
- } catch (e) {
- actual = e;
- }
-
- message = (expected && expected.name ? ' (' + expected.name + ').' : '.') +
- (message ? ' ' + message : '.');
-
- if (shouldThrow && !actual) {
- fail('Missing expected exception' + message);
- }
-
- if (!shouldThrow && expectedException(actual, expected)) {
- fail('Got unwanted exception' + message);
- }
-
- if ((shouldThrow && actual && expected &&
- !expectedException(actual, expected)) || (!shouldThrow && actual)) {
- throw actual;
- }
-}
-
-// 11. Expected to throw an error:
-// assert.throws(block, Error_opt, message_opt);
-
-assert.throws = function(block, /*optional*/error, /*optional*/message) {
- _throws.apply(this, [true].concat(pSlice.call(arguments)));
-};
-
-// EXTENSION! This is annoying to write outside this module.
-assert.doesNotThrow = function(block, /*optional*/error, /*optional*/message) {
- _throws.apply(this, [false].concat(pSlice.call(arguments)));
-};
-
-assert.ifError = function(err) { if (err) {throw err;}};
-
-})()
-},{"util":8,"buffer":13}],11:[function(require,module,exports){
-(function(){// Underscore.js 1.4.4
-// http://underscorejs.org
-// (c) 2009-2013 Jeremy Ashkenas, DocumentCloud Inc.
-// Underscore may be freely distributed under the MIT license.
-
-(function() {
-
- // Baseline setup
- // --------------
-
- // Establish the root object, `window` in the browser, or `global` on the server.
- var root = this;
-
- // Save the previous value of the `_` variable.
- var previousUnderscore = root._;
-
- // Establish the object that gets returned to break out of a loop iteration.
- var breaker = {};
-
- // Save bytes in the minified (but not gzipped) version:
- var ArrayProto = Array.prototype, ObjProto = Object.prototype, FuncProto = Function.prototype;
-
- // Create quick reference variables for speed access to core prototypes.
- var push = ArrayProto.push,
- slice = ArrayProto.slice,
- concat = ArrayProto.concat,
- toString = ObjProto.toString,
- hasOwnProperty = ObjProto.hasOwnProperty;
-
- // All **ECMAScript 5** native function implementations that we hope to use
- // are declared here.
- var
- nativeForEach = ArrayProto.forEach,
- nativeMap = ArrayProto.map,
- nativeReduce = ArrayProto.reduce,
- nativeReduceRight = ArrayProto.reduceRight,
- nativeFilter = ArrayProto.filter,
- nativeEvery = ArrayProto.every,
- nativeSome = ArrayProto.some,
- nativeIndexOf = ArrayProto.indexOf,
- nativeLastIndexOf = ArrayProto.lastIndexOf,
- nativeIsArray = Array.isArray,
- nativeKeys = Object.keys,
- nativeBind = FuncProto.bind;
-
- // Create a safe reference to the Underscore object for use below.
- var _ = function(obj) {
- if (obj instanceof _) return obj;
- if (!(this instanceof _)) return new _(obj);
- this._wrapped = obj;
- };
-
- // Export the Underscore object for **Node.js**, with
- // backwards-compatibility for the old `require()` API. If we're in
- // the browser, add `_` as a global object via a string identifier,
- // for Closure Compiler "advanced" mode.
- if (typeof exports !== 'undefined') {
- if (typeof module !== 'undefined' && module.exports) {
- exports = module.exports = _;
- }
- exports._ = _;
- } else {
- root._ = _;
- }
-
- // Current version.
- _.VERSION = '1.4.4';
-
- // Collection Functions
- // --------------------
-
- // The cornerstone, an `each` implementation, aka `forEach`.
- // Handles objects with the built-in `forEach`, arrays, and raw objects.
- // Delegates to **ECMAScript 5**'s native `forEach` if available.
- var each = _.each = _.forEach = function(obj, iterator, context) {
- if (obj == null) return;
- if (nativeForEach && obj.forEach === nativeForEach) {
- obj.forEach(iterator, context);
- } else if (obj.length === +obj.length) {
- for (var i = 0, l = obj.length; i < l; i++) {
- if (iterator.call(context, obj[i], i, obj) === breaker) return;
- }
- } else {
- for (var key in obj) {
- if (_.has(obj, key)) {
- if (iterator.call(context, obj[key], key, obj) === breaker) return;
- }
- }
- }
- };
-
- // Return the results of applying the iterator to each element.
- // Delegates to **ECMAScript 5**'s native `map` if available.
- _.map = _.collect = function(obj, iterator, context) {
- var results = [];
- if (obj == null) return results;
- if (nativeMap && obj.map === nativeMap) return obj.map(iterator, context);
- each(obj, function(value, index, list) {
- results[results.length] = iterator.call(context, value, index, list);
- });
- return results;
- };
-
- var reduceError = 'Reduce of empty array with no initial value';
-
- // **Reduce** builds up a single result from a list of values, aka `inject`,
- // or `foldl`. Delegates to **ECMAScript 5**'s native `reduce` if available.
- _.reduce = _.foldl = _.inject = function(obj, iterator, memo, context) {
- var initial = arguments.length > 2;
- if (obj == null) obj = [];
- if (nativeReduce && obj.reduce === nativeReduce) {
- if (context) iterator = _.bind(iterator, context);
- return initial ? obj.reduce(iterator, memo) : obj.reduce(iterator);
- }
- each(obj, function(value, index, list) {
- if (!initial) {
- memo = value;
- initial = true;
- } else {
- memo = iterator.call(context, memo, value, index, list);
- }
- });
- if (!initial) throw new TypeError(reduceError);
- return memo;
- };
-
- // The right-associative version of reduce, also known as `foldr`.
- // Delegates to **ECMAScript 5**'s native `reduceRight` if available.
- _.reduceRight = _.foldr = function(obj, iterator, memo, context) {
- var initial = arguments.length > 2;
- if (obj == null) obj = [];
- if (nativeReduceRight && obj.reduceRight === nativeReduceRight) {
- if (context) iterator = _.bind(iterator, context);
- return initial ? obj.reduceRight(iterator, memo) : obj.reduceRight(iterator);
- }
- var length = obj.length;
- if (length !== +length) {
- var keys = _.keys(obj);
- length = keys.length;
- }
- each(obj, function(value, index, list) {
- index = keys ? keys[--length] : --length;
- if (!initial) {
- memo = obj[index];
- initial = true;
- } else {
- memo = iterator.call(context, memo, obj[index], index, list);
- }
- });
- if (!initial) throw new TypeError(reduceError);
- return memo;
- };
-
- // Return the first value which passes a truth test. Aliased as `detect`.
- _.find = _.detect = function(obj, iterator, context) {
- var result;
- any(obj, function(value, index, list) {
- if (iterator.call(context, value, index, list)) {
- result = value;
- return true;
- }
- });
- return result;
- };
-
- // Return all the elements that pass a truth test.
- // Delegates to **ECMAScript 5**'s native `filter` if available.
- // Aliased as `select`.
- _.filter = _.select = function(obj, iterator, context) {
- var results = [];
- if (obj == null) return results;
- if (nativeFilter && obj.filter === nativeFilter) return obj.filter(iterator, context);
- each(obj, function(value, index, list) {
- if (iterator.call(context, value, index, list)) results[results.length] = value;
- });
- return results;
- };
-
- // Return all the elements for which a truth test fails.
- _.reject = function(obj, iterator, context) {
- return _.filter(obj, function(value, index, list) {
- return !iterator.call(context, value, index, list);
- }, context);
- };
-
- // Determine whether all of the elements match a truth test.
- // Delegates to **ECMAScript 5**'s native `every` if available.
- // Aliased as `all`.
- _.every = _.all = function(obj, iterator, context) {
- iterator || (iterator = _.identity);
- var result = true;
- if (obj == null) return result;
- if (nativeEvery && obj.every === nativeEvery) return obj.every(iterator, context);
- each(obj, function(value, index, list) {
- if (!(result = result && iterator.call(context, value, index, list))) return breaker;
- });
- return !!result;
- };
-
- // Determine if at least one element in the object matches a truth test.
- // Delegates to **ECMAScript 5**'s native `some` if available.
- // Aliased as `any`.
- var any = _.some = _.any = function(obj, iterator, context) {
- iterator || (iterator = _.identity);
- var result = false;
- if (obj == null) return result;
- if (nativeSome && obj.some === nativeSome) return obj.some(iterator, context);
- each(obj, function(value, index, list) {
- if (result || (result = iterator.call(context, value, index, list))) return breaker;
- });
- return !!result;
- };
-
- // Determine if the array or object contains a given value (using `===`).
- // Aliased as `include`.
- _.contains = _.include = function(obj, target) {
- if (obj == null) return false;
- if (nativeIndexOf && obj.indexOf === nativeIndexOf) return obj.indexOf(target) != -1;
- return any(obj, function(value) {
- return value === target;
- });
- };
-
- // Invoke a method (with arguments) on every item in a collection.
- _.invoke = function(obj, method) {
- var args = slice.call(arguments, 2);
- var isFunc = _.isFunction(method);
- return _.map(obj, function(value) {
- return (isFunc ? method : value[method]).apply(value, args);
- });
- };
-
- // Convenience version of a common use case of `map`: fetching a property.
- _.pluck = function(obj, key) {
- return _.map(obj, function(value){ return value[key]; });
- };
-
- // Convenience version of a common use case of `filter`: selecting only objects
- // containing specific `key:value` pairs.
- _.where = function(obj, attrs, first) {
- if (_.isEmpty(attrs)) return first ? null : [];
- return _[first ? 'find' : 'filter'](obj, function(value) {
- for (var key in attrs) {
- if (attrs[key] !== value[key]) return false;
- }
- return true;
- });
- };
-
- // Convenience version of a common use case of `find`: getting the first object
- // containing specific `key:value` pairs.
- _.findWhere = function(obj, attrs) {
- return _.where(obj, attrs, true);
- };
-
- // Return the maximum element or (element-based computation).
- // Can't optimize arrays of integers longer than 65,535 elements.
- // See: https://bugs.webkit.org/show_bug.cgi?id=80797
- _.max = function(obj, iterator, context) {
- if (!iterator && _.isArray(obj) && obj[0] === +obj[0] && obj.length < 65535) {
- return Math.max.apply(Math, obj);
- }
- if (!iterator && _.isEmpty(obj)) return -Infinity;
- var result = {computed : -Infinity, value: -Infinity};
- each(obj, function(value, index, list) {
- var computed = iterator ? iterator.call(context, value, index, list) : value;
- computed >= result.computed && (result = {value : value, computed : computed});
- });
- return result.value;
- };
-
- // Return the minimum element (or element-based computation).
- _.min = function(obj, iterator, context) {
- if (!iterator && _.isArray(obj) && obj[0] === +obj[0] && obj.length < 65535) {
- return Math.min.apply(Math, obj);
- }
- if (!iterator && _.isEmpty(obj)) return Infinity;
- var result = {computed : Infinity, value: Infinity};
- each(obj, function(value, index, list) {
- var computed = iterator ? iterator.call(context, value, index, list) : value;
- computed < result.computed && (result = {value : value, computed : computed});
- });
- return result.value;
- };
-
- // Shuffle an array.
- _.shuffle = function(obj) {
- var rand;
- var index = 0;
- var shuffled = [];
- each(obj, function(value) {
- rand = _.random(index++);
- shuffled[index - 1] = shuffled[rand];
- shuffled[rand] = value;
- });
- return shuffled;
- };
-
- // An internal function to generate lookup iterators.
- var lookupIterator = function(value) {
- return _.isFunction(value) ? value : function(obj){ return obj[value]; };
- };
-
- // Sort the object's values by a criterion produced by an iterator.
- _.sortBy = function(obj, value, context) {
- var iterator = lookupIterator(value);
- return _.pluck(_.map(obj, function(value, index, list) {
- return {
- value : value,
- index : index,
- criteria : iterator.call(context, value, index, list)
- };
- }).sort(function(left, right) {
- var a = left.criteria;
- var b = right.criteria;
- if (a !== b) {
- if (a > b || a === void 0) return 1;
- if (a < b || b === void 0) return -1;
- }
- return left.index < right.index ? -1 : 1;
- }), 'value');
- };
-
- // An internal function used for aggregate "group by" operations.
- var group = function(obj, value, context, behavior) {
- var result = {};
- var iterator = lookupIterator(value || _.identity);
- each(obj, function(value, index) {
- var key = iterator.call(context, value, index, obj);
- behavior(result, key, value);
- });
- return result;
- };
-
- // Groups the object's values by a criterion. Pass either a string attribute
- // to group by, or a function that returns the criterion.
- _.groupBy = function(obj, value, context) {
- return group(obj, value, context, function(result, key, value) {
- (_.has(result, key) ? result[key] : (result[key] = [])).push(value);
- });
- };
-
- // Counts instances of an object that group by a certain criterion. Pass
- // either a string attribute to count by, or a function that returns the
- // criterion.
- _.countBy = function(obj, value, context) {
- return group(obj, value, context, function(result, key) {
- if (!_.has(result, key)) result[key] = 0;
- result[key]++;
- });
- };
-
- // Use a comparator function to figure out the smallest index at which
- // an object should be inserted so as to maintain order. Uses binary search.
- _.sortedIndex = function(array, obj, iterator, context) {
- iterator = iterator == null ? _.identity : lookupIterator(iterator);
- var value = iterator.call(context, obj);
- var low = 0, high = array.length;
- while (low < high) {
- var mid = (low + high) >>> 1;
- iterator.call(context, array[mid]) < value ? low = mid + 1 : high = mid;
- }
- return low;
- };
-
- // Safely convert anything iterable into a real, live array.
- _.toArray = function(obj) {
- if (!obj) return [];
- if (_.isArray(obj)) return slice.call(obj);
- if (obj.length === +obj.length) return _.map(obj, _.identity);
- return _.values(obj);
- };
-
- // Return the number of elements in an object.
- _.size = function(obj) {
- if (obj == null) return 0;
- return (obj.length === +obj.length) ? obj.length : _.keys(obj).length;
- };
-
- // Array Functions
- // ---------------
-
- // Get the first element of an array. Passing **n** will return the first N
- // values in the array. Aliased as `head` and `take`. The **guard** check
- // allows it to work with `_.map`.
- _.first = _.head = _.take = function(array, n, guard) {
- if (array == null) return void 0;
- return (n != null) && !guard ? slice.call(array, 0, n) : array[0];
- };
-
- // Returns everything but the last entry of the array. Especially useful on
- // the arguments object. Passing **n** will return all the values in
- // the array, excluding the last N. The **guard** check allows it to work with
- // `_.map`.
- _.initial = function(array, n, guard) {
- return slice.call(array, 0, array.length - ((n == null) || guard ? 1 : n));
- };
-
- // Get the last element of an array. Passing **n** will return the last N
- // values in the array. The **guard** check allows it to work with `_.map`.
- _.last = function(array, n, guard) {
- if (array == null) return void 0;
- if ((n != null) && !guard) {
- return slice.call(array, Math.max(array.length - n, 0));
- } else {
- return array[array.length - 1];
- }
- };
-
- // Returns everything but the first entry of the array. Aliased as `tail` and `drop`.
- // Especially useful on the arguments object. Passing an **n** will return
- // the rest N values in the array. The **guard**
- // check allows it to work with `_.map`.
- _.rest = _.tail = _.drop = function(array, n, guard) {
- return slice.call(array, (n == null) || guard ? 1 : n);
- };
-
- // Trim out all falsy values from an array.
- _.compact = function(array) {
- return _.filter(array, _.identity);
- };
-
- // Internal implementation of a recursive `flatten` function.
- var flatten = function(input, shallow, output) {
- each(input, function(value) {
- if (_.isArray(value)) {
- shallow ? push.apply(output, value) : flatten(value, shallow, output);
- } else {
- output.push(value);
- }
- });
- return output;
- };
-
- // Return a completely flattened version of an array.
- _.flatten = function(array, shallow) {
- return flatten(array, shallow, []);
- };
-
- // Return a version of the array that does not contain the specified value(s).
- _.without = function(array) {
- return _.difference(array, slice.call(arguments, 1));
- };
-
- // Produce a duplicate-free version of the array. If the array has already
- // been sorted, you have the option of using a faster algorithm.
- // Aliased as `unique`.
- _.uniq = _.unique = function(array, isSorted, iterator, context) {
- if (_.isFunction(isSorted)) {
- context = iterator;
- iterator = isSorted;
- isSorted = false;
- }
- var initial = iterator ? _.map(array, iterator, context) : array;
- var results = [];
- var seen = [];
- each(initial, function(value, index) {
- if (isSorted ? (!index || seen[seen.length - 1] !== value) : !_.contains(seen, value)) {
- seen.push(value);
- results.push(array[index]);
- }
- });
- return results;
- };
-
- // Produce an array that contains the union: each distinct element from all of
- // the passed-in arrays.
- _.union = function() {
- return _.uniq(concat.apply(ArrayProto, arguments));
- };
-
- // Produce an array that contains every item shared between all the
- // passed-in arrays.
- _.intersection = function(array) {
- var rest = slice.call(arguments, 1);
- return _.filter(_.uniq(array), function(item) {
- return _.every(rest, function(other) {
- return _.indexOf(other, item) >= 0;
- });
- });
- };
-
- // Take the difference between one array and a number of other arrays.
- // Only the elements present in just the first array will remain.
- _.difference = function(array) {
- var rest = concat.apply(ArrayProto, slice.call(arguments, 1));
- return _.filter(array, function(value){ return !_.contains(rest, value); });
- };
-
- // Zip together multiple lists into a single array -- elements that share
- // an index go together.
- _.zip = function() {
- var args = slice.call(arguments);
- var length = _.max(_.pluck(args, 'length'));
- var results = new Array(length);
- for (var i = 0; i < length; i++) {
- results[i] = _.pluck(args, "" + i);
- }
- return results;
- };
-
- // Converts lists into objects. Pass either a single array of `[key, value]`
- // pairs, or two parallel arrays of the same length -- one of keys, and one of
- // the corresponding values.
- _.object = function(list, values) {
- if (list == null) return {};
- var result = {};
- for (var i = 0, l = list.length; i < l; i++) {
- if (values) {
- result[list[i]] = values[i];
- } else {
- result[list[i][0]] = list[i][1];
- }
- }
- return result;
- };
-
- // If the browser doesn't supply us with indexOf (I'm looking at you, **MSIE**),
- // we need this function. Return the position of the first occurrence of an
- // item in an array, or -1 if the item is not included in the array.
- // Delegates to **ECMAScript 5**'s native `indexOf` if available.
- // If the array is large and already in sort order, pass `true`
- // for **isSorted** to use binary search.
- _.indexOf = function(array, item, isSorted) {
- if (array == null) return -1;
- var i = 0, l = array.length;
- if (isSorted) {
- if (typeof isSorted == 'number') {
- i = (isSorted < 0 ? Math.max(0, l + isSorted) : isSorted);
- } else {
- i = _.sortedIndex(array, item);
- return array[i] === item ? i : -1;
- }
- }
- if (nativeIndexOf && array.indexOf === nativeIndexOf) return array.indexOf(item, isSorted);
- for (; i < l; i++) if (array[i] === item) return i;
- return -1;
- };
-
- // Delegates to **ECMAScript 5**'s native `lastIndexOf` if available.
- _.lastIndexOf = function(array, item, from) {
- if (array == null) return -1;
- var hasIndex = from != null;
- if (nativeLastIndexOf && array.lastIndexOf === nativeLastIndexOf) {
- return hasIndex ? array.lastIndexOf(item, from) : array.lastIndexOf(item);
- }
- var i = (hasIndex ? from : array.length);
- while (i--) if (array[i] === item) return i;
- return -1;
- };
-
- // Generate an integer Array containing an arithmetic progression. A port of
- // the native Python `range()` function. See
- // [the Python documentation](http://docs.python.org/library/functions.html#range).
- _.range = function(start, stop, step) {
- if (arguments.length <= 1) {
- stop = start || 0;
- start = 0;
- }
- step = arguments[2] || 1;
-
- var len = Math.max(Math.ceil((stop - start) / step), 0);
- var idx = 0;
- var range = new Array(len);
-
- while(idx < len) {
- range[idx++] = start;
- start += step;
- }
-
- return range;
- };
-
- // Function (ahem) Functions
- // ------------------
-
- // Create a function bound to a given object (assigning `this`, and arguments,
- // optionally). Delegates to **ECMAScript 5**'s native `Function.bind` if
- // available.
- _.bind = function(func, context) {
- if (func.bind === nativeBind && nativeBind) return nativeBind.apply(func, slice.call(arguments, 1));
- var args = slice.call(arguments, 2);
- return function() {
- return func.apply(context, args.concat(slice.call(arguments)));
- };
- };
-
- // Partially apply a function by creating a version that has had some of its
- // arguments pre-filled, without changing its dynamic `this` context.
- _.partial = function(func) {
- var args = slice.call(arguments, 1);
- return function() {
- return func.apply(this, args.concat(slice.call(arguments)));
- };
- };
-
- // Bind all of an object's methods to that object. Useful for ensuring that
- // all callbacks defined on an object belong to it.
- _.bindAll = function(obj) {
- var funcs = slice.call(arguments, 1);
- if (funcs.length === 0) funcs = _.functions(obj);
- each(funcs, function(f) { obj[f] = _.bind(obj[f], obj); });
- return obj;
- };
-
- // Memoize an expensive function by storing its results.
- _.memoize = function(func, hasher) {
- var memo = {};
- hasher || (hasher = _.identity);
- return function() {
- var key = hasher.apply(this, arguments);
- return _.has(memo, key) ? memo[key] : (memo[key] = func.apply(this, arguments));
- };
- };
-
- // Delays a function for the given number of milliseconds, and then calls
- // it with the arguments supplied.
- _.delay = function(func, wait) {
- var args = slice.call(arguments, 2);
- return setTimeout(function(){ return func.apply(null, args); }, wait);
- };
-
- // Defers a function, scheduling it to run after the current call stack has
- // cleared.
- _.defer = function(func) {
- return _.delay.apply(_, [func, 1].concat(slice.call(arguments, 1)));
- };
-
- // Returns a function, that, when invoked, will only be triggered at most once
- // during a given window of time.
- _.throttle = function(func, wait) {
- var context, args, timeout, result;
- var previous = 0;
- var later = function() {
- previous = new Date;
- timeout = null;
- result = func.apply(context, args);
- };
- return function() {
- var now = new Date;
- var remaining = wait - (now - previous);
- context = this;
- args = arguments;
- if (remaining <= 0) {
- clearTimeout(timeout);
- timeout = null;
- previous = now;
- result = func.apply(context, args);
- } else if (!timeout) {
- timeout = setTimeout(later, remaining);
- }
- return result;
- };
- };
-
- // Returns a function, that, as long as it continues to be invoked, will not
- // be triggered. The function will be called after it stops being called for
- // N milliseconds. If `immediate` is passed, trigger the function on the
- // leading edge, instead of the trailing.
- _.debounce = function(func, wait, immediate) {
- var timeout, result;
- return function() {
- var context = this, args = arguments;
- var later = function() {
- timeout = null;
- if (!immediate) result = func.apply(context, args);
- };
- var callNow = immediate && !timeout;
- clearTimeout(timeout);
- timeout = setTimeout(later, wait);
- if (callNow) result = func.apply(context, args);
- return result;
- };
- };
-
- // Returns a function that will be executed at most one time, no matter how
- // often you call it. Useful for lazy initialization.
- _.once = function(func) {
- var ran = false, memo;
- return function() {
- if (ran) return memo;
- ran = true;
- memo = func.apply(this, arguments);
- func = null;
- return memo;
- };
- };
-
- // Returns the first function passed as an argument to the second,
- // allowing you to adjust arguments, run code before and after, and
- // conditionally execute the original function.
- _.wrap = function(func, wrapper) {
- return function() {
- var args = [func];
- push.apply(args, arguments);
- return wrapper.apply(this, args);
- };
- };
-
- // Returns a function that is the composition of a list of functions, each
- // consuming the return value of the function that follows.
- _.compose = function() {
- var funcs = arguments;
- return function() {
- var args = arguments;
- for (var i = funcs.length - 1; i >= 0; i--) {
- args = [funcs[i].apply(this, args)];
- }
- return args[0];
- };
- };
-
- // Returns a function that will only be executed after being called N times.
- _.after = function(times, func) {
- if (times <= 0) return func();
- return function() {
- if (--times < 1) {
- return func.apply(this, arguments);
- }
- };
- };
-
- // Object Functions
- // ----------------
-
- // Retrieve the names of an object's properties.
- // Delegates to **ECMAScript 5**'s native `Object.keys`
- _.keys = nativeKeys || function(obj) {
- if (obj !== Object(obj)) throw new TypeError('Invalid object');
- var keys = [];
- for (var key in obj) if (_.has(obj, key)) keys[keys.length] = key;
- return keys;
- };
-
- // Retrieve the values of an object's properties.
- _.values = function(obj) {
- var values = [];
- for (var key in obj) if (_.has(obj, key)) values.push(obj[key]);
- return values;
- };
-
- // Convert an object into a list of `[key, value]` pairs.
- _.pairs = function(obj) {
- var pairs = [];
- for (var key in obj) if (_.has(obj, key)) pairs.push([key, obj[key]]);
- return pairs;
- };
-
- // Invert the keys and values of an object. The values must be serializable.
- _.invert = function(obj) {
- var result = {};
- for (var key in obj) if (_.has(obj, key)) result[obj[key]] = key;
- return result;
- };
-
- // Return a sorted list of the function names available on the object.
- // Aliased as `methods`
- _.functions = _.methods = function(obj) {
- var names = [];
- for (var key in obj) {
- if (_.isFunction(obj[key])) names.push(key);
- }
- return names.sort();
- };
-
- // Extend a given object with all the properties in passed-in object(s).
- _.extend = function(obj) {
- each(slice.call(arguments, 1), function(source) {
- if (source) {
- for (var prop in source) {
- obj[prop] = source[prop];
- }
- }
- });
- return obj;
- };
-
- // Return a copy of the object only containing the whitelisted properties.
- _.pick = function(obj) {
- var copy = {};
- var keys = concat.apply(ArrayProto, slice.call(arguments, 1));
- each(keys, function(key) {
- if (key in obj) copy[key] = obj[key];
- });
- return copy;
- };
-
- // Return a copy of the object without the blacklisted properties.
- _.omit = function(obj) {
- var copy = {};
- var keys = concat.apply(ArrayProto, slice.call(arguments, 1));
- for (var key in obj) {
- if (!_.contains(keys, key)) copy[key] = obj[key];
- }
- return copy;
- };
-
- // Fill in a given object with default properties.
- _.defaults = function(obj) {
- each(slice.call(arguments, 1), function(source) {
- if (source) {
- for (var prop in source) {
- if (obj[prop] == null) obj[prop] = source[prop];
- }
- }
- });
- return obj;
- };
-
- // Create a (shallow-cloned) duplicate of an object.
- _.clone = function(obj) {
- if (!_.isObject(obj)) return obj;
- return _.isArray(obj) ? obj.slice() : _.extend({}, obj);
- };
-
- // Invokes interceptor with the obj, and then returns obj.
- // The primary purpose of this method is to "tap into" a method chain, in
- // order to perform operations on intermediate results within the chain.
- _.tap = function(obj, interceptor) {
- interceptor(obj);
- return obj;
- };
-
- // Internal recursive comparison function for `isEqual`.
- var eq = function(a, b, aStack, bStack) {
- // Identical objects are equal. `0 === -0`, but they aren't identical.
- // See the Harmony `egal` proposal: http://wiki.ecmascript.org/doku.php?id=harmony:egal.
- if (a === b) return a !== 0 || 1 / a == 1 / b;
- // A strict comparison is necessary because `null == undefined`.
- if (a == null || b == null) return a === b;
- // Unwrap any wrapped objects.
- if (a instanceof _) a = a._wrapped;
- if (b instanceof _) b = b._wrapped;
- // Compare `[[Class]]` names.
- var className = toString.call(a);
- if (className != toString.call(b)) return false;
- switch (className) {
- // Strings, numbers, dates, and booleans are compared by value.
- case '[object String]':
- // Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is
- // equivalent to `new String("5")`.
- return a == String(b);
- case '[object Number]':
- // `NaN`s are equivalent, but non-reflexive. An `egal` comparison is performed for
- // other numeric values.
- return a != +a ? b != +b : (a == 0 ? 1 / a == 1 / b : a == +b);
- case '[object Date]':
- case '[object Boolean]':
- // Coerce dates and booleans to numeric primitive values. Dates are compared by their
- // millisecond representations. Note that invalid dates with millisecond representations
- // of `NaN` are not equivalent.
- return +a == +b;
- // RegExps are compared by their source patterns and flags.
- case '[object RegExp]':
- return a.source == b.source &&
- a.global == b.global &&
- a.multiline == b.multiline &&
- a.ignoreCase == b.ignoreCase;
- }
- if (typeof a != 'object' || typeof b != 'object') return false;
- // Assume equality for cyclic structures. The algorithm for detecting cyclic
- // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`.
- var length = aStack.length;
- while (length--) {
- // Linear search. Performance is inversely proportional to the number of
- // unique nested structures.
- if (aStack[length] == a) return bStack[length] == b;
- }
- // Add the first object to the stack of traversed objects.
- aStack.push(a);
- bStack.push(b);
- var size = 0, result = true;
- // Recursively compare objects and arrays.
- if (className == '[object Array]') {
- // Compare array lengths to determine if a deep comparison is necessary.
- size = a.length;
- result = size == b.length;
- if (result) {
- // Deep compare the contents, ignoring non-numeric properties.
- while (size--) {
- if (!(result = eq(a[size], b[size], aStack, bStack))) break;
- }
- }
- } else {
- // Objects with different constructors are not equivalent, but `Object`s
- // from different frames are.
- var aCtor = a.constructor, bCtor = b.constructor;
- if (aCtor !== bCtor && !(_.isFunction(aCtor) && (aCtor instanceof aCtor) &&
- _.isFunction(bCtor) && (bCtor instanceof bCtor))) {
- return false;
- }
- // Deep compare objects.
- for (var key in a) {
- if (_.has(a, key)) {
- // Count the expected number of properties.
- size++;
- // Deep compare each member.
- if (!(result = _.has(b, key) && eq(a[key], b[key], aStack, bStack))) break;
- }
- }
- // Ensure that both objects contain the same number of properties.
- if (result) {
- for (key in b) {
- if (_.has(b, key) && !(size--)) break;
- }
- result = !size;
- }
- }
- // Remove the first object from the stack of traversed objects.
- aStack.pop();
- bStack.pop();
- return result;
- };
-
- // Perform a deep comparison to check if two objects are equal.
- _.isEqual = function(a, b) {
- return eq(a, b, [], []);
- };
-
- // Is a given array, string, or object empty?
- // An "empty" object has no enumerable own-properties.
- _.isEmpty = function(obj) {
- if (obj == null) return true;
- if (_.isArray(obj) || _.isString(obj)) return obj.length === 0;
- for (var key in obj) if (_.has(obj, key)) return false;
- return true;
- };
-
- // Is a given value a DOM element?
- _.isElement = function(obj) {
- return !!(obj && obj.nodeType === 1);
- };
-
- // Is a given value an array?
- // Delegates to ECMA5's native Array.isArray
- _.isArray = nativeIsArray || function(obj) {
- return toString.call(obj) == '[object Array]';
- };
-
- // Is a given variable an object?
- _.isObject = function(obj) {
- return obj === Object(obj);
- };
-
- // Add some isType methods: isArguments, isFunction, isString, isNumber, isDate, isRegExp.
- each(['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp'], function(name) {
- _['is' + name] = function(obj) {
- return toString.call(obj) == '[object ' + name + ']';
- };
- });
-
- // Define a fallback version of the method in browsers (ahem, IE), where
- // there isn't any inspectable "Arguments" type.
- if (!_.isArguments(arguments)) {
- _.isArguments = function(obj) {
- return !!(obj && _.has(obj, 'callee'));
- };
- }
-
- // Optimize `isFunction` if appropriate.
- if (typeof (/./) !== 'function') {
- _.isFunction = function(obj) {
- return typeof obj === 'function';
- };
- }
-
- // Is a given object a finite number?
- _.isFinite = function(obj) {
- return isFinite(obj) && !isNaN(parseFloat(obj));
- };
-
- // Is the given value `NaN`? (NaN is the only number which does not equal itself).
- _.isNaN = function(obj) {
- return _.isNumber(obj) && obj != +obj;
- };
-
- // Is a given value a boolean?
- _.isBoolean = function(obj) {
- return obj === true || obj === false || toString.call(obj) == '[object Boolean]';
- };
-
- // Is a given value equal to null?
- _.isNull = function(obj) {
- return obj === null;
- };
-
- // Is a given variable undefined?
- _.isUndefined = function(obj) {
- return obj === void 0;
- };
-
- // Shortcut function for checking if an object has a given property directly
- // on itself (in other words, not on a prototype).
- _.has = function(obj, key) {
- return hasOwnProperty.call(obj, key);
- };
-
- // Utility Functions
- // -----------------
-
- // Run Underscore.js in *noConflict* mode, returning the `_` variable to its
- // previous owner. Returns a reference to the Underscore object.
- _.noConflict = function() {
- root._ = previousUnderscore;
- return this;
- };
-
- // Keep the identity function around for default iterators.
- _.identity = function(value) {
- return value;
- };
-
- // Run a function **n** times.
- _.times = function(n, iterator, context) {
- var accum = Array(n);
- for (var i = 0; i < n; i++) accum[i] = iterator.call(context, i);
- return accum;
- };
-
- // Return a random integer between min and max (inclusive).
- _.random = function(min, max) {
- if (max == null) {
- max = min;
- min = 0;
- }
- return min + Math.floor(Math.random() * (max - min + 1));
- };
-
- // List of HTML entities for escaping.
- var entityMap = {
- escape: {
- '&': '&amp;',
- '<': '&lt;',
- '>': '&gt;',
- '"': '&quot;',
- "'": '&#x27;',
- '/': '&#x2F;'
- }
- };
- entityMap.unescape = _.invert(entityMap.escape);
-
- // Regexes containing the keys and values listed immediately above.
- var entityRegexes = {
- escape: new RegExp('[' + _.keys(entityMap.escape).join('') + ']', 'g'),
- unescape: new RegExp('(' + _.keys(entityMap.unescape).join('|') + ')', 'g')
- };
-
- // Functions for escaping and unescaping strings to/from HTML interpolation.
- _.each(['escape', 'unescape'], function(method) {
- _[method] = function(string) {
- if (string == null) return '';
- return ('' + string).replace(entityRegexes[method], function(match) {
- return entityMap[method][match];
- });
- };
- });
-
- // If the value of the named property is a function then invoke it;
- // otherwise, return it.
- _.result = function(object, property) {
- if (object == null) return null;
- var value = object[property];
- return _.isFunction(value) ? value.call(object) : value;
- };
-
- // Add your own custom functions to the Underscore object.
- _.mixin = function(obj) {
- each(_.functions(obj), function(name){
- var func = _[name] = obj[name];
- _.prototype[name] = function() {
- var args = [this._wrapped];
- push.apply(args, arguments);
- return result.call(this, func.apply(_, args));
- };
- });
- };
-
- // Generate a unique integer id (unique within the entire client session).
- // Useful for temporary DOM ids.
- var idCounter = 0;
- _.uniqueId = function(prefix) {
- var id = ++idCounter + '';
- return prefix ? prefix + id : id;
- };
-
- // By default, Underscore uses ERB-style template delimiters, change the
- // following template settings to use alternative delimiters.
- _.templateSettings = {
- evaluate : /<%([\s\S]+?)%>/g,
- interpolate : /<%=([\s\S]+?)%>/g,
- escape : /<%-([\s\S]+?)%>/g
- };
-
- // When customizing `templateSettings`, if you don't want to define an
- // interpolation, evaluation or escaping regex, we need one that is
- // guaranteed not to match.
- var noMatch = /(.)^/;
-
- // Certain characters need to be escaped so that they can be put into a
- // string literal.
- var escapes = {
- "'": "'",
- '\\': '\\',
- '\r': 'r',
- '\n': 'n',
- '\t': 't',
- '\u2028': 'u2028',
- '\u2029': 'u2029'
- };
-
- var escaper = /\\|'|\r|\n|\t|\u2028|\u2029/g;
-
- // JavaScript micro-templating, similar to John Resig's implementation.
- // Underscore templating handles arbitrary delimiters, preserves whitespace,
- // and correctly escapes quotes within interpolated code.
- _.template = function(text, data, settings) {
- var render;
- settings = _.defaults({}, settings, _.templateSettings);
-
- // Combine delimiters into one regular expression via alternation.
- var matcher = new RegExp([
- (settings.escape || noMatch).source,
- (settings.interpolate || noMatch).source,
- (settings.evaluate || noMatch).source
- ].join('|') + '|$', 'g');
-
- // Compile the template source, escaping string literals appropriately.
- var index = 0;
- var source = "__p+='";
- text.replace(matcher, function(match, escape, interpolate, evaluate, offset) {
- source += text.slice(index, offset)
- .replace(escaper, function(match) { return '\\' + escapes[match]; });
-
- if (escape) {
- source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'";
- }
- if (interpolate) {
- source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'";
- }
- if (evaluate) {
- source += "';\n" + evaluate + "\n__p+='";
- }
- index = offset + match.length;
- return match;
- });
- source += "';\n";
-
- // If a variable is not specified, place data values in local scope.
- if (!settings.variable) source = 'with(obj||{}){\n' + source + '}\n';
-
- source = "var __t,__p='',__j=Array.prototype.join," +
- "print=function(){__p+=__j.call(arguments,'');};\n" +
- source + "return __p;\n";
-
- try {
- render = new Function(settings.variable || 'obj', '_', source);
- } catch (e) {
- e.source = source;
- throw e;
- }
-
- if (data) return render(data, _);
- var template = function(data) {
- return render.call(this, data, _);
- };
-
- // Provide the compiled function source as a convenience for precompilation.
- template.source = 'function(' + (settings.variable || 'obj') + '){\n' + source + '}';
-
- return template;
- };
-
- // Add a "chain" function, which will delegate to the wrapper.
- _.chain = function(obj) {
- return _(obj).chain();
- };
-
- // OOP
- // ---------------
- // If Underscore is called as a function, it returns a wrapped object that
- // can be used OO-style. This wrapper holds altered versions of all the
- // underscore functions. Wrapped objects may be chained.
-
- // Helper function to continue chaining intermediate results.
- var result = function(obj) {
- return this._chain ? _(obj).chain() : obj;
- };
-
- // Add all of the Underscore functions to the wrapper object.
- _.mixin(_);
-
- // Add all mutator Array functions to the wrapper.
- each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) {
- var method = ArrayProto[name];
- _.prototype[name] = function() {
- var obj = this._wrapped;
- method.apply(obj, arguments);
- if ((name == 'shift' || name == 'splice') && obj.length === 0) delete obj[0];
- return result.call(this, obj);
- };
- });
-
- // Add all accessor Array functions to the wrapper.
- each(['concat', 'join', 'slice'], function(name) {
- var method = ArrayProto[name];
- _.prototype[name] = function() {
- return result.call(this, method.apply(this._wrapped, arguments));
- };
- });
-
- _.extend(_.prototype, {
-
- // Start chaining a wrapped Underscore object.
- chain: function() {
- this._chain = true;
- return this;
- },
-
- // Extracts the result from a wrapped and chained object.
- value: function() {
- return this._wrapped;
- }
-
- });
-
-}).call(this);
-
-})()
-},{}],14:[function(require,module,exports){
-exports.readIEEE754 = function(buffer, offset, isBE, mLen, nBytes) {
- var e, m,
- eLen = nBytes * 8 - mLen - 1,
- eMax = (1 << eLen) - 1,
- eBias = eMax >> 1,
- nBits = -7,
- i = isBE ? 0 : (nBytes - 1),
- d = isBE ? 1 : -1,
- s = buffer[offset + i];
-
- i += d;
-
- e = s & ((1 << (-nBits)) - 1);
- s >>= (-nBits);
- nBits += eLen;
- for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8);
-
- m = e & ((1 << (-nBits)) - 1);
- e >>= (-nBits);
- nBits += mLen;
- for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8);
-
- if (e === 0) {
- e = 1 - eBias;
- } else if (e === eMax) {
- return m ? NaN : ((s ? -1 : 1) * Infinity);
- } else {
- m = m + Math.pow(2, mLen);
- e = e - eBias;
- }
- return (s ? -1 : 1) * m * Math.pow(2, e - mLen);
-};
-
-exports.writeIEEE754 = function(buffer, value, offset, isBE, mLen, nBytes) {
- var e, m, c,
- eLen = nBytes * 8 - mLen - 1,
- eMax = (1 << eLen) - 1,
- eBias = eMax >> 1,
- rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0),
- i = isBE ? (nBytes - 1) : 0,
- d = isBE ? -1 : 1,
- s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0;
-
- value = Math.abs(value);
-
- if (isNaN(value) || value === Infinity) {
- m = isNaN(value) ? 1 : 0;
- e = eMax;
- } else {
- e = Math.floor(Math.log(value) / Math.LN2);
- if (value * (c = Math.pow(2, -e)) < 1) {
- e--;
- c *= 2;
- }
- if (e + eBias >= 1) {
- value += rt / c;
- } else {
- value += rt * Math.pow(2, 1 - eBias);
- }
- if (value * c >= 2) {
- e++;
- c /= 2;
- }
-
- if (e + eBias >= eMax) {
- m = 0;
- e = eMax;
- } else if (e + eBias >= 1) {
- m = (value * c - 1) * Math.pow(2, mLen);
- e = e + eBias;
- } else {
- m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen);
- e = 0;
- }
- }
-
- for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8);
-
- e = (e << mLen) | m;
- eLen += mLen;
- for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8);
-
- buffer[offset + i - d] |= s * 128;
-};
-
-},{}],13:[function(require,module,exports){
-(function(){function SlowBuffer (size) {
- this.length = size;
-};
-
-var assert = require('assert');
-
-exports.INSPECT_MAX_BYTES = 50;
-
-
-function toHex(n) {
- if (n < 16) return '0' + n.toString(16);
- return n.toString(16);
-}
-
-function utf8ToBytes(str) {
- var byteArray = [];
- for (var i = 0; i < str.length; i++)
- if (str.charCodeAt(i) <= 0x7F)
- byteArray.push(str.charCodeAt(i));
- else {
- var h = encodeURIComponent(str.charAt(i)).substr(1).split('%');
- for (var j = 0; j < h.length; j++)
- byteArray.push(parseInt(h[j], 16));
- }
-
- return byteArray;
-}
-
-function asciiToBytes(str) {
- var byteArray = []
- for (var i = 0; i < str.length; i++ )
- // Node's code seems to be doing this and not & 0x7F..
- byteArray.push( str.charCodeAt(i) & 0xFF );
-
- return byteArray;
-}
-
-function base64ToBytes(str) {
- return require("base64-js").toByteArray(str);
-}
-
-SlowBuffer.byteLength = function (str, encoding) {
- switch (encoding || "utf8") {
- case 'hex':
- return str.length / 2;
-
- case 'utf8':
- case 'utf-8':
- return utf8ToBytes(str).length;
-
- case 'ascii':
- case 'binary':
- return str.length;
-
- case 'base64':
- return base64ToBytes(str).length;
-
- default:
- throw new Error('Unknown encoding');
- }
-};
-
-function blitBuffer(src, dst, offset, length) {
- var pos, i = 0;
- while (i < length) {
- if ((i+offset >= dst.length) || (i >= src.length))
- break;
-
- dst[i + offset] = src[i];
- i++;
- }
- return i;
-}
-
-SlowBuffer.prototype.utf8Write = function (string, offset, length) {
- var bytes, pos;
- return SlowBuffer._charsWritten = blitBuffer(utf8ToBytes(string), this, offset, length);
-};
-
-SlowBuffer.prototype.asciiWrite = function (string, offset, length) {
- var bytes, pos;
- return SlowBuffer._charsWritten = blitBuffer(asciiToBytes(string), this, offset, length);
-};
-
-SlowBuffer.prototype.binaryWrite = SlowBuffer.prototype.asciiWrite;
-
-SlowBuffer.prototype.base64Write = function (string, offset, length) {
- var bytes, pos;
- return SlowBuffer._charsWritten = blitBuffer(base64ToBytes(string), this, offset, length);
-};
-
-SlowBuffer.prototype.base64Slice = function (start, end) {
- var bytes = Array.prototype.slice.apply(this, arguments)
- return require("base64-js").fromByteArray(bytes);
-}
-
-function decodeUtf8Char(str) {
- try {
- return decodeURIComponent(str);
- } catch (err) {
- return String.fromCharCode(0xFFFD); // UTF 8 invalid char
- }
-}
-
-SlowBuffer.prototype.utf8Slice = function () {
- var bytes = Array.prototype.slice.apply(this, arguments);
- var res = "";
- var tmp = "";
- var i = 0;
- while (i < bytes.length) {
- if (bytes[i] <= 0x7F) {
- res += decodeUtf8Char(tmp) + String.fromCharCode(bytes[i]);
- tmp = "";
- } else
- tmp += "%" + bytes[i].toString(16);
-
- i++;
- }
-
- return res + decodeUtf8Char(tmp);
-}
-
-SlowBuffer.prototype.asciiSlice = function () {
- var bytes = Array.prototype.slice.apply(this, arguments);
- var ret = "";
- for (var i = 0; i < bytes.length; i++)
- ret += String.fromCharCode(bytes[i]);
- return ret;
-}
-
-SlowBuffer.prototype.binarySlice = SlowBuffer.prototype.asciiSlice;
-
-SlowBuffer.prototype.inspect = function() {
- var out = [],
- len = this.length;
- for (var i = 0; i < len; i++) {
- out[i] = toHex(this[i]);
- if (i == exports.INSPECT_MAX_BYTES) {
- out[i + 1] = '...';
- break;
- }
- }
- return '<SlowBuffer ' + out.join(' ') + '>';
-};
-
-
-SlowBuffer.prototype.hexSlice = function(start, end) {
- var len = this.length;
-
- if (!start || start < 0) start = 0;
- if (!end || end < 0 || end > len) end = len;
-
- var out = '';
- for (var i = start; i < end; i++) {
- out += toHex(this[i]);
- }
- return out;
-};
-
-
-SlowBuffer.prototype.toString = function(encoding, start, end) {
- encoding = String(encoding || 'utf8').toLowerCase();
- start = +start || 0;
- if (typeof end == 'undefined') end = this.length;
-
- // Fastpath empty strings
- if (+end == start) {
- return '';
- }
-
- switch (encoding) {
- case 'hex':
- return this.hexSlice(start, end);
-
- case 'utf8':
- case 'utf-8':
- return this.utf8Slice(start, end);
-
- case 'ascii':
- return this.asciiSlice(start, end);
-
- case 'binary':
- return this.binarySlice(start, end);
-
- case 'base64':
- return this.base64Slice(start, end);
-
- case 'ucs2':
- case 'ucs-2':
- return this.ucs2Slice(start, end);
-
- default:
- throw new Error('Unknown encoding');
- }
-};
-
-
-SlowBuffer.prototype.hexWrite = function(string, offset, length) {
- offset = +offset || 0;
- var remaining = this.length - offset;
- if (!length) {
- length = remaining;
- } else {
- length = +length;
- if (length > remaining) {
- length = remaining;
- }
- }
-
- // must be an even number of digits
- var strLen = string.length;
- if (strLen % 2) {
- throw new Error('Invalid hex string');
- }
- if (length > strLen / 2) {
- length = strLen / 2;
- }
- for (var i = 0; i < length; i++) {
- var byte = parseInt(string.substr(i * 2, 2), 16);
- if (isNaN(byte)) throw new Error('Invalid hex string');
- this[offset + i] = byte;
- }
- SlowBuffer._charsWritten = i * 2;
- return i;
-};
-
-
-SlowBuffer.prototype.write = function(string, offset, length, encoding) {
- // Support both (string, offset, length, encoding)
- // and the legacy (string, encoding, offset, length)
- if (isFinite(offset)) {
- if (!isFinite(length)) {
- encoding = length;
- length = undefined;
- }
- } else { // legacy
- var swap = encoding;
- encoding = offset;
- offset = length;
- length = swap;
- }
-
- offset = +offset || 0;
- var remaining = this.length - offset;
- if (!length) {
- length = remaining;
- } else {
- length = +length;
- if (length > remaining) {
- length = remaining;
- }
- }
- encoding = String(encoding || 'utf8').toLowerCase();
-
- switch (encoding) {
- case 'hex':
- return this.hexWrite(string, offset, length);
-
- case 'utf8':
- case 'utf-8':
- return this.utf8Write(string, offset, length);
-
- case 'ascii':
- return this.asciiWrite(string, offset, length);
-
- case 'binary':
- return this.binaryWrite(string, offset, length);
-
- case 'base64':
- return this.base64Write(string, offset, length);
-
- case 'ucs2':
- case 'ucs-2':
- return this.ucs2Write(string, offset, length);
-
- default:
- throw new Error('Unknown encoding');
- }
-};
-
-
-// slice(start, end)
-SlowBuffer.prototype.slice = function(start, end) {
- if (end === undefined) end = this.length;
-
- if (end > this.length) {
- throw new Error('oob');
- }
- if (start > end) {
- throw new Error('oob');
- }
-
- return new Buffer(this, end - start, +start);
-};
-
-SlowBuffer.prototype.copy = function(target, targetstart, sourcestart, sourceend) {
- var temp = [];
- for (var i=sourcestart; i<sourceend; i++) {
- assert.ok(typeof this[i] !== 'undefined', "copying undefined buffer bytes!");
- temp.push(this[i]);
- }
-
- for (var i=targetstart; i<targetstart+temp.length; i++) {
- target[i] = temp[i-targetstart];
- }
-};
-
-SlowBuffer.prototype.fill = function(value, start, end) {
- if (end > this.length) {
- throw new Error('oob');
- }
- if (start > end) {
- throw new Error('oob');
- }
-
- for (var i = start; i < end; i++) {
- this[i] = value;
- }
-}
-
-function coerce(length) {
- // Coerce length to a number (possibly NaN), round up
- // in case it's fractional (e.g. 123.456) then do a
- // double negate to coerce a NaN to 0. Easy, right?
- length = ~~Math.ceil(+length);
- return length < 0 ? 0 : length;
-}
-
-
-// Buffer
-
-function Buffer(subject, encoding, offset) {
- if (!(this instanceof Buffer)) {
- return new Buffer(subject, encoding, offset);
- }
-
- var type;
-
- // Are we slicing?
- if (typeof offset === 'number') {
- this.length = coerce(encoding);
- this.parent = subject;
- this.offset = offset;
- } else {
- // Find the length
- switch (type = typeof subject) {
- case 'number':
- this.length = coerce(subject);
- break;
-
- case 'string':
- this.length = Buffer.byteLength(subject, encoding);
- break;
-
- case 'object': // Assume object is an array
- this.length = coerce(subject.length);
- break;
-
- default:
- throw new Error('First argument needs to be a number, ' +
- 'array or string.');
- }
-
- if (this.length > Buffer.poolSize) {
- // Big buffer, just alloc one.
- this.parent = new SlowBuffer(this.length);
- this.offset = 0;
-
- } else {
- // Small buffer.
- if (!pool || pool.length - pool.used < this.length) allocPool();
- this.parent = pool;
- this.offset = pool.used;
- pool.used += this.length;
- }
-
- // Treat array-ish objects as a byte array.
- if (isArrayIsh(subject)) {
- for (var i = 0; i < this.length; i++) {
- if (subject instanceof Buffer) {
- this.parent[i + this.offset] = subject.readUInt8(i);
- }
- else {
- this.parent[i + this.offset] = subject[i];
- }
- }
- } else if (type == 'string') {
- // We are a string
- this.length = this.write(subject, 0, encoding);
- }
- }
-
-}
-
-function isArrayIsh(subject) {
- return Array.isArray(subject) || Buffer.isBuffer(subject) ||
- subject && typeof subject === 'object' &&
- typeof subject.length === 'number';
-}
-
-exports.SlowBuffer = SlowBuffer;
-exports.Buffer = Buffer;
-
-Buffer.poolSize = 8 * 1024;
-var pool;
-
-function allocPool() {
- pool = new SlowBuffer(Buffer.poolSize);
- pool.used = 0;
-}
-
-
-// Static methods
-Buffer.isBuffer = function isBuffer(b) {
- return b instanceof Buffer || b instanceof SlowBuffer;
-};
-
-Buffer.concat = function (list, totalLength) {
- if (!Array.isArray(list)) {
- throw new Error("Usage: Buffer.concat(list, [totalLength])\n \
- list should be an Array.");
- }
-
- if (list.length === 0) {
- return new Buffer(0);
- } else if (list.length === 1) {
- return list[0];
- }
-
- if (typeof totalLength !== 'number') {
- totalLength = 0;
- for (var i = 0; i < list.length; i++) {
- var buf = list[i];
- totalLength += buf.length;
- }
- }
-
- var buffer = new Buffer(totalLength);
- var pos = 0;
- for (var i = 0; i < list.length; i++) {
- var buf = list[i];
- buf.copy(buffer, pos);
- pos += buf.length;
- }
- return buffer;
-};
-
-// Inspect
-Buffer.prototype.inspect = function inspect() {
- var out = [],
- len = this.length;
-
- for (var i = 0; i < len; i++) {
- out[i] = toHex(this.parent[i + this.offset]);
- if (i == exports.INSPECT_MAX_BYTES) {
- out[i + 1] = '...';
- break;
- }
- }
-
- return '<Buffer ' + out.join(' ') + '>';
-};
-
-
-Buffer.prototype.get = function get(i) {
- if (i < 0 || i >= this.length) throw new Error('oob');
- return this.parent[this.offset + i];
-};
-
-
-Buffer.prototype.set = function set(i, v) {
- if (i < 0 || i >= this.length) throw new Error('oob');
- return this.parent[this.offset + i] = v;
-};
-
-
-// write(string, offset = 0, length = buffer.length-offset, encoding = 'utf8')
-Buffer.prototype.write = function(string, offset, length, encoding) {
- // Support both (string, offset, length, encoding)
- // and the legacy (string, encoding, offset, length)
- if (isFinite(offset)) {
- if (!isFinite(length)) {
- encoding = length;
- length = undefined;
- }
- } else { // legacy
- var swap = encoding;
- encoding = offset;
- offset = length;
- length = swap;
- }
-
- offset = +offset || 0;
- var remaining = this.length - offset;
- if (!length) {
- length = remaining;
- } else {
- length = +length;
- if (length > remaining) {
- length = remaining;
- }
- }
- encoding = String(encoding || 'utf8').toLowerCase();
-
- var ret;
- switch (encoding) {
- case 'hex':
- ret = this.parent.hexWrite(string, this.offset + offset, length);
- break;
-
- case 'utf8':
- case 'utf-8':
- ret = this.parent.utf8Write(string, this.offset + offset, length);
- break;
-
- case 'ascii':
- ret = this.parent.asciiWrite(string, this.offset + offset, length);
- break;
-
- case 'binary':
- ret = this.parent.binaryWrite(string, this.offset + offset, length);
- break;
-
- case 'base64':
- // Warning: maxLength not taken into account in base64Write
- ret = this.parent.base64Write(string, this.offset + offset, length);
- break;
-
- case 'ucs2':
- case 'ucs-2':
- ret = this.parent.ucs2Write(string, this.offset + offset, length);
- break;
-
- default:
- throw new Error('Unknown encoding');
- }
-
- Buffer._charsWritten = SlowBuffer._charsWritten;
-
- return ret;
-};
-
-
-// toString(encoding, start=0, end=buffer.length)
-Buffer.prototype.toString = function(encoding, start, end) {
- encoding = String(encoding || 'utf8').toLowerCase();
-
- if (typeof start == 'undefined' || start < 0) {
- start = 0;
- } else if (start > this.length) {
- start = this.length;
- }
-
- if (typeof end == 'undefined' || end > this.length) {
- end = this.length;
- } else if (end < 0) {
- end = 0;
- }
-
- start = start + this.offset;
- end = end + this.offset;
-
- switch (encoding) {
- case 'hex':
- return this.parent.hexSlice(start, end);
-
- case 'utf8':
- case 'utf-8':
- return this.parent.utf8Slice(start, end);
-
- case 'ascii':
- return this.parent.asciiSlice(start, end);
-
- case 'binary':
- return this.parent.binarySlice(start, end);
-
- case 'base64':
- return this.parent.base64Slice(start, end);
-
- case 'ucs2':
- case 'ucs-2':
- return this.parent.ucs2Slice(start, end);
-
- default:
- throw new Error('Unknown encoding');
- }
-};
-
-
-// byteLength
-Buffer.byteLength = SlowBuffer.byteLength;
-
-
-// fill(value, start=0, end=buffer.length)
-Buffer.prototype.fill = function fill(value, start, end) {
- value || (value = 0);
- start || (start = 0);
- end || (end = this.length);
-
- if (typeof value === 'string') {
- value = value.charCodeAt(0);
- }
- if (!(typeof value === 'number') || isNaN(value)) {
- throw new Error('value is not a number');
- }
-
- if (end < start) throw new Error('end < start');
-
- // Fill 0 bytes; we're done
- if (end === start) return 0;
- if (this.length == 0) return 0;
-
- if (start < 0 || start >= this.length) {
- throw new Error('start out of bounds');
- }
-
- if (end < 0 || end > this.length) {
- throw new Error('end out of bounds');
- }
-
- return this.parent.fill(value,
- start + this.offset,
- end + this.offset);
-};
-
-
-// copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length)
-Buffer.prototype.copy = function(target, target_start, start, end) {
- var source = this;
- start || (start = 0);
- end || (end = this.length);
- target_start || (target_start = 0);
-
- if (end < start) throw new Error('sourceEnd < sourceStart');
-
- // Copy 0 bytes; we're done
- if (end === start) return 0;
- if (target.length == 0 || source.length == 0) return 0;
-
- if (target_start < 0 || target_start >= target.length) {
- throw new Error('targetStart out of bounds');
- }
-
- if (start < 0 || start >= source.length) {
- throw new Error('sourceStart out of bounds');
- }
-
- if (end < 0 || end > source.length) {
- throw new Error('sourceEnd out of bounds');
- }
-
- // Are we oob?
- if (end > this.length) {
- end = this.length;
- }
-
- if (target.length - target_start < end - start) {
- end = target.length - target_start + start;
- }
-
- return this.parent.copy(target.parent,
- target_start + target.offset,
- start + this.offset,
- end + this.offset);
-};
-
-
-// slice(start, end)
-Buffer.prototype.slice = function(start, end) {
- if (end === undefined) end = this.length;
- if (end > this.length) throw new Error('oob');
- if (start > end) throw new Error('oob');
-
- return new Buffer(this.parent, end - start, +start + this.offset);
-};
-
-
-// Legacy methods for backwards compatibility.
-
-Buffer.prototype.utf8Slice = function(start, end) {
- return this.toString('utf8', start, end);
-};
-
-Buffer.prototype.binarySlice = function(start, end) {
- return this.toString('binary', start, end);
-};
-
-Buffer.prototype.asciiSlice = function(start, end) {
- return this.toString('ascii', start, end);
-};
-
-Buffer.prototype.utf8Write = function(string, offset) {
- return this.write(string, offset, 'utf8');
-};
-
-Buffer.prototype.binaryWrite = function(string, offset) {
- return this.write(string, offset, 'binary');
-};
-
-Buffer.prototype.asciiWrite = function(string, offset) {
- return this.write(string, offset, 'ascii');
-};
-
-Buffer.prototype.readUInt8 = function(offset, noAssert) {
- var buffer = this;
-
- if (!noAssert) {
- assert.ok(offset !== undefined && offset !== null,
- 'missing offset');
-
- assert.ok(offset < buffer.length,
- 'Trying to read beyond buffer length');
- }
-
- if (offset >= buffer.length) return;
-
- return buffer.parent[buffer.offset + offset];
-};
-
-function readUInt16(buffer, offset, isBigEndian, noAssert) {
- var val = 0;
-
-
- if (!noAssert) {
- assert.ok(typeof (isBigEndian) === 'boolean',
- 'missing or invalid endian');
-
- assert.ok(offset !== undefined && offset !== null,
- 'missing offset');
-
- assert.ok(offset + 1 < buffer.length,
- 'Trying to read beyond buffer length');
- }
-
- if (offset >= buffer.length) return 0;
-
- if (isBigEndian) {
- val = buffer.parent[buffer.offset + offset] << 8;
- if (offset + 1 < buffer.length) {
- val |= buffer.parent[buffer.offset + offset + 1];
- }
- } else {
- val = buffer.parent[buffer.offset + offset];
- if (offset + 1 < buffer.length) {
- val |= buffer.parent[buffer.offset + offset + 1] << 8;
- }
- }
-
- return val;
-}
-
-Buffer.prototype.readUInt16LE = function(offset, noAssert) {
- return readUInt16(this, offset, false, noAssert);
-};
-
-Buffer.prototype.readUInt16BE = function(offset, noAssert) {
- return readUInt16(this, offset, true, noAssert);
-};
-
-function readUInt32(buffer, offset, isBigEndian, noAssert) {
- var val = 0;
-
- if (!noAssert) {
- assert.ok(typeof (isBigEndian) === 'boolean',
- 'missing or invalid endian');
-
- assert.ok(offset !== undefined && offset !== null,
- 'missing offset');
-
- assert.ok(offset + 3 < buffer.length,
- 'Trying to read beyond buffer length');
- }
-
- if (offset >= buffer.length) return 0;
-
- if (isBigEndian) {
- if (offset + 1 < buffer.length)
- val = buffer.parent[buffer.offset + offset + 1] << 16;
- if (offset + 2 < buffer.length)
- val |= buffer.parent[buffer.offset + offset + 2] << 8;
- if (offset + 3 < buffer.length)
- val |= buffer.parent[buffer.offset + offset + 3];
- val = val + (buffer.parent[buffer.offset + offset] << 24 >>> 0);
- } else {
- if (offset + 2 < buffer.length)
- val = buffer.parent[buffer.offset + offset + 2] << 16;
- if (offset + 1 < buffer.length)
- val |= buffer.parent[buffer.offset + offset + 1] << 8;
- val |= buffer.parent[buffer.offset + offset];
- if (offset + 3 < buffer.length)
- val = val + (buffer.parent[buffer.offset + offset + 3] << 24 >>> 0);
- }
-
- return val;
-}
-
-Buffer.prototype.readUInt32LE = function(offset, noAssert) {
- return readUInt32(this, offset, false, noAssert);
-};
-
-Buffer.prototype.readUInt32BE = function(offset, noAssert) {
- return readUInt32(this, offset, true, noAssert);
-};
-
-
-/*
- * Signed integer types, yay team! A reminder on how two's complement actually
- * works. The first bit is the signed bit, i.e. tells us whether or not the
- * number should be positive or negative. If the two's complement value is
- * positive, then we're done, as it's equivalent to the unsigned representation.
- *
- * Now if the number is positive, you're pretty much done, you can just leverage
- * the unsigned translations and return those. Unfortunately, negative numbers
- * aren't quite that straightforward.
- *
- * At first glance, one might be inclined to use the traditional formula to
- * translate binary numbers between the positive and negative values in two's
- * complement. (Though it doesn't quite work for the most negative value)
- * Mainly:
- * - invert all the bits
- * - add one to the result
- *
- * Of course, this doesn't quite work in Javascript. Take for example the value
- * of -128. This could be represented in 16 bits (big-endian) as 0xff80. But of
- * course, Javascript will do the following:
- *
- * > ~0xff80
- * -65409
- *
- * Whoh there, Javascript, that's not quite right. But wait, according to
- * Javascript that's perfectly correct. When Javascript ends up seeing the
- * constant 0xff80, it has no notion that it is actually a signed number. It
- * assumes that we've input the unsigned value 0xff80. Thus, when it does the
- * binary negation, it casts it into a signed value, (positive 0xff80). Then
- * when you perform binary negation on that, it turns it into a negative number.
- *
- * Instead, we're going to have to use the following general formula, that works
- * in a rather Javascript friendly way. I'm glad we don't support this kind of
- * weird numbering scheme in the kernel.
- *
- * (BIT-MAX - (unsigned)val + 1) * -1
- *
- * The astute observer, may think that this doesn't make sense for 8-bit numbers
- * (really it isn't necessary for them). However, when you get 16-bit numbers,
- * you do. Let's go back to our prior example and see how this will look:
- *
- * (0xffff - 0xff80 + 1) * -1
- * (0x007f + 1) * -1
- * (0x0080) * -1
- */
-Buffer.prototype.readInt8 = function(offset, noAssert) {
- var buffer = this;
- var neg;
-
- if (!noAssert) {
- assert.ok(offset !== undefined && offset !== null,
- 'missing offset');
-
- assert.ok(offset < buffer.length,
- 'Trying to read beyond buffer length');
- }
-
- if (offset >= buffer.length) return;
-
- neg = buffer.parent[buffer.offset + offset] & 0x80;
- if (!neg) {
- return (buffer.parent[buffer.offset + offset]);
- }
-
- return ((0xff - buffer.parent[buffer.offset + offset] + 1) * -1);
-};
-
-function readInt16(buffer, offset, isBigEndian, noAssert) {
- var neg, val;
-
- if (!noAssert) {
- assert.ok(typeof (isBigEndian) === 'boolean',
- 'missing or invalid endian');
-
- assert.ok(offset !== undefined && offset !== null,
- 'missing offset');
-
- assert.ok(offset + 1 < buffer.length,
- 'Trying to read beyond buffer length');
- }
-
- val = readUInt16(buffer, offset, isBigEndian, noAssert);
- neg = val & 0x8000;
- if (!neg) {
- return val;
- }
-
- return (0xffff - val + 1) * -1;
-}
-
-Buffer.prototype.readInt16LE = function(offset, noAssert) {
- return readInt16(this, offset, false, noAssert);
-};
-
-Buffer.prototype.readInt16BE = function(offset, noAssert) {
- return readInt16(this, offset, true, noAssert);
-};
-
-function readInt32(buffer, offset, isBigEndian, noAssert) {
- var neg, val;
-
- if (!noAssert) {
- assert.ok(typeof (isBigEndian) === 'boolean',
- 'missing or invalid endian');
-
- assert.ok(offset !== undefined && offset !== null,
- 'missing offset');
-
- assert.ok(offset + 3 < buffer.length,
- 'Trying to read beyond buffer length');
- }
-
- val = readUInt32(buffer, offset, isBigEndian, noAssert);
- neg = val & 0x80000000;
- if (!neg) {
- return (val);
- }
-
- return (0xffffffff - val + 1) * -1;
-}
-
-Buffer.prototype.readInt32LE = function(offset, noAssert) {
- return readInt32(this, offset, false, noAssert);
-};
-
-Buffer.prototype.readInt32BE = function(offset, noAssert) {
- return readInt32(this, offset, true, noAssert);
-};
-
-function readFloat(buffer, offset, isBigEndian, noAssert) {
- if (!noAssert) {
- assert.ok(typeof (isBigEndian) === 'boolean',
- 'missing or invalid endian');
-
- assert.ok(offset + 3 < buffer.length,
- 'Trying to read beyond buffer length');
- }
-
- return require('./buffer_ieee754').readIEEE754(buffer, offset, isBigEndian,
- 23, 4);
-}
-
-Buffer.prototype.readFloatLE = function(offset, noAssert) {
- return readFloat(this, offset, false, noAssert);
-};
-
-Buffer.prototype.readFloatBE = function(offset, noAssert) {
- return readFloat(this, offset, true, noAssert);
-};
-
-function readDouble(buffer, offset, isBigEndian, noAssert) {
- if (!noAssert) {
- assert.ok(typeof (isBigEndian) === 'boolean',
- 'missing or invalid endian');
-
- assert.ok(offset + 7 < buffer.length,
- 'Trying to read beyond buffer length');
- }
-
- return require('./buffer_ieee754').readIEEE754(buffer, offset, isBigEndian,
- 52, 8);
-}
-
-Buffer.prototype.readDoubleLE = function(offset, noAssert) {
- return readDouble(this, offset, false, noAssert);
-};
-
-Buffer.prototype.readDoubleBE = function(offset, noAssert) {
- return readDouble(this, offset, true, noAssert);
-};
-
-
-/*
- * We have to make sure that the value is a valid integer. This means that it is
- * non-negative. It has no fractional component and that it does not exceed the
- * maximum allowed value.
- *
- * value The number to check for validity
- *
- * max The maximum value
- */
-function verifuint(value, max) {
- assert.ok(typeof (value) == 'number',
- 'cannot write a non-number as a number');
-
- assert.ok(value >= 0,
- 'specified a negative value for writing an unsigned value');
-
- assert.ok(value <= max, 'value is larger than maximum value for type');
-
- assert.ok(Math.floor(value) === value, 'value has a fractional component');
-}
-
-Buffer.prototype.writeUInt8 = function(value, offset, noAssert) {
- var buffer = this;
-
- if (!noAssert) {
- assert.ok(value !== undefined && value !== null,
- 'missing value');
-
- assert.ok(offset !== undefined && offset !== null,
- 'missing offset');
-
- assert.ok(offset < buffer.length,
- 'trying to write beyond buffer length');
-
- verifuint(value, 0xff);
- }
-
- if (offset < buffer.length) {
- buffer.parent[buffer.offset + offset] = value;
- }
-};
-
-function writeUInt16(buffer, value, offset, isBigEndian, noAssert) {
- if (!noAssert) {
- assert.ok(value !== undefined && value !== null,
- 'missing value');
-
- assert.ok(typeof (isBigEndian) === 'boolean',
- 'missing or invalid endian');
-
- assert.ok(offset !== undefined && offset !== null,
- 'missing offset');
-
- assert.ok(offset + 1 < buffer.length,
- 'trying to write beyond buffer length');
-
- verifuint(value, 0xffff);
- }
-
- for (var i = 0; i < Math.min(buffer.length - offset, 2); i++) {
- buffer.parent[buffer.offset + offset + i] =
- (value & (0xff << (8 * (isBigEndian ? 1 - i : i)))) >>>
- (isBigEndian ? 1 - i : i) * 8;
- }
-
-}
-
-Buffer.prototype.writeUInt16LE = function(value, offset, noAssert) {
- writeUInt16(this, value, offset, false, noAssert);
-};
-
-Buffer.prototype.writeUInt16BE = function(value, offset, noAssert) {
- writeUInt16(this, value, offset, true, noAssert);
-};
-
-function writeUInt32(buffer, value, offset, isBigEndian, noAssert) {
- if (!noAssert) {
- assert.ok(value !== undefined && value !== null,
- 'missing value');
-
- assert.ok(typeof (isBigEndian) === 'boolean',
- 'missing or invalid endian');
-
- assert.ok(offset !== undefined && offset !== null,
- 'missing offset');
-
- assert.ok(offset + 3 < buffer.length,
- 'trying to write beyond buffer length');
-
- verifuint(value, 0xffffffff);
- }
-
- for (var i = 0; i < Math.min(buffer.length - offset, 4); i++) {
- buffer.parent[buffer.offset + offset + i] =
- (value >>> (isBigEndian ? 3 - i : i) * 8) & 0xff;
- }
-}
-
-Buffer.prototype.writeUInt32LE = function(value, offset, noAssert) {
- writeUInt32(this, value, offset, false, noAssert);
-};
-
-Buffer.prototype.writeUInt32BE = function(value, offset, noAssert) {
- writeUInt32(this, value, offset, true, noAssert);
-};
-
-
-/*
- * We now move onto our friends in the signed number category. Unlike unsigned
- * numbers, we're going to have to worry a bit more about how we put values into
- * arrays. Since we are only worrying about signed 32-bit values, we're in
- * slightly better shape. Unfortunately, we really can't do our favorite binary
- * & in this system. It really seems to do the wrong thing. For example:
- *
- * > -32 & 0xff
- * 224
- *
- * What's happening above is really: 0xe0 & 0xff = 0xe0. However, the results of
- * this aren't treated as a signed number. Ultimately a bad thing.
- *
- * What we're going to want to do is basically create the unsigned equivalent of
- * our representation and pass that off to the wuint* functions. To do that
- * we're going to do the following:
- *
- * - if the value is positive
- * we can pass it directly off to the equivalent wuint
- * - if the value is negative
- * we do the following computation:
- * mb + val + 1, where
- * mb is the maximum unsigned value in that byte size
- * val is the Javascript negative integer
- *
- *
- * As a concrete value, take -128. In signed 16 bits this would be 0xff80. If
- * you do out the computations:
- *
- * 0xffff - 128 + 1
- * 0xffff - 127
- * 0xff80
- *
- * You can then encode this value as the signed version. This is really rather
- * hacky, but it should work and get the job done which is our goal here.
- */
-
-/*
- * A series of checks to make sure we actually have a signed 32-bit number
- */
-function verifsint(value, max, min) {
- assert.ok(typeof (value) == 'number',
- 'cannot write a non-number as a number');
-
- assert.ok(value <= max, 'value larger than maximum allowed value');
-
- assert.ok(value >= min, 'value smaller than minimum allowed value');
-
- assert.ok(Math.floor(value) === value, 'value has a fractional component');
-}
-
-function verifIEEE754(value, max, min) {
- assert.ok(typeof (value) == 'number',
- 'cannot write a non-number as a number');
-
- assert.ok(value <= max, 'value larger than maximum allowed value');
-
- assert.ok(value >= min, 'value smaller than minimum allowed value');
-}
-
-Buffer.prototype.writeInt8 = function(value, offset, noAssert) {
- var buffer = this;
-
- if (!noAssert) {
- assert.ok(value !== undefined && value !== null,
- 'missing value');
-
- assert.ok(offset !== undefined && offset !== null,
- 'missing offset');
-
- assert.ok(offset < buffer.length,
- 'Trying to write beyond buffer length');
-
- verifsint(value, 0x7f, -0x80);
- }
-
- if (value >= 0) {
- buffer.writeUInt8(value, offset, noAssert);
- } else {
- buffer.writeUInt8(0xff + value + 1, offset, noAssert);
- }
-};
-
-function writeInt16(buffer, value, offset, isBigEndian, noAssert) {
- if (!noAssert) {
- assert.ok(value !== undefined && value !== null,
- 'missing value');
-
- assert.ok(typeof (isBigEndian) === 'boolean',
- 'missing or invalid endian');
-
- assert.ok(offset !== undefined && offset !== null,
- 'missing offset');
-
- assert.ok(offset + 1 < buffer.length,
- 'Trying to write beyond buffer length');
-
- verifsint(value, 0x7fff, -0x8000);
- }
-
- if (value >= 0) {
- writeUInt16(buffer, value, offset, isBigEndian, noAssert);
- } else {
- writeUInt16(buffer, 0xffff + value + 1, offset, isBigEndian, noAssert);
- }
-}
-
-Buffer.prototype.writeInt16LE = function(value, offset, noAssert) {
- writeInt16(this, value, offset, false, noAssert);
-};
-
-Buffer.prototype.writeInt16BE = function(value, offset, noAssert) {
- writeInt16(this, value, offset, true, noAssert);
-};
-
-function writeInt32(buffer, value, offset, isBigEndian, noAssert) {
- if (!noAssert) {
- assert.ok(value !== undefined && value !== null,
- 'missing value');
-
- assert.ok(typeof (isBigEndian) === 'boolean',
- 'missing or invalid endian');
-
- assert.ok(offset !== undefined && offset !== null,
- 'missing offset');
-
- assert.ok(offset + 3 < buffer.length,
- 'Trying to write beyond buffer length');
-
- verifsint(value, 0x7fffffff, -0x80000000);
- }
-
- if (value >= 0) {
- writeUInt32(buffer, value, offset, isBigEndian, noAssert);
- } else {
- writeUInt32(buffer, 0xffffffff + value + 1, offset, isBigEndian, noAssert);
- }
-}
-
-Buffer.prototype.writeInt32LE = function(value, offset, noAssert) {
- writeInt32(this, value, offset, false, noAssert);
-};
-
-Buffer.prototype.writeInt32BE = function(value, offset, noAssert) {
- writeInt32(this, value, offset, true, noAssert);
-};
-
-function writeFloat(buffer, value, offset, isBigEndian, noAssert) {
- if (!noAssert) {
- assert.ok(value !== undefined && value !== null,
- 'missing value');
-
- assert.ok(typeof (isBigEndian) === 'boolean',
- 'missing or invalid endian');
-
- assert.ok(offset !== undefined && offset !== null,
- 'missing offset');
-
- assert.ok(offset + 3 < buffer.length,
- 'Trying to write beyond buffer length');
-
- verifIEEE754(value, 3.4028234663852886e+38, -3.4028234663852886e+38);
- }
-
- require('./buffer_ieee754').writeIEEE754(buffer, value, offset, isBigEndian,
- 23, 4);
-}
-
-Buffer.prototype.writeFloatLE = function(value, offset, noAssert) {
- writeFloat(this, value, offset, false, noAssert);
-};
-
-Buffer.prototype.writeFloatBE = function(value, offset, noAssert) {
- writeFloat(this, value, offset, true, noAssert);
-};
-
-function writeDouble(buffer, value, offset, isBigEndian, noAssert) {
- if (!noAssert) {
- assert.ok(value !== undefined && value !== null,
- 'missing value');
-
- assert.ok(typeof (isBigEndian) === 'boolean',
- 'missing or invalid endian');
-
- assert.ok(offset !== undefined && offset !== null,
- 'missing offset');
-
- assert.ok(offset + 7 < buffer.length,
- 'Trying to write beyond buffer length');
-
- verifIEEE754(value, 1.7976931348623157E+308, -1.7976931348623157E+308);
- }
-
- require('./buffer_ieee754').writeIEEE754(buffer, value, offset, isBigEndian,
- 52, 8);
-}
-
-Buffer.prototype.writeDoubleLE = function(value, offset, noAssert) {
- writeDouble(this, value, offset, false, noAssert);
-};
-
-Buffer.prototype.writeDoubleBE = function(value, offset, noAssert) {
- writeDouble(this, value, offset, true, noAssert);
-};
-
-SlowBuffer.prototype.readUInt8 = Buffer.prototype.readUInt8;
-SlowBuffer.prototype.readUInt16LE = Buffer.prototype.readUInt16LE;
-SlowBuffer.prototype.readUInt16BE = Buffer.prototype.readUInt16BE;
-SlowBuffer.prototype.readUInt32LE = Buffer.prototype.readUInt32LE;
-SlowBuffer.prototype.readUInt32BE = Buffer.prototype.readUInt32BE;
-SlowBuffer.prototype.readInt8 = Buffer.prototype.readInt8;
-SlowBuffer.prototype.readInt16LE = Buffer.prototype.readInt16LE;
-SlowBuffer.prototype.readInt16BE = Buffer.prototype.readInt16BE;
-SlowBuffer.prototype.readInt32LE = Buffer.prototype.readInt32LE;
-SlowBuffer.prototype.readInt32BE = Buffer.prototype.readInt32BE;
-SlowBuffer.prototype.readFloatLE = Buffer.prototype.readFloatLE;
-SlowBuffer.prototype.readFloatBE = Buffer.prototype.readFloatBE;
-SlowBuffer.prototype.readDoubleLE = Buffer.prototype.readDoubleLE;
-SlowBuffer.prototype.readDoubleBE = Buffer.prototype.readDoubleBE;
-SlowBuffer.prototype.writeUInt8 = Buffer.prototype.writeUInt8;
-SlowBuffer.prototype.writeUInt16LE = Buffer.prototype.writeUInt16LE;
-SlowBuffer.prototype.writeUInt16BE = Buffer.prototype.writeUInt16BE;
-SlowBuffer.prototype.writeUInt32LE = Buffer.prototype.writeUInt32LE;
-SlowBuffer.prototype.writeUInt32BE = Buffer.prototype.writeUInt32BE;
-SlowBuffer.prototype.writeInt8 = Buffer.prototype.writeInt8;
-SlowBuffer.prototype.writeInt16LE = Buffer.prototype.writeInt16LE;
-SlowBuffer.prototype.writeInt16BE = Buffer.prototype.writeInt16BE;
-SlowBuffer.prototype.writeInt32LE = Buffer.prototype.writeInt32LE;
-SlowBuffer.prototype.writeInt32BE = Buffer.prototype.writeInt32BE;
-SlowBuffer.prototype.writeFloatLE = Buffer.prototype.writeFloatLE;
-SlowBuffer.prototype.writeFloatBE = Buffer.prototype.writeFloatBE;
-SlowBuffer.prototype.writeDoubleLE = Buffer.prototype.writeDoubleLE;
-SlowBuffer.prototype.writeDoubleBE = Buffer.prototype.writeDoubleBE;
-
-})()
-},{"assert":9,"./buffer_ieee754":14,"base64-js":15}],15:[function(require,module,exports){
-(function (exports) {
- 'use strict';
-
- var lookup = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
-
- function b64ToByteArray(b64) {
- var i, j, l, tmp, placeHolders, arr;
-
- if (b64.length % 4 > 0) {
- throw 'Invalid string. Length must be a multiple of 4';
- }
-
- // the number of equal signs (place holders)
- // if there are two placeholders, than the two characters before it
- // represent one byte
- // if there is only one, then the three characters before it represent 2 bytes
- // this is just a cheap hack to not do indexOf twice
- placeHolders = b64.indexOf('=');
- placeHolders = placeHolders > 0 ? b64.length - placeHolders : 0;
-
- // base64 is 4/3 + up to two characters of the original data
- arr = [];//new Uint8Array(b64.length * 3 / 4 - placeHolders);
-
- // if there are placeholders, only get up to the last complete 4 chars
- l = placeHolders > 0 ? b64.length - 4 : b64.length;
-
- for (i = 0, j = 0; i < l; i += 4, j += 3) {
- tmp = (lookup.indexOf(b64[i]) << 18) | (lookup.indexOf(b64[i + 1]) << 12) | (lookup.indexOf(b64[i + 2]) << 6) | lookup.indexOf(b64[i + 3]);
- arr.push((tmp & 0xFF0000) >> 16);
- arr.push((tmp & 0xFF00) >> 8);
- arr.push(tmp & 0xFF);
- }
-
- if (placeHolders === 2) {
- tmp = (lookup.indexOf(b64[i]) << 2) | (lookup.indexOf(b64[i + 1]) >> 4);
- arr.push(tmp & 0xFF);
- } else if (placeHolders === 1) {
- tmp = (lookup.indexOf(b64[i]) << 10) | (lookup.indexOf(b64[i + 1]) << 4) | (lookup.indexOf(b64[i + 2]) >> 2);
- arr.push((tmp >> 8) & 0xFF);
- arr.push(tmp & 0xFF);
- }
-
- return arr;
- }
-
- function uint8ToBase64(uint8) {
- var i,
- extraBytes = uint8.length % 3, // if we have 1 byte left, pad 2 bytes
- output = "",
- temp, length;
-
- function tripletToBase64 (num) {
- return lookup[num >> 18 & 0x3F] + lookup[num >> 12 & 0x3F] + lookup[num >> 6 & 0x3F] + lookup[num & 0x3F];
- };
-
- // go through the array every three bytes, we'll deal with trailing stuff later
- for (i = 0, length = uint8.length - extraBytes; i < length; i += 3) {
- temp = (uint8[i] << 16) + (uint8[i + 1] << 8) + (uint8[i + 2]);
- output += tripletToBase64(temp);
- }
-
- // pad the end with zeros, but make sure to not forget the extra bytes
- switch (extraBytes) {
- case 1:
- temp = uint8[uint8.length - 1];
- output += lookup[temp >> 2];
- output += lookup[(temp << 4) & 0x3F];
- output += '==';
- break;
- case 2:
- temp = (uint8[uint8.length - 2] << 8) + (uint8[uint8.length - 1]);
- output += lookup[temp >> 10];
- output += lookup[(temp >> 4) & 0x3F];
- output += lookup[(temp << 2) & 0x3F];
- output += '=';
- break;
- }
-
- return output;
- }
-
- module.exports.toByteArray = b64ToByteArray;
- module.exports.fromByteArray = uint8ToBase64;
-}());
-
-},{}]},{},["E/GbHF"])
-;
-JSHINT = require('jshint').JSHINT;
-}());
diff --git a/dom/system/gonk/tests/marionette/ril_jshint/jshintrc b/dom/system/gonk/tests/marionette/ril_jshint/jshintrc
deleted file mode 100644
index 437fe1a6f5..0000000000
--- a/dom/system/gonk/tests/marionette/ril_jshint/jshintrc
+++ /dev/null
@@ -1,118 +0,0 @@
-{
- // JSHint Default Configuration File (as on JSHint website)
- // See http://jshint.com/docs/ for more details
-
- // Modify for RIL usage.
-
- "maxerr" : 10000, // {int} Maximum error before stopping
-
- // Enforcing
- "bitwise" : false, // true: Prohibit bitwise operators (&, |, ^, etc.)
- "camelcase" : false, // true: Identifiers must be in camelCase
- "curly" : false, // true: Require {} for every new block or scope
- "eqeqeq" : false, // true: Require triple equals (===) for comparison
- "forin" : false, // true: Require filtering for..in loops with obj.hasOwnProperty()
- "immed" : false, // true: Require immediate invocations to be wrapped in parens e.g. `(function () { } ());`
- //"indent" : 2, // {int} Number of spaces to use for indentation
- "latedef" : false, // true: Require variables/functions to be defined before being used
- "newcap" : false, // true: Require capitalization of all constructor functions e.g. `new F()`
- "noarg" : true, // true: Prohibit use of `arguments.caller` and `arguments.callee`
- "noempty" : false, // true: Prohibit use of empty blocks
- "nonew" : false, // true: Prohibit use of constructors for side-effects (without assignment)
- "plusplus" : false, // true: Prohibit use of `++` & `--`
- "quotmark" : false, // Quotation mark consistency:
- // false : do nothing (default)
- // true : ensure whatever is used is consistent
- // "single" : require single quotes
- // "double" : require double quotes
- "undef" : false, // true: Require all non-global variables to be declared (prevents global leaks)
- "unused" : false, // true: Require all defined variables be used
- "strict" : false, // true: Requires all functions run in ES5 Strict Mode
- "trailing" : false, // true: Prohibit trailing whitespaces
- "maxparams" : false, // {int} Max number of formal params allowed per function
- "maxdepth" : false, // {int} Max depth of nested blocks (within functions)
- "maxstatements" : false, // {int} Max number statements per function
- "maxcomplexity" : false, // {int} Max cyclomatic complexity per function
- "maxlen" : false, // {int} Max number of characters per line
-
- // Relaxing
- "asi" : false, // true: Tolerate Automatic Semicolon Insertion (no semicolons)
- "boss" : false, // true: Tolerate assignments where comparisons would be expected
- "debug" : false, // true: Allow debugger statements e.g. browser breakpoints.
- "eqnull" : true, // true: Tolerate use of `== null`
- "es5" : false, // true: Allow ES5 syntax (ex: getters and setters)
- "esnext" : false, // true: Allow ES.next (ES6) syntax (ex: `const`)
- "moz" : true, // true: Allow Mozilla specific syntax (extends and overrides esnext features)
- // (ex: `for each`, multiple try/catch, function expression…)
- "evil" : false, // true: Tolerate use of `eval` and `new Function()`
- "expr" : false, // true: Tolerate `ExpressionStatement` as Programs
- "funcscope" : false, // true: Tolerate defining variables inside control statements"
- "globalstrict" : true, // true: Allow global "use strict" (also enables 'strict')
- "iterator" : false, // true: Tolerate using the `__iterator__` property
- "lastsemic" : false, // true: Tolerate omitting a semicolon for the last statement of a 1-line block
- "laxbreak" : true, // true: Tolerate possibly unsafe line breakings
- "laxcomma" : false, // true: Tolerate comma-first style coding
- "loopfunc" : false, // true: Tolerate functions being defined in loops
- "multistr" : false, // true: Tolerate multi-line strings
- "proto" : true, // true: Tolerate using the `__proto__` property
- "scripturl" : false, // true: Tolerate script-targeted URLs
- "smarttabs" : false, // true: Tolerate mixed tabs/spaces when used for alignment
- "shadow" : false, // true: Allows re-define variables later in code e.g. `var x=1; x=2;`
- "sub" : false, // true: Tolerate using `[]` notation when it can still be expressed in dot notation
- "supernew" : false, // true: Tolerate `new function () { ... };` and `new Object;`
- "validthis" : true, // true: Tolerate using this in a non-constructor function
-
- // Environments
- "browser" : false, // Web Browser (window, document, etc)
- "couch" : false, // CouchDB
- "devel" : true, // Development/debugging (alert, confirm, etc)
- "dojo" : false, // Dojo Toolkit
- "jquery" : false, // jQuery
- "mootools" : false, // MooTools
- "node" : false, // Node.js
- "nonstandard" : false, // Widely adopted globals (escape, unescape, etc)
- "prototypejs" : false, // Prototype and Scriptaculous
- "rhino" : false, // Rhino
- "worker" : true, // Web Workers
- "wsh" : false, // Windows Scripting Host
- "yui" : false, // Yahoo User Interface
-
- // Legacy
- "nomen" : false, // true: Prohibit dangling `_` in variables
- "onevar" : false, // true: Allow only one `var` statement per function
- "passfail" : false, // true: Stop on first error
- "white" : false, // true: Check against strict whitespace and indentation rules
-
- // Custom Globals
- "predef" : [ ], // additional predefined global variables
-
- "globals": {
- "ChromeWorker": false,
- "Components": false,
- "DOMRequestIpcHelper": false,
- "ObjectWrapper": false,
- "PhoneNumberUtils": false,
- "RILNetworkInterface": false,
- "Services": false,
- "Uint8Array": false,
- "WAP": false,
- "XPCOMUtils": false,
- "cpmm": false,
- "dump": false,
- "gAudioManager": false,
- "gMessageManager": false,
- "gMobileMessageDatabaseService": false,
- "gMobileMessageService": false,
- "gNetworkManager": false,
- "gPowerManagerService": false,
- "gSettingsService": false,
- "gSmsService": false,
- "gSystemMessenger": false,
- "gSystemWorkerManager": false,
- "gTimeService": false,
- "gUUIDGenerator": false,
- "ppmm": true,
-
- "__end_guardian_for_easy_sorting__": false
- }
-}
diff --git a/dom/system/gonk/tests/marionette/test_all_network_info.js b/dom/system/gonk/tests/marionette/test_all_network_info.js
deleted file mode 100644
index 5225ab6d6c..0000000000
--- a/dom/system/gonk/tests/marionette/test_all_network_info.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";
-
-var networkManager =
- Cc["@mozilla.org/network/manager;1"].getService(Ci.nsINetworkManager);
-ok(networkManager,
- "networkManager.constructor is " + networkManager.constructor);
-
-var wifiManager = window.navigator.mozWifiManager;
-ok(wifiManager, "wifiManager.constructor is " + wifiManager.constructor);
-
-function setEmulatorAPN() {
- let apn = [
- [{"carrier":"T-Mobile US",
- "apn":"epc.tmobile.com",
- "mmsc":"http://mms.msg.eng.t-mobile.com/mms/wapenc",
- "types":["default","supl","mms","ims","dun", "fota"]}]
- ];
-
- return setSettings(SETTINGS_KEY_DATA_APN_SETTINGS, apn);
-}
-
-function ensureWifiEnabled(aEnabled) {
- if (wifiManager.enabled === aEnabled) {
- log('Already ' + (aEnabled ? 'enabled' : 'disabled'));
- return Promise.resolve();
- }
- return requestWifiEnabled(aEnabled);
-}
-
-function requestWifiEnabled(aEnabled) {
- let promises = [];
-
- promises.push(waitForTargetEvent(wifiManager, aEnabled ? 'enabled' : 'disabled',
- function() {
- return wifiManager.enabled === aEnabled ? true : false;
- }));
- promises.push(setSettings(SETTINGS_KEY_WIFI_ENABLED, aEnabled));
-
- return Promise.all(promises);
-}
-
-// Test initial State
-function verifyInitialState() {
- log("= verifyInitialState =");
-
- // Data and wifi should be off before starting any test.
- return getSettings(SETTINGS_KEY_DATA_ENABLED)
- .then(value => {
- is(value, false, "Data must be off");
- })
- .then(() => ensureWifiEnabled(false));
-}
-
-function testAllNetworkInfo(aAnyConnected) {
- log("= testAllNetworkInfo = " + aAnyConnected);
-
- let allNetworkInfo = networkManager.allNetworkInfo;
- ok(allNetworkInfo, "NetworkManager.allNetworkInfo");
-
- let count = Object.keys(allNetworkInfo).length;
- ok(count > 0, "NetworkManager.allNetworkInfo count");
-
- let connected = false;
- for (let networkId in allNetworkInfo) {
- if (allNetworkInfo.hasOwnProperty(networkId)) {
- let networkInfo = allNetworkInfo[networkId];
- if (networkInfo.state == Ci.nsINetworkInfo.NETWORK_STATE_CONNECTED) {
- connected = true;
- break;
- }
- }
- }
-
- is(aAnyConnected, connected, "NetworkManager.allNetworkInfo any connected");
-}
-
-// Start test
-startTestBase(function() {
-
- let origApnSettings, origWifiEnabled;
- return Promise.resolve()
- .then(() => {
- origWifiEnabled = wifiManager.enabled;
- })
- .then(() => verifyInitialState())
- .then(() => getSettings(SETTINGS_KEY_DATA_APN_SETTINGS))
- .then(value => {
- origApnSettings = value;
- })
- .then(() => setEmulatorAPN())
- .then(() => setDataEnabledAndWait(true))
- .then(() => testAllNetworkInfo(true))
- .then(() => setDataEnabledAndWait(false))
- .then(() => testAllNetworkInfo(false))
- // Restore original apn settings and wifi state.
- .then(() => {
- if (origApnSettings) {
- return setSettings(SETTINGS_KEY_DATA_APN_SETTINGS, origApnSettings);
- }
- })
- .then(() => ensureWifiEnabled(origWifiEnabled));
-});
diff --git a/dom/system/gonk/tests/marionette/test_data_connection.js b/dom/system/gonk/tests/marionette/test_data_connection.js
deleted file mode 100644
index 5a53b1e5f0..0000000000
--- a/dom/system/gonk/tests/marionette/test_data_connection.js
+++ /dev/null
@@ -1,70 +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";
-
-function setEmulatorAPN() {
- let apn = [
- [{"carrier":"T-Mobile US",
- "apn":"epc.tmobile.com",
- "mmsc":"http://mms.msg.eng.t-mobile.com/mms/wapenc",
- "types":["default","supl","mms","ims","dun", "fota"]}]
- ];
-
- return setSettings(SETTINGS_KEY_DATA_APN_SETTINGS, apn);
-}
-
-// Test initial State
-function testInitialState() {
- log("= testInitialState =");
-
- // Data should be off before starting any test.
- return getSettings(SETTINGS_KEY_DATA_ENABLED)
- .then(value => {
- is(value, false, "Data must be off");
- });
-}
-
-// Test default data Connection
-function testDefaultDataConnection() {
- log("= testDefaultDataConnection =");
-
- // Enable default data
- return setDataEnabledAndWait(true)
- // Disable default data
- .then(() => setDataEnabledAndWait(false));
-}
-
-// Test non default data connection
-function testNonDefaultDataConnection() {
- log("= testNonDefaultDataConnection =");
-
- function doTestNonDefaultDataConnection(type) {
- log("doTestNonDefaultDataConnection: " + type);
-
- return setupDataCallAndWait(type)
- .then(() => deactivateDataCallAndWait(type));
- }
-
- let currentApn;
- return getSettings(SETTINGS_KEY_DATA_APN_SETTINGS)
- .then(value => {
- currentApn = value;
- })
- .then(setEmulatorAPN)
- .then(() => doTestNonDefaultDataConnection(NETWORK_TYPE_MOBILE_MMS))
- .then(() => doTestNonDefaultDataConnection(NETWORK_TYPE_MOBILE_SUPL))
- .then(() => doTestNonDefaultDataConnection(NETWORK_TYPE_MOBILE_IMS))
- .then(() => doTestNonDefaultDataConnection(NETWORK_TYPE_MOBILE_DUN))
- .then(() => doTestNonDefaultDataConnection(NETWORK_TYPE_MOBILE_FOTA))
- // Restore APN settings
- .then(() => setSettings(SETTINGS_KEY_DATA_APN_SETTINGS, currentApn));
-}
-
-// Start test
-startTestBase(function() {
- return testInitialState()
- .then(() => testDefaultDataConnection())
- .then(() => testNonDefaultDataConnection());
-});
diff --git a/dom/system/gonk/tests/marionette/test_data_connection_proxy.js b/dom/system/gonk/tests/marionette/test_data_connection_proxy.js
deleted file mode 100644
index a991875383..0000000000
--- a/dom/system/gonk/tests/marionette/test_data_connection_proxy.js
+++ /dev/null
@@ -1,99 +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 HTTP_PROXY = "10.0.2.200";
-const HTTP_PROXY_PORT = "8080";
-const MANUAL_PROXY_CONFIGURATION = 1;
-
-// Test initial State
-function verifyInitialState() {
- log("= verifyInitialState =");
-
- // Data should be off before starting any test.
- return getSettings(SETTINGS_KEY_DATA_ENABLED)
- .then(value => {
- is(value, false, "Data must be off");
- });
-}
-
-function setTestApn() {
- let apn = [
- [ {"carrier": "T-Mobile US",
- "apn": "epc.tmobile.com",
- "proxy": HTTP_PROXY,
- "port": HTTP_PROXY_PORT,
- "mmsc": "http://mms.msg.eng.t-mobile.com/mms/wapenc",
- "types": ["default","supl","mms"]} ]
- ];
-
- return setSettings(SETTINGS_KEY_DATA_APN_SETTINGS, apn);
-}
-
-function waitForHttpProxyVerified(aShouldBeSet) {
- let TIME_OUT_VALUE = 20000;
-
- return new Promise(function(aResolve, aReject) {
- try {
- waitFor(aResolve, () => {
- let proxyType = SpecialPowers.getIntPref("network.proxy.type");
- let httpProxy = SpecialPowers.getCharPref("network.proxy.http");
- let sslProxy = SpecialPowers.getCharPref("network.proxy.ssl");
- let httpProxyPort = SpecialPowers.getIntPref("network.proxy.http_port");
- let sslProxyPort = SpecialPowers.getIntPref("network.proxy.ssl_port");
-
- if ((aShouldBeSet &&
- proxyType == MANUAL_PROXY_CONFIGURATION &&
- httpProxy == HTTP_PROXY &&
- sslProxy == HTTP_PROXY &&
- httpProxyPort == HTTP_PROXY_PORT &&
- sslProxyPort == HTTP_PROXY_PORT) ||
- (!aShouldBeSet && proxyType != MANUAL_PROXY_CONFIGURATION &&
- !httpProxy && !sslProxy && !httpProxyPort && !sslProxyPort)) {
- return true;
- }
-
- return false;
- }, TIME_OUT_VALUE);
- } catch(aError) {
- // Timed out.
- aReject(aError);
- }
- });
-}
-
-function testDefaultDataHttpProxy() {
- log("= testDefaultDataHttpProxy =");
-
- return setDataEnabledAndWait(true)
- .then(() => waitForHttpProxyVerified(true))
- .then(() => setDataEnabledAndWait(false))
- .then(() => waitForHttpProxyVerified(false));
-}
-
-function testNonDefaultDataHttpProxy(aType) {
- log("= testNonDefaultDataHttpProxy - " + aType + " =");
-
- return setupDataCallAndWait(aType)
- // Http proxy should not be set for non-default data connections.
- .then(() => waitForHttpProxyVerified(false))
- .then(() => deactivateDataCallAndWait(aType));
-}
-
-// Start test
-startTestBase(function() {
- let origApnSettings;
- return verifyInitialState()
- .then(() => getSettings(SETTINGS_KEY_DATA_APN_SETTINGS))
- .then(value => {
- origApnSettings = value;
- })
- .then(() => setTestApn())
- .then(() => testDefaultDataHttpProxy())
- .then(() => testNonDefaultDataHttpProxy(NETWORK_TYPE_MOBILE_MMS))
- .then(() => testNonDefaultDataHttpProxy(NETWORK_TYPE_MOBILE_SUPL))
- // Restore APN settings
- .then(() => setSettings(SETTINGS_KEY_DATA_APN_SETTINGS, origApnSettings));
-});
diff --git a/dom/system/gonk/tests/marionette/test_dsds_numRadioInterfaces.js b/dom/system/gonk/tests/marionette/test_dsds_numRadioInterfaces.js
deleted file mode 100644
index e178b8b658..0000000000
--- a/dom/system/gonk/tests/marionette/test_dsds_numRadioInterfaces.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_CONTEXT = "chrome";
-
-Cu.import("resource://gre/modules/Promise.jsm");
-Cu.import("resource://gre/modules/systemlibs.js");
-
-const NS_RIL_CONTRACTID = "@mozilla.org/ril;1";
-
-const PROP_RO_MOZ_RIL_NUMCLIENTS = "ro.moz.ril.numclients";
-
-const PREF_RIL_NUM_RADIO_INTERFACES = "ril.numRadioInterfaces";
-
-ok(libcutils, "libcutils is available");
-
-var propNum = (function() {
- try {
- let numString = libcutils.property_get(PROP_RO_MOZ_RIL_NUMCLIENTS, "1");
- let num = parseInt(numString, 10);
- if (num >= 0) {
- return num;
- }
- } catch (e) {}
-})();
-
-log("Retrieved '" + PROP_RO_MOZ_RIL_NUMCLIENTS + "' = " + propNum);
-ok(propNum, PROP_RO_MOZ_RIL_NUMCLIENTS);
-
-var prefNum = Services.prefs.getIntPref(PREF_RIL_NUM_RADIO_INTERFACES);
-log("Retrieved '" + PREF_RIL_NUM_RADIO_INTERFACES + "' = " + prefNum);
-
-var ril = Cc[NS_RIL_CONTRACTID].getService(Ci.nsIRadioInterfaceLayer);
-ok(ril, "ril.constructor is " + ril.constructor);
-
-var ifaceNum = ril.numRadioInterfaces;
-log("Retrieved 'nsIRadioInterfaceLayer.numRadioInterfaces' = " + ifaceNum);
-
-is(propNum, prefNum);
-is(propNum, ifaceNum);
-
-finish();
diff --git a/dom/system/gonk/tests/marionette/test_fakevolume.js b/dom/system/gonk/tests/marionette/test_fakevolume.js
deleted file mode 100644
index 173f9ac11b..0000000000
--- a/dom/system/gonk/tests/marionette/test_fakevolume.js
+++ /dev/null
@@ -1,25 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-MARIONETTE_TIMEOUT = 10000;
-
-var Cc = SpecialPowers.Cc;
-var Ci = SpecialPowers.Ci;
-
-var volumeService = Cc["@mozilla.org/telephony/volume-service;1"].getService(Ci.nsIVolumeService);
-ok(volumeService, "Should have volume service");
-
-var volName = "fake";
-var mountPoint = "/data/fake/storage";
-volumeService.createFakeVolume(volName, mountPoint);
-
-var vol = volumeService.getVolumeByName(volName);
-ok(vol, "volume shouldn't be null");
-
-is(volName, vol.name, "name");
-is(mountPoint, vol.mountPoint, "moutnPoint");
-is(Ci.nsIVolume.STATE_MOUNTED, vol.state, "state");
-
-ok(vol.mountGeneration > 0, "mount generation should not be zero");
-
-finish();
diff --git a/dom/system/gonk/tests/marionette/test_geolocation.js b/dom/system/gonk/tests/marionette/test_geolocation.js
deleted file mode 100644
index 201c8b3e3a..0000000000
--- a/dom/system/gonk/tests/marionette/test_geolocation.js
+++ /dev/null
@@ -1,117 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-MARIONETTE_TIMEOUT = 10000;
-
-var geolocation = window.navigator.geolocation;
-ok(geolocation);
-
-var sample = [];
-var result = [];
-var wpid;
-
-/**
- * Grant special power to get the geolocation
- */
-SpecialPowers.addPermission("geolocation", true, document);
-
-/**
- * Disable wifi geolocation provider
- */
-wifiUri = SpecialPowers.getCharPref("geo.wifi.uri");
-SpecialPowers.setCharPref("geo.wifi.uri", "http://mochi.test:8888/tests/dom/tests/mochitest/geolocation/network_geolocation.sjs?action=stop-responding");
-
-/**
- * Helper that compares the geolocation against the web API.
- */
-function verifyLocation() {
-
- log("Sample:" + sample.join(','));
- log("Result:" + result.join(','));
-
- for (i in sample) {
- is(sample.pop(), result.pop());
- }
-
- window.setTimeout(cleanup, 0);
-}
-
-/**
- * Test story begins here.
- */
-function setup() {
- log("Providing initial setup: set geographic position watcher.");
-
-
- wpid = geolocation.watchPosition(function(position) {
- log("Position changes: (" + position.coords.latitude + "/" + position.coords.longitude + ")");
- result.push(""+position.coords.latitude + "/" + position.coords.longitude);
- });
-
- lat = 0;
- lon = 0;
-
- cmd = "geo fix " + lon + " " + lat;
- sample.push(lat+"/"+lon);
-
- runEmulatorCmd(cmd, function(result) {
- window.setTimeout(movePosition_1, 0);
- });
-}
-
-function movePosition_1() {
- log("Geolocation changes. Move to Position 1.");
-
- lat = 25;
- lon = 121.56499833333334;
-
- cmd = "geo fix " + lon + " " + lat;
- sample.push(lat+"/"+lon);
-
- runEmulatorCmd(cmd, function(result) {
- window.setTimeout(movePosition_2, 0);
- });
-}
-
-function movePosition_2() {
- log("Geolocation changes to a negative longitude. Move to Position 2.");
-
- lat = 37.393;
- lon = -122.08199833333335;
-
- cmd = "geo fix " + lon + " " + lat;
- sample.push(lat+"/"+lon);
-
- runEmulatorCmd(cmd, function(result) {
- window.setTimeout(movePosition_3, 0);
- });
-}
-
-function movePosition_3() {
- log("Geolocation changes with WatchPosition. Move to Position 3.");
-
- lat = -22;
- lon = -43;
-
- cmd = "geo fix " + lon + " " + lat;
- sample.push(lat+"/"+lon);
-
- geolocation.getCurrentPosition(function(position) {
- log("getCurrentPosition: Expected location: ("+lat+"/"+lon+"); Current location: (" + position.coords.latitude + "/" + position.coords.longitude + ")");
- is(lat, position.coords.latitude);
- is(lon, position.coords.longitude);
- });
-
- runEmulatorCmd(cmd, function(result) {
- window.setTimeout(verifyLocation, 0);
- });
-}
-
-function cleanup() {
- geolocation.clearWatch(wpid);
- SpecialPowers.removePermission("geolocation", document);
- SpecialPowers.setCharPref("geo.wifi.uri", wifiUri);
- finish();
-}
-
-setup();
diff --git a/dom/system/gonk/tests/marionette/test_multiple_data_connection.js b/dom/system/gonk/tests/marionette/test_multiple_data_connection.js
deleted file mode 100644
index 24abd44513..0000000000
--- a/dom/system/gonk/tests/marionette/test_multiple_data_connection.js
+++ /dev/null
@@ -1,89 +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";
-
-// Must sync with hardware/ril/reference-ril/reference-ril.c
-const MAX_DATA_CONTEXTS = 4;
-
-function setEmulatorAPN() {
- // Use different apn for each network type.
- let apn = [[ { "carrier":"T-Mobile US",
- "apn":"epc1.tmobile.com",
- "types":["default"] },
- { "carrier":"T-Mobile US",
- "apn":"epc2.tmobile.com",
- "mmsc":"http://mms.msg.eng.t-mobile.com/mms/wapenc",
- "types":["mms"] },
- { "carrier":"T-Mobile US",
- "apn":"epc3.tmobile.com",
- "types":["supl"] },
- { "carrier":"T-Mobile US",
- "apn":"epc4.tmobile.com",
- "types":["ims"] },
- { "carrier":"T-Mobile US",
- "apn":"epc5.tmobile.com",
- "types":["dun"] },
- { "carrier":"T-Mobile US",
- "apn":"epc6.tmobile.com",
- "types":["fota"] }]];
-
- return setSettings(SETTINGS_KEY_DATA_APN_SETTINGS, apn);
-}
-
-// Test initial State
-function testInitialState() {
- log("= testInitialState =");
-
- // Data should be off before starting any test.
- return getSettings(SETTINGS_KEY_DATA_ENABLED)
- .then(value => {
- is(value, false, "Data must be off");
- });
-}
-
-function testSetupConcurrentDataCalls() {
- log("= testSetupConcurrentDataCalls =");
-
- let promise = Promise.resolve();
- // Skip default mobile type.
- for (let i = 1; i < MAX_DATA_CONTEXTS; i++) {
- let type = networkTypes[i];
- promise = promise.then(() => setupDataCallAndWait(type));
- }
- return promise;
-}
-
-function testDeactivateConcurrentDataCalls() {
- log("= testDeactivateConcurrentDataCalls =");
-
- let promise = Promise.resolve();
- // Skip default mobile type.
- for (let i = 1; i < MAX_DATA_CONTEXTS; i++) {
- let type = networkTypes[i];
- promise = promise.then(() => deactivateDataCallAndWait(type));
- }
- return promise;
-}
-
-// Start test
-startTestBase(function() {
-
- let origApnSettings;
- return testInitialState()
- .then(() => getSettings(SETTINGS_KEY_DATA_APN_SETTINGS))
- .then(value => {
- origApnSettings = value;
- })
- .then(() => setEmulatorAPN())
- .then(() => setDataEnabledAndWait(true))
- .then(() => testSetupConcurrentDataCalls())
- .then(() => testDeactivateConcurrentDataCalls())
- .then(() => setDataEnabledAndWait(false))
- .then(() => {
- if (origApnSettings) {
- return setSettings(SETTINGS_KEY_DATA_APN_SETTINGS, origApnSettings);
- }
- });
-});
diff --git a/dom/system/gonk/tests/marionette/test_network_active_changed.js b/dom/system/gonk/tests/marionette/test_network_active_changed.js
deleted file mode 100644
index 5886f37ed4..0000000000
--- a/dom/system/gonk/tests/marionette/test_network_active_changed.js
+++ /dev/null
@@ -1,52 +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";
-
-var networkManager =
- Cc["@mozilla.org/network/manager;1"].getService(Ci.nsINetworkManager);
-ok(networkManager,
- "networkManager.constructor is " + networkManager.constructor);
-
-function testInitialState() {
- return getSettings(SETTINGS_KEY_DATA_ENABLED)
- .then((enabled) => {
- is(enabled, false, "data should be off by default");
- is(networkManager.activeNetworkInfo, null,
- "networkManager.activeNetworkInfo should be null by default");
- });
-}
-
-function testActiveNetworkChangedBySwitchingDataCall(aDataCallEnabled) {
- log("Test active network by switching dataCallEnabled to " + aDataCallEnabled);
-
- let promises = [];
- promises.push(waitForObserverEvent(TOPIC_NETWORK_ACTIVE_CHANGED));
- promises.push(setSettings(SETTINGS_KEY_DATA_ENABLED, aDataCallEnabled));
-
- return Promise.all(promises).then(function(results) {
- let subject = results[0];
-
- if (aDataCallEnabled) {
- ok(subject instanceof Ci.nsINetworkInfo,
- "subject should be an instance of nsINetworkInfo");
- ok(subject instanceof Ci.nsIRilNetworkInfo,
- "subject should be an instance of nsIRilNetworkInfo");
- is(subject.type, NETWORK_TYPE_MOBILE,
- "subject.type should be NETWORK_TYPE_MOBILE");
- }
-
- is(subject, networkManager.activeNetworkInfo,
- "subject should be equal with networkManager.activeNetworkInfo");
- });
-}
-
-// Start test
-startTestBase(function() {
- return testInitialState()
- // Test active network changed by enabling data call.
- .then(() => testActiveNetworkChangedBySwitchingDataCall(true))
- // Test active network changed by disabling data call.
- .then(() => testActiveNetworkChangedBySwitchingDataCall(false));
-});
diff --git a/dom/system/gonk/tests/marionette/test_network_interface_list_service.js b/dom/system/gonk/tests/marionette/test_network_interface_list_service.js
deleted file mode 100644
index 549940fa5b..0000000000
--- a/dom/system/gonk/tests/marionette/test_network_interface_list_service.js
+++ /dev/null
@@ -1,95 +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";
-
-function getNetworkInfo(aType) {
- let networkListService =
- Cc["@mozilla.org/network/interface-list-service;1"].
- getService(Ci.nsINetworkInterfaceListService);
- // Get all available interfaces
- let networkList = networkListService.getDataInterfaceList(0);
-
- // Try to get nsINetworkInterface for aType.
- let numberOfInterface = networkList.getNumberOfInterface();
- for (let i = 0; i < numberOfInterface; i++) {
- let info = networkList.getInterfaceInfo(i);
- if (info.type === aType) {
- return info;
- }
- }
-
- return null;
-}
-
-// Test getDataInterfaceList by enabling/disabling mobile data.
-function testGetDataInterfaceList(aMobileDataEnabled) {
- log("Test getDataInterfaceList with mobile data " +
- aMobileDataEnabled ? "enabled" : "disabled");
-
- return setDataEnabledAndWait(aMobileDataEnabled)
- .then(() => getNetworkInfo(NETWORK_TYPE_MOBILE))
- .then((networkInfo) => {
- if (!networkInfo) {
- ok(false, "Should get an valid nsINetworkInfo for mobile");
- return;
- }
-
- ok(networkInfo instanceof Ci.nsINetworkInfo,
- "networkInfo should be an instance of nsINetworkInfo");
-
- let ipAddresses = {};
- let prefixs = {};
- let numOfGateways = {};
- let numOfDnses = {};
- let numOfIpAddresses = networkInfo.getAddresses(ipAddresses, prefixs);
- let gateways = networkInfo.getGateways(numOfGateways);
- let dnses = networkInfo.getDnses(numOfDnses);
-
- if (aMobileDataEnabled) {
- // Mobile data is enabled.
- is(networkInfo.state, NETWORK_STATE_CONNECTED, "check state");
- ok(numOfIpAddresses > 0, "check number of ipAddresses");
- ok(ipAddresses.value.length > 0, "check ipAddresses.length");
- ok(prefixs.value.length > 0, "check prefixs.length");
- ok(numOfGateways.value > 0, "check number of gateways");
- ok(prefixs.value.length > 0, "check prefixs.length");
- ok(gateways.length > 0, "check gateways.length");
- ok(numOfDnses.value > 0, "check number of dnses");
- ok(dnses.length > 0, "check dnses.length");
- } else {
- // Mobile data is disabled.
- is(networkInfo.state, NETWORK_STATE_DISCONNECTED, "check state");
- is(numOfIpAddresses, 0, "check number of ipAddresses");
- is(ipAddresses.value.length, 0, "check ipAddresses.length");
- is(prefixs.value.length, 0, "check prefixs.length");
- is(numOfGateways.value, 0, "check number of gateways");
- is(prefixs.value.length, 0, "check prefixs.length");
- is(gateways.length, 0, "check gateways.length");
- is(numOfDnses.value, 0, "check number of dnses");
- is(dnses.length, 0, "check dnses.length");
- }
- });
-}
-
-// Start test
-startTestBase(function() {
- return Promise.resolve()
- // Test initial State
- .then(() => {
- log("Test initial state");
-
- // Data should be off before starting any test.
- return getSettings(SETTINGS_KEY_DATA_ENABLED)
- .then(value => {
- is(value, false, "Mobile data must be off");
- });
- })
-
- // Test getDataInterfaceList with mobile data enabled.
- .then(() => testGetDataInterfaceList(true))
-
- // Test getDataInterfaceList with mobile data disabled.
- .then(() => testGetDataInterfaceList(false));
-});
diff --git a/dom/system/gonk/tests/marionette/test_network_interface_mtu.js b/dom/system/gonk/tests/marionette/test_network_interface_mtu.js
deleted file mode 100644
index 679efe2ed3..0000000000
--- a/dom/system/gonk/tests/marionette/test_network_interface_mtu.js
+++ /dev/null
@@ -1,100 +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 TEST_MTU1 = "1410";
-const TEST_MTU2 = "1440";
-
-function setEmulatorAPN() {
- let apn = [
- [ { "carrier":"T-Mobile US",
- "apn":"epc1.tmobile.com",
- "types":["default"],
- "mtu": TEST_MTU1 },
- { "carrier":"T-Mobile US",
- "apn":"epc2.tmobile.com",
- "mmsc":"http://mms.msg.eng.t-mobile.com/mms/wapenc",
- "types":["supl","mms","ims","dun", "fota"],
- "mtu": TEST_MTU2 } ]
- ];
-
- return setSettings(SETTINGS_KEY_DATA_APN_SETTINGS, apn);
-}
-
-function verifyInitialState() {
- // Data should be off before starting any test.
- return getSettings(SETTINGS_KEY_DATA_ENABLED)
- .then(value => {
- is(value, false, "Data must be off");
- });
-}
-
-function verifyMtu(aInterfaceName, aMtu) {
- return runEmulatorShellCmdSafe(['ip', 'link', 'show', 'dev', aInterfaceName])
- .then(aLines => {
- // Sample output:
- //
- // 4: rmnet0: <BROADCAST,MULTICAST> mtu 1410 qdisc pfifo_fast state DOWN mode DEFAULT qlen 1000
- // link/ether 52:54:00:12:34:58 brd ff:ff:ff:ff:ff:ff
- //
- let mtu;
- aLines.some(function (aLine) {
- let tokens = aLine.trim().split(/\s+/);
- let mtuIndex = tokens.indexOf('mtu');
- if (mtuIndex < 0 || mtuIndex + 1 >= tokens.length) {
- return false;
- }
-
- mtu = tokens[mtuIndex + 1];
- return true;
- });
-
- is(mtu, aMtu, aInterfaceName + "'s mtu.");
- });
-}
-
-function testDefaultDataCallMtu() {
- log("= testDefaultDataCallMtu =");
-
- return setDataEnabledAndWait(true)
- .then(aNetworkInfo => verifyMtu(aNetworkInfo.name, TEST_MTU1))
- .then(() => setDataEnabledAndWait(false));
-}
-
-function testNonDefaultDataCallMtu() {
- log("= testNonDefaultDataCallMtu =");
-
- function doTestNonDefaultDataCallMtu(aType) {
- log("doTestNonDefaultDataCallMtu: " + aType);
-
- return setupDataCallAndWait(aType)
- .then(aNetworkInfo => verifyMtu(aNetworkInfo.name, TEST_MTU2))
- .then(() => deactivateDataCallAndWait(aType));
- }
-
- return doTestNonDefaultDataCallMtu(NETWORK_TYPE_MOBILE_MMS)
- .then(() => doTestNonDefaultDataCallMtu(NETWORK_TYPE_MOBILE_SUPL))
- .then(() => doTestNonDefaultDataCallMtu(NETWORK_TYPE_MOBILE_IMS))
- .then(() => doTestNonDefaultDataCallMtu(NETWORK_TYPE_MOBILE_DUN))
- .then(() => doTestNonDefaultDataCallMtu(NETWORK_TYPE_MOBILE_FOTA));
-}
-
-// Start test
-startTestBase(function() {
- let origApnSettings;
- return verifyInitialState()
- .then(() => getSettings(SETTINGS_KEY_DATA_APN_SETTINGS))
- .then(value => {
- origApnSettings = value;
- })
- .then(() => setEmulatorAPN())
- .then(() => testDefaultDataCallMtu())
- .then(() => testNonDefaultDataCallMtu())
- .then(() => {
- if (origApnSettings) {
- return setSettings(SETTINGS_KEY_DATA_APN_SETTINGS, origApnSettings);
- }
- });
-});
diff --git a/dom/system/gonk/tests/marionette/test_ril_code_quality.py b/dom/system/gonk/tests/marionette/test_ril_code_quality.py
deleted file mode 100644
index d741d8a2e8..0000000000
--- a/dom/system/gonk/tests/marionette/test_ril_code_quality.py
+++ /dev/null
@@ -1,371 +0,0 @@
-"""
-The test performs the static code analysis check by JSHint.
-
-Target js files:
-- RadioInterfaceLayer.js
-- ril_worker.js
-- ril_consts.js
-
-If the js file contains the line of 'importScript()' (Ex: ril_worker.js), the
-test will perform a special merge step before excuting JSHint.
-
-Ex: Script A
---------------------------------
-importScripts('Script B')
-...
---------------------------------
-
-We merge these two scripts into one by the following way.
-
---------------------------------
-[Script B (ex: ril_consts.js)]
-(function(){ [Script A (ex: ril_worker.js)]
-})();
---------------------------------
-
-Script A (ril_worker.js) runs global strict mode.
-Script B (ril_consts.js) not.
-
-The above merge way ensures the correct scope of 'strict mode.'
-"""
-
-import bisect
-import inspect
-import os
-import os.path
-import re
-import unicodedata
-
-from marionette_harness import MarionetteTestCase
-
-
-class StringUtility:
-
- """A collection of some string utilities."""
-
- @staticmethod
- def find_match_lines(lines, pattern):
- """Return a list of lines that contains given pattern."""
- return [line for line in lines if pattern in line]
-
- @staticmethod
- def remove_non_ascii(data):
- """Remove non ascii characters in data and return it as new string."""
- if type(data).__name__ == 'unicode':
- data = unicodedata.normalize(
- 'NFKD', data).encode('ascii', 'ignore')
- return data
-
- @staticmethod
- def auto_close(lines):
- """Ensure every line ends with '\n'."""
- if lines and not lines[-1].endswith('\n'):
- lines[-1] += '\n'
- return lines
-
- @staticmethod
- def auto_wrap_strict_mode(lines):
- """Wrap by function scope if lines contain 'use strict'."""
- if StringUtility.find_match_lines(lines, 'use strict'):
- lines[0] = '(function(){' + lines[0]
- lines.append('})();\n')
- return lines
-
- @staticmethod
- def get_imported_list(lines):
- """Get a list of imported items."""
- return [item
- for line in StringUtility.find_match_lines(lines, 'importScripts')
- for item in StringUtility._get_imported_list_from_line(line)]
-
- @staticmethod
- def _get_imported_list_from_line(line):
- """Extract all items from 'importScripts(...)'.
-
- importScripts("ril_consts.js", "systemlibs.js")
- => ['ril_consts', 'systemlibs.js']
-
- """
- pattern = re.compile(r'\s*importScripts\((.*)\)')
- m = pattern.match(line)
- if not m:
- raise Exception('Parse importScripts error.')
- return [name.translate(None, '\' "') for name in m.group(1).split(',')]
-
-
-class ResourceUriFileReader:
-
- """Handle the process of reading the source code from system."""
-
- URI_PREFIX = 'resource://gre/'
- URI_PATH = {
- 'RadioInterfaceLayer.js': 'components/RadioInterfaceLayer.js',
- 'ril_worker.js': 'modules/ril_worker.js',
- 'ril_consts.js': 'modules/ril_consts.js',
- 'systemlibs.js': 'modules/systemlibs.js',
- 'worker_buf.js': 'modules/workers/worker_buf.js',
- }
-
- CODE_OPEN_CHANNEL_BY_URI = '''
- var Cc = Components.classes;
- var Ci = Components.interfaces;
- var ios = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
- var secMan = Cc["@mozilla.org/scriptsecuritymanager;1"].getService(Ci.nsIScriptSecurityManager);
- global.uri = '%(uri)s';
- global.channel = ios.newChannel2(global.uri,
- null,
- null,
- null, // aLoadingNode
- secMan.getSystemPrincipal(),
- null, // aTriggeringPrincipal
- Ci.nsILoadInfo.SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL,
- Ci.nsIContentPolicy.TYPE_OTHER);
- '''
-
- CODE_GET_SPEC = '''
- return global.channel.URI.spec;
- '''
-
- CODE_READ_CONTENT = '''
- var Cc = Components.classes;
- var Ci = Components.interfaces;
-
- var zipReader = Cc["@mozilla.org/libjar/zip-reader;1"].createInstance(Ci.nsIZipReader);
- var inputStream = Cc["@mozilla.org/scriptableinputstream;1"].createInstance(Ci.nsIScriptableInputStream);
-
- var jaruri = global.channel.URI.QueryInterface(Ci.nsIJARURI);
- var file = jaruri.JARFile.QueryInterface(Ci.nsIFileURL).file;
- var entry = jaruri.JAREntry;
- zipReader.open(file);
- inputStream.init(zipReader.getInputStream(entry));
- var content = inputStream.read(inputStream.available());
- inputStream.close();
- zipReader.close();
- return content;
- '''
-
- @classmethod
- def get_uri(cls, filename):
- """Convert filename to URI in system."""
- if filename.startswith(cls.URI_PREFIX):
- return filename
- else:
- return cls.URI_PREFIX + cls.URI_PATH[filename]
-
- def __init__(self, marionette):
- self.runjs = lambda x: marionette.execute_script(x,
- new_sandbox=False,
- sandbox='system')
-
- def read_file(self, filename):
- """Read file and return the contents as string."""
- content = self._read_uri(self.get_uri(filename))
- content = content.replace('"use strict";', '')
- return StringUtility.remove_non_ascii(content)
-
- def _read_uri(self, uri):
- """Read URI in system and return the contents as string."""
- # Open the uri as a channel.
- self.runjs(self.CODE_OPEN_CHANNEL_BY_URI % {'uri': uri})
-
- # Make sure spec is a jar uri, and not recursive.
- # Ex: 'jar:file:///system/b2g/omni.ja!/modules/ril_worker.js'
- #
- # For simplicity, we don't handle other special cases in this test.
- # If B2G build system changes in the future, such as put the jar in
- # another jar, the test case will fail.
- spec = self.runjs(self.CODE_GET_SPEC)
- if (not spec.startswith('jar:file://')) or (spec.count('jar:') != 1):
- raise Exception('URI resolve error')
-
- # Read the content from channel.
- content = self.runjs(self.CODE_READ_CONTENT)
- return content
-
-
-class JSHintEngine:
-
- """Invoke jshint script on system."""
-
- CODE_INIT_JSHINT = '''
- %(script)s;
- global.JSHINT = JSHINT;
- global.options = JSON.parse(%(config_string)s);
- global.globals = global.options.globals;
- delete global.options.globals;
- '''
-
- CODE_RUN_JSHINT = '''
- global.script = %(code)s;
- return global.JSHINT(global.script, global.options, global.globals);
- '''
-
- CODE_GET_JSHINT_ERROR = '''
- return global.JSHINT.errors;
- '''
-
- def __init__(self, marionette, script, config):
- # Remove single line comment in config.
- config = '\n'.join([line.partition('//')[0]
- for line in config.splitlines()])
-
- # Set global (JSHINT, options, global) in js environment.
- self.runjs = lambda x: marionette.execute_script(x,
- new_sandbox=False,
- sandbox='system')
- self.runjs(self.CODE_INIT_JSHINT %
- {'script': script, 'config_string': repr(config)})
-
- def run(self, code, filename=''):
- """Excute JShint check for the given code."""
- check_pass = self.runjs(self.CODE_RUN_JSHINT % {'code': repr(code)})
- errors = self.runjs(self.CODE_GET_JSHINT_ERROR)
- return check_pass, self._get_error_messages(errors, filename)
-
- def _get_error_messages(self, errors, filename=''):
- """
- Convert an error object to a list of readable string.
-
- [{"a": null, "c": null, "code": "W033", "d": null, "character": 6,
- "evidence": "var a", "raw": "Missing semicolon.",
- "reason": "Missing semicolon.", "b": null, "scope": "(main)", "line": 1,
- "id": "(error)"}]
- => line 1, col 6, Missing semicolon.
-
- """
- LINE, COL, REASON = u'line', u'character', u'reason'
- return ["%s: line %s, col %s, %s" %
- (filename, error[LINE], error[COL], error[REASON])
- for error in errors if error]
-
-
-class Linter:
-
- """Handle the linting related process."""
-
- def __init__(self, code_reader, jshint, reporter=None):
- """Set the linter with code_reader, jshint engine, and reporter.
-
- Should have following functionality.
- - code_reader.read_file(filename)
- - jshint.run(code, filename)
- - reporter([...])
-
- """
- self.code_reader = code_reader
- self.jshint = jshint
- if reporter is None:
- self.reporter = lambda x: '\n'.join(x)
- else:
- self.reporter = reporter
-
- def lint_file(self, filename):
- """Lint the file and return (pass, error_message)."""
- # Get code contents.
- code = self.code_reader.read_file(filename)
- lines = code.splitlines()
- import_list = StringUtility.get_imported_list(lines)
- if not import_list:
- check_pass, error_message = self.jshint.run(code, filename)
- else:
- newlines, info = self._merge_multiple_codes(filename, import_list)
- # Each line of |newlines| contains '\n'.
- check_pass, error_message = self.jshint.run(''.join(newlines))
- error_message = self._convert_merged_result(error_message, info)
- # Only keep errors for this file.
- error_message = [line for line in error_message
- if line.startswith(filename)]
- check_pass = (len(error_message) == 0)
- return check_pass, self.reporter(error_message)
-
- def _merge_multiple_codes(self, filename, import_list):
- """Merge multiple codes from filename and import_list."""
- dirname, filename = os.path.split(filename)
- dst_line = 1
- dst_results = []
- info = []
-
- # Put the imported script first, and then the original script.
- for f in import_list + [filename]:
- filepath = os.path.join(dirname, f)
-
- # Maintain a mapping table.
- # New line number after merge => original file and line number.
- info.append((dst_line, filepath, 1))
- try:
- code = self.code_reader.read_file(filepath)
- lines = code.splitlines(True) # Keep '\n'.
- src_results = StringUtility.auto_wrap_strict_mode(
- StringUtility.auto_close(lines))
- dst_results.extend(src_results)
- dst_line += len(src_results)
- except:
- info.pop()
- return dst_results, info
-
- def _convert_merged_result(self, error_lines, line_info):
- pattern = re.compile(r'(.*): line (\d+),(.*)')
- start_line = [info[0] for info in line_info]
- new_result_lines = []
- for line in error_lines:
- m = pattern.match(line)
- if not m:
- continue
-
- line_number, remain = int(m.group(2)), m.group(3)
-
- # [1, 2, 7, 8]
- # ^ for 7, pos = 3
- # ^ for 6, pos = 2
- pos = bisect.bisect_right(start_line, line_number)
- dst_line, name, src_line = line_info[pos - 1]
- real_line_number = line_number - dst_line + src_line
- new_result_lines.append(
- "%s: line %s,%s" % (name, real_line_number, remain))
- return new_result_lines
-
-
-class TestRILCodeQuality(MarionetteTestCase):
-
- JSHINT_PATH = 'ril_jshint/jshint.js'
- JSHINTRC_PATH = 'ril_jshint/jshintrc'
-
- def _read_local_file(self, filepath):
- """Read file content from local (folder of this test case)."""
- test_dir = os.path.dirname(inspect.getfile(TestRILCodeQuality))
- return open(os.path.join(test_dir, filepath)).read()
-
- def _get_extended_error_message(self, error_message):
- return '\n'.join(['See errors below and more information in Bug 880643',
- '\n'.join(error_message),
- 'See errors above and more information in Bug 880643'])
-
- def _check(self, filename):
- check_pass, error_message = self.linter.lint_file(filename)
- self.assertTrue(check_pass, error_message)
-
- def setUp(self):
- MarionetteTestCase.setUp(self)
- self.linter = Linter(
- ResourceUriFileReader(self.marionette),
- JSHintEngine(self.marionette,
- self._read_local_file(self.JSHINT_PATH),
- self._read_local_file(self.JSHINTRC_PATH)),
- self._get_extended_error_message)
-
- def tearDown(self):
- MarionetteTestCase.tearDown(self)
-
- def test_RadioInterfaceLayer(self):
- self._check('RadioInterfaceLayer.js')
-
- # Bug 936504. Disable the test for 'ril_worker.js'. It sometimes runs very
- # slow and causes the timeout fail on try server.
- #def test_ril_worker(self):
- # self._check('ril_worker.js')
-
- def test_ril_consts(self):
- self._check('ril_consts.js')
-
- def test_worker_buf(self):
- self._check('worker_buf.js')
diff --git a/dom/system/gonk/tests/marionette/test_screen_state.js b/dom/system/gonk/tests/marionette/test_screen_state.js
deleted file mode 100644
index 2281412d54..0000000000
--- a/dom/system/gonk/tests/marionette/test_screen_state.js
+++ /dev/null
@@ -1,47 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-MARIONETTE_TIMEOUT = 10000;
-
-var Services = SpecialPowers.Services;
-
-function testScreenState(on, expected, msg) {
- // send event to RadioInterface
- Services.obs.notifyObservers(null, 'screen-state-changed', on);
- // maybe rild/qemu needs some time to process the event
- window.setTimeout(function() {
- runEmulatorCmd('gsm report creg', function(result) {
- is(result.pop(), 'OK', '\'gsm report creg\' successful');
- ok(result.indexOf(expected) !== -1, msg);
- runNextTest();
- })}, 1000);
-}
-
-function testScreenStateDisabled() {
- testScreenState('off', '+CREG: 1', 'screen is disabled');
-}
-
-function testScreenStateEnabled() {
- testScreenState('on', '+CREG: 2', 'screen is enabled');
-}
-
-var tests = [
- testScreenStateDisabled,
- testScreenStateEnabled
-];
-
-function runNextTest() {
- let test = tests.shift();
- if (!test) {
- cleanUp();
- return;
- }
-
- test();
-}
-
-function cleanUp() {
- finish();
-}
-
-runNextTest();
diff --git a/dom/system/gonk/tests/marionette/test_timezone_changes.js b/dom/system/gonk/tests/marionette/test_timezone_changes.js
deleted file mode 100644
index 11dbaec5a8..0000000000
--- a/dom/system/gonk/tests/marionette/test_timezone_changes.js
+++ /dev/null
@@ -1,135 +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';
-
-function init() {
- let promises = [];
-
- /*
- * The initial timezone of the emulator could be anywhere, depends the host
- * machine. Ensure resetting it to UTC before testing.
- */
- promises.push(runEmulatorCmdSafe('gsm timezone 0'));
- promises.push(new Promise((aResolve, aReject) => {
- waitFor(aResolve, () => {
- return new Date().getTimezoneOffset() === 0;
- });
- }));
-
- return Promise.all(promises);
-}
-
-function paddingZeros(aNumber, aLength) {
- let str = '' + aNumber;
- while (str.length < aLength) {
- str = '0' + str;
- }
-
- return str;
-}
-
-function verifyDate(aTestDate, aUTCOffsetDate) {
- // Verify basic properties.
- is(aUTCOffsetDate.getUTCFullYear(), aTestDate.getFullYear(), 'year');
- is(aUTCOffsetDate.getUTCMonth(), aTestDate.getMonth(), 'month');
- is(aUTCOffsetDate.getUTCDate(), aTestDate.getDate(), 'date');
- is(aUTCOffsetDate.getUTCHours(), aTestDate.getHours(), 'hours');
- is(aUTCOffsetDate.getUTCMinutes(), aTestDate.getMinutes(), 'minutes');
- is(aUTCOffsetDate.getUTCMilliseconds(), aTestDate.getMilliseconds(), 'milliseconds');
-
- // Ensure toLocaleString also uses correct timezone.
- // It uses ICU's timezone instead of the offset calculated from gecko prtime.
- let expectedDateString =
- paddingZeros(aUTCOffsetDate.getUTCMonth() + 1, 2) + '/' +
- paddingZeros(aUTCOffsetDate.getUTCDate(), 2);
- let dateString = aTestDate.toLocaleString('en-US', {
- month: '2-digit',
- day: '2-digit',
- });
- let expectedTimeString =
- paddingZeros(aUTCOffsetDate.getUTCHours(), 2) + ':' +
- paddingZeros(aUTCOffsetDate.getUTCMinutes(), 2);
- let timeString = aTestDate.toLocaleString('en-US', {
- hour12: false,
- hour: '2-digit',
- minute: '2-digit'
- });
-
- is(expectedDateString, dateString, 'dateString');
- is(expectedTimeString, timeString, 'timeString');
-}
-
-function waitForTimezoneUpdate(aTzOffset,
- aTestDateInMillis = 86400000, // Use 'UTC 00:00:00, 2nd of Jan, 1970' by default.
- aTransTzOffset, aTransTestDateInMillis) {
- return new Promise(function(aResolve, aReject) {
- window.addEventListener('moztimechange', function onevent(aEvent) {
- // Since there could be multiple duplicate moztimechange event, wait until
- // timezone is actually changed to expected value before removing the
- // listener.
- let testDate = new Date(aTestDateInMillis);
- if (testDate.getTimezoneOffset() === aTzOffset) {
- window.removeEventListener('moztimechange', onevent);
-
- // The UTC time of offsetDate is the same as the expected local time of
- // testDate. We'll use it to verify the values.
- let offsetDate = new Date(aTestDateInMillis - aTzOffset * 60 * 1000);
- verifyDate(testDate, offsetDate);
-
- // Verify transition time if given.
- if (aTransTzOffset !== undefined) {
- testDate = new Date(aTransTestDateInMillis);
- is(testDate.getTimezoneOffset(), aTransTzOffset);
-
- // Verify transition date.
- offsetDate = new Date(aTransTestDateInMillis - aTransTzOffset * 60 * 1000);
- verifyDate(testDate, offsetDate);
- }
-
- aResolve(aEvent);
- }
- });
- });
-}
-
-function testChangeNitzTimezone(aTzDiff) {
- let promises = [];
-
- // aTzOffset should be the expected value for getTimezoneOffset().
- // Note that getTimezoneOffset() is not so straightforward,
- // it values (UTC - localtime), so UTC+08:00 returns -480.
- promises.push(waitForTimezoneUpdate(-aTzDiff * 15));
- promises.push(runEmulatorCmdSafe('gsm timezone ' + aTzDiff));
-
- return Promise.all(promises);
-}
-
-function testChangeOlsonTimezone(aOlsonTz, aTzOffset, aTestDateInMillis,
- aTransTzOffset, aTransTestDateInMillis) {
- let promises = [];
-
- promises.push(waitForTimezoneUpdate(aTzOffset, aTestDateInMillis,
- aTransTzOffset, aTransTestDateInMillis));
- promises.push(setSettings('time.timezone', aOlsonTz));
-
- return Promise.all(promises);
-}
-
-// Start test
-startTestBase(function() {
- return init()
- .then(() => testChangeNitzTimezone(36)) // UTC+09:00
- .then(() => testChangeOlsonTimezone('America/New_York',
- 300, 1446357600000, // 2015/11/01 02:00 UTC-04:00 => 01:00 UTC-05:00 (EST)
- 240, 1425798000000)) // 2015/03/08 02:00 UTC-05:00 => 03:00 UTC-04:00 (EDT)
- .then(() => testChangeNitzTimezone(-22)) // UTC-05:30
- .then(() => testChangeNitzTimezone(51)) // UTC+12:45
- .then(() => testChangeOlsonTimezone('Australia/Adelaide',
- -570, 1428165000000, // 2015/04/05 03:00 UTC+10:30 => 02:00 UTC+09:30 (ACST)
- -630, 1443889800000)) // 2015/10/04 02:00 UTC+09:30 => 03:00 UTC+10:30 (ACDT)
- .then(() => testChangeNitzTimezone(-38)) // UTC-09:30
- .then(() => testChangeNitzTimezone(0)) // UTC
- .then(() => runEmulatorCmdSafe('gsm timezone auto'));
-});
diff --git a/dom/system/gonk/tests/test_ril_system_messenger.js b/dom/system/gonk/tests/test_ril_system_messenger.js
deleted file mode 100644
index a588d0ddb8..0000000000
--- a/dom/system/gonk/tests/test_ril_system_messenger.js
+++ /dev/null
@@ -1,1187 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-var {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
-
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-
-var RIL = {};
-Cu.import("resource://gre/modules/ril_consts.js", RIL);
-
-XPCOMUtils.defineLazyServiceGetter(this, "gStkCmdFactory",
- "@mozilla.org/icc/stkcmdfactory;1",
- "nsIStkCmdFactory");
-
-/**
- * Name space for RILSystemMessenger.jsm. Only initialized after first call to
- * newRILSystemMessenger.
- */
-var RSM;
-
-var gReceivedMsgType = null;
-var gReceivedMessage = null;
-
-/**
- * Create a new RILSystemMessenger instance.
- *
- * @return a RILSystemMessenger instance.
- */
-function newRILSystemMessenger() {
- if (!RSM) {
- RSM = Cu.import("resource://gre/modules/RILSystemMessenger.jsm", {});
- equal(typeof RSM.RILSystemMessenger, "function", "RSM.RILSystemMessenger");
- }
-
- let rsm = new RSM.RILSystemMessenger();
- rsm.broadcastMessage = (aType, aMessage) => {
- gReceivedMsgType = aType;
- gReceivedMessage = aMessage;
- };
-
- rsm.createCommandMessage = (aStkProactiveCmd) => {
- return gStkCmdFactory.createCommandMessage(aStkProactiveCmd);
- };
-
- return rsm;
-}
-
-function equal_received_system_message(aType, aMessage) {
- equal(aType, gReceivedMsgType);
- deepEqual(aMessage, gReceivedMessage);
- gReceivedMsgType = null;
- gReceivedMessage = null;
-}
-
-/**
- * Verify that each nsIXxxMessenger could be retrieved.
- */
-function run_test() {
- let telephonyMessenger = Cc["@mozilla.org/ril/system-messenger-helper;1"]
- .getService(Ci.nsITelephonyMessenger);
-
- let smsMessenger = Cc["@mozilla.org/ril/system-messenger-helper;1"]
- .getService(Ci.nsISmsMessenger);
-
- let cellbroadcastMessenger = Cc["@mozilla.org/ril/system-messenger-helper;1"]
- .getService(Ci.nsICellbroadcastMessenger);
-
- let mobileConnectionMessenger = Cc["@mozilla.org/ril/system-messenger-helper;1"]
- .getService(Ci.nsIMobileConnectionMessenger);
-
- let iccMessenger = Cc["@mozilla.org/ril/system-messenger-helper;1"]
- .getService(Ci.nsIIccMessenger);
-
- ok(telephonyMessenger !== null, "Get TelephonyMessenger.");
- ok(smsMessenger != null, "Get SmsMessenger.");
- ok(cellbroadcastMessenger != null, "Get CellbroadcastMessenger.");
- ok(mobileConnectionMessenger != null, "Get MobileConnectionMessenger.");
- ok(iccMessenger != null, "Get IccMessenger.");
-
- run_next_test();
-}
-
-/**
- * Verify RILSystemMessenger.notifyNewCall()
- */
-add_test(function test_telephony_messenger_notify_new_call() {
- let messenger = newRILSystemMessenger();
-
- messenger.notifyNewCall();
- equal_received_system_message("telephony-new-call", {});
-
- run_next_test();
-});
-
-/**
- * Verify RILSystemMessenger.notifyCallEnded()
- */
-add_test(function test_telephony_messenger_notify_call_ended() {
- let messenger = newRILSystemMessenger();
-
- messenger.notifyCallEnded(1,
- "+0987654321",
- null,
- true,
- 500,
- false,
- true);
-
- equal_received_system_message("telephony-call-ended", {
- serviceId: 1,
- number: "+0987654321",
- emergency: true,
- duration: 500,
- direction: "incoming",
- hangUpLocal: true
- });
-
- // Verify 'optional' parameter of secondNumber.
- messenger.notifyCallEnded(1,
- "+0987654321",
- "+1234567890",
- true,
- 500,
- true,
- false);
-
- equal_received_system_message("telephony-call-ended", {
- serviceId: 1,
- number: "+0987654321",
- emergency: true,
- duration: 500,
- direction: "outgoing",
- hangUpLocal: false,
- secondNumber: "+1234567890"
- });
-
- run_next_test();
-});
-
-/**
- * Verify RILSystemMessenger.notifySms()
- */
-add_test(function test_sms_messenger_notify_sms() {
- let messenger = newRILSystemMessenger();
- let timestamp = Date.now();
- let sentTimestamp = timestamp + 100;
- let deliveryTimestamp = sentTimestamp + 100;
-
- // Verify 'sms-received' system message.
- messenger.notifySms(Ci.nsISmsMessenger.NOTIFICATION_TYPE_RECEIVED,
- 1,
- 2,
- "99887766554433221100",
- Ci.nsISmsService.DELIVERY_TYPE_RECEIVED,
- Ci.nsISmsService.DELIVERY_STATUS_TYPE_SUCCESS,
- "+0987654321",
- null,
- "Incoming message",
- Ci.nsISmsService.MESSAGE_CLASS_TYPE_CLASS_2,
- timestamp,
- sentTimestamp,
- 0,
- false);
-
- equal_received_system_message("sms-received", {
- iccId: "99887766554433221100",
- type: "sms",
- id: 1,
- threadId: 2,
- delivery: "received",
- deliveryStatus: "success",
- sender: "+0987654321",
- receiver: null,
- body: "Incoming message",
- messageClass: "class-2",
- timestamp: timestamp,
- sentTimestamp: sentTimestamp,
- deliveryTimestamp: 0,
- read: false
- });
-
- // Verify 'sms-sent' system message.
- messenger.notifySms(Ci.nsISmsMessenger.NOTIFICATION_TYPE_SENT,
- 3,
- 4,
- "99887766554433221100",
- Ci.nsISmsService.DELIVERY_TYPE_SENT,
- Ci.nsISmsService.DELIVERY_STATUS_TYPE_PENDING,
- null,
- "+0987654321",
- "Outgoing message",
- Ci.nsISmsService.MESSAGE_CLASS_TYPE_NORMAL,
- timestamp,
- 0,
- 0,
- true);
-
- equal_received_system_message("sms-sent", {
- iccId: "99887766554433221100",
- type: "sms",
- id: 3,
- threadId: 4,
- delivery: "sent",
- deliveryStatus: "pending",
- sender: null,
- receiver: "+0987654321",
- body: "Outgoing message",
- messageClass: "normal",
- timestamp: timestamp,
- sentTimestamp: 0,
- deliveryTimestamp: 0,
- read: true
- });
-
- // Verify 'sms-delivery-success' system message.
- messenger.notifySms(Ci.nsISmsMessenger.NOTIFICATION_TYPE_DELIVERY_SUCCESS,
- 5,
- 6,
- "99887766554433221100",
- Ci.nsISmsService.DELIVERY_TYPE_SENT,
- Ci.nsISmsService.DELIVERY_STATUS_TYPE_SUCCESS,
- null,
- "+0987654321",
- "Outgoing message",
- Ci.nsISmsService.MESSAGE_CLASS_TYPE_NORMAL,
- timestamp,
- 0,
- deliveryTimestamp,
- true);
-
- equal_received_system_message("sms-delivery-success", {
- iccId: "99887766554433221100",
- type: "sms",
- id: 5,
- threadId: 6,
- delivery: "sent",
- deliveryStatus: "success",
- sender: null,
- receiver: "+0987654321",
- body: "Outgoing message",
- messageClass: "normal",
- timestamp: timestamp,
- sentTimestamp: 0,
- deliveryTimestamp: deliveryTimestamp,
- read: true
- });
-
- // Verify 'sms-failed' system message.
- messenger.notifySms(Ci.nsISmsMessenger.NOTIFICATION_TYPE_SENT_FAILED,
- 7,
- 8,
- "99887766554433221100",
- Ci.nsISmsService.DELIVERY_TYPE_ERROR,
- Ci.nsISmsService.DELIVERY_STATUS_TYPE_ERROR,
- null,
- "+0987654321",
- "Outgoing message",
- Ci.nsISmsService.MESSAGE_CLASS_TYPE_NORMAL,
- timestamp,
- 0,
- 0,
- true);
-
- equal_received_system_message("sms-failed", {
- iccId: "99887766554433221100",
- type: "sms",
- id: 7,
- threadId: 8,
- delivery: "error",
- deliveryStatus: "error",
- sender: null,
- receiver: "+0987654321",
- body: "Outgoing message",
- messageClass: "normal",
- timestamp: timestamp,
- sentTimestamp: 0,
- deliveryTimestamp: 0,
- read: true
- });
-
- // Verify 'sms-delivery-error' system message.
- messenger.notifySms(Ci.nsISmsMessenger.NOTIFICATION_TYPE_DELIVERY_ERROR,
- 9,
- 10,
- "99887766554433221100",
- Ci.nsISmsService.DELIVERY_TYPE_SENT,
- Ci.nsISmsService.DELIVERY_STATUS_TYPE_ERROR,
- null,
- "+0987654321",
- "Outgoing message",
- Ci.nsISmsService.MESSAGE_CLASS_TYPE_NORMAL,
- timestamp,
- 0,
- 0,
- true);
-
- equal_received_system_message("sms-delivery-error", {
- iccId: "99887766554433221100",
- type: "sms",
- id: 9,
- threadId: 10,
- delivery: "sent",
- deliveryStatus: "error",
- sender: null,
- receiver: "+0987654321",
- body: "Outgoing message",
- messageClass: "normal",
- timestamp: timestamp,
- sentTimestamp: 0,
- deliveryTimestamp: 0,
- read: true
- });
-
- // Verify the protection of invalid nsISmsMessenger.NOTIFICATION_TYPEs.
- try {
- messenger.notifySms(5,
- 1,
- 2,
- "99887766554433221100",
- Ci.nsISmsService.DELIVERY_TYPE_RECEIVED,
- Ci.nsISmsService.DELIVERY_STATUS_TYPE_SUCCESS,
- "+0987654321",
- null,
- "Incoming message",
- Ci.nsISmsService.MESSAGE_CLASS_TYPE_NORMAL,
- timestamp,
- sentTimestamp,
- 0,
- false);
- ok(false, "Failed to verify the protection of invalid nsISmsMessenger.NOTIFICATION_TYPE!");
- } catch (e) {}
-
- run_next_test();
-});
-
-/**
- * Verify RILSystemMessenger.notifyCbMessageReceived()
- */
-add_test(function test_cellbroadcast_messenger_notify_cb_message_received() {
- let messenger = newRILSystemMessenger();
- let timestamp = Date.now();
-
- // Verify ETWS
- messenger.notifyCbMessageReceived(0,
- Ci.nsICellBroadcastService.GSM_GEOGRAPHICAL_SCOPE_CELL_IMMEDIATE,
- 256,
- 4352,
- null,
- null,
- Ci.nsICellBroadcastService.GSM_MESSAGE_CLASS_NORMAL,
- timestamp,
- Ci.nsICellBroadcastService.CDMA_SERVICE_CATEGORY_INVALID,
- true,
- Ci.nsICellBroadcastService.GSM_ETWS_WARNING_EARTHQUAKE,
- false,
- true);
- equal_received_system_message("cellbroadcast-received", {
- serviceId: 0,
- gsmGeographicalScope: "cell-immediate",
- messageCode: 256,
- messageId: 4352,
- language: null,
- body: null,
- messageClass: "normal",
- timestamp: timestamp,
- cdmaServiceCategory: null,
- etws: {
- warningType: "earthquake",
- emergencyUserAlert: false,
- popup: true
- }
- });
-
- // Verify Normal CB Message
- messenger.notifyCbMessageReceived(1,
- Ci.nsICellBroadcastService.GSM_GEOGRAPHICAL_SCOPE_PLMN,
- 0,
- 50,
- "en",
- "The quick brown fox jumps over the lazy dog",
- Ci.nsICellBroadcastService.GSM_MESSAGE_CLASS_NORMAL,
- timestamp,
- Ci.nsICellBroadcastService.CDMA_SERVICE_CATEGORY_INVALID,
- false,
- Ci.nsICellBroadcastService.GSM_ETWS_WARNING_INVALID,
- false,
- false);
- equal_received_system_message("cellbroadcast-received", {
- serviceId: 1,
- gsmGeographicalScope: "plmn",
- messageCode: 0,
- messageId: 50,
- language: "en",
- body: "The quick brown fox jumps over the lazy dog",
- messageClass: "normal",
- timestamp: timestamp,
- cdmaServiceCategory: null,
- etws: null
- });
-
- // Verify CB Message with ETWS Info
- messenger.notifyCbMessageReceived(0,
- Ci.nsICellBroadcastService.GSM_GEOGRAPHICAL_SCOPE_LOCATION_AREA,
- 0,
- 4354,
- "en",
- "Earthquake & Tsunami Warning!",
- Ci.nsICellBroadcastService.GSM_MESSAGE_CLASS_0,
- timestamp,
- Ci.nsICellBroadcastService.CDMA_SERVICE_CATEGORY_INVALID,
- true,
- Ci.nsICellBroadcastService.GSM_ETWS_WARNING_EARTHQUAKE_TSUNAMI,
- true,
- false);
- equal_received_system_message("cellbroadcast-received", {
- serviceId: 0,
- gsmGeographicalScope: "location-area",
- messageCode: 0,
- messageId: 4354,
- language: "en",
- body: "Earthquake & Tsunami Warning!",
- messageClass: "class-0",
- timestamp: timestamp,
- cdmaServiceCategory: null,
- etws: {
- warningType: "earthquake-tsunami",
- emergencyUserAlert: true,
- popup: false
- }
- });
-
- // Verify CDMA CB Message
- messenger.notifyCbMessageReceived(0,
- Ci.nsICellBroadcastService.GSM_GEOGRAPHICAL_SCOPE_INVALID,
- 0,
- 0,
- null,
- "CDMA CB Message",
- Ci.nsICellBroadcastService.GSM_MESSAGE_CLASS_NORMAL,
- timestamp,
- 512,
- false,
- Ci.nsICellBroadcastService.GSM_ETWS_WARNING_INVALID,
- false,
- false);
- equal_received_system_message("cellbroadcast-received", {
- serviceId: 0,
- gsmGeographicalScope: null,
- messageCode: 0,
- messageId: 0,
- language: null,
- body: "CDMA CB Message",
- messageClass: "normal",
- timestamp: timestamp,
- cdmaServiceCategory: 512,
- etws: null
- });
-
- run_next_test();
-});
-
-/**
- * Verify RILSystemMessenger.notifyUssdReceived()
- */
-add_test(function test_mobileconnection_notify_ussd_received() {
- let messenger = newRILSystemMessenger();
-
- messenger.notifyUssdReceived(0, "USSD Message", false);
-
- equal_received_system_message("ussd-received", {
- serviceId: 0,
- message: "USSD Message",
- sessionEnded: false
- });
-
- messenger.notifyUssdReceived(1, "USSD Message", true);
-
- equal_received_system_message("ussd-received", {
- serviceId: 1,
- message: "USSD Message",
- sessionEnded: true
- });
-
- run_next_test();
-});
-
-/**
- * Verify RILSystemMessenger.notifyCdmaInfoRecXXX()
- */
-add_test(function test_mobileconnection_notify_cdma_info() {
- let messenger = newRILSystemMessenger();
-
- messenger.notifyCdmaInfoRecDisplay(0, "CDMA Display Info");
-
- equal_received_system_message("cdma-info-rec-received", {
- clientId: 0,
- display: "CDMA Display Info"
- });
-
- messenger.notifyCdmaInfoRecCalledPartyNumber(1, 1, 2, "+0987654321", 3, 4);
-
- equal_received_system_message("cdma-info-rec-received", {
- clientId: 1,
- calledNumber: {
- type: 1,
- plan: 2,
- number: "+0987654321",
- pi: 3,
- si: 4
- }
- });
-
- messenger.notifyCdmaInfoRecCallingPartyNumber(0, 5, 6, "+1234567890", 7, 8);
-
- equal_received_system_message("cdma-info-rec-received", {
- clientId: 0,
- callingNumber: {
- type: 5,
- plan: 6,
- number: "+1234567890",
- pi: 7,
- si: 8
- }
- });
-
- messenger.notifyCdmaInfoRecConnectedPartyNumber(1, 4, 3, "+56473839201", 2, 1);
-
- equal_received_system_message("cdma-info-rec-received", {
- clientId: 1,
- connectedNumber: {
- type: 4,
- plan: 3,
- number: "+56473839201",
- pi: 2,
- si: 1
- }
- });
-
- messenger.notifyCdmaInfoRecSignal(0, 1, 2, 3);
-
- equal_received_system_message("cdma-info-rec-received", {
- clientId: 0,
- signal: {
- type: 1,
- alertPitch: 2,
- signal: 3
- }
- });
-
- messenger.notifyCdmaInfoRecRedirectingNumber(1, 8, 7, "+1029384756", 6, 5, 4);
-
- equal_received_system_message("cdma-info-rec-received", {
- clientId: 1,
- redirect: {
- type: 8,
- plan: 7,
- number: "+1029384756",
- pi: 6,
- si: 5,
- reason: 4
- }
- });
-
- messenger.notifyCdmaInfoRecLineControl(0, 1, 0, 1, 255);
-
- equal_received_system_message("cdma-info-rec-received", {
- clientId: 0,
- lineControl: {
- polarityIncluded: 1,
- toggle: 0,
- reverse: 1,
- powerDenial: 255
- }
- });
-
- messenger.notifyCdmaInfoRecClir(1, 256);
-
- equal_received_system_message("cdma-info-rec-received", {
- clientId: 1,
- clirCause: 256
- });
-
- messenger.notifyCdmaInfoRecAudioControl(0, 255, -1);
-
- equal_received_system_message("cdma-info-rec-received", {
- clientId: 0,
- audioControl: {
- upLink: 255,
- downLink: -1
- }
- });
-
- run_next_test();
-});
-
-/**
- * Verify Error Handling of StkProactiveCmdFactory.createCommand()
- */
-add_test(function test_icc_stk_cmd_factory_create_command_error() {
- let messenger = newRILSystemMessenger();
-
- // Verify the protection of invalid typeOfCommand.
- try {
- gStkCmdFactory.createCommand({
- commandNumber: 0,
- typeOfCommand: RIL.STK_CMD_MORE_TIME, // Invalid TypeOfCommand
- commandQualifier: 0x00
- });
-
- ok(false, "Failed to verify the protection of createCommand()!");
- } catch (e) {
- ok(e.message.indexOf("Unknown Command Type") !== -1,
- "Invalid typeOfCommand!");
- }
-
- run_next_test();
-});
-
-/**
- * Verify Error Handling of StkProactiveCmdFactory.createCommandMessage()
- */
-add_test(function test_icc_stk_cmd_factory_create_system_msg_invalid_cmd_type() {
- let messenger = newRILSystemMessenger();
- let iccId = "99887766554433221100";
-
- // Verify the protection of invalid typeOfCommand.
- try {
- gStkCmdFactory.createCommandMessage({
- QueryInterface: XPCOMUtils.generateQI([Ci.nsIStkProactiveCmd]),
-
- // nsIStkProactiveCmd
- commandNumber: 0,
- typeOfCommand: RIL.STK_CMD_MORE_TIME, // Invalid TypeOfCommand
- commandQualifier: 0
- });
-
- ok(false, "Failed to identify invalid typeOfCommand!");
- } catch (e) {
- ok(e.message.indexOf("Unknown Command Type") !== -1,
- "Invalid typeOfCommand!");
- }
-
- run_next_test();
-});
-
-/**
- * Verify Error Handling of StkProactiveCmdFactory.createCommandMessage()
- */
-add_test(function test_icc_stk_cmd_factory_create_system_msg_incorrect_cmd_type() {
- let messenger = newRILSystemMessenger();
- let iccId = "99887766554433221100";
-
- // Verify the protection of invalid typeOfCommand.
- try {
- gStkCmdFactory.createCommandMessage({
- QueryInterface: XPCOMUtils.generateQI([Ci.nsIStkProactiveCmd,
- Ci.nsIStkProvideLocalInfoCmd]),
-
- // nsIStkProactiveCmd
- commandNumber: 0,
- typeOfCommand: RIL.STK_CMD_POLL_INTERVAL, // Incorrect typeOfCommand
- commandQualifier: 0,
- // nsIStkProvideLocalInfoCmd
- localInfoType: 0x00,
- });
-
- ok(false, "Failed to identify incorrect typeOfCommand!");
- } catch (e) {
- ok(e.message.indexOf("Failed to convert command into concrete class: ") !== -1);
- }
-
- run_next_test();
-});
-
-/**
- * Verify RILSystemMessenger.notifyStkProactiveCommand()
- */
-add_test(function test_icc_notify_stk_proactive_command() {
- let messenger = newRILSystemMessenger();
- let iccId = "99887766554433221100";
- let WHT = 0xFFFFFFFF;
- let BLK = 0x000000FF;
- let RED = 0xFF0000FF;
- let GRN = 0x00FF00FF;
- let BLU = 0x0000FFFF;
- let TSP = 0;
- // Basic Image, see Anex B.1 in TS 31.102.
- let basicIcon = {
- width: 8,
- height: 8,
- codingScheme: "basic",
- pixels: [WHT, WHT, WHT, WHT, WHT, WHT, WHT, WHT,
- BLK, BLK, BLK, BLK, BLK, BLK, WHT, WHT,
- WHT, BLK, WHT, BLK, BLK, WHT, BLK, WHT,
- WHT, BLK, BLK, WHT, WHT, BLK, BLK, WHT,
- WHT, BLK, BLK, WHT, WHT, BLK, BLK, WHT,
- WHT, BLK, WHT, BLK, BLK, WHT, BLK, WHT,
- WHT, WHT, BLK, BLK, BLK, BLK, WHT, WHT,
- WHT, WHT, WHT, WHT, WHT, WHT, WHT, WHT]
- };
- // Color Image, see Anex B.2 in TS 31.102.
- let colorIcon = {
- width: 8,
- height: 8,
- codingScheme: "color",
- pixels: [BLU, BLU, BLU, BLU, BLU, BLU, BLU, BLU,
- BLU, RED, RED, RED, RED, RED, RED, BLU,
- BLU, RED, GRN, GRN, GRN, RED, RED, BLU,
- BLU, RED, RED, GRN, GRN, RED, RED, BLU,
- BLU, RED, RED, GRN, GRN, RED, RED, BLU,
- BLU, RED, RED, GRN, GRN, GRN, RED, BLU,
- BLU, RED, RED, RED, RED, RED, RED, BLU,
- BLU, BLU, BLU, BLU, BLU, BLU, BLU, BLU]
- };
- // Color Image with Transparency, see Anex B.2 in TS 31.102.
- let colorTransparencyIcon = {
- width: 8,
- height: 8,
- codingScheme: "color-transparency",
- pixels: [TSP, TSP, TSP, TSP, TSP, TSP, TSP, TSP,
- TSP, RED, RED, RED, RED, RED, RED, TSP,
- TSP, RED, GRN, GRN, GRN, RED, RED, TSP,
- TSP, RED, RED, GRN, GRN, RED, RED, TSP,
- TSP, RED, RED, GRN, GRN, RED, RED, TSP,
- TSP, RED, RED, GRN, GRN, GRN, RED, TSP,
- TSP, RED, RED, RED, RED, RED, RED, TSP,
- TSP, TSP, TSP, TSP, TSP, TSP, TSP, TSP]
- };
-
- let cmdCount = 0;
-
- // Test Messages:
- let messages = [
- // STK_CMD_REFRESH
- {
- commandNumber: ++cmdCount,
- typeOfCommand: RIL.STK_CMD_REFRESH,
- commandQualifier: 0x04 // UICC Reset
- },
- // STK_CMD_POLL_INTERVAL
- {
- commandNumber: ++cmdCount,
- typeOfCommand: RIL.STK_CMD_POLL_INTERVAL,
- commandQualifier: 0x00, // RFU
- options: {
- timeUnit: RIL.STK_TIME_UNIT_TENTH_SECOND,
- timeInterval: 0x05
- }
- },
- // STK_CMD_POLL_OFF
- {
- commandNumber: ++cmdCount,
- typeOfCommand: RIL.STK_CMD_POLL_OFF,
- commandQualifier: 0x00, // RFU
- },
- // STK_CMD_PROVIDE_LOCAL_INFO
- {
- commandNumber: ++cmdCount,
- typeOfCommand: RIL.STK_CMD_PROVIDE_LOCAL_INFO,
- commandQualifier: 0x01, // IMEI of the terminal
- options: {
- localInfoType: 0x01 // IMEI of the terminal
- }
- },
- // STK_CMD_SET_UP_EVENT_LIST with eventList
- {
- commandNumber: ++cmdCount,
- typeOfCommand: RIL.STK_CMD_SET_UP_EVENT_LIST,
- commandQualifier: 0x00, // RFU
- options: {
- eventList: [ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
- 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
- 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
- 0x18, 0x19, 0x1A, 0x1B, 0x1C ]
- }
- },
- // STK_CMD_SET_UP_EVENT_LIST without eventList
- {
- commandNumber: ++cmdCount,
- typeOfCommand: RIL.STK_CMD_SET_UP_EVENT_LIST,
- commandQualifier: 0x00, // RFU
- options: {
- eventList: null
- }
- },
- // STK_CMD_SET_UP_MENU with mandatory properties.
- {
- commandNumber: ++cmdCount,
- typeOfCommand: RIL.STK_CMD_SET_UP_MENU,
- commandQualifier: 0x80, // bit 8: 1 = help information available
- options: {
- title: "Toolkit Menu 1",
- items: [
- { identifier: 0x01, text: "Menu Item 1" },
- { identifier: 0x02, text: "Menu Item 2" },
- { identifier: 0x03, text: "Menu Item 3" }
- ],
- isHelpAvailable: true
- }
- },
- // STK_CMD_SET_UP_MENU with optional properties including:
- // iconInfo for this menu, iconInfo for each item and nextActionList.
- {
- commandNumber: ++cmdCount,
- typeOfCommand: RIL.STK_CMD_SET_UP_MENU,
- commandQualifier: 0x00, // bit 8: 0 = help information is not available
- options: {
- title: "Toolkit Menu 2",
- items: [
- { identifier: 0x01,
- text: "Menu Item 1",
- iconSelfExplanatory: true,
- icons: [basicIcon]
- },
- { identifier: 0x02,
- text: "Menu Item 2",
- iconSelfExplanatory: false,
- icons: [basicIcon, colorIcon]
- },
- { identifier: 0x03,
- text: "Menu Item 3",
- iconSelfExplanatory: true,
- icons: [basicIcon, colorIcon, colorTransparencyIcon]
- },
- ],
- nextActionList: [
- RIL.STK_NEXT_ACTION_END_PROACTIVE_SESSION,
- RIL.STK_NEXT_ACTION_NULL,
- RIL.STK_NEXT_ACTION_NULL,
- RIL.STK_NEXT_ACTION_NULL
- ],
- iconSelfExplanatory: false,
- icons: [basicIcon, colorIcon, colorTransparencyIcon],
- isHelpAvailable: false
- }
- },
- // STK_CMD_SELECT_ITEM with mandatory properties.
- {
- commandNumber: ++cmdCount,
- typeOfCommand: RIL.STK_CMD_SELECT_ITEM,
- commandQualifier: RIL.STK_PRESENTATION_TYPE_NOT_SPECIFIED,
- options: {
- title: null,
- items: [
- { identifier: 0x01, text: "Menu Item 1" },
- { identifier: 0x02, text: "Menu Item 2" },
- { identifier: 0x03, text: "Menu Item 3" }
- ],
- presentationType: RIL.STK_PRESENTATION_TYPE_NOT_SPECIFIED,
- isHelpAvailable: false
- }
- },
- // STK_CMD_SELECT_ITEM with optional properties including:
- // title, iconInfo for this menu, iconInfo for each item and nextActionList.
- {
- commandNumber: ++cmdCount,
- typeOfCommand: RIL.STK_CMD_SELECT_ITEM,
- commandQualifier: RIL.STK_PRESENTATION_TYPE_NAVIGATION_OPTIONS,
- options: {
- title: "Selected Toolkit Menu",
- items: [
- { identifier: 0x01,
- text: "Menu Item 1",
- iconSelfExplanatory: true,
- icons: [basicIcon]
- },
- { identifier: 0x02,
- text: "Menu Item 2",
- iconSelfExplanatory: false,
- icons: [basicIcon, colorIcon]
- },
- { identifier: 0x03,
- text: "Menu Item 3",
- iconSelfExplanatory: true,
- icons: [basicIcon, colorIcon, colorTransparencyIcon]
- },
- ],
- nextActionList: [
- RIL.STK_NEXT_ACTION_END_PROACTIVE_SESSION,
- RIL.STK_NEXT_ACTION_NULL,
- RIL.STK_NEXT_ACTION_NULL,
- RIL.STK_NEXT_ACTION_NULL
- ],
- defaultItem: 0x02,
- iconSelfExplanatory: false,
- icons: [basicIcon, colorIcon, colorTransparencyIcon],
- presentationType: RIL.STK_PRESENTATION_TYPE_NAVIGATION_OPTIONS,
- isHelpAvailable: false
- }
- },
- // STK_CMD_DISPLAY_TEXT with mandatory properties.
- {
- commandNumber: ++cmdCount,
- typeOfCommand: RIL.STK_CMD_DISPLAY_TEXT,
- commandQualifier: 0x01, // bit 1: High Priority
- options: {
- text: "Display Text 1",
- isHighPriority: true,
- userClear: false,
- responseNeeded: false
- }
- },
- // STK_CMD_DISPLAY_TEXT with optional properties.
- {
- commandNumber: ++cmdCount,
- typeOfCommand: RIL.STK_CMD_DISPLAY_TEXT,
- commandQualifier: 0x80, // bit 8: User Clear
- options: {
- text: "Display Text 2",
- isHighPriority: false,
- userClear: true,
- responseNeeded: true,
- duration: {
- timeUnit: RIL.STK_TIME_UNIT_TENTH_SECOND,
- timeInterval: 0x05
- },
- iconSelfExplanatory: true,
- icons: [basicIcon]
- }
- },
- // STK_CMD_SET_UP_IDLE_MODE_TEXT
- {
- commandNumber: ++cmdCount,
- typeOfCommand: RIL.STK_CMD_SET_UP_IDLE_MODE_TEXT,
- commandQualifier: 0x00, // RFU
- options: {
- text: "Setup Idle Mode Text"
- }
- },
- // STK_CMD_SEND_SS
- {
- commandNumber: ++cmdCount,
- typeOfCommand: RIL.STK_CMD_SEND_SS,
- commandQualifier: 0x00, // RFU
- options: {
- text: "Send SS",
- iconSelfExplanatory: true,
- icons: [colorIcon]
- }
- },
- // STK_CMD_SEND_USSD
- {
- commandNumber: ++cmdCount,
- typeOfCommand: RIL.STK_CMD_SEND_USSD,
- commandQualifier: 0x00, // RFU
- options: {
- text: "Send USSD"
- }
- },
- // STK_CMD_SEND_SMS
- {
- commandNumber: ++cmdCount,
- typeOfCommand: RIL.STK_CMD_SEND_SMS,
- commandQualifier: 0x00, // RFU
- options: {
- text: "Send SMS",
- iconSelfExplanatory: false,
- icons: [colorTransparencyIcon]
- }
- },
- // STK_CMD_SEND_DTMF
- {
- commandNumber: ++cmdCount,
- typeOfCommand: RIL.STK_CMD_SEND_DTMF,
- commandQualifier: 0x00, // RFU
- options: {
- text: "Send DTMF",
- iconSelfExplanatory: true,
- icons: [basicIcon]
- }
- },
- // STK_CMD_GET_INKEY
- {
- commandNumber: ++cmdCount,
- typeOfCommand: RIL.STK_CMD_GET_INKEY,
- commandQualifier: 0x84, // bit 3: isYesNoRequested, bit 8: isHelpAvailable
- options: {
- text: "Get Input Key",
- minLength: 1,
- maxLength: 1,
- duration: {
- timeUnit: RIL.STK_TIME_UNIT_SECOND,
- timeInterval: 0x0A
- },
- isAlphabet: false,
- isUCS2: false,
- isYesNoRequested: true,
- isHelpAvailable: true,
- defaultText: null,
- iconSelfExplanatory: false,
- icons: [colorIcon]
- }
- },
- // STK_CMD_GET_INPUT
- {
- commandNumber: ++cmdCount,
- typeOfCommand: RIL.STK_CMD_GET_INPUT,
- commandQualifier: 0x0F, // bit 1-4: isAlphabet, isUCS2, hideInput, isPacked
- options: {
- text: "Get Input Text",
- minLength: 1,
- maxLength: 255,
- defaultText: "Default Input Text",
- isAlphabet: true,
- isUCS2: true,
- hideInput: true,
- isPacked: true,
- isHelpAvailable: false,
- defaultText: null,
- iconSelfExplanatory: true,
- icons: [basicIcon]
- }
- },
- // STK_CMD_SET_UP_CALL with mandatory properties.
- {
- commandNumber: ++cmdCount,
- typeOfCommand: RIL.STK_CMD_SET_UP_CALL,
- commandQualifier: 0x00, // RFU
- options: {
- address: "+0987654321"
- }
- },
- // STK_CMD_SET_UP_CALL with optional properties.
- {
- commandNumber: ++cmdCount,
- typeOfCommand: RIL.STK_CMD_SET_UP_CALL,
- commandQualifier: 0x00, // RFU
- options: {
- address: "+0987654321",
- confirmMessage: {
- text: "Confirm Message",
- iconSelfExplanatory: false,
- icons: [colorIcon]
- },
- callMessage: {
- text: "Call Message",
- iconSelfExplanatory: true,
- icons: [basicIcon]
- },
- duration: {
- timeUnit: RIL.STK_TIME_UNIT_SECOND,
- timeInterval: 0x0A
- }
- }
- },
- // STK_CMD_LAUNCH_BROWSER with mandatory properties.
- {
- commandNumber: ++cmdCount,
- typeOfCommand: RIL.STK_CMD_LAUNCH_BROWSER,
- commandQualifier: RIL.STK_BROWSER_MODE_USING_NEW_BROWSER,
- options: {
- url: "http://www.mozilla.org",
- mode: RIL.STK_BROWSER_MODE_USING_NEW_BROWSER
- }
- },
- // STK_CMD_LAUNCH_BROWSER with optional properties.
- {
- commandNumber: ++cmdCount,
- typeOfCommand: RIL.STK_CMD_LAUNCH_BROWSER,
- commandQualifier: RIL.STK_BROWSER_MODE_USING_NEW_BROWSER,
- options: {
- url: "http://www.mozilla.org",
- mode: RIL.STK_BROWSER_MODE_USING_NEW_BROWSER,
- confirmMessage: {
- text: "Confirm Message for Launch Browser",
- iconSelfExplanatory: false,
- icons: [colorTransparencyIcon]
- }
- }
- },
- // STK_CMD_PLAY_TONE with mandatory properties.
- {
- commandNumber: ++cmdCount,
- typeOfCommand: RIL.STK_CMD_PLAY_TONE,
- commandQualifier: 0x01, // isVibrate
- options: {
- text: null,
- isVibrate: true
- }
- },
- // STK_CMD_PLAY_TONE with optional properties.
- {
- commandNumber: ++cmdCount,
- typeOfCommand: RIL.STK_CMD_PLAY_TONE,
- commandQualifier: 0x00, // isVibrate = false
- options: {
- text: "Play Tone",
- tone: RIL.STK_TONE_TYPE_CONGESTION,
- isVibrate: false,
- duration: {
- timeUnit: RIL.STK_TIME_UNIT_SECOND,
- timeInterval: 0x0A
- },
- iconSelfExplanatory: true,
- icons: [basicIcon]
- }
- },
- // STK_CMD_TIMER_MANAGEMENT with mandatory properties.
- {
- commandNumber: ++cmdCount,
- typeOfCommand: RIL.STK_CMD_TIMER_MANAGEMENT,
- commandQualifier: RIL.STK_TIMER_DEACTIVATE,
- options: {
- timerId: 0x08,
- timerAction: RIL.STK_TIMER_DEACTIVATE
- }
- },
- // STK_CMD_TIMER_MANAGEMENT with optional properties.
- {
- commandNumber: ++cmdCount,
- typeOfCommand: RIL.STK_CMD_TIMER_MANAGEMENT,
- commandQualifier: RIL.STK_TIMER_START,
- options: {
- timerId: 0x01,
- timerValue: (12 * 60 * 60) + (30 * 60) + (30), // 12:30:30
- timerAction: RIL.STK_TIMER_START
- }
- },
- // STK_CMD_OPEN_CHANNEL with mandatory properties.
- {
- commandNumber: ++cmdCount,
- typeOfCommand: RIL.STK_CMD_OPEN_CHANNEL,
- commandQualifier: 0x00, //RFU
- options: {
- text: null,
- }
- },
- // STK_CMD_OPEN_CHANNEL with optional properties.
- {
- commandNumber: ++cmdCount,
- typeOfCommand: RIL.STK_CMD_OPEN_CHANNEL,
- commandQualifier: 0x00, //RFU
- options: {
- text: "Open Channel",
- iconSelfExplanatory: false,
- icons: [colorIcon]
- }
- },
- // STK_CMD_CLOSE_CHANNEL with optional properties.
- {
- commandNumber: ++cmdCount,
- typeOfCommand: RIL.STK_CMD_CLOSE_CHANNEL,
- commandQualifier: 0x00, //RFU
- options: {
- text: "Close Channel",
- iconSelfExplanatory: true,
- icons: [colorTransparencyIcon]
- }
- },
- // STK_CMD_SEND_DATA with optional properties.
- {
- commandNumber: ++cmdCount,
- typeOfCommand: RIL.STK_CMD_SEND_DATA,
- commandQualifier: 0x00, //RFU
- options: {
- text: null,
- iconSelfExplanatory: false,
- icons: [basicIcon]
- }
- },
- // STK_CMD_RECEIVE_DATA with optional properties.
- {
- commandNumber: ++cmdCount,
- typeOfCommand: RIL.STK_CMD_RECEIVE_DATA,
- commandQualifier: 0x00, //RFU
- options: {
- text: "Receive Data"
- }
- },
- null // Termination condition to run_next_test()
- ];
-
- messages.forEach(function(aMessage) {
- if (!aMessage) {
- run_next_test();
- return;
- }
-
- messenger.notifyStkProactiveCommand(iccId,
- gStkCmdFactory.createCommand(aMessage));
-
- equal_received_system_message("icc-stkcommand", {
- iccId: iccId,
- command: aMessage
- });
- });
-});
diff --git a/dom/system/gonk/tests/test_ril_worker_barring_password.js b/dom/system/gonk/tests/test_ril_worker_barring_password.js
deleted file mode 100644
index fcd3e44051..0000000000
--- a/dom/system/gonk/tests/test_ril_worker_barring_password.js
+++ /dev/null
@@ -1,61 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-subscriptLoader.loadSubScript("resource://gre/modules/ril_consts.js", this);
-
-function run_test() {
- run_next_test();
-}
-
-const PIN = "0000";
-const NEW_PIN = "1234";
-
-add_test(function test_change_call_barring_password() {
- let worker = newUint8Worker();
- let context = worker.ContextPool._contexts[0];
- let buf = context.Buf;
-
- function do_test(facility, pin, newPin) {
- buf.sendParcel = function fakeSendParcel () {
- // Request Type.
- equal(this.readInt32(), REQUEST_CHANGE_BARRING_PASSWORD);
-
- // Token : we don't care.
- this.readInt32();
-
- let parcel = this.readStringList();
- equal(parcel.length, 3);
- equal(parcel[0], facility);
- equal(parcel[1], pin);
- equal(parcel[2], newPin);
- };
-
- let options = {facility: facility, pin: pin, newPin: newPin};
- context.RIL.changeCallBarringPassword(options);
- }
-
- do_test(ICC_CB_FACILITY_BA_ALL, PIN, NEW_PIN);
-
- run_next_test();
-});
-
-add_test(function test_check_change_call_barring_password_result() {
- let barringPasswordOptions;
- let workerHelper = newInterceptWorker();
- let worker = workerHelper.worker;
-
- let context = worker.ContextPool._contexts[0];
- context.RIL.changeCallBarringPassword =
- function fakeChangeCallBarringPassword(options) {
- barringPasswordOptions = options;
- context.RIL[REQUEST_CHANGE_BARRING_PASSWORD](0, {});
- };
-
- context.RIL.changeCallBarringPassword({pin: PIN, newPin: NEW_PIN});
-
- let postedMessage = workerHelper.postedMessage;
- equal(barringPasswordOptions.pin, PIN);
- equal(barringPasswordOptions.newPin, NEW_PIN);
-
- run_next_test();
-});
diff --git a/dom/system/gonk/tests/test_ril_worker_buf.js b/dom/system/gonk/tests/test_ril_worker_buf.js
deleted file mode 100644
index 30054a8815..0000000000
--- a/dom/system/gonk/tests/test_ril_worker_buf.js
+++ /dev/null
@@ -1,187 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-function run_test() {
- run_next_test();
-}
-
-/**
- * Add test function with specified parcel and request handler.
- *
- * @param parcel
- * Incoming parcel to be tested.
- * @param handler
- * Handler to be invoked as RIL request handler.
- */
-function add_test_incoming_parcel(parcel, handler) {
- add_test(function test_incoming_parcel() {
- let worker = newWorker({
- postRILMessage: function(data) {
- // do nothing
- },
- postMessage: function(message) {
- // do nothing
- }
- });
-
- if (!parcel) {
- parcel = newIncomingParcel(-1,
- worker.RESPONSE_TYPE_UNSOLICITED,
- worker.REQUEST_VOICE_REGISTRATION_STATE,
- [0, 0, 0, 0]);
- }
-
- let context = worker.ContextPool._contexts[0];
- // supports only requests less or equal than UINT8_MAX(255).
- let buf = context.Buf;
- let request = parcel[buf.PARCEL_SIZE_SIZE + buf.UINT32_SIZE];
- context.RIL[request] = function ril_request_handler() {
- handler.apply(this, arguments);
- };
-
- worker.onRILMessage(0, parcel);
-
- // end of incoming parcel's trip, let's do next test.
- run_next_test();
- });
-}
-
-// Test normal parcel handling.
-add_test_incoming_parcel(null,
- function test_normal_parcel_handling() {
- let self = this;
- try {
- // reads exactly the same size, should not throw anything.
- self.context.Buf.readInt32();
- } catch (e) {
- ok(false, "Got exception: " + e);
- }
- }
-);
-
-// Test parcel under read.
-add_test_incoming_parcel(null,
- function test_parcel_under_read() {
- let self = this;
- try {
- // reads less than parcel size, should not throw.
- self.context.Buf.readUint16();
- } catch (e) {
- ok(false, "Got exception: " + e);
- }
- }
-);
-
-// Test parcel over read.
-add_test_incoming_parcel(null,
- function test_parcel_over_read() {
- let buf = this.context.Buf;
-
- // read all data available
- while (buf.readAvailable > 0) {
- buf.readUint8();
- }
-
- throws(function over_read_handler() {
- // reads more than parcel size, should throw an error.
- buf.readUint8();
- },"Trying to read data beyond the parcel end!");
- }
-);
-
-// Test Bug 814761: buffer overwritten
-add_test(function test_incoming_parcel_buffer_overwritten() {
- let worker = newWorker({
- postRILMessage: function(data) {
- // do nothing
- },
- postMessage: function(message) {
- // do nothing
- }
- });
-
- let context = worker.ContextPool._contexts[0];
- // A convenient alias.
- let buf = context.Buf;
-
- // Allocate an array of specified size and set each of its elements to value.
- function calloc(length, value) {
- let array = new Array(length);
- for (let i = 0; i < length; i++) {
- array[i] = value;
- }
- return array;
- }
-
- // Do nothing in handleParcel().
- let request = worker.REQUEST_VOICE_REGISTRATION_STATE;
- context.RIL[request] = null;
-
- // Prepare two parcels, whose sizes are both smaller than the incoming buffer
- // size but larger when combined, to trigger the bug.
- let pA_dataLength = buf.incomingBufferLength / 2;
- let pA = newIncomingParcel(-1,
- worker.RESPONSE_TYPE_UNSOLICITED,
- request,
- calloc(pA_dataLength, 1));
- let pA_parcelSize = pA.length - buf.PARCEL_SIZE_SIZE;
-
- let pB_dataLength = buf.incomingBufferLength * 3 / 4;
- let pB = newIncomingParcel(-1,
- worker.RESPONSE_TYPE_UNSOLICITED,
- request,
- calloc(pB_dataLength, 1));
- let pB_parcelSize = pB.length - buf.PARCEL_SIZE_SIZE;
-
- // First, send an incomplete pA and verifies related data pointer:
- let p1 = pA.subarray(0, pA.length - 1);
- worker.onRILMessage(0, p1);
- // The parcel should not have been processed.
- equal(buf.readAvailable, 0);
- // buf.currentParcelSize should have been set because incoming data has more
- // than 4 octets.
- equal(buf.currentParcelSize, pA_parcelSize);
- // buf.readIncoming should contains remaining unconsumed octets count.
- equal(buf.readIncoming, p1.length - buf.PARCEL_SIZE_SIZE);
- // buf.incomingWriteIndex should be ready to accept the last octet.
- equal(buf.incomingWriteIndex, p1.length);
-
- // Second, send the last octet of pA and whole pB. The Buf should now expand
- // to cover both pA & pB.
- let p2 = new Uint8Array(1 + pB.length);
- p2.set(pA.subarray(pA.length - 1), 0);
- p2.set(pB, 1);
- worker.onRILMessage(0, p2);
- // The parcels should have been both consumed.
- equal(buf.readAvailable, 0);
- // No parcel data remains.
- equal(buf.currentParcelSize, 0);
- // No parcel data remains.
- equal(buf.readIncoming, 0);
- // The Buf should now expand to cover both pA & pB.
- equal(buf.incomingWriteIndex, pA.length + pB.length);
-
- // end of incoming parcel's trip, let's do next test.
- run_next_test();
-});
-
-// Test Buf.readUint8Array.
-add_test_incoming_parcel(null,
- function test_buf_readUint8Array() {
- let buf = this.context.Buf;
-
- let u8array = buf.readUint8Array(1);
- equal(u8array instanceof Uint8Array, true);
- equal(u8array.length, 1);
- equal(buf.readAvailable, 3);
-
- u8array = buf.readUint8Array(2);
- equal(u8array.length, 2);
- equal(buf.readAvailable, 1);
-
- throws(function over_read_handler() {
- // reads more than parcel size, should throw an error.
- u8array = buf.readUint8Array(2);
- }, "Trying to read data beyond the parcel end!");
- }
-);
diff --git a/dom/system/gonk/tests/test_ril_worker_cdma_info_rec.js b/dom/system/gonk/tests/test_ril_worker_cdma_info_rec.js
deleted file mode 100644
index 335c0c403d..0000000000
--- a/dom/system/gonk/tests/test_ril_worker_cdma_info_rec.js
+++ /dev/null
@@ -1,234 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-subscriptLoader.loadSubScript("resource://gre/modules/ril_consts.js", this);
-
-function run_test() {
- run_next_test();
-}
-
-/**
- * Helper function.
- */
-function newWorkerWithParcel(parcelBuf) {
- let worker = newWorker({
- postRILMessage: function(data) {
- // Do nothing
- },
- postMessage: function(message) {
- // Do nothing
- }
- });
-
- let index = 0; // index for read
- let buf = parcelBuf;
-
- let context = worker.ContextPool._contexts[0];
- context.Buf.readUint8 = function() {
- return buf[index++];
- };
-
- context.Buf.readUint16 = function() {
- return buf[index++];
- };
-
- context.Buf.readInt32 = function() {
- return buf[index++];
- };
-
- context.Buf.seekIncoming = function(offset) {
- index += offset / context.Buf.UINT32_SIZE;
- };
-
- return worker;
-}
-
-// Test CDMA information record decoder.
-
-/**
- * Verify decoder for type DISPLAY
- */
-add_test(function test_display() {
- let worker = newWorkerWithParcel([
- 0x01, // one inforemation record
- 0x00, // type: display
- 0x09, // length: 9
- 0x54, 0x65, 0x73, 0x74, 0x20, 0x49, 0x6E, 0x66,
- 0x6F, 0x00]);
- let context = worker.ContextPool._contexts[0];
- let helper = context.CdmaPDUHelper;
- let records = helper.decodeInformationRecord();
-
- equal(records[0].display, "Test Info");
-
- run_next_test();
-});
-
-/**
- * Verify decoder for type EXTENDED DISPLAY
- */
-add_test(function test_extended_display() {
- let worker = newWorkerWithParcel([
- 0x01, // one inforemation record
- 0x07, // type: extended display
- 0x12, // length: 18
- 0x54, 0x65, 0x73, 0x74, 0x20, 0x45, 0x78, 0x74,
- 0x65, 0x6E, 0x64, 0x65, 0x64, 0x20, 0x49, 0x6E,
- 0x66, 0x6F, 0x00, 0x00]);
- let context = worker.ContextPool._contexts[0];
- let helper = context.CdmaPDUHelper;
- let records = helper.decodeInformationRecord();
-
- equal(records[0].display, "Test Extended Info");
-
- run_next_test();
-});
-
-/**
- * Verify decoder for mixed type
- */
-add_test(function test_mixed() {
- let worker = newWorkerWithParcel([
- 0x02, // two inforemation record
- 0x00, // type: display
- 0x0B, // length: 11
- 0x54, 0x65, 0x73, 0x74, 0x20, 0x49, 0x6E, 0x66,
- 0x6F, 0x20, 0x31, 0x00,
- 0x07, // type: extended display
- 0x0B, // length: 11
- 0x54, 0x65, 0x73, 0x74, 0x20, 0x49, 0x6E, 0x66,
- 0x6F, 0x20, 0x32, 0x00]);
- let context = worker.ContextPool._contexts[0];
- let helper = context.CdmaPDUHelper;
- let records = helper.decodeInformationRecord();
-
- equal(records[0].display, "Test Info 1");
- equal(records[1].display, "Test Info 2");
-
- run_next_test();
-});
-
-/**
- * Verify decoder for multiple types
- */
-add_test(function test_multiple() {
- let worker = newWorkerWithParcel([
- 0x02, // two inforemation record
- 0x00, // type: display
- 0x0B, // length: 11
- 0x54, 0x65, 0x73, 0x74, 0x20, 0x49, 0x6E, 0x66,
- 0x6F, 0x20, 0x31, 0x00,
- 0x00, // type: display
- 0x0B, // length: 11
- 0x54, 0x65, 0x73, 0x74, 0x20, 0x49, 0x6E, 0x66,
- 0x6F, 0x20, 0x32, 0x00]);
- let context = worker.ContextPool._contexts[0];
- let helper = context.CdmaPDUHelper;
- let records = helper.decodeInformationRecord();
-
- equal(records[0].display, "Test Info 1");
- equal(records[1].display, "Test Info 2");
-
- run_next_test();
-});
-
-/**
- * Verify decoder for Signal Type
- */
-add_test(function test_signal() {
- let worker = newWorkerWithParcel([
- 0x01, // one inforemation record
- 0x04, // type: signal
- 0x01, // isPresent: non-zero
- 0x00, // signalType: Tone signal (00)
- 0x01, // alertPitch: High pitch
- 0x03]); // signal: Abbreviated intercept (000011)
- let context = worker.ContextPool._contexts[0];
- let helper = context.CdmaPDUHelper;
- let records = helper.decodeInformationRecord();
-
- equal(records[0].signal.type, 0x00);
- equal(records[0].signal.alertPitch, 0x01);
- equal(records[0].signal.signal, 0x03);
-
- run_next_test();
-});
-
-/**
- * Verify decoder for Signal Type for Not Presented
- */
-add_test(function test_signal_not_present() {
- let worker = newWorkerWithParcel([
- 0x01, // one inforemation record
- 0x04, // type: signal
- 0x00, // isPresent: zero
- 0x00, // signalType: Tone signal (00)
- 0x01, // alertPitch: High pitch
- 0x03]); // signal: Abbreviated intercept (000011)
- let context = worker.ContextPool._contexts[0];
- let helper = context.CdmaPDUHelper;
- let records = helper.decodeInformationRecord();
-
- equal(records.length, 0);
-
- run_next_test();
-});
-
-/**
- * Verify decoder for Line Control
- */
-add_test(function test_line_control() {
- let worker = newWorkerWithParcel([
- 0x01, // one inforemation record
- 0x06, // type: line control
- 0x01, // polarity included
- 0x00, // not toggled
- 0x01, // reversed
- 0xFF]); // Power denial timeout: 255 * 5 ms
- let context = worker.ContextPool._contexts[0];
- let helper = context.CdmaPDUHelper;
- let records = helper.decodeInformationRecord();
-
- equal(records[0].lineControl.polarityIncluded, 1);
- equal(records[0].lineControl.toggle, 0);
- equal(records[0].lineControl.reverse, 1);
- equal(records[0].lineControl.powerDenial, 255);
-
- run_next_test();
-});
-
-/**
- * Verify decoder for CLIR Cause
- */
-add_test(function test_clir() {
- let worker = newWorkerWithParcel([
- 0x01, // one inforemation record
- 0x08, // type: clir
- 0x01]); // cause: Rejected by user
- let context = worker.ContextPool._contexts[0];
- let helper = context.CdmaPDUHelper;
- let records = helper.decodeInformationRecord();
-
- equal(records[0].clirCause, 1);
-
- run_next_test();
-});
-
-/**
- * Verify decoder for Audio Control
- */
-add_test(function test_clir() {
- let worker = newWorkerWithParcel([
- 0x01, // one inforemation record
- 0x0A, // type: audio control
- 0x01, // uplink
- 0xFF]); // downlink
- let context = worker.ContextPool._contexts[0];
- let helper = context.CdmaPDUHelper;
- let records = helper.decodeInformationRecord();
-
- equal(records[0].audioControl.upLink, 1);
- equal(records[0].audioControl.downLink, 255);
-
- run_next_test();
-});
diff --git a/dom/system/gonk/tests/test_ril_worker_cellbroadcast_config.js b/dom/system/gonk/tests/test_ril_worker_cellbroadcast_config.js
deleted file mode 100644
index d5645a3cf1..0000000000
--- a/dom/system/gonk/tests/test_ril_worker_cellbroadcast_config.js
+++ /dev/null
@@ -1,470 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-subscriptLoader.loadSubScript("resource://gre/modules/ril_consts.js", this);
-
-function run_test() {
- run_next_test();
-}
-
-add_test(function test_ril_worker_cellbroadcast_activate() {
- let worker = newWorker({
- postRILMessage: function(id, parcel) {
- // Do nothing
- },
- postMessage: function(message) {
- // Do nothing
- }
- });
- let context = worker.ContextPool._contexts[0];
-
- let parcelTypes = [];
- let org_newParcel = context.Buf.newParcel;
- context.Buf.newParcel = function(type, options) {
- parcelTypes.push(type);
- org_newParcel.apply(this, arguments);
- };
-
- function setup(isCdma) {
- context.RIL._isCdma = isCdma;
- context.RIL.cellBroadcastDisabled = false;
- context.RIL.mergedCellBroadcastConfig = [1, 2, 4, 7]; // 1, 4-6
- parcelTypes = [];
- }
-
- function test(isCdma, expectedRequest) {
- setup(isCdma);
- context.RIL.setCellBroadcastDisabled({disabled: true});
- // Makesure that request parcel is sent out.
- notEqual(parcelTypes.indexOf(expectedRequest), -1);
- equal(context.RIL.cellBroadcastDisabled, true);
- }
-
- test(false, REQUEST_GSM_SMS_BROADCAST_ACTIVATION);
- test(true, REQUEST_CDMA_SMS_BROADCAST_ACTIVATION);
-
- run_next_test();
-});
-
-add_test(function test_ril_worker_cellbroadcast_config() {
- let currentParcel;
- let worker = newWorker({
- postRILMessage: function(id, parcel) {
- currentParcel = parcel;
- },
- postMessage: function(message) {
- // Do nothing
- }
- });
- let context = worker.ContextPool._contexts[0];
-
- function U32ArrayFromParcelArray(pa) {
- do_print(pa);
- let out = [];
- for (let i = 0; i < pa.length; i += 4) {
- let data = pa[i] + (pa[i+1] << 8) + (pa[i+2] << 16) + (pa[i+3] << 24);
- out.push(data);
- }
- return out;
- }
-
- function test(isCdma, configs, expected) {
- let parcelType = isCdma ? REQUEST_CDMA_SET_BROADCAST_SMS_CONFIG
- : REQUEST_GSM_SET_BROADCAST_SMS_CONFIG;
-
- let found = false;
- worker.postRILMessage = function(id, parcel) {
- let u32Parcel = U32ArrayFromParcelArray(Array.slice(parcel));
- if (u32Parcel[1] != parcelType) {
- return;
- }
-
- found = true;
- // Check parcel. Data start from 4th word (32bit)
- equal(u32Parcel.slice(3).toString(), expected);
- };
-
- context.RIL._isCdma = isCdma;
- context.RIL.setSmsBroadcastConfig(configs);
-
- // Makesure that request parcel is sent out.
- ok(found);
- }
-
- // (GSM) RIL writes the following data to outgoing parcel:
- // nums [(from, to, 0, 0xFF, 1), ... ]
- test(false,
- [1, 2, 4, 7] /* 1, 4-6 */,
- ["2", "1,1,0,255,1", "4,6,0,255,1"].join());
-
- // (CDMA) RIL writes the following data to outgoing parcel:
- // nums [(id, 0, 1), ... ]
- test(true,
- [1, 2, 4, 7] /* 1, 4-6 */,
- ["4", "1,0,1", "4,0,1", "5,0,1", "6,0,1"].join());
-
- run_next_test();
-});
-
-add_test(function test_ril_worker_cellbroadcast_merge_config() {
- let worker = newWorker({
- postRILMessage: function(id, parcel) {
- // Do nothing
- },
- postMessage: function(message) {
- // Do nothing
- }
- });
- let context = worker.ContextPool._contexts[0];
-
- function test(isCdma, configs, expected) {
- context.RIL._isCdma = isCdma;
- context.RIL.cellBroadcastConfigs = configs;
- context.RIL._mergeAllCellBroadcastConfigs();
- equal(context.RIL.mergedCellBroadcastConfig.toString(), expected);
- }
-
- let configs = {
- MMI: [1, 2, 4, 7], // 1, 4-6
- CBMI: [6, 9], // 6-8
- CBMID: [8, 11], // 8-10
- CBMIR: [10, 13] // 10-12
- };
-
- test(false, configs, "1,2,4,13");
- test(true, configs, "1,2,4,7");
-
- run_next_test();
-});
-
-add_test(function test_ril_worker_cellbroadcast_set_search_list() {
- let worker = newWorker({
- postRILMessage: function(id, parcel) {
- // Do nothing
- },
- postMessage: function(message) {
- // Do nothing
- }
- });
-
- let context = worker.ContextPool._contexts[0];
-
- function test(aIsCdma, aSearchList, aExpected) {
- context.RIL._isCdma = aIsCdma;
-
- let options = { searchList: aSearchList };
- context.RIL.setCellBroadcastSearchList(options);
- // Enforce the MMI result to string for comparison.
- equal("" + context.RIL.cellBroadcastConfigs.MMI, aExpected);
- do_check_eq(options.errorMsg, undefined);
- }
-
- let searchListStr = "1,2,3,4";
- let searchList = { gsm: "1,2,3,4", cdma: "5,6,7,8" };
-
- test(false, searchListStr, "1,2,2,3,3,4,4,5");
- test(true, searchListStr, "1,2,2,3,3,4,4,5");
- test(false, searchList, "1,2,2,3,3,4,4,5");
- test(true, searchList, "5,6,6,7,7,8,8,9");
- test(false, null, "null");
- test(true, null, "null");
-
- run_next_test();
-});
-
-add_test(function test_ril_worker_mergeCellBroadcastConfigs() {
- let worker = newWorker({
- postRILMessage: function(data) {
- // Do nothing
- },
- postMessage: function(message) {
- // Do nothing
- }
- });
-
- let context = worker.ContextPool._contexts[0];
- let ril = context.RIL;
-
- function test(olist, from, to, expected) {
- let result = ril._mergeCellBroadcastConfigs(olist, from, to);
- equal(JSON.stringify(expected), JSON.stringify(result));
- }
-
- test(null, 0, 1, [0, 1]);
-
- test([10, 13], 7, 8, [ 7, 8, 10, 13]);
- test([10, 13], 7, 9, [ 7, 9, 10, 13]);
- test([10, 13], 7, 10, [ 7, 13]);
- test([10, 13], 7, 11, [ 7, 13]);
- test([10, 13], 7, 12, [ 7, 13]);
- test([10, 13], 7, 13, [ 7, 13]);
- test([10, 13], 7, 14, [ 7, 14]);
- test([10, 13], 7, 15, [ 7, 15]);
- test([10, 13], 7, 16, [ 7, 16]);
- test([10, 13], 8, 9, [ 8, 9, 10, 13]);
- test([10, 13], 8, 10, [ 8, 13]);
- test([10, 13], 8, 11, [ 8, 13]);
- test([10, 13], 8, 12, [ 8, 13]);
- test([10, 13], 8, 13, [ 8, 13]);
- test([10, 13], 8, 14, [ 8, 14]);
- test([10, 13], 8, 15, [ 8, 15]);
- test([10, 13], 8, 16, [ 8, 16]);
- test([10, 13], 9, 10, [ 9, 13]);
- test([10, 13], 9, 11, [ 9, 13]);
- test([10, 13], 9, 12, [ 9, 13]);
- test([10, 13], 9, 13, [ 9, 13]);
- test([10, 13], 9, 14, [ 9, 14]);
- test([10, 13], 9, 15, [ 9, 15]);
- test([10, 13], 9, 16, [ 9, 16]);
- test([10, 13], 10, 11, [10, 13]);
- test([10, 13], 10, 12, [10, 13]);
- test([10, 13], 10, 13, [10, 13]);
- test([10, 13], 10, 14, [10, 14]);
- test([10, 13], 10, 15, [10, 15]);
- test([10, 13], 10, 16, [10, 16]);
- test([10, 13], 11, 12, [10, 13]);
- test([10, 13], 11, 13, [10, 13]);
- test([10, 13], 11, 14, [10, 14]);
- test([10, 13], 11, 15, [10, 15]);
- test([10, 13], 11, 16, [10, 16]);
- test([10, 13], 12, 13, [10, 13]);
- test([10, 13], 12, 14, [10, 14]);
- test([10, 13], 12, 15, [10, 15]);
- test([10, 13], 12, 16, [10, 16]);
- test([10, 13], 13, 14, [10, 14]);
- test([10, 13], 13, 15, [10, 15]);
- test([10, 13], 13, 16, [10, 16]);
- test([10, 13], 14, 15, [10, 13, 14, 15]);
- test([10, 13], 14, 16, [10, 13, 14, 16]);
- test([10, 13], 15, 16, [10, 13, 15, 16]);
-
- test([10, 13, 14, 17], 7, 8, [ 7, 8, 10, 13, 14, 17]);
- test([10, 13, 14, 17], 7, 9, [ 7, 9, 10, 13, 14, 17]);
- test([10, 13, 14, 17], 7, 10, [ 7, 13, 14, 17]);
- test([10, 13, 14, 17], 7, 11, [ 7, 13, 14, 17]);
- test([10, 13, 14, 17], 7, 12, [ 7, 13, 14, 17]);
- test([10, 13, 14, 17], 7, 13, [ 7, 13, 14, 17]);
- test([10, 13, 14, 17], 7, 14, [ 7, 17]);
- test([10, 13, 14, 17], 7, 15, [ 7, 17]);
- test([10, 13, 14, 17], 7, 16, [ 7, 17]);
- test([10, 13, 14, 17], 7, 17, [ 7, 17]);
- test([10, 13, 14, 17], 7, 18, [ 7, 18]);
- test([10, 13, 14, 17], 7, 19, [ 7, 19]);
- test([10, 13, 14, 17], 8, 9, [ 8, 9, 10, 13, 14, 17]);
- test([10, 13, 14, 17], 8, 10, [ 8, 13, 14, 17]);
- test([10, 13, 14, 17], 8, 11, [ 8, 13, 14, 17]);
- test([10, 13, 14, 17], 8, 12, [ 8, 13, 14, 17]);
- test([10, 13, 14, 17], 8, 13, [ 8, 13, 14, 17]);
- test([10, 13, 14, 17], 8, 14, [ 8, 17]);
- test([10, 13, 14, 17], 8, 15, [ 8, 17]);
- test([10, 13, 14, 17], 8, 16, [ 8, 17]);
- test([10, 13, 14, 17], 8, 17, [ 8, 17]);
- test([10, 13, 14, 17], 8, 18, [ 8, 18]);
- test([10, 13, 14, 17], 8, 19, [ 8, 19]);
- test([10, 13, 14, 17], 9, 10, [ 9, 13, 14, 17]);
- test([10, 13, 14, 17], 9, 11, [ 9, 13, 14, 17]);
- test([10, 13, 14, 17], 9, 12, [ 9, 13, 14, 17]);
- test([10, 13, 14, 17], 9, 13, [ 9, 13, 14, 17]);
- test([10, 13, 14, 17], 9, 14, [ 9, 17]);
- test([10, 13, 14, 17], 9, 15, [ 9, 17]);
- test([10, 13, 14, 17], 9, 16, [ 9, 17]);
- test([10, 13, 14, 17], 9, 17, [ 9, 17]);
- test([10, 13, 14, 17], 9, 18, [ 9, 18]);
- test([10, 13, 14, 17], 9, 19, [ 9, 19]);
- test([10, 13, 14, 17], 10, 11, [10, 13, 14, 17]);
- test([10, 13, 14, 17], 10, 12, [10, 13, 14, 17]);
- test([10, 13, 14, 17], 10, 13, [10, 13, 14, 17]);
- test([10, 13, 14, 17], 10, 14, [10, 17]);
- test([10, 13, 14, 17], 10, 15, [10, 17]);
- test([10, 13, 14, 17], 10, 16, [10, 17]);
- test([10, 13, 14, 17], 10, 17, [10, 17]);
- test([10, 13, 14, 17], 10, 18, [10, 18]);
- test([10, 13, 14, 17], 10, 19, [10, 19]);
- test([10, 13, 14, 17], 11, 12, [10, 13, 14, 17]);
- test([10, 13, 14, 17], 11, 13, [10, 13, 14, 17]);
- test([10, 13, 14, 17], 11, 14, [10, 17]);
- test([10, 13, 14, 17], 11, 15, [10, 17]);
- test([10, 13, 14, 17], 11, 16, [10, 17]);
- test([10, 13, 14, 17], 11, 17, [10, 17]);
- test([10, 13, 14, 17], 11, 18, [10, 18]);
- test([10, 13, 14, 17], 11, 19, [10, 19]);
- test([10, 13, 14, 17], 12, 13, [10, 13, 14, 17]);
- test([10, 13, 14, 17], 12, 14, [10, 17]);
- test([10, 13, 14, 17], 12, 15, [10, 17]);
- test([10, 13, 14, 17], 12, 16, [10, 17]);
- test([10, 13, 14, 17], 12, 17, [10, 17]);
- test([10, 13, 14, 17], 12, 18, [10, 18]);
- test([10, 13, 14, 17], 12, 19, [10, 19]);
- test([10, 13, 14, 17], 13, 14, [10, 17]);
- test([10, 13, 14, 17], 13, 15, [10, 17]);
- test([10, 13, 14, 17], 13, 16, [10, 17]);
- test([10, 13, 14, 17], 13, 17, [10, 17]);
- test([10, 13, 14, 17], 13, 18, [10, 18]);
- test([10, 13, 14, 17], 13, 19, [10, 19]);
- test([10, 13, 14, 17], 14, 15, [10, 13, 14, 17]);
- test([10, 13, 14, 17], 14, 16, [10, 13, 14, 17]);
- test([10, 13, 14, 17], 14, 17, [10, 13, 14, 17]);
- test([10, 13, 14, 17], 14, 18, [10, 13, 14, 18]);
- test([10, 13, 14, 17], 14, 19, [10, 13, 14, 19]);
- test([10, 13, 14, 17], 15, 16, [10, 13, 14, 17]);
- test([10, 13, 14, 17], 15, 17, [10, 13, 14, 17]);
- test([10, 13, 14, 17], 15, 18, [10, 13, 14, 18]);
- test([10, 13, 14, 17], 15, 19, [10, 13, 14, 19]);
- test([10, 13, 14, 17], 16, 17, [10, 13, 14, 17]);
- test([10, 13, 14, 17], 16, 18, [10, 13, 14, 18]);
- test([10, 13, 14, 17], 16, 19, [10, 13, 14, 19]);
- test([10, 13, 14, 17], 17, 18, [10, 13, 14, 18]);
- test([10, 13, 14, 17], 17, 19, [10, 13, 14, 19]);
- test([10, 13, 14, 17], 18, 19, [10, 13, 14, 17, 18, 19]);
-
- test([10, 13, 16, 19], 7, 14, [ 7, 14, 16, 19]);
- test([10, 13, 16, 19], 7, 15, [ 7, 15, 16, 19]);
- test([10, 13, 16, 19], 7, 16, [ 7, 19]);
- test([10, 13, 16, 19], 8, 14, [ 8, 14, 16, 19]);
- test([10, 13, 16, 19], 8, 15, [ 8, 15, 16, 19]);
- test([10, 13, 16, 19], 8, 16, [ 8, 19]);
- test([10, 13, 16, 19], 9, 14, [ 9, 14, 16, 19]);
- test([10, 13, 16, 19], 9, 15, [ 9, 15, 16, 19]);
- test([10, 13, 16, 19], 9, 16, [ 9, 19]);
- test([10, 13, 16, 19], 10, 14, [10, 14, 16, 19]);
- test([10, 13, 16, 19], 10, 15, [10, 15, 16, 19]);
- test([10, 13, 16, 19], 10, 16, [10, 19]);
- test([10, 13, 16, 19], 11, 14, [10, 14, 16, 19]);
- test([10, 13, 16, 19], 11, 15, [10, 15, 16, 19]);
- test([10, 13, 16, 19], 11, 16, [10, 19]);
- test([10, 13, 16, 19], 12, 14, [10, 14, 16, 19]);
- test([10, 13, 16, 19], 12, 15, [10, 15, 16, 19]);
- test([10, 13, 16, 19], 12, 16, [10, 19]);
- test([10, 13, 16, 19], 13, 14, [10, 14, 16, 19]);
- test([10, 13, 16, 19], 13, 15, [10, 15, 16, 19]);
- test([10, 13, 16, 19], 13, 16, [10, 19]);
- test([10, 13, 16, 19], 14, 15, [10, 13, 14, 15, 16, 19]);
- test([10, 13, 16, 19], 14, 16, [10, 13, 14, 19]);
- test([10, 13, 16, 19], 15, 16, [10, 13, 15, 19]);
-
- run_next_test();
-});
-
-add_test(function test_ril_consts_cellbroadcast_misc() {
- // Must be 16 for indexing.
- equal(CB_DCS_LANG_GROUP_1.length, 16);
- equal(CB_DCS_LANG_GROUP_2.length, 16);
-
- // Array length must be even.
- equal(CB_NON_MMI_SETTABLE_RANGES.length & 0x01, 0);
- for (let i = 0; i < CB_NON_MMI_SETTABLE_RANGES.length;) {
- let from = CB_NON_MMI_SETTABLE_RANGES[i++];
- let to = CB_NON_MMI_SETTABLE_RANGES[i++];
- equal(from < to, true);
- }
-
- run_next_test();
-});
-
-add_test(function test_ril_worker_checkCellBroadcastMMISettable() {
- let worker = newWorker({
- postRILMessage: function(data) {
- // Do nothing
- },
- postMessage: function(message) {
- // Do nothing
- }
- });
-
- let context = worker.ContextPool._contexts[0];
- let ril = context.RIL;
-
- function test(from, to, expected) {
- equal(expected, ril._checkCellBroadcastMMISettable(from, to));
- }
-
- test(-2, -1, false);
- test(-1, 0, false);
- test(0, 1, true);
- test(1, 1, false);
- test(2, 1, false);
- test(65536, 65537, false);
-
- // We have both [4096, 4224), [4224, 4352), so it's actually [4096, 4352),
- // and [61440, 65536), [65535, 65536), so it's actually [61440, 65536).
- for (let i = 0; i < CB_NON_MMI_SETTABLE_RANGES.length;) {
- let from = CB_NON_MMI_SETTABLE_RANGES[i++];
- let to = CB_NON_MMI_SETTABLE_RANGES[i++];
- if ((from != 4224) && (from != 65535)) {
- test(from - 1, from, true);
- }
- test(from - 1, from + 1, false);
- test(from - 1, to, false);
- test(from - 1, to + 1, false);
- test(from, from + 1, false);
- test(from, to, false);
- test(from, to + 1, false);
- if ((from + 1) < to) {
- test(from + 1, to, false);
- test(from + 1, to + 1, false);
- }
- if ((to != 4224) && (to < 65535)) {
- test(to, to + 1, true);
- test(to + 1, to + 2, true);
- }
- }
-
- run_next_test();
-});
-
-add_test(function test_ril_worker_CellBroadcastDisabled() {
- let count = 0;
- let worker = newWorker({
- postRILMessage: function(data) {
- // Do nothing
- },
- postMessage: function(message) {
- if (message.rilMessageType == "cellbroadcast-received") {
- ok(true, "cellbroadcast-received: " + JSON.stringify(message));
- count++;
- }
- }
- });
-
- function buildPdu(aMessageId) {
- return "C002" + aMessageId + "011154741914AFA7C76B9058" +
- "FEBEBB41E6371EA4AEB7E173D0DB5E96" +
- "83E8E832881DD6E741E4F7B9D168341A" +
- "8D46A3D168341A8D46A3D168341A8D46" +
- "A3D168341A8D46A3D168341A8D46A3D1" +
- "68341A8D46A3D100";
- }
-
- worker.ContextPool._contexts[0].RIL.cellBroadcastDisabled = true;
-
- let networkAlertIds = [
- "1100", "1107", // ETWS
- "1112", "112F", // CMAS
- "1130", "18FF", // PWS
- ];
- networkAlertIds.forEach(aMessageId => {
- worker.onRILMessage(
- 0,
- newIncomingParcel(
- -1,
- RESPONSE_TYPE_UNSOLICITED,
- UNSOLICITED_RESPONSE_NEW_BROADCAST_SMS,
- hexStringToParcelByteArrayData(buildPdu(aMessageId))));
- });
- equal(count, networkAlertIds.length, "Alerts shall not be ignored.");
-
- count = 0;
- let normalMsgIds = [ "0000", "03E7", "1108", "1901" ];
- normalMsgIds.forEach(aMessageId => {
- worker.onRILMessage(
- 0,
- newIncomingParcel(
- -1,
- RESPONSE_TYPE_UNSOLICITED,
- UNSOLICITED_RESPONSE_NEW_BROADCAST_SMS,
- hexStringToParcelByteArrayData(buildPdu(aMessageId))));
- });
- equal(count, 0, "Normal messages shall be ignored.");
-
- run_next_test();
-});
diff --git a/dom/system/gonk/tests/test_ril_worker_cellbroadcast_gsm.js b/dom/system/gonk/tests/test_ril_worker_cellbroadcast_gsm.js
deleted file mode 100644
index b08b64135a..0000000000
--- a/dom/system/gonk/tests/test_ril_worker_cellbroadcast_gsm.js
+++ /dev/null
@@ -1,230 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-subscriptLoader.loadSubScript("resource://gre/modules/ril_consts.js", this);
-
-function run_test() {
- run_next_test();
-}
-
-add_test(function test_ril_worker_GsmPDUHelper_readCbDataCodingScheme() {
- let worker = newWorker({
- postRILMessage: function(data) {
- // Do nothing
- },
- postMessage: function(message) {
- // Do nothing
- }
- });
-
- let context = worker.ContextPool._contexts[0];
- function test_dcs(dcs, encoding, language, hasLanguageIndicator, messageClass) {
- context.Buf.readUint8 = function() {
- return dcs;
- };
-
- let msg = {};
- context.GsmPDUHelper.readCbDataCodingScheme(msg);
-
- equal(msg.dcs, dcs);
- equal(msg.encoding, encoding);
- equal(msg.language, language);
- equal(msg.hasLanguageIndicator, hasLanguageIndicator);
- equal(msg.messageClass, messageClass);
- }
-
- function test_dcs_throws(dcs) {
- context.Buf.readUint8 = function() {
- return dcs;
- };
-
- throws(function() {
- context.GsmPDUHelper.readCbDataCodingScheme({});
- }, "Unsupported CBS data coding scheme: " + dcs);
- }
-
- // Group 0000
- for (let i = 0; i < 16; i++) {
- test_dcs(i, PDU_DCS_MSG_CODING_7BITS_ALPHABET, CB_DCS_LANG_GROUP_1[i],
- false, GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_NORMAL]);
- }
-
- // Group 0001
- // 0000 GSM 7 bit default alphabet; message preceded by language indication.
- test_dcs(0x10, PDU_DCS_MSG_CODING_7BITS_ALPHABET, null, true,
- GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_NORMAL]);
- // 0001 UCS2; message preceded by language indication.
- test_dcs(0x11, PDU_DCS_MSG_CODING_16BITS_ALPHABET, null, true,
- GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_NORMAL]);
-
- // Group 0010
- // 0000..0100
- for (let i = 0; i < 5; i++) {
- test_dcs(0x20 + i, PDU_DCS_MSG_CODING_7BITS_ALPHABET,
- CB_DCS_LANG_GROUP_2[i], false,
- GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_NORMAL]);
- }
- // 0101..1111 Reserved
- for (let i = 5; i < 16; i++) {
- test_dcs(0x20 + i, PDU_DCS_MSG_CODING_7BITS_ALPHABET, null, false,
- GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_NORMAL]);
- }
-
- // Group 0100, 0101, 1001
- for (let group of [0x40, 0x50, 0x90]) {
- for (let i = 0; i < 16; i++) {
- let encoding = i & 0x0C;
- if (encoding == 0x0C) {
- encoding = PDU_DCS_MSG_CODING_7BITS_ALPHABET;
- }
- let messageClass = GECKO_SMS_MESSAGE_CLASSES[i & PDU_DCS_MSG_CLASS_BITS];
- test_dcs(group + i, encoding, null, false, messageClass);
- }
- }
-
- // Group 1111
- for (let i = 0; i < 16; i ++) {
- let encoding = i & 0x04 ? PDU_DCS_MSG_CODING_8BITS_ALPHABET
- : PDU_DCS_MSG_CODING_7BITS_ALPHABET;
- let messageClass;
- switch(i & PDU_DCS_MSG_CLASS_BITS) {
- case 0x01: messageClass = PDU_DCS_MSG_CLASS_USER_1; break;
- case 0x02: messageClass = PDU_DCS_MSG_CLASS_USER_2; break;
- case 0x03: messageClass = PDU_DCS_MSG_CLASS_3; break;
- default: messageClass = PDU_DCS_MSG_CLASS_NORMAL; break;
- }
- test_dcs(0xF0 + i, encoding, null, false,
- GECKO_SMS_MESSAGE_CLASSES[messageClass]);
- }
-
- // Group 0011, 1000, 1010, 1011, 1100
- // 0000..1111 Reserved
- for (let group of [0x30, 0x80, 0xA0, 0xB0, 0xC0]) {
- for (let i = 0; i < 16; i++) {
- test_dcs(group + i, PDU_DCS_MSG_CODING_7BITS_ALPHABET, null, false,
- GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_NORMAL]);
- }
- }
-
- // Group 0110, 0111, 1101, 1110
- // TODO: unsupported
- for (let group of [0x60, 0x70, 0xD0, 0xE0]) {
- for (let i = 0; i < 16; i++) {
- test_dcs_throws(group + i);
- }
- }
-
- run_next_test();
-});
-
-add_test(function test_ril_worker_GsmPDUHelper_readGsmCbData() {
- let worker = newWorker({
- postRILMessage: function(data) {
- // Do nothing
- },
- postMessage: function(message) {
- // Do nothing
- }
- });
-
- let context = worker.ContextPool._contexts[0];
- function test_data(options, expected) {
- let readIndex = 0;
- context.Buf.readUint8 = function() {
- return options[3][readIndex++];
- };
- context.Buf.readUint8Array = function(length) {
- let array = new Uint8Array(length);
- for (let i = 0; i < length; i++) {
- array[i] = this.readUint8();
- }
- return array;
- };
-
- let msg = {
- encoding: options[0],
- language: options[1],
- hasLanguageIndicator: options[2]
- };
- context.GsmPDUHelper.readGsmCbData(msg, options[3].length);
-
- equal(msg.body, expected[0]);
- equal(msg.data == null, expected[1] == null);
- if (expected[1] != null) {
- equal(msg.data.length, expected[1].length);
- for (let i = 0; i < expected[1].length; i++) {
- equal(msg.data[i], expected[1][i]);
- }
- }
- equal(msg.language, expected[2]);
- }
-
- // We're testing Cell Broadcast message body with all zeros octet stream. As
- // shown in 3GPP TS 23.038, septet 0x00 will be decoded as '@' when both
- // langTableIndex and langShiftTableIndex equal to
- // PDU_DCS_MSG_CODING_7BITS_ALPHABET.
-
- // PDU_DCS_MSG_CODING_7BITS_ALPHABET
- test_data([PDU_DCS_MSG_CODING_7BITS_ALPHABET, null, false,
- [0]],
- ["@", null, null]);
- test_data([PDU_DCS_MSG_CODING_7BITS_ALPHABET, null, true,
- [0, 0, 0, 0]],
- ["@", null, "@@"]);
- test_data([PDU_DCS_MSG_CODING_7BITS_ALPHABET, "@@", false,
- [0]],
- ["@", null, "@@"]);
-
- // PDU_DCS_MSG_CODING_8BITS_ALPHABET
- test_data([PDU_DCS_MSG_CODING_8BITS_ALPHABET, null, false,
- [0]],
- [null, [0], null]);
-
- // PDU_DCS_MSG_CODING_16BITS_ALPHABET
- test_data([PDU_DCS_MSG_CODING_16BITS_ALPHABET, null, false,
- [0x00, 0x40]],
- ["@", null, null]);
- test_data([PDU_DCS_MSG_CODING_16BITS_ALPHABET, null, true,
- [0x00, 0x00, 0x00, 0x40]],
- ["@", null, "@@"]);
- test_data([PDU_DCS_MSG_CODING_16BITS_ALPHABET, "@@", false,
- [0x00, 0x40]],
- ["@", null, "@@"]);
-
- run_next_test();
-});
-
-add_test(function test_ril_worker_Sim_Download_Message() {
- let worker = newWorker({
- postRILMessage: function(data) {
- // Do nothing
- },
- postMessage: function(message) {
- ok(message.rilMessageType !== "cellbroadcast-received",
- "Data-Download message shall be ignored.");
- }
- });
-
- function buildPdu(aMessageId) {
- return "C002" + aMessageId + "011154741914AFA7C76B9058" +
- "FEBEBB41E6371EA4AEB7E173D0DB5E96" +
- "83E8E832881DD6E741E4F7B9D168341A" +
- "8D46A3D168341A8D46A3D168341A8D46" +
- "A3D168341A8D46A3D168341A8D46A3D1" +
- "68341A8D46A3D100";
- }
-
- ["1000", "107F", "1080", "10FF"].forEach(aMessageId => {
- worker.onRILMessage(
- 0,
- newIncomingParcel(
- -1,
- RESPONSE_TYPE_UNSOLICITED,
- UNSOLICITED_RESPONSE_NEW_BROADCAST_SMS,
- hexStringToParcelByteArrayData(buildPdu(aMessageId))));
- });
-
- ok(true, "All Data-Download Messages are ingored.");
-
- run_next_test();
-});
diff --git a/dom/system/gonk/tests/test_ril_worker_cellbroadcast_umts.js b/dom/system/gonk/tests/test_ril_worker_cellbroadcast_umts.js
deleted file mode 100644
index 0380c4122e..0000000000
--- a/dom/system/gonk/tests/test_ril_worker_cellbroadcast_umts.js
+++ /dev/null
@@ -1,105 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-subscriptLoader.loadSubScript("resource://gre/modules/ril_consts.js", this);
-
-function run_test() {
- run_next_test();
-}
-
-function buildHexStr(aNum, aNumSemiOctets) {
- let str = aNum.toString(16);
- while (str.length < aNumSemiOctets) {
- str = "0" + str;
- }
- return str;
-}
-
-/**
- * Verify GsmPDUHelper#readUmtsCbMessage with numOfPages from 1 to 15.
- */
-add_test(function test_GsmPDUHelper_readUmtsCbMessage_MultiParts() {
- let CB_UMTS_MESSAGE_PAGE_SIZE = 82;
- let CB_MAX_CONTENT_PER_PAGE_7BIT = 93;
- let workerHelper = newInterceptWorker(),
- worker = workerHelper.worker,
- context = worker.ContextPool._contexts[0],
- GsmPDUHelper = context.GsmPDUHelper;
-
- function test_MultiParts(aNumOfPages) {
- let pdu = buildHexStr(CB_UMTS_MESSAGE_TYPE_CBS, 2) // msg_type
- + buildHexStr(0, 4) // skip msg_id
- + buildHexStr(0, 4) // skip SN
- + buildHexStr(0, 2) // skip dcs
- + buildHexStr(aNumOfPages, 2); // set num_of_pages
- for (let i = 1; i <= aNumOfPages; i++) {
- pdu = pdu + buildHexStr(0, CB_UMTS_MESSAGE_PAGE_SIZE * 2)
- + buildHexStr(CB_UMTS_MESSAGE_PAGE_SIZE, 2); // msg_info_length
- }
-
- worker.onRILMessage(0, newIncomingParcel(-1,
- RESPONSE_TYPE_UNSOLICITED,
- UNSOLICITED_RESPONSE_NEW_BROADCAST_SMS,
- hexStringToParcelByteArrayData(pdu)));
-
- let postedMessage = workerHelper.postedMessage;
- equal("cellbroadcast-received", postedMessage.rilMessageType);
- equal(postedMessage.fullBody.length,
- aNumOfPages * CB_MAX_CONTENT_PER_PAGE_7BIT);
- }
-
- [1, 5, 15].forEach(function(i) {
- test_MultiParts(i);
- });
-
- run_next_test();
-});
-
-/**
- * Verify GsmPDUHelper#readUmtsCbMessage with 8bit encoded.
- */
-add_test(function test_GsmPDUHelper_readUmtsCbMessage_Binary() {
- let CB_UMTS_MESSAGE_PAGE_SIZE = 82;
- let CB_MAX_CONTENT_PER_PAGE_7BIT = 93;
- let TEXT_BINARY = "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
- + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
- + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
- + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
- + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
- + "FFFF";
- let workerHelper = newInterceptWorker(),
- worker = workerHelper.worker,
- context = worker.ContextPool._contexts[0],
- GsmPDUHelper = context.GsmPDUHelper;
-
- function test_MultiPartsBinary(aNumOfPages) {
- let pdu = buildHexStr(CB_UMTS_MESSAGE_TYPE_CBS, 2) // msg_type
- + buildHexStr(0, 4) // skip msg_id
- + buildHexStr(0, 4) // skip SN
- + buildHexStr(68, 2) // set DCS to 8bit data
- + buildHexStr(aNumOfPages, 2); // set num_of_pages
- for (let i = 1; i <= aNumOfPages; i++) {
- pdu = pdu + TEXT_BINARY
- + buildHexStr(CB_UMTS_MESSAGE_PAGE_SIZE, 2); // msg_info_length
- }
-
- worker.onRILMessage(0, newIncomingParcel(-1,
- RESPONSE_TYPE_UNSOLICITED,
- UNSOLICITED_RESPONSE_NEW_BROADCAST_SMS,
- hexStringToParcelByteArrayData(pdu)));
-
- let postedMessage = workerHelper.postedMessage;
- equal("cellbroadcast-received", postedMessage.rilMessageType);
- equal(postedMessage.fullData.length,
- aNumOfPages * CB_UMTS_MESSAGE_PAGE_SIZE);
- for (let i = 0; i < postedMessage.fullData.length; i++) {
- equal(postedMessage.fullData[i], 255);
- }
- }
-
- [1, 5, 15].forEach(function(i) {
- test_MultiPartsBinary(i);
- });
-
- run_next_test();
-});
diff --git a/dom/system/gonk/tests/test_ril_worker_cf.js b/dom/system/gonk/tests/test_ril_worker_cf.js
deleted file mode 100644
index b8db716b7c..0000000000
--- a/dom/system/gonk/tests/test_ril_worker_cf.js
+++ /dev/null
@@ -1,126 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-subscriptLoader.loadSubScript("resource://gre/modules/ril_consts.js", this);
-
-function run_test() {
- run_next_test();
-}
-
-function toaFromString(number) {
- let worker = newWorker({
- postRILMessage: function(data) {
- // Do nothing
- },
- postMessage: function(message) {
- // Do nothing
- }
- });
- let context = worker.ContextPool._contexts[0];
- return context.RIL._toaFromString(number);
-}
-
-add_test(function test_toaFromString_empty() {
- let retval = toaFromString("");
-
- equal(retval, TOA_UNKNOWN);
-
- run_next_test();
-});
-
-add_test(function test_toaFromString_undefined() {
- let retval = toaFromString();
-
- equal(retval, TOA_UNKNOWN);
-
- run_next_test();
-});
-
-add_test(function test_toaFromString_unknown() {
- let retval = toaFromString("666222333");
-
- equal(retval, TOA_UNKNOWN);
-
- run_next_test();
-});
-
-add_test(function test_toaFromString_international() {
- let retval = toaFromString("+34666222333");
-
- equal(retval, TOA_INTERNATIONAL);
-
- run_next_test();
-});
-
-add_test(function test_setCallForward_unconditional() {
- let workerHelper = newInterceptWorker();
- let worker = workerHelper.worker;
- let context = worker.ContextPool._contexts[0];
-
- context.RIL.setCallForward = function fakeSetCallForward(options) {
- context.RIL[REQUEST_SET_CALL_FORWARD](0, {});
- };
-
- context.RIL.setCallForward({
- action: CALL_FORWARD_ACTION_REGISTRATION,
- reason: CALL_FORWARD_REASON_UNCONDITIONAL,
- serviceClass: ICC_SERVICE_CLASS_VOICE,
- number: "666222333",
- timeSeconds: 10
- });
-
- let postedMessage = workerHelper.postedMessage;
-
- equal(postedMessage.errorMsg, undefined);
-
- run_next_test();
-});
-
-add_test(function test_queryCallForwardStatus_unconditional() {
- let workerHelper = newInterceptWorker();
- let worker = workerHelper.worker;
- let context = worker.ContextPool._contexts[0];
-
- context.RIL.setCallForward = function fakeSetCallForward(options) {
- context.RIL[REQUEST_SET_CALL_FORWARD](0, {});
- };
-
- context.Buf.readInt32 = function fakeReadUint32() {
- return context.Buf.int32Array.pop();
- };
-
- context.Buf.readString = function fakeReadString() {
- return "+34666222333";
- };
-
- context.RIL.queryCallForwardStatus = function fakeQueryCallForward(options) {
- context.Buf.int32Array = [
- 0, // rules.timeSeconds
- 145, // rules.toa
- 49, // rules.serviceClass
- CALL_FORWARD_REASON_UNCONDITIONAL, // rules.reason
- 1, // rules.active
- 1 // rulesLength
- ];
- context.RIL[REQUEST_QUERY_CALL_FORWARD_STATUS](1, {});
- };
-
- context.RIL.queryCallForwardStatus({
- action: CALL_FORWARD_ACTION_QUERY_STATUS,
- reason: CALL_FORWARD_REASON_UNCONDITIONAL,
- serviceClass: ICC_SERVICE_CLASS_VOICE,
- number: "666222333",
- timeSeconds: 10
- });
-
- let postedMessage = workerHelper.postedMessage;
-
- equal(postedMessage.errorMsg, undefined);
- ok(Array.isArray(postedMessage.rules));
- do_print(postedMessage.rules.length);
- equal(postedMessage.rules.length, 1);
- ok(postedMessage.rules[0].active);
- equal(postedMessage.rules[0].reason, CALL_FORWARD_REASON_UNCONDITIONAL);
- equal(postedMessage.rules[0].number, "+34666222333");
- run_next_test();
-});
diff --git a/dom/system/gonk/tests/test_ril_worker_clip.js b/dom/system/gonk/tests/test_ril_worker_clip.js
deleted file mode 100644
index d1ce5f6179..0000000000
--- a/dom/system/gonk/tests/test_ril_worker_clip.js
+++ /dev/null
@@ -1,59 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-subscriptLoader.loadSubScript("resource://gre/modules/ril_consts.js", this);
-
-function run_test() {
- run_next_test();
-}
-
-add_test(function test_queryCLIP_provisioned() {
- let workerHelper = newInterceptWorker();
- let worker = workerHelper.worker;
- let context = worker.ContextPool._contexts[0];
-
- context.Buf.readInt32 = function fakeReadUint32() {
- return context.Buf.int32Array.pop();
- };
-
- context.RIL.queryCLIP = function fakeQueryCLIP(options) {
- context.Buf.int32Array = [
- 1, // CLIP provisioned.
- 1 // Length.
- ];
- context.RIL[REQUEST_QUERY_CLIP](1, {});
- };
-
- context.RIL.queryCLIP({});
-
- let postedMessage = workerHelper.postedMessage;
-
- equal(postedMessage.errorMsg, undefined);
- equal(postedMessage.provisioned, 1);
- run_next_test();
-});
-
-add_test(function test_getCLIP_error_generic_failure_invalid_length() {
- let workerHelper = newInterceptWorker();
- let worker = workerHelper.worker;
- let context = worker.ContextPool._contexts[0];
-
- context.Buf.readInt32 = function fakeReadUint32() {
- return context.Buf.int32Array.pop();
- };
-
- context.RIL.queryCLIP = function fakeQueryCLIP(options) {
- context.Buf.int32Array = [
- 1, // CLIP provisioned.
- 0 // Length.
- ];
- context.RIL[REQUEST_QUERY_CLIP](1, {});
- };
-
- context.RIL.queryCLIP({});
-
- let postedMessage = workerHelper.postedMessage;
-
- equal(postedMessage.errorMsg, GECKO_ERROR_GENERIC_FAILURE);
- run_next_test();
-});
diff --git a/dom/system/gonk/tests/test_ril_worker_clir.js b/dom/system/gonk/tests/test_ril_worker_clir.js
deleted file mode 100644
index 5882a3c4cc..0000000000
--- a/dom/system/gonk/tests/test_ril_worker_clir.js
+++ /dev/null
@@ -1,122 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-subscriptLoader.loadSubScript("resource://gre/modules/ril_consts.js", this);
-
-// Calling line identification restriction constants.
-
-// Uses subscription default value.
-const CLIR_DEFAULT = 0;
-// Restricts CLI presentation.
-const CLIR_INVOCATION = 1;
-// Allows CLI presentation.
-const CLIR_SUPPRESSION = 2;
-
-function run_test() {
- run_next_test();
-}
-
-add_test(function test_setCLIR_success() {
- let workerHelper = newInterceptWorker();
- let worker = workerHelper.worker;
- let context = worker.ContextPool._contexts[0];
-
- context.RIL.setCLIR = function fakeSetCLIR(options) {
- context.RIL[REQUEST_SET_CLIR](0, {
- rilMessageType: "setCLIR"
- });
- };
-
- context.RIL.setCLIR({
- clirMode: CLIR_DEFAULT
- });
-
- let postedMessage = workerHelper.postedMessage;
-
- equal(postedMessage.errorMsg, undefined);
-
- run_next_test();
-});
-
-add_test(function test_setCLIR_generic_failure() {
- let workerHelper = newInterceptWorker();
- let worker = workerHelper.worker;
- let context = worker.ContextPool._contexts[0];
-
- context.RIL.setCLIR = function fakeSetCLIR(options) {
- context.RIL[REQUEST_SET_CLIR](0, {
- rilMessageType: "setCLIR",
- errorMsg: GECKO_ERROR_GENERIC_FAILURE
- });
- };
-
- context.RIL.setCLIR({
- clirMode: CLIR_DEFAULT
- });
-
- let postedMessage = workerHelper.postedMessage;
-
- equal(postedMessage.errorMsg, GECKO_ERROR_GENERIC_FAILURE);
-
- run_next_test();
-});
-
-add_test(function test_getCLIR_n0_m1() {
- let workerHelper = newInterceptWorker();
- let worker = workerHelper.worker;
- let context = worker.ContextPool._contexts[0];
-
- context.Buf.readInt32 = function fakeReadUint32() {
- return context.Buf.int32Array.pop();
- };
-
- context.RIL.getCLIR = function fakeGetCLIR(options) {
- context.Buf.int32Array = [
- 1, // Presentation indicator is used according to the subscription
- // of the CLIR service.
- 0, // CLIR provisioned in permanent mode.
- 2 // Length.
- ];
- context.RIL[REQUEST_GET_CLIR](1, {
- rilMessageType: "setCLIR"
- });
- };
-
- context.RIL.getCLIR({});
-
- let postedMessage = workerHelper.postedMessage;
-
- equal(postedMessage.errorMsg, undefined);
- equal(postedMessage.n, 0);
- equal(postedMessage.m, 1);
- run_next_test();
-});
-
-add_test(function test_getCLIR_error_generic_failure_invalid_length() {
- let workerHelper = newInterceptWorker();
- let worker = workerHelper.worker;
- let context = worker.ContextPool._contexts[0];
-
- context.Buf.readInt32 = function fakeReadUint32() {
- return context.Buf.int32Array.pop();
- };
-
- context.RIL.getCLIR = function fakeGetCLIR(options) {
- context.Buf.int32Array = [
- 1, // Presentation indicator is used according to the subscription
- // of the CLIR service.
- 0, // CLIR provisioned in permanent mode.
- 0 // Length (invalid one).
- ];
- context.RIL[REQUEST_GET_CLIR](1, {
- rilMessageType: "setCLIR"
- });
- };
-
- context.RIL.getCLIR({});
-
- let postedMessage = workerHelper.postedMessage;
-
- equal(postedMessage.errorMsg, GECKO_ERROR_GENERIC_FAILURE);
- run_next_test();
-});
diff --git a/dom/system/gonk/tests/test_ril_worker_cw.js b/dom/system/gonk/tests/test_ril_worker_cw.js
deleted file mode 100644
index efa8b5c21d..0000000000
--- a/dom/system/gonk/tests/test_ril_worker_cw.js
+++ /dev/null
@@ -1,104 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-subscriptLoader.loadSubScript("resource://gre/modules/ril_consts.js", this);
-
-function run_test() {
- run_next_test();
-}
-
-add_test(function test_setCallWaiting_success() {
- let workerHelper = newInterceptWorker();
- let worker = workerHelper.worker;
- let context = worker.ContextPool._contexts[0];
-
- context.RIL.setCallWaiting = function fakeSetCallWaiting(options) {
- context.RIL[REQUEST_SET_CALL_WAITING](0, {});
- };
-
- context.RIL.setCallWaiting({
- enabled: true
- });
-
- let postedMessage = workerHelper.postedMessage;
-
- equal(postedMessage.errorMsg, undefined);
-
- run_next_test();
-});
-
-add_test(function test_setCallWaiting_generic_failure() {
- let workerHelper = newInterceptWorker();
- let worker = workerHelper.worker;
- let context = worker.ContextPool._contexts[0];
-
- context.RIL.setCallWaiting = function fakeSetCallWaiting(options) {
- context.RIL[REQUEST_SET_CALL_WAITING](0, {
- errorMsg: GECKO_ERROR_GENERIC_FAILURE
- });
- };
-
- context.RIL.setCallWaiting({
- enabled: true
- });
-
- let postedMessage = workerHelper.postedMessage;
-
- equal(postedMessage.errorMsg, GECKO_ERROR_GENERIC_FAILURE);
-
- run_next_test();
-});
-
-add_test(function test_queryCallWaiting_success_enabled_true() {
- let workerHelper = newInterceptWorker();
- let worker = workerHelper.worker;
- let context = worker.ContextPool._contexts[0];
-
- context.Buf.readInt32 = function fakeReadUint32() {
- return context.Buf.int32Array.pop();
- };
-
- context.RIL.queryCallWaiting = function fakeQueryCallWaiting(options) {
- context.Buf.int32Array = [
- 1, // serviceClass
- 1, // enabled
- 2 // length
- ];
- context.RIL[REQUEST_QUERY_CALL_WAITING](1, {});
- };
-
- context.RIL.queryCallWaiting({});
-
- let postedMessage = workerHelper.postedMessage;
-
- equal(postedMessage.errorMsg, undefined);
- equal(postedMessage.serviceClass, 1);
- run_next_test();
-});
-
-add_test(function test_queryCallWaiting_success_enabled_false() {
- let workerHelper = newInterceptWorker();
- let worker = workerHelper.worker;
- let context = worker.ContextPool._contexts[0];
-
- context.Buf.readInt32 = function fakeReadUint32() {
- return context.Buf.int32Array.pop();
- };
-
- context.RIL.queryCallWaiting = function fakeQueryCallWaiting(options) {
- context.Buf.int32Array = [
- 1, // serviceClass
- 0, // enabled
- 2 // length
- ];
- context.RIL[REQUEST_QUERY_CALL_WAITING](1, {});
- };
-
- context.RIL.queryCallWaiting({});
-
- let postedMessage = workerHelper.postedMessage;
-
- equal(postedMessage.errorMsg, undefined);
- equal(postedMessage.serviceClass, ICC_SERVICE_CLASS_NONE);
- run_next_test();
-});
diff --git a/dom/system/gonk/tests/test_ril_worker_ecm.js b/dom/system/gonk/tests/test_ril_worker_ecm.js
deleted file mode 100644
index d10cba9ec8..0000000000
--- a/dom/system/gonk/tests/test_ril_worker_ecm.js
+++ /dev/null
@@ -1,168 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-subscriptLoader.loadSubScript("resource://gre/modules/ril_consts.js", this);
-
-function run_test() {
- run_next_test();
-}
-
-var timeoutCallback = null;
-var timeoutDelayMs = 0;
-const TIMER_ID = 1234;
-const TIMEOUT_VALUE = 300000; // 5 mins.
-
-// No window in xpcshell-test. Create our own timer mechanism.
-
-function setTimeout(callback, timeoutMs) {
- timeoutCallback = callback;
- timeoutDelayMs = timeoutMs;
- equal(timeoutMs, TIMEOUT_VALUE);
- return TIMER_ID;
-}
-
-function clearTimeout(timeoutId) {
- equal(timeoutId, TIMER_ID);
- timeoutCallback = null;
-}
-
-function fireTimeout() {
- notEqual(timeoutCallback, null);
- if (timeoutCallback) {
- timeoutCallback();
- timeoutCallback = null;
- }
-}
-
-add_test(function test_enter_emergencyCbMode() {
- let workerHelper = newInterceptWorker();
- let worker = workerHelper.worker;
- let context = worker.ContextPool._contexts[0];
-
- // Do it twice. Should always send the event.
- for (let i = 0; i < 2; ++i) {
- context.RIL[UNSOLICITED_ENTER_EMERGENCY_CALLBACK_MODE]();
- let postedMessage = workerHelper.postedMessage;
-
- // Should store the mode.
- equal(context.RIL._isInEmergencyCbMode, true);
-
- // Should notify change.
- equal(postedMessage.rilMessageType, "emergencyCbModeChange");
- equal(postedMessage.active, true);
- equal(postedMessage.timeoutMs, TIMEOUT_VALUE);
-
- // Should start timer.
- equal(context.RIL._exitEmergencyCbModeTimeoutID, TIMER_ID);
- }
-
- run_next_test();
-});
-
-add_test(function test_exit_emergencyCbMode() {
- let workerHelper = newInterceptWorker();
- let worker = workerHelper.worker;
- let context = worker.ContextPool._contexts[0];
-
- context.RIL[UNSOLICITED_ENTER_EMERGENCY_CALLBACK_MODE]();
- context.RIL[UNSOLICITED_EXIT_EMERGENCY_CALLBACK_MODE]();
- let postedMessage = workerHelper.postedMessage;
-
- // Should store the mode.
- equal(context.RIL._isInEmergencyCbMode, false);
-
- // Should notify change.
- equal(postedMessage.rilMessageType, "emergencyCbModeChange");
- equal(postedMessage.active, false);
-
- // Should clear timer.
- equal(context.RIL._exitEmergencyCbModeTimeoutID, null);
-
- run_next_test();
-});
-
-add_test(function test_request_exit_emergencyCbMode_when_timeout() {
- let workerHelper = newInterceptWorker();
- let worker = workerHelper.worker;
- let context = worker.ContextPool._contexts[0];
-
- context.RIL[UNSOLICITED_ENTER_EMERGENCY_CALLBACK_MODE]();
- equal(context.RIL._isInEmergencyCbMode, true);
- equal(context.RIL._exitEmergencyCbModeTimeoutID, TIMER_ID);
-
- let parcelTypes = [];
- context.Buf.newParcel = function(type, options) {
- parcelTypes.push(type);
- };
-
- // Timeout.
- fireTimeout();
-
- // Should clear timeout event.
- equal(context.RIL._exitEmergencyCbModeTimeoutID, null);
-
- // Check indeed sent out REQUEST_EXIT_EMERGENCY_CALLBACK_MODE.
- notEqual(parcelTypes.indexOf(REQUEST_EXIT_EMERGENCY_CALLBACK_MODE), -1);
-
- run_next_test();
-});
-
-add_test(function test_request_exit_emergencyCbMode_when_dial() {
- let workerHelper = newInterceptWorker();
- let worker = workerHelper.worker;
- let context = worker.ContextPool._contexts[0];
-
- context.RIL[UNSOLICITED_ENTER_EMERGENCY_CALLBACK_MODE]();
- equal(context.RIL._isInEmergencyCbMode, true);
- equal(context.RIL._exitEmergencyCbModeTimeoutID, TIMER_ID);
-
- let parcelTypes = [];
- context.Buf.newParcel = function(type, options) {
- parcelTypes.push(type);
- };
-
- // Dial non-emergency call.
- context.RIL.dial({number: "0912345678",
- isEmergency: false,
- isDialEmergency: false});
-
- // Should clear timeout event.
- equal(context.RIL._exitEmergencyCbModeTimeoutID, null);
-
- // Check indeed sent out REQUEST_EXIT_EMERGENCY_CALLBACK_MODE.
- notEqual(parcelTypes.indexOf(REQUEST_EXIT_EMERGENCY_CALLBACK_MODE), -1);
-
- run_next_test();
-});
-
-add_test(function test_request_exit_emergencyCbMode_explicitly() {
- let workerHelper = newInterceptWorker();
- let worker = workerHelper.worker;
- let context = worker.ContextPool._contexts[0];
-
- context.RIL[UNSOLICITED_ENTER_EMERGENCY_CALLBACK_MODE]();
- equal(context.RIL._isInEmergencyCbMode, true);
- equal(context.RIL._exitEmergencyCbModeTimeoutID, TIMER_ID);
-
- let parcelTypes = [];
- context.Buf.newParcel = function(type, options) {
- parcelTypes.push(type);
- };
-
- context.RIL.handleChromeMessage({rilMessageType: "exitEmergencyCbMode"});
- context.RIL[REQUEST_EXIT_EMERGENCY_CALLBACK_MODE](1, {
- rilMessageType: "exitEmergencyCbMode"
- });
- let postedMessage = workerHelper.postedMessage;
-
- // Should clear timeout event.
- equal(context.RIL._exitEmergencyCbModeTimeoutID, null);
-
- // Check indeed sent out REQUEST_EXIT_EMERGENCY_CALLBACK_MODE.
- notEqual(parcelTypes.indexOf(REQUEST_EXIT_EMERGENCY_CALLBACK_MODE), -1);
-
- // Send back the response.
- equal(postedMessage.rilMessageType, "exitEmergencyCbMode");
-
- run_next_test();
-});
diff --git a/dom/system/gonk/tests/test_ril_worker_icc_BerTlvHelper.js b/dom/system/gonk/tests/test_ril_worker_icc_BerTlvHelper.js
deleted file mode 100644
index 89fcd874d0..0000000000
--- a/dom/system/gonk/tests/test_ril_worker_icc_BerTlvHelper.js
+++ /dev/null
@@ -1,87 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-subscriptLoader.loadSubScript("resource://gre/modules/ril_consts.js", this);
-
-function run_test() {
- run_next_test();
-}
-
-// Test ICC_COMMAND_GET_RESPONSE with FCP template format.
-/**
- * Verify transparent structure with FCP template format.
- */
-add_test(function test_fcp_template_for_transparent_structure() {
- let worker = newUint8Worker();
- let context = worker.ContextPool._contexts[0];
- let pduHelper = context.GsmPDUHelper;
- let berHelper = context.BerTlvHelper;
-
- let tag_test = [
- 0x62,
- 0x22,
- 0x82, 0x02, 0x41, 0x21,
- 0x83, 0x02, 0x2F, 0xE2,
- 0xA5, 0x09, 0xC1, 0x04, 0x40, 0x0F, 0xF5, 0x55, 0x92, 0x01, 0x00,
- 0x8A, 0x01, 0x05,
- 0x8B, 0x03, 0x2F, 0x06, 0x0B,
- 0x80, 0x02, 0x00, 0x0A,
- 0x88, 0x01, 0x10];
-
- for (let i = 0; i < tag_test.length; i++) {
- pduHelper.writeHexOctet(tag_test[i]);
- }
-
- let berTlv = berHelper.decode(tag_test.length);
- let iter = berTlv.value.values();
- let tlv = berHelper.searchForNextTag(BER_FCP_FILE_DESCRIPTOR_TAG, iter);
- equal(tlv.value.fileStructure, UICC_EF_STRUCTURE[EF_STRUCTURE_TRANSPARENT]);
-
- tlv = berHelper.searchForNextTag(BER_FCP_FILE_IDENTIFIER_TAG, iter);
- equal(tlv.value.fileId, 0x2FE2);
-
- tlv = berHelper.searchForNextTag(BER_FCP_FILE_SIZE_DATA_TAG, iter);
- equal(tlv.value.fileSizeData, 0x0A);
-
- run_next_test();
-});
-
-/**
- * Verify linear fixed structure with FCP template format.
- */
-add_test(function test_fcp_template_for_linear_fixed_structure() {
- let worker = newUint8Worker();
- let context = worker.ContextPool._contexts[0];
- let pduHelper = context.GsmPDUHelper;
- let berHelper = context.BerTlvHelper;
-
- let tag_test = [
- 0x62,
- 0x1E,
- 0x82, 0x05, 0x42, 0x21, 0x00, 0x1A, 0x01,
- 0x83, 0x02, 0x6F, 0x40,
- 0xA5, 0x03, 0x92, 0x01, 0x00,
- 0x8A, 0x01, 0x07,
- 0x8B, 0x03, 0x6F, 0x06, 0x02,
- 0x80, 0x02, 0x00, 0x1A,
- 0x88, 0x00];
-
- for (let i = 0; i < tag_test.length; i++) {
- pduHelper.writeHexOctet(tag_test[i]);
- }
-
- let berTlv = berHelper.decode(tag_test.length);
- let iter = berTlv.value.values();
- let tlv = berHelper.searchForNextTag(BER_FCP_FILE_DESCRIPTOR_TAG, iter);
- equal(tlv.value.fileStructure, UICC_EF_STRUCTURE[EF_STRUCTURE_LINEAR_FIXED]);
- equal(tlv.value.recordLength, 0x1A);
- equal(tlv.value.numOfRecords, 0x01);
-
- tlv = berHelper.searchForNextTag(BER_FCP_FILE_IDENTIFIER_TAG, iter);
- equal(tlv.value.fileId, 0x6F40);
-
- tlv = berHelper.searchForNextTag(BER_FCP_FILE_SIZE_DATA_TAG, iter);
- equal(tlv.value.fileSizeData, 0x1A);
-
- run_next_test();
-});
diff --git a/dom/system/gonk/tests/test_ril_worker_icc_CardLock.js b/dom/system/gonk/tests/test_ril_worker_icc_CardLock.js
deleted file mode 100644
index dc7eb93b9d..0000000000
--- a/dom/system/gonk/tests/test_ril_worker_icc_CardLock.js
+++ /dev/null
@@ -1,282 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-subscriptLoader.loadSubScript("resource://gre/modules/ril_consts.js", this);
-
-function run_test() {
- run_next_test();
-}
-
-/**
- * Verify RIL.iccGetCardLockEnabled
- */
-add_test(function test_icc_get_card_lock_enabled() {
- let worker = newUint8Worker();
- let context = worker.ContextPool._contexts[0];
- let buf = context.Buf;
- let ril = context.RIL;
- ril.aid = "123456789";
-
- function do_test(aLock) {
- const serviceClass = ICC_SERVICE_CLASS_VOICE |
- ICC_SERVICE_CLASS_DATA |
- ICC_SERVICE_CLASS_FAX;
-
- buf.sendParcel = function fakeSendParcel() {
- // Request Type.
- equal(this.readInt32(), REQUEST_QUERY_FACILITY_LOCK)
-
- // Token : we don't care.
- this.readInt32();
-
- // Data
- let parcel = this.readStringList();
- equal(parcel.length, 4);
- equal(parcel[0], GECKO_CARDLOCK_TO_FACILITY[aLock]);
- equal(parcel[1], "");
- equal(parcel[2], serviceClass.toString());
- equal(parcel[3], ril.aid);
- };
-
- ril.iccGetCardLockEnabled({lockType: aLock});
- }
-
- do_test(GECKO_CARDLOCK_PIN)
- do_test(GECKO_CARDLOCK_FDN)
-
- run_next_test();
-});
-
-add_test(function test_path_id_for_spid_and_spn() {
- let worker = newWorker({
- postRILMessage: function(data) {
- // Do nothing
- },
- postMessage: function(message) {
- // Do nothing
- }});
- let context = worker.ContextPool._contexts[0];
- let RIL = context.RIL;
- let ICCFileHelper = context.ICCFileHelper;
-
- // Test SIM
- RIL.appType = CARD_APPTYPE_SIM;
- equal(ICCFileHelper.getEFPath(ICC_EF_SPDI),
- EF_PATH_MF_SIM + EF_PATH_DF_GSM);
- equal(ICCFileHelper.getEFPath(ICC_EF_SPN),
- EF_PATH_MF_SIM + EF_PATH_DF_GSM);
-
- // Test USIM
- RIL.appType = CARD_APPTYPE_USIM;
- equal(ICCFileHelper.getEFPath(ICC_EF_SPDI),
- EF_PATH_MF_SIM + EF_PATH_ADF_USIM);
- equal(ICCFileHelper.getEFPath(ICC_EF_SPDI),
- EF_PATH_MF_SIM + EF_PATH_ADF_USIM);
- run_next_test();
-});
-
-/**
- * Verify RIL.iccSetCardLockEnabled
- */
-add_test(function test_icc_set_card_lock_enabled() {
- let worker = newUint8Worker();
- let context = worker.ContextPool._contexts[0];
- let buf = context.Buf;
- let ril = context.RIL;
- ril.aid = "123456789";
-
- function do_test(aLock, aPassword, aEnabled) {
- const serviceClass = ICC_SERVICE_CLASS_VOICE |
- ICC_SERVICE_CLASS_DATA |
- ICC_SERVICE_CLASS_FAX;
-
- buf.sendParcel = function fakeSendParcel() {
- // Request Type.
- equal(this.readInt32(), REQUEST_SET_FACILITY_LOCK);
-
- // Token : we don't care
- this.readInt32();
-
- // Data
- let parcel = this.readStringList();
- equal(parcel.length, 5);
- equal(parcel[0], GECKO_CARDLOCK_TO_FACILITY[aLock]);
- equal(parcel[1], aEnabled ? "1" : "0");
- equal(parcel[2], aPassword);
- equal(parcel[3], serviceClass.toString());
- equal(parcel[4], ril.aid);
- };
-
- ril.iccSetCardLockEnabled({
- lockType: aLock,
- enabled: aEnabled,
- password: aPassword});
- }
-
- do_test(GECKO_CARDLOCK_PIN, "1234", true);
- do_test(GECKO_CARDLOCK_PIN, "1234", false);
- do_test(GECKO_CARDLOCK_FDN, "4321", true);
- do_test(GECKO_CARDLOCK_FDN, "4321", false);
-
- run_next_test();
-});
-
-/**
- * Verify RIL.iccChangeCardLockPassword
- */
-add_test(function test_icc_change_card_lock_password() {
- let worker = newUint8Worker();
- let context = worker.ContextPool._contexts[0];
- let buf = context.Buf;
- let ril = context.RIL;
-
-
- function do_test(aLock, aPassword, aNewPassword) {
- let GECKO_CARDLOCK_TO_REQUEST = {};
- GECKO_CARDLOCK_TO_REQUEST[GECKO_CARDLOCK_PIN] = REQUEST_CHANGE_SIM_PIN;
- GECKO_CARDLOCK_TO_REQUEST[GECKO_CARDLOCK_PIN2] = REQUEST_CHANGE_SIM_PIN2;
-
- buf.sendParcel = function fakeSendParcel() {
- // Request Type.
- equal(this.readInt32(), GECKO_CARDLOCK_TO_REQUEST[aLock]);
-
- // Token : we don't care
- this.readInt32();
-
- // Data
- let parcel = this.readStringList();
- equal(parcel.length, 3);
- equal(parcel[0], aPassword);
- equal(parcel[1], aNewPassword);
- equal(parcel[2], ril.aid);
- };
-
- ril.iccChangeCardLockPassword({
- lockType: aLock,
- password: aPassword,
- newPassword: aNewPassword});
- }
-
- do_test(GECKO_CARDLOCK_PIN, "1234", "4321");
- do_test(GECKO_CARDLOCK_PIN2, "1234", "4321");
-
- run_next_test();
-});
-
-/**
- * Verify RIL.iccUnlockCardLock - PIN
- */
-add_test(function test_icc_unlock_card_lock_pin() {
- let worker = newUint8Worker();
- let context = worker.ContextPool._contexts[0];
- let ril = context.RIL;
- let buf = context.Buf;
- ril.aid = "123456789";
-
- function do_test(aLock, aPassword) {
- let GECKO_CARDLOCK_TO_REQUEST = {};
- GECKO_CARDLOCK_TO_REQUEST[GECKO_CARDLOCK_PIN] = REQUEST_ENTER_SIM_PIN;
- GECKO_CARDLOCK_TO_REQUEST[GECKO_CARDLOCK_PIN2] = REQUEST_ENTER_SIM_PIN2;
-
- buf.sendParcel = function fakeSendParcel() {
- // Request Type.
- equal(this.readInt32(), GECKO_CARDLOCK_TO_REQUEST[aLock]);
-
- // Token : we don't care
- this.readInt32();
-
- // Data
- let parcel = this.readStringList();
- equal(parcel.length, 2);
- equal(parcel[0], aPassword);
- equal(parcel[1], ril.aid);
- };
-
- ril.iccUnlockCardLock({
- lockType: aLock,
- password: aPassword
- });
- }
-
- do_test(GECKO_CARDLOCK_PIN, "1234");
- do_test(GECKO_CARDLOCK_PIN2, "1234");
-
- run_next_test();
-});
-
-/**
- * Verify RIL.iccUnlockCardLock - PUK
- */
-add_test(function test_icc_unlock_card_lock_puk() {
- let worker = newUint8Worker();
- let context = worker.ContextPool._contexts[0];
- let ril = context.RIL;
- let buf = context.Buf;
- ril.aid = "123456789";
-
- function do_test(aLock, aPassword, aNewPin) {
- let GECKO_CARDLOCK_TO_REQUEST = {};
- GECKO_CARDLOCK_TO_REQUEST[GECKO_CARDLOCK_PUK] = REQUEST_ENTER_SIM_PUK;
- GECKO_CARDLOCK_TO_REQUEST[GECKO_CARDLOCK_PUK2] = REQUEST_ENTER_SIM_PUK2;
-
- buf.sendParcel = function fakeSendParcel() {
- // Request Type.
- equal(this.readInt32(), GECKO_CARDLOCK_TO_REQUEST[aLock]);
-
- // Token : we don't care
- this.readInt32();
-
- // Data
- let parcel = this.readStringList();
- equal(parcel.length, 3);
- equal(parcel[0], aPassword);
- equal(parcel[1], aNewPin);
- equal(parcel[2], ril.aid);
- };
-
- ril.iccUnlockCardLock({
- lockType: aLock,
- password: aPassword,
- newPin: aNewPin
- });
- }
-
- do_test(GECKO_CARDLOCK_PUK, "12345678", "1234");
- do_test(GECKO_CARDLOCK_PUK2, "12345678", "1234");
-
- run_next_test();
-});
-
-/**
- * Verify RIL.iccUnlockCardLock - Depersonalization
- */
-add_test(function test_icc_unlock_card_lock_depersonalization() {
- let worker = newUint8Worker();
- let context = worker.ContextPool._contexts[0];
- let ril = context.RIL;
- let buf = context.Buf;
-
- function do_test(aPassword) {
- buf.sendParcel = function fakeSendParcel() {
- // Request Type.
- equal(this.readInt32(), REQUEST_ENTER_NETWORK_DEPERSONALIZATION_CODE);
-
- // Token : we don't care
- this.readInt32();
-
- // Data
- let parcel = this.readStringList();
- equal(parcel.length, 1);
- equal(parcel[0], aPassword);
- };
-
- ril.iccUnlockCardLock({
- lockType: GECKO_CARDLOCK_NCK,
- password: aPassword
- });
- }
-
- do_test("12345678");
-
- run_next_test();
-});
diff --git a/dom/system/gonk/tests/test_ril_worker_icc_CardState.js b/dom/system/gonk/tests/test_ril_worker_icc_CardState.js
deleted file mode 100644
index 788df5073f..0000000000
--- a/dom/system/gonk/tests/test_ril_worker_icc_CardState.js
+++ /dev/null
@@ -1,210 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-subscriptLoader.loadSubScript("resource://gre/modules/ril_consts.js", this);
-
-function run_test() {
- run_next_test();
-}
-
-add_test(function test_personalization_state() {
- let worker = newUint8Worker();
- let context = worker.ContextPool._contexts[0];
- let ril = context.RIL;
-
- context.ICCRecordHelper.readICCID = function fakeReadICCID() {};
-
- function testPersonalization(isCdma, cardPersoState, geckoCardState) {
- let iccStatus = {
- cardState: CARD_STATE_PRESENT,
- gsmUmtsSubscriptionAppIndex: (!isCdma) ? 0 : -1,
- cdmaSubscriptionAppIndex: (isCdma) ? 0 : -1,
- apps: [
- {
- app_state: CARD_APPSTATE_SUBSCRIPTION_PERSO,
- perso_substate: cardPersoState
- }],
- };
-
- ril._isCdma = isCdma;
- ril._processICCStatus(iccStatus);
- equal(ril.cardState, geckoCardState);
- }
-
- // Test GSM personalization state.
- testPersonalization(false, CARD_PERSOSUBSTATE_SIM_NETWORK,
- Ci.nsIIcc.CARD_STATE_NETWORK_LOCKED);
- testPersonalization(false, CARD_PERSOSUBSTATE_SIM_NETWORK_SUBSET,
- Ci.nsIIcc.CARD_STATE_NETWORK_SUBSET_LOCKED);
- testPersonalization(false, CARD_PERSOSUBSTATE_SIM_CORPORATE,
- Ci.nsIIcc.CARD_STATE_CORPORATE_LOCKED);
- testPersonalization(false, CARD_PERSOSUBSTATE_SIM_SERVICE_PROVIDER,
- Ci.nsIIcc.CARD_STATE_SERVICE_PROVIDER_LOCKED);
- testPersonalization(false, CARD_PERSOSUBSTATE_SIM_SIM,
- Ci.nsIIcc.CARD_STATE_SIM_LOCKED);
- testPersonalization(false, CARD_PERSOSUBSTATE_SIM_NETWORK_PUK,
- Ci.nsIIcc.CARD_STATE_NETWORK_PUK_REQUIRED);
- testPersonalization(false, CARD_PERSOSUBSTATE_SIM_NETWORK_SUBSET_PUK,
- Ci.nsIIcc.CARD_STATE_NETWORK_SUBSET_PUK_REQUIRED);
- testPersonalization(false, CARD_PERSOSUBSTATE_SIM_CORPORATE_PUK,
- Ci.nsIIcc.CARD_STATE_CORPORATE_PUK_REQUIRED);
- testPersonalization(false, CARD_PERSOSUBSTATE_SIM_SERVICE_PROVIDER_PUK,
- Ci.nsIIcc.CARD_STATE_SERVICE_PROVIDER_PUK_REQUIRED);
- testPersonalization(false, CARD_PERSOSUBSTATE_SIM_SIM_PUK,
- Ci.nsIIcc.CARD_STATE_SIM_PUK_REQUIRED);
-
- testPersonalization(false, CARD_PERSOSUBSTATE_UNKNOWN,
- Ci.nsIIcc.CARD_STATE_UNKNOWN);
- testPersonalization(false, CARD_PERSOSUBSTATE_IN_PROGRESS,
- Ci.nsIIcc.CARD_STATE_PERSONALIZATION_IN_PROGRESS);
- testPersonalization(false, CARD_PERSOSUBSTATE_READY,
- Ci.nsIIcc.CARD_STATE_PERSONALIZATION_READY);
-
- // Test CDMA personalization state.
- testPersonalization(true, CARD_PERSOSUBSTATE_RUIM_NETWORK1,
- Ci.nsIIcc.CARD_STATE_NETWORK1_LOCKED);
- testPersonalization(true, CARD_PERSOSUBSTATE_RUIM_NETWORK2,
- Ci.nsIIcc.CARD_STATE_NETWORK2_LOCKED);
- testPersonalization(true, CARD_PERSOSUBSTATE_RUIM_HRPD,
- Ci.nsIIcc.CARD_STATE_HRPD_NETWORK_LOCKED);
- testPersonalization(true, CARD_PERSOSUBSTATE_RUIM_CORPORATE,
- Ci.nsIIcc.CARD_STATE_RUIM_CORPORATE_LOCKED);
- testPersonalization(true, CARD_PERSOSUBSTATE_RUIM_SERVICE_PROVIDER,
- Ci.nsIIcc.CARD_STATE_RUIM_SERVICE_PROVIDER_LOCKED);
- testPersonalization(true, CARD_PERSOSUBSTATE_RUIM_RUIM,
- Ci.nsIIcc.CARD_STATE_RUIM_LOCKED);
- testPersonalization(true, CARD_PERSOSUBSTATE_RUIM_NETWORK1_PUK,
- Ci.nsIIcc.CARD_STATE_NETWORK1_PUK_REQUIRED);
- testPersonalization(true, CARD_PERSOSUBSTATE_RUIM_NETWORK2_PUK,
- Ci.nsIIcc.CARD_STATE_NETWORK2_PUK_REQUIRED);
- testPersonalization(true, CARD_PERSOSUBSTATE_RUIM_HRPD_PUK,
- Ci.nsIIcc.CARD_STATE_HRPD_NETWORK_PUK_REQUIRED);
- testPersonalization(true, CARD_PERSOSUBSTATE_RUIM_CORPORATE_PUK,
- Ci.nsIIcc.CARD_STATE_RUIM_CORPORATE_PUK_REQUIRED);
- testPersonalization(true, CARD_PERSOSUBSTATE_RUIM_SERVICE_PROVIDER_PUK,
- Ci.nsIIcc.CARD_STATE_RUIM_SERVICE_PROVIDER_PUK_REQUIRED);
- testPersonalization(true, CARD_PERSOSUBSTATE_RUIM_RUIM_PUK,
- Ci.nsIIcc.CARD_STATE_RUIM_PUK_REQUIRED);
-
- testPersonalization(true, CARD_PERSOSUBSTATE_UNKNOWN,
- Ci.nsIIcc.CARD_STATE_UNKNOWN);
- testPersonalization(true, CARD_PERSOSUBSTATE_IN_PROGRESS,
- Ci.nsIIcc.CARD_STATE_PERSONALIZATION_IN_PROGRESS);
- testPersonalization(true, CARD_PERSOSUBSTATE_READY,
- Ci.nsIIcc.CARD_STATE_PERSONALIZATION_READY);
-
- run_next_test();
-});
-
-/**
- * Verify SIM app_state in _processICCStatus
- */
-add_test(function test_card_app_state() {
- let worker = newUint8Worker();
- let context = worker.ContextPool._contexts[0];
- let ril = context.RIL;
-
- context.ICCRecordHelper.readICCID = function fakeReadICCID() {};
-
- function testCardAppState(cardAppState, geckoCardState) {
- let iccStatus = {
- cardState: CARD_STATE_PRESENT,
- gsmUmtsSubscriptionAppIndex: 0,
- apps: [
- {
- app_state: cardAppState
- }],
- };
-
- ril._processICCStatus(iccStatus);
- equal(ril.cardState, geckoCardState);
- }
-
- testCardAppState(CARD_APPSTATE_ILLEGAL,
- Ci.nsIIcc.CARD_STATE_ILLEGAL);
- testCardAppState(CARD_APPSTATE_PIN,
- Ci.nsIIcc.CARD_STATE_PIN_REQUIRED);
- testCardAppState(CARD_APPSTATE_PUK,
- Ci.nsIIcc.CARD_STATE_PUK_REQUIRED);
- testCardAppState(CARD_APPSTATE_READY,
- Ci.nsIIcc.CARD_STATE_READY);
- testCardAppState(CARD_APPSTATE_UNKNOWN,
- Ci.nsIIcc.CARD_STATE_UNKNOWN);
- testCardAppState(CARD_APPSTATE_DETECTED,
- Ci.nsIIcc.CARD_STATE_UNKNOWN);
-
- run_next_test();
-});
-
-/**
- * Verify permanent blocked for ICC.
- */
-add_test(function test_icc_permanent_blocked() {
- let worker = newUint8Worker();
- let context = worker.ContextPool._contexts[0];
- let ril = context.RIL;
-
- context.ICCRecordHelper.readICCID = function fakeReadICCID() {};
-
- function testPermanentBlocked(pin1_replaced, universalPINState, pin1) {
- let iccStatus = {
- cardState: CARD_STATE_PRESENT,
- gsmUmtsSubscriptionAppIndex: 0,
- universalPINState: universalPINState,
- apps: [
- {
- pin1_replaced: pin1_replaced,
- pin1: pin1
- }]
- };
-
- ril._processICCStatus(iccStatus);
- equal(ril.cardState, Ci.nsIIcc.CARD_STATE_PERMANENT_BLOCKED);
- }
-
- testPermanentBlocked(1,
- CARD_PINSTATE_ENABLED_PERM_BLOCKED,
- CARD_PINSTATE_UNKNOWN);
- testPermanentBlocked(1,
- CARD_PINSTATE_ENABLED_PERM_BLOCKED,
- CARD_PINSTATE_ENABLED_PERM_BLOCKED);
- testPermanentBlocked(0,
- CARD_PINSTATE_UNKNOWN,
- CARD_PINSTATE_ENABLED_PERM_BLOCKED);
-
- run_next_test();
-});
-
-/**
- * Verify ICC without app index.
- */
-add_test(function test_icc_without_app_index() {
- const ICCID = "123456789";
-
- let worker = newUint8Worker();
- let context = worker.ContextPool._contexts[0];
- let ril = context.RIL;
-
- let iccStatus = {
- cardState: CARD_STATE_PRESENT,
- gsmUmtsSubscriptionAppIndex: -1,
- universalPINState: CARD_PINSTATE_DISABLED,
- apps: [
- {
- app_state: CARD_APPSTATE_READY
- }]
- };
-
- context.ICCRecordHelper.readICCID = function fakeReadICCID() {
- ril.iccInfo.iccid = ICCID;
- };
-
- ril._processICCStatus(iccStatus);
-
- // Should read icc id event if the app index is -1.
- equal(ril.iccInfo.iccid, ICCID);
- // cardState is "unknown" if the app index is -1.
- equal(ril.cardState, GECKO_CARDSTATE_UNKNOWN);
-
- run_next_test();
-});
diff --git a/dom/system/gonk/tests/test_ril_worker_icc_GsmPDUHelper.js b/dom/system/gonk/tests/test_ril_worker_icc_GsmPDUHelper.js
deleted file mode 100644
index 0d074da793..0000000000
--- a/dom/system/gonk/tests/test_ril_worker_icc_GsmPDUHelper.js
+++ /dev/null
@@ -1,79 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-subscriptLoader.loadSubScript("resource://gre/modules/ril_consts.js", this);
-
-function run_test() {
- run_next_test();
-}
-
-/**
- * Verify GsmPDUHelper.writeTimestamp
- */
-add_test(function test_write_timestamp() {
- let worker = newUint8Worker();
- let context = worker.ContextPool._contexts[0];
- let helper = context.GsmPDUHelper;
-
- // current date
- let dateInput = new Date();
- let dateOutput = new Date();
- helper.writeTimestamp(dateInput);
- dateOutput.setTime(helper.readTimestamp());
-
- equal(dateInput.getFullYear(), dateOutput.getFullYear());
- equal(dateInput.getMonth(), dateOutput.getMonth());
- equal(dateInput.getDate(), dateOutput.getDate());
- equal(dateInput.getHours(), dateOutput.getHours());
- equal(dateInput.getMinutes(), dateOutput.getMinutes());
- equal(dateInput.getSeconds(), dateOutput.getSeconds());
- equal(dateInput.getTimezoneOffset(), dateOutput.getTimezoneOffset());
-
- // 2034-01-23 12:34:56 -0800 GMT
- let time = Date.UTC(2034, 1, 23, 12, 34, 56);
- time = time - (8 * 60 * 60 * 1000);
- dateInput.setTime(time);
- helper.writeTimestamp(dateInput);
- dateOutput.setTime(helper.readTimestamp());
-
- equal(dateInput.getFullYear(), dateOutput.getFullYear());
- equal(dateInput.getMonth(), dateOutput.getMonth());
- equal(dateInput.getDate(), dateOutput.getDate());
- equal(dateInput.getHours(), dateOutput.getHours());
- equal(dateInput.getMinutes(), dateOutput.getMinutes());
- equal(dateInput.getSeconds(), dateOutput.getSeconds());
- equal(dateInput.getTimezoneOffset(), dateOutput.getTimezoneOffset());
-
- run_next_test();
-});
-
-/**
- * Verify GsmPDUHelper.octectToBCD and GsmPDUHelper.BCDToOctet
- */
-add_test(function test_octect_BCD() {
- let worker = newUint8Worker();
- let context = worker.ContextPool._contexts[0];
- let helper = context.GsmPDUHelper;
-
- // 23
- let number = 23;
- let octet = helper.BCDToOctet(number);
- equal(helper.octetToBCD(octet), number);
-
- // 56
- number = 56;
- octet = helper.BCDToOctet(number);
- equal(helper.octetToBCD(octet), number);
-
- // 0x23
- octet = 0x23;
- number = helper.octetToBCD(octet);
- equal(helper.BCDToOctet(number), octet);
-
- // 0x56
- octet = 0x56;
- number = helper.octetToBCD(octet);
- equal(helper.BCDToOctet(number), octet);
-
- run_next_test();
-});
diff --git a/dom/system/gonk/tests/test_ril_worker_icc_ICCContactHelper.js b/dom/system/gonk/tests/test_ril_worker_icc_ICCContactHelper.js
deleted file mode 100644
index 29b83b76a8..0000000000
--- a/dom/system/gonk/tests/test_ril_worker_icc_ICCContactHelper.js
+++ /dev/null
@@ -1,1042 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-subscriptLoader.loadSubScript("resource://gre/modules/ril_consts.js", this);
-
-function run_test() {
- run_next_test();
-}
-
-/**
- * Test error message returned in onerror for readICCContacts.
- */
-add_test(function test_error_message_read_icc_contact () {
- let worker = newUint8Worker();
- let context = worker.ContextPool._contexts[0];
- let ril = context.RIL;
-
- function do_test(options, expectedErrorMsg) {
- ril.sendChromeMessage = function(message) {
- equal(message.errorMsg, expectedErrorMsg);
- }
- ril.readICCContacts(options);
- }
-
- // Error 1, didn't specify correct contactType.
- do_test({}, CONTACT_ERR_REQUEST_NOT_SUPPORTED);
-
- // Error 2, specifying a non-supported contactType.
- ril.appType = CARD_APPTYPE_USIM;
- do_test({contactType: "foo"}, CONTACT_ERR_CONTACT_TYPE_NOT_SUPPORTED);
-
- // Error 3, suppose we update the supported PBR fields in USIM_PBR_FIELDS,
- // but forget to add implemenetations for it.
- USIM_PBR_FIELDS.push("pbc");
- do_test({contactType: GECKO_CARDCONTACT_TYPE_ADN},
- CONTACT_ERR_FIELD_NOT_SUPPORTED);
-
- run_next_test();
-});
-
-/**
- * Test error message returned in onerror for updateICCContact.
- */
-add_test(function test_error_message_update_icc_contact() {
- let worker = newUint8Worker();
- let context = worker.ContextPool._contexts[0];
- let ril = context.RIL;
-
- const ICCID = "123456789";
- ril.iccInfo.iccid = ICCID;
-
- function do_test(options, expectedErrorMsg) {
- ril.sendChromeMessage = function(message) {
- equal(message.errorMsg, expectedErrorMsg);
- }
- ril.updateICCContact(options);
- }
-
- // Error 1, didn't specify correct contactType.
- do_test({}, CONTACT_ERR_REQUEST_NOT_SUPPORTED);
-
- // Error 2, specifying a correct contactType, but without providing 'contact'.
- do_test({contactType: GECKO_CARDCONTACT_TYPE_ADN},
- CONTACT_ERR_REQUEST_NOT_SUPPORTED);
-
- // Error 3, specifying a non-supported contactType.
- ril.appType = CARD_APPTYPE_USIM;
- do_test({contactType: GECKO_CARDCONTACT_TYPE_SDN, contact: {}},
- CONTACT_ERR_CONTACT_TYPE_NOT_SUPPORTED);
-
- // Error 4, without supplying pin2.
- do_test({contactType: GECKO_CARDCONTACT_TYPE_FDN,
- contact: {contactId: ICCID + "1"}},
- GECKO_ERROR_SIM_PIN2);
-
- // Error 5, No free record found in EF_ADN.
- let record = context.ICCRecordHelper;
- record.readPBR = function(onsuccess, onerror) {
- onsuccess([{adn: {fileId: 0x4f3a}}]);
- };
-
- let io = context.ICCIOHelper;
- io.loadLinearFixedEF = function(options) {
- options.totalRecords = 1;
- options.p1 = 1;
- options.callback(options);
- };
-
- do_test({contactType: GECKO_CARDCONTACT_TYPE_ADN, contact: {}},
- CONTACT_ERR_NO_FREE_RECORD_FOUND);
-
- // Error 6, ICC IO Error.
- io.loadLinearFixedEF = function(options) {
- ril[REQUEST_SIM_IO](0, {
- errorMsg: GECKO_ERROR_GENERIC_FAILURE
- });
- };
- do_test({contactType: GECKO_CARDCONTACT_TYPE_ADN,
- contact: {contactId: ICCID + "1"}},
- GECKO_ERROR_GENERIC_FAILURE);
-
- // Error 7, suppose we update the supported PBR fields in USIM_PBR_FIELDS,
- // but forget to add implemenetations for it.
- USIM_PBR_FIELDS.push("pbc");
- do_test({contactType: GECKO_CARDCONTACT_TYPE_ADN,
- contact: {contactId: ICCID + "1"}},
- CONTACT_ERR_FIELD_NOT_SUPPORTED);
-
- // Error 8, EF_PBR doesn't exist.
- record.readPBR = function(onsuccess, onerror) {
- onsuccess([]);
- };
-
- do_test({contactType: GECKO_CARDCONTACT_TYPE_ADN,
- contact: {contactId: ICCID + "1"}},
- CONTACT_ERR_CANNOT_ACCESS_PHONEBOOK);
-
- run_next_test();
-});
-
-/**
- * Verify ICCContactHelper.readICCContacts
- */
-add_test(function test_read_icc_contacts() {
- let worker = newUint8Worker();
- let context = worker.ContextPool._contexts[0];
- let record = context.ICCRecordHelper;
- let contactHelper = context.ICCContactHelper;
- let ril = context.RIL;
- let test_data = [
- //Record 1.
- {
- comment: "Test read SIM adn contact",
- rawData: {
- simType: CARD_APPTYPE_SIM,
- contactType: GECKO_CARDCONTACT_TYPE_ADN,
- adnLike: [{recordId: 1, alphaId: "name", number: "111111"}],
- },
- expectedContact: [{
- recordId: 1,
- alphaId: "name",
- number: "111111"
- }],
- },
- //Record 2.
- {
- comment: "Test read SIM fdn contact",
- rawData: {
- simType: CARD_APPTYPE_SIM,
- contactType: GECKO_CARDCONTACT_TYPE_FDN,
- adnLike: [{recordId: 1, alphaId: "name", number: "111111"}],
- },
- expectedContact: [{
- recordId: 1,
- alphaId: "name",
- number: "111111"
- }],
- },
- //Record 3.
- {
- comment: "Test read USIM adn contact",
- rawData: {
- simType: CARD_APPTYPE_USIM,
- contactType: GECKO_CARDCONTACT_TYPE_ADN,
- pbrs: [{adn:{fileId: 0x6f3a}, email: {}, anr0: {}}],
- adnLike: [{recordId: 1, alphaId: "name", number: "111111"}],
- email: "hello@mail.com",
- anr: "123456",
- },
- expectedContact: [{
- pbrIndex: 0,
- recordId: 1,
- alphaId: "name",
- number: "111111",
- email: "hello@mail.com",
- anr: ["123456"]
- }],
- },
- //Record 4.
- {
- comment: "Test read USIM adn contacts",
- rawData: {
- simType: CARD_APPTYPE_USIM,
- contactType: GECKO_CARDCONTACT_TYPE_ADN,
- pbrs: [{adn:{fileId: 0x6f3a}, email: {}, anr0: {}},
- {adn:{fileId: 0x6f3b}, email: {}, anr0: {}}],
- adnLike: [{recordId: 1, alphaId: "name1", number: "111111"},
- {recordId: 2, alphaId: "name2", number: "222222"}],
- email: "hello@mail.com",
- anr: "123456",
- },
- expectedContact: [
- {
- pbrIndex: 0,
- recordId: 1,
- alphaId: "name1",
- number: "111111",
- email: "hello@mail.com",
- anr: ["123456"]
- }, {
- pbrIndex: 0,
- recordId: 2,
- alphaId: "name2",
- number: "222222",
- email: "hello@mail.com",
- anr: ["123456"]
- }, {
- pbrIndex: 1,
- recordId: 1,
- alphaId: "name1",
- number: "111111",
- email: "hello@mail.com",
- anr: ["123456"]
- }, {
- pbrIndex: 1,
- recordId: 2,
- alphaId: "name2",
- number: "222222",
- email: "hello@mail.com",
- anr: ["123456"]
- }
- ],
- },
- //Record 5.
- {
- comment: "Test read USIM fdn contact",
- rawData: {
- simType: CARD_APPTYPE_USIM,
- contactType: GECKO_CARDCONTACT_TYPE_FDN,
- adnLike: [{recordId: 1, alphaId: "name", number: "111111"}],
- },
- expectedContact: [{
- recordId: 1,
- alphaId: "name",
- number: "111111"
- }],
- },
- //Record 6.
- {
- comment: "Test read RUIM adn contact",
- rawData: {
- simType: CARD_APPTYPE_RUIM,
- contactType: GECKO_CARDCONTACT_TYPE_ADN,
- adnLike: [{recordId: 1, alphaId: "name", number: "111111"}],
- },
- expectedContact: [{
- recordId: 1,
- alphaId: "name",
- number: "111111"
- }],
- },
- //Record 7.
- {
- comment: "Test read RUIM fdn contact",
- rawData: {
- simType: CARD_APPTYPE_RUIM,
- contactType: GECKO_CARDCONTACT_TYPE_FDN,
- adnLike: [{recordId: 1, alphaId: "name", number: "111111"}],
- },
- expectedContact: [{
- recordId: 1,
- alphaId: "name",
- number: "111111"
- }],
- },
- //Record 8.
- {
- comment: "Test read RUIM adn contact with enhanced phone book",
- rawData: {
- simType: CARD_APPTYPE_RUIM,
- contactType: GECKO_CARDCONTACT_TYPE_ADN,
- pbrs: [{adn:{fileId: 0x6f3a}, email: {}, anr0: {}}],
- adnLike: [{recordId: 1, alphaId: "name", number: "111111"}],
- email: "hello@mail.com",
- anr: "123456",
- enhancedPhoneBook: true,
- },
- expectedContact: [{
- pbrIndex: 0,
- recordId: 1,
- alphaId: "name",
- number: "111111",
- email: "hello@mail.com",
- anr: ["123456"]
- }],
- },
- //Record 9.
- {
- comment: "Test read RUIM adn contacts with enhanced phone book",
- rawData: {
- simType: CARD_APPTYPE_RUIM,
- contactType: GECKO_CARDCONTACT_TYPE_ADN,
- pbrs: [{adn:{fileId: 0x6f3a}, email: {}, anr0: {}},
- {adn:{fileId: 0x6f3b}, email: {}, anr0: {}}],
- adnLike: [{recordId: 1, alphaId: "name1", number: "111111"},
- {recordId: 2, alphaId: "name2", number: "222222"}],
- email: "hello@mail.com",
- anr: "123456",
- enhancedPhoneBook: true,
- },
- expectedContact: [
- {
- pbrIndex: 0,
- recordId: 1,
- alphaId: "name1",
- number: "111111",
- email: "hello@mail.com",
- anr: ["123456"]
- }, {
- pbrIndex: 0,
- recordId: 2,
- alphaId: "name2",
- number: "222222",
- email: "hello@mail.com",
- anr: ["123456"]
- }, {
- pbrIndex: 1,
- recordId: 1,
- alphaId: "name1",
- number: "111111",
- email: "hello@mail.com",
- anr: ["123456"]
- }, {
- pbrIndex: 1,
- recordId: 2,
- alphaId: "name2",
- number: "222222",
- email: "hello@mail.com",
- anr: ["123456"]
- }
- ],
- },
- ];
-
- function do_test(aTestData, aExpectedContact) {
- ril.appType = aTestData.simType;
- ril._isCdma = (aTestData.simType === CARD_APPTYPE_RUIM);
- ril.iccInfoPrivate.cst = (aTestData.enhancedPhoneBook) ?
- [0x20, 0x0C, 0x0, 0x0, 0x0]:
- [0x20, 0x00, 0x0, 0x0, 0x0];
-
- ril.iccInfoPrivate.sst = (aTestData.simType === CARD_APPTYPE_SIM)?
- [0x20, 0x0, 0x0, 0x0, 0x0]:
- [0x2, 0x0, 0x0, 0x0, 0x0];
-
- // Override some functions to test.
- contactHelper.getContactFieldRecordId = function(pbr, contact, field, onsuccess, onerror) {
- onsuccess(1);
- };
-
- record.readPBR = function readPBR(onsuccess, onerror) {
- onsuccess(JSON.parse(JSON.stringify(aTestData.pbrs)));
- };
-
- record.readADNLike = function readADNLike(fileId, extFileId, onsuccess, onerror) {
- onsuccess(JSON.parse(JSON.stringify(aTestData.adnLike)));
- };
-
- record.readEmail = function readEmail(fileId, fileType, recordNumber, onsuccess, onerror) {
- onsuccess(aTestData.email);
- };
-
- record.readANR = function readANR(fileId, fileType, recordNumber, onsuccess, onerror) {
- onsuccess(aTestData.anr);
- };
-
- let onsuccess = function onsuccess(contacts) {
- for (let i = 0; i < contacts.length; i++) {
- do_print("check contacts[" + i + "]:" + JSON.stringify(contacts[i]));
- deepEqual(contacts[i], aExpectedContact[i]);
- }
- };
-
- let onerror = function onerror(errorMsg) {
- do_print("readICCContacts failed: " + errorMsg);
- ok(false);
- };
-
- contactHelper.readICCContacts(aTestData.simType, aTestData.contactType, onsuccess, onerror);
- }
-
- for (let i = 0; i < test_data.length; i++) {
- do_print(test_data[i].comment);
- do_test(test_data[i].rawData, test_data[i].expectedContact);
- }
-
- run_next_test();
-});
-
-/**
- * Verify ICCContactHelper.updateICCContact with appType is CARD_APPTYPE_USIM.
- */
-add_test(function test_update_icc_contact() {
- const ADN_RECORD_ID = 100;
- const ADN_SFI = 1;
- const IAP_FILE_ID = 0x4f17;
- const EMAIL_FILE_ID = 0x4f50;
- const EMAIL_RECORD_ID = 20;
- const ANR0_FILE_ID = 0x4f11;
- const ANR0_RECORD_ID = 30;
- const EXT_RECORD_ID = 0x01;
-
- let worker = newUint8Worker();
- let context = worker.ContextPool._contexts[0];
- let recordHelper = context.ICCRecordHelper;
- let contactHelper = context.ICCContactHelper;
- let ril = context.RIL;
-
- function do_test(aSimType, aContactType, aContact, aPin2, aFileType, aHaveIapIndex, aEnhancedPhoneBook) {
- ril.appType = aSimType;
- ril._isCdma = (aSimType === CARD_APPTYPE_RUIM);
- ril.iccInfoPrivate.cst = (aEnhancedPhoneBook) ? [0x20, 0x0C, 0x28, 0x0, 0x20]
- : [0x20, 0x0, 0x28, 0x0, 0x20];
- ril.iccInfoPrivate.sst = (aSimType === CARD_APPTYPE_SIM)?
- [0x20, 0x0, 0x28, 0x0, 0x20]:
- [0x16, 0x0, 0x0, 0x0, 0x0];
-
- recordHelper.readPBR = function(onsuccess, onerror) {
- if (aFileType === ICC_USIM_TYPE1_TAG) {
- onsuccess([{
- adn: {fileId: ICC_EF_ADN},
- email: {fileId: EMAIL_FILE_ID,
- fileType: ICC_USIM_TYPE1_TAG},
- anr0: {fileId: ANR0_FILE_ID,
- fileType: ICC_USIM_TYPE1_TAG},
- ext1: {fileId: ICC_EF_EXT1}
-
- }]);
- } else if (aFileType === ICC_USIM_TYPE2_TAG) {
- onsuccess([{
- adn: {fileId: ICC_EF_ADN,
- sfi: ADN_SFI},
- iap: {fileId: IAP_FILE_ID},
- email: {fileId: EMAIL_FILE_ID,
- fileType: ICC_USIM_TYPE2_TAG,
- indexInIAP: 0},
- anr0: {fileId: ANR0_FILE_ID,
- fileType: ICC_USIM_TYPE2_TAG,
- indexInIAP: 1},
- ext1: {fileId: ICC_EF_EXT1}
- }]);
- }
- };
-
- recordHelper.updateADNLike = function(fileId, extRecordNumber, contact, pin2, onsuccess, onerror) {
- if (aContactType === GECKO_CARDCONTACT_TYPE_FDN) {
- equal(fileId, ICC_EF_FDN);
- } else if (aContactType === GECKO_CARDCONTACT_TYPE_ADN) {
- equal(fileId, ICC_EF_ADN);
- }
-
- if (aContact.number.length > ADN_MAX_NUMBER_DIGITS) {
- equal(extRecordNumber, EXT_RECORD_ID);
- } else {
- equal(extRecordNumber, 0xff);
- }
-
- equal(pin2, aPin2);
- equal(contact.alphaId, aContact.alphaId);
- equal(contact.number, aContact.number);
- onsuccess({alphaId: contact.alphaId,
- number: contact.number.substring(0, ADN_MAX_NUMBER_DIGITS)});
- };
-
- recordHelper.getADNLikeExtensionRecordNumber = function(fileId, recordNumber, onsuccess, onerror) {
- onsuccess(EXT_RECORD_ID);
- };
-
- recordHelper.updateExtension = function(fileId, recordNumber, number, onsuccess, onerror) {
- onsuccess();
- };
-
- recordHelper.findFreeRecordId = function(fileId, onsuccess, onerror) {
- onsuccess(EXT_RECORD_ID);
- };
-
- recordHelper.cleanEFRecord = function(fileId, recordNumber, onsuccess, onerror) {
- onsuccess();
- }
-
- recordHelper.readIAP = function(fileId, recordNumber, onsuccess, onerror) {
- equal(fileId, IAP_FILE_ID);
- equal(recordNumber, ADN_RECORD_ID);
- onsuccess((aHaveIapIndex) ? [EMAIL_RECORD_ID, ANR0_RECORD_ID]
- : [0xff, 0xff]);
- };
-
- recordHelper.updateIAP = function(fileId, recordNumber, iap, onsuccess, onerror) {
- equal(fileId, IAP_FILE_ID);
- equal(recordNumber, ADN_RECORD_ID);
- onsuccess();
- };
-
- recordHelper.updateEmail = function(pbr, recordNumber, email, adnRecordId, onsuccess, onerror) {
- equal(pbr.email.fileId, EMAIL_FILE_ID);
- if (pbr.email.fileType === ICC_USIM_TYPE1_TAG) {
- equal(recordNumber, ADN_RECORD_ID);
- } else if (pbr.email.fileType === ICC_USIM_TYPE2_TAG) {
- equal(recordNumber, EMAIL_RECORD_ID);
- }
- equal(email, aContact.email);
- onsuccess(email);
- };
-
- recordHelper.updateANR = function(pbr, recordNumber, number, adnRecordId, onsuccess, onerror) {
- equal(pbr.anr0.fileId, ANR0_FILE_ID);
- if (pbr.anr0.fileType === ICC_USIM_TYPE1_TAG) {
- equal(recordNumber, ADN_RECORD_ID);
- } else if (pbr.anr0.fileType === ICC_USIM_TYPE2_TAG) {
- equal(recordNumber, ANR0_RECORD_ID);
- }
- if (Array.isArray(aContact.anr)) {
- equal(number, aContact.anr[0]);
- }
- onsuccess(number);
- };
-
- recordHelper.findFreeRecordId = function(fileId, onsuccess, onerror) {
- let recordId = 0;
- if (fileId === EMAIL_FILE_ID) {
- recordId = EMAIL_RECORD_ID;
- } else if (fileId === ANR0_FILE_ID) {
- recordId = ANR0_RECORD_ID;
- }
- onsuccess(recordId);
- };
-
- let isSuccess = false;
- let onsuccess = function onsuccess(updatedContact) {
- equal(ADN_RECORD_ID, updatedContact.recordId);
- equal(aContact.alphaId, updatedContact.alphaId);
- equal(aContact.number.substring(0, ADN_MAX_NUMBER_DIGITS + EXT_MAX_NUMBER_DIGITS),
- updatedContact.number);
- if ((aSimType == CARD_APPTYPE_USIM || aSimType == CARD_APPTYPE_RUIM) &&
- (aFileType == ICC_USIM_TYPE1_TAG || aFileType == ICC_USIM_TYPE2_TAG)) {
- if (aContact.hasOwnProperty('email')) {
- equal(aContact.email, updatedContact.email);
- }
-
- if (aContact.hasOwnProperty('anr')) {
- equal(aContact.anr[0], updatedContact.anr[0]);
- }
- } else {
- equal(updatedContact.email, null);
- equal(updatedContact.anr, null);
- }
-
- do_print("updateICCContact success");
- isSuccess = true;
- };
-
- let onerror = function onerror(errorMsg) {
- do_print("updateICCContact failed: " + errorMsg);
- };
-
- contactHelper.updateICCContact(aSimType, aContactType, aContact, aPin2, onsuccess, onerror);
- ok(isSuccess);
- }
-
- let contacts = [
- {
- pbrIndex: 0,
- recordId: ADN_RECORD_ID,
- alphaId: "test",
- number: "123456",
- email: "test@mail.com",
- anr: ["+654321"]
- },
- // a contact without email and anr.
- {
- pbrIndex: 0,
- recordId: ADN_RECORD_ID,
- alphaId: "test2",
- number: "123456",
- },
- // a contact with email but no anr.
- {
- pbrIndex: 0,
- recordId: ADN_RECORD_ID,
- alphaId: "test3",
- number: "123456",
- email: "test@mail.com"
- },
- // a contact with anr but no email.
- {
- pbrIndex: 0,
- recordId: ADN_RECORD_ID,
- alphaId: "test4",
- number: "123456",
- anr: ["+654321"]
- },
- // a contact number over 20 digits.
- {
- pbrIndex: 0,
- recordId: ADN_RECORD_ID,
- alphaId: "test4",
- number: "0123456789012345678901234567890123456789",
- anr: ["+654321"]
- },
- // a contact number over 40 digits.
- {
- pbrIndex: 0,
- recordId: ADN_RECORD_ID,
- alphaId: "test5",
- number: "01234567890123456789012345678901234567890123456789",
- anr: ["+654321"]
- }];
-
- for (let i = 0; i < contacts.length; i++) {
- let contact = contacts[i];
- // SIM
- do_print("Test update SIM adn contacts");
- do_test(CARD_APPTYPE_SIM, GECKO_CARDCONTACT_TYPE_ADN, contact);
-
- do_print("Test update SIM fdn contacts");
- do_test(CARD_APPTYPE_SIM, GECKO_CARDCONTACT_TYPE_FDN, contact, "1234");
-
- // USIM
- do_print("Test update USIM adn contacts");
- do_test(CARD_APPTYPE_USIM, GECKO_CARDCONTACT_TYPE_ADN, contact, null,
- ICC_USIM_TYPE1_TAG);
- do_test(CARD_APPTYPE_USIM, GECKO_CARDCONTACT_TYPE_ADN, contact, null,
- ICC_USIM_TYPE2_TAG, true);
- do_test(CARD_APPTYPE_USIM, GECKO_CARDCONTACT_TYPE_ADN, contact, null,
- ICC_USIM_TYPE2_TAG, false);
-
- do_print("Test update USIM fdn contacts");
- do_test(CARD_APPTYPE_USIM, GECKO_CARDCONTACT_TYPE_FDN, contact, "1234");
-
- // RUIM
- do_print("Test update RUIM adn contacts");
- do_test(CARD_APPTYPE_RUIM, GECKO_CARDCONTACT_TYPE_ADN, contact);
-
- do_print("Test update RUIM fdn contacts");
- do_test(CARD_APPTYPE_RUIM, GECKO_CARDCONTACT_TYPE_FDN, contact, "1234");
-
- // RUIM with enhanced phone book
- do_print("Test update RUIM adn contacts with enhanced phone book");
- do_test(CARD_APPTYPE_RUIM, GECKO_CARDCONTACT_TYPE_ADN, contact, null,
- ICC_USIM_TYPE1_TAG, null,true);
- do_test(CARD_APPTYPE_RUIM, GECKO_CARDCONTACT_TYPE_ADN, contact, null,
- ICC_USIM_TYPE2_TAG, true, true);
- do_test(CARD_APPTYPE_RUIM, GECKO_CARDCONTACT_TYPE_ADN, contact, null,
- ICC_USIM_TYPE2_TAG, false, true);
-
- do_print("Test update RUIM fdn contacts with enhanced phone book");
- do_test(CARD_APPTYPE_RUIM, GECKO_CARDCONTACT_TYPE_FDN, contact, "1234",
- null, true);
- }
-
- run_next_test();
-});
-
-/**
- * Verify ICCContactHelper.updateICCContact with appType is CARD_APPTYPE_USIM and
- * insufficient space to store Type 2 USIM contact fields.
- */
-add_test(function test_update_icc_contact_full_email_and_anr_field() {
- const ADN_RECORD_ID = 100;
- const ADN_SFI = 1;
- const IAP_FILE_ID = 0x4f17;
- const EMAIL_FILE_ID = 0x4f50;
- const EMAIL_RECORD_ID = 20;
- const ANR0_FILE_ID = 0x4f11;
- const ANR0_RECORD_ID = 30;
-
- let worker = newUint8Worker();
- let context = worker.ContextPool._contexts[0];
- let recordHelper = context.ICCRecordHelper;
- let contactHelper = context.ICCContactHelper;
- let ril = context.RIL;
-
- function do_test(aSimType, aContactType, aContact, aPin2) {
- ril.appType = CARD_APPTYPE_USIM;
- ril.iccInfoPrivate.sst = [0x2, 0x0, 0x0, 0x0, 0x0];
-
- recordHelper.readPBR = function(onsuccess, onerror) {
- onsuccess([{
- adn: {fileId: ICC_EF_ADN,
- sfi: ADN_SFI},
- iap: {fileId: IAP_FILE_ID},
- email: {fileId: EMAIL_FILE_ID,
- fileType: ICC_USIM_TYPE2_TAG,
- indexInIAP: 0},
- anr0: {fileId: ANR0_FILE_ID,
- fileType: ICC_USIM_TYPE2_TAG,
- indexInIAP: 1}
- }]);
- };
-
- recordHelper.updateADNLike = function(fileId, extRecordNumber, contact, pin2, onsuccess, onerror) {
- if (aContactType === GECKO_CARDCONTACT_TYPE_ADN) {
- equal(fileId, ICC_EF_ADN);
- }
- equal(pin2, aPin2);
- equal(contact.alphaId, aContact.alphaId);
- equal(contact.number, aContact.number);
- onsuccess({alphaId: contact.alphaId,
- number: contact.number});
- };
-
- recordHelper.readIAP = function(fileId, recordNumber, onsuccess, onerror) {
- equal(fileId, IAP_FILE_ID);
- equal(recordNumber, ADN_RECORD_ID);
- onsuccess([0xff, 0xff]);
- };
-
- recordHelper.updateIAP = function(fileId, recordNumber, iap, onsuccess, onerror) {
- equal(fileId, IAP_FILE_ID);
- equal(recordNumber, ADN_RECORD_ID);
- onsuccess();
- };
-
- recordHelper.findFreeRecordId = function(fileId, onsuccess, onerror) {
- let recordId = 0;
- // emulate email and anr don't have free record.
- if (fileId === EMAIL_FILE_ID || fileId === ANR0_FILE_ID) {
- onerror(CONTACT_ERR_NO_FREE_RECORD_FOUND);
- } else {
- onsuccess(recordId);
- }
- };
-
- let isSuccess = false;
- let onsuccess = function onsuccess(updatedContact) {
- equal(ADN_RECORD_ID, updatedContact.recordId);
- equal(aContact.alphaId, updatedContact.alphaId);
- equal(updatedContact.email, null);
- equal(updatedContact.anr, null);
-
- do_print("updateICCContact success");
- isSuccess = true;
- };
-
- let onerror = function onerror(errorMsg) {
- do_print("updateICCContact failed: " + errorMsg);
- };
-
- contactHelper.updateICCContact(aSimType, aContactType, aContact, aPin2, onsuccess, onerror);
- ok(isSuccess);
- }
-
- let contact = {
- pbrIndex: 0,
- recordId: ADN_RECORD_ID,
- alphaId: "test",
- number: "123456",
- email: "test@mail.com",
- anr: ["+654321"]
- };
-
- // USIM
- do_print("Test update USIM adn contacts");
- do_test(CARD_APPTYPE_USIM, GECKO_CARDCONTACT_TYPE_ADN, contact, null);
-
- run_next_test();
-});
-
-/**
- * Verify updateICCContact with removal of anr and email with File Type 1.
- */
-add_test(function test_update_icc_contact_with_remove_type1_attr() {
- const ADN_RECORD_ID = 100;
- const IAP_FILE_ID = 0x4f17;
- const EMAIL_FILE_ID = 0x4f50;
- const EMAIL_RECORD_ID = 20;
- const ANR0_FILE_ID = 0x4f11;
- const ANR0_RECORD_ID = 30;
-
- let worker = newUint8Worker();
- let context = worker.ContextPool._contexts[0];
- let recordHelper = context.ICCRecordHelper;
- let contactHelper = context.ICCContactHelper;
-
- recordHelper.updateADNLike = function(fileId, extRecordNumber, contact, pin2, onsuccess, onerror) {
- onsuccess({alphaId: contact.alphaId,
- number: contact.number});
- };
-
- let contact = {
- pbrIndex: 0,
- recordId: ADN_RECORD_ID,
- alphaId: "test2",
- number: "123456",
- };
-
- recordHelper.readIAP = function(fileId, recordNumber, onsuccess, onerror) {
- onsuccess([EMAIL_RECORD_ID, ANR0_RECORD_ID]);
- };
-
- recordHelper.updateEmail = function(pbr, recordNumber, email, adnRecordId, onsuccess, onerror) {
- ok(email == null);
- onsuccess(email);
- };
-
- recordHelper.updateANR = function(pbr, recordNumber, number, adnRecordId, onsuccess, onerror) {
- ok(number == null);
- onsuccess(number);
- };
-
- function do_test(type) {
- recordHelper.readPBR = function(onsuccess, onerror) {
- if (type == ICC_USIM_TYPE1_TAG) {
- onsuccess([{
- adn: {fileId: ICC_EF_ADN},
- email: {fileId: EMAIL_FILE_ID,
- fileType: ICC_USIM_TYPE1_TAG},
- anr0: {fileId: ANR0_FILE_ID,
- fileType: ICC_USIM_TYPE1_TAG}}]);
- } else {
- onsuccess([{
- adn: {fileId: ICC_EF_ADN},
- iap: {fileId: IAP_FILE_ID},
- email: {fileId: EMAIL_FILE_ID,
- fileType: ICC_USIM_TYPE2_TAG,
- indexInIAP: 0},
- anr0: {fileId: ANR0_FILE_ID,
- fileType: ICC_USIM_TYPE2_TAG,
- indexInIAP: 1}}]);
- }
- };
-
- let successCb = function(updatedContact) {
- equal(updatedContact.email, null);
- equal(updatedContact.anr, null);
- ok(true);
- };
-
- let errorCb = function(errorMsg) {
- do_print(errorMsg);
- ok(false);
- };
-
- contactHelper.updateICCContact(CARD_APPTYPE_USIM,
- GECKO_CARDCONTACT_TYPE_ADN,
- contact, null, successCb, errorCb);
- }
-
- do_test(ICC_USIM_TYPE1_TAG);
- do_test(ICC_USIM_TYPE2_TAG);
-
- run_next_test();
-});
-
-/**
- * Verify ICCContactHelper.findFreeICCContact in SIM
- */
-add_test(function test_find_free_icc_contact_sim() {
- let worker = newUint8Worker();
- let context = worker.ContextPool._contexts[0];
- let recordHelper = context.ICCRecordHelper;
- let contactHelper = context.ICCContactHelper;
- // Correct record Id starts with 1, so put a null element at index 0.
- let records = [null];
- const MAX_RECORDS = 3;
- const PBR_INDEX = 0;
-
- recordHelper.findFreeRecordId = function(fileId, onsuccess, onerror) {
- if (records.length > MAX_RECORDS) {
- onerror("No free record found.");
- return;
- }
-
- onsuccess(records.length);
- };
-
- let successCb = function(pbrIndex, recordId) {
- equal(pbrIndex, PBR_INDEX);
- records[recordId] = {};
- };
-
- let errorCb = function(errorMsg) {
- do_print(errorMsg);
- ok(false);
- };
-
- for (let i = 0; i < MAX_RECORDS; i++) {
- contactHelper.findFreeICCContact(CARD_APPTYPE_SIM,
- GECKO_CARDCONTACT_TYPE_ADN,
- successCb, errorCb);
- }
- // The 1st element, records[0], is null.
- equal(records.length - 1, MAX_RECORDS);
-
- // Now the EF is full, so finding a free one should result failure.
- successCb = function(pbrIndex, recordId) {
- ok(false);
- };
-
- errorCb = function(errorMsg) {
- ok(errorMsg === "No free record found.");
- };
- contactHelper.findFreeICCContact(CARD_APPTYPE_SIM, GECKO_CARDCONTACT_TYPE_ADN,
- successCb, errorCb);
-
- run_next_test();
-});
-
-/**
- * Verify ICCContactHelper.findFreeICCContact in USIM
- */
-add_test(function test_find_free_icc_contact_usim() {
- let worker = newUint8Worker();
- let context = worker.ContextPool._contexts[0];
- let recordHelper = context.ICCRecordHelper;
- let contactHelper = context.ICCContactHelper;
- const ADN1_FILE_ID = 0x6f3a;
- const ADN2_FILE_ID = 0x6f3b;
- const MAX_RECORDS = 3;
-
- // The adn in the first phonebook set has already two records, which means
- // only 1 free record remained.
- let pbrs = [{adn: {fileId: ADN1_FILE_ID, records: [null, {}, {}]}},
- {adn: {fileId: ADN2_FILE_ID, records: [null]}}];
-
- recordHelper.readPBR = function readPBR(onsuccess, onerror) {
- onsuccess(pbrs);
- };
-
- recordHelper.findFreeRecordId = function(fileId, onsuccess, onerror) {
- let pbr = (fileId == ADN1_FILE_ID ? pbrs[0]: pbrs[1]);
- if (pbr.adn.records.length > MAX_RECORDS) {
- onerror("No free record found.");
- return;
- }
-
- onsuccess(pbr.adn.records.length);
- };
-
- let successCb = function(pbrIndex, recordId) {
- equal(pbrIndex, 0);
- pbrs[pbrIndex].adn.records[recordId] = {};
- };
-
- let errorCb = function(errorMsg) {
- ok(false);
- };
-
- contactHelper.findFreeICCContact(CARD_APPTYPE_USIM,
- GECKO_CARDCONTACT_TYPE_ADN,
- successCb, errorCb);
-
- // Now the EF_ADN in the 1st phonebook set is full, so the next free contact
- // will come from the 2nd phonebook set.
- successCb = function(pbrIndex, recordId) {
- equal(pbrIndex, 1);
- equal(recordId, 1);
- }
- contactHelper.findFreeICCContact(CARD_APPTYPE_USIM,
- GECKO_CARDCONTACT_TYPE_ADN,
- successCb, errorCb);
-
- run_next_test();
-});
-
-/**
- * Verify ICCContactHelper.updateADNLikeWithExtension
- */
-add_test(function test_update_adn_like_with_extension() {
- let worker = newUint8Worker();
- let context = worker.ContextPool._contexts[0];
- let ril = context.RIL;
- let record = context.ICCRecordHelper;
- let contactHelper = context.ICCContactHelper;
- ril.appType = CARD_APPTYPE_SIM;
- // Correct record Id starts from 1, so put a null element at index 0.
- // ext_records contains data at index 1, and it only has 1 free record at index 2.
- let notFree = 0x01;
- let ext_records = [null, notFree, null];
-
- function do_test(contact, extRecordNumber, expectedExtRecordNumber, expectedNumber, expectedCleanEFRecord) {
- // Override some functions to test.
- record.getADNLikeExtensionRecordNumber = function(fileId, recordNumber, onsuccess, onerror) {
- onsuccess(extRecordNumber);
- }
-
- record.updateADNLike = function(fileId, extRecordNumber, contact, pin2, onsuccess, onerror) {
- equal(extRecordNumber, expectedExtRecordNumber);
- onsuccess({alphaId: contact.alphaId,
- number: contact.number.substring(0, ADN_MAX_NUMBER_DIGITS)});
- }
-
- record.updateExtension = function(fileId, recordNumber, number, onsuccess, onerror) {
- if (recordNumber > ext_records.length) {
- onerror("updateExtension failed.");
- return;
- }
- ext_records[recordNumber] = number;
- onsuccess();
- }
-
- record.findFreeRecordId = function(fileId, onsuccess, onerror) {
- for (let i = 1; i < ext_records.length; i++) {
- if (!ext_records[i]) {
- onsuccess(i);
- return;
- }
- }
-
- onerror("No free record found.");
- }
-
- let isCleanEFRecord = false;
- record.cleanEFRecord = function(fileId, recordNumber, onsuccess, onerror) {
- if (recordNumber > ext_records.length) {
- onerror("cleanEFRecord failed.");
- return;
- }
- ext_records[recordNumber] = null;
- isCleanEFRecord = true;
- onsuccess();
- }
-
- let successCb = function successCb(updatedContact) {
- equal(updatedContact.number, expectedNumber);
- };
-
- let errorCb = function errorCb(errorMsg) {
- do_print("updateADNLikeWithExtension failed, msg = " + errorMsg);
- ok(false);
- };
-
- contactHelper.updateADNLikeWithExtension(ICC_EF_ADN, ICC_EF_EXT1, contact, null, successCb, errorCb);
-
- if (expectedCleanEFRecord) {
- ok(isCleanEFRecord);
- }
- }
-
- // Update extension record with previous extension record number.
- do_test({recordId: 1, alphaId: "test", number: "001122334455667788991234"}, 0x01, 0x01, "001122334455667788991234");
- // Update extension record and find a free record.
- do_test({recordId: 1, alphaId: "test", number: "001122334455667788995678"}, 0xff, 0x02, "001122334455667788995678");
- // Update extension record with no free extension record.
- do_test({recordId: 1, alphaId: "test", number: "001122334455667788994321"}, 0xff, 0xff, "00112233445566778899");
- // Update extension record with clean previous extension record.
- do_test({recordId: 1, alphaId: "test", number: "00112233445566778899"}, 0x01, 0xff, "00112233445566778899", true);
- // Update extension record with no extension record and previous extension record.
- do_test({recordId: 1, alphaId: "test", number: "00112233445566778899"}, 0xff, 0xff, "00112233445566778899");
-
- run_next_test();
-}); \ No newline at end of file
diff --git a/dom/system/gonk/tests/test_ril_worker_icc_ICCIOHelper.js b/dom/system/gonk/tests/test_ril_worker_icc_ICCIOHelper.js
deleted file mode 100644
index e690b1206e..0000000000
--- a/dom/system/gonk/tests/test_ril_worker_icc_ICCIOHelper.js
+++ /dev/null
@@ -1,173 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-subscriptLoader.loadSubScript("resource://gre/modules/ril_consts.js", this);
-
-function run_test() {
- run_next_test();
-}
-
-/**
- * Verify ICCIOHelper.loadLinearFixedEF with recordSize.
- */
-add_test(function test_load_linear_fixed_ef() {
- let worker = newUint8Worker();
- let context = worker.ContextPool._contexts[0];
- let ril = context.RIL;
- let io = context.ICCIOHelper;
-
- io.getResponse = function fakeGetResponse(options) {
- // When recordSize is provided, loadLinearFixedEF should call iccIO directly.
- ok(false);
- run_next_test();
- };
-
- ril.iccIO = function fakeIccIO(options) {
- ok(true);
- run_next_test();
- };
-
- io.loadLinearFixedEF({recordSize: 0x20});
-});
-
-/**
- * Verify ICCIOHelper.loadLinearFixedEF without recordSize.
- */
-add_test(function test_load_linear_fixed_ef() {
- let worker = newUint8Worker();
- let context = worker.ContextPool._contexts[0];
- let ril = context.RIL;
- let io = context.ICCIOHelper;
-
- io.getResponse = function fakeGetResponse(options) {
- ok(true);
- run_next_test();
- };
-
- ril.iccIO = function fakeIccIO(options) {
- // When recordSize is not provided, loadLinearFixedEF should call getResponse.
- ok(false);
- run_next_test();
- };
-
- io.loadLinearFixedEF({});
-});
-
-/**
- * Verify ICC IO Error.
- */
-add_test(function test_process_icc_io_error() {
- let worker = newUint8Worker();
- let context = worker.ContextPool._contexts[0];
- let buf = context.Buf;
-
- function do_test(sw1, sw2, expectedErrorMsg) {
- let called = false;
- function errorCb(errorMsg) {
- called = true;
- equal(errorMsg, expectedErrorMsg);
- }
-
- // Write sw1 and sw2 to buffer.
- buf.writeInt32(sw1);
- buf.writeInt32(sw2);
-
- context.RIL[REQUEST_SIM_IO](0, {fileId: 0xffff,
- command: 0xff,
- onerror: errorCb});
-
- // onerror callback should be triggered.
- ok(called);
- }
-
- let TEST_DATA = [
- // [sw1, sw2, expectError]
- [ICC_STATUS_ERROR_COMMAND_NOT_ALLOWED, 0xff, GECKO_ERROR_GENERIC_FAILURE],
- [ICC_STATUS_ERROR_WRONG_PARAMETERS, 0xff, GECKO_ERROR_GENERIC_FAILURE],
- ];
-
- for (let i = 0; i < TEST_DATA.length; i++) {
- do_test.apply(null, TEST_DATA[i]);
- }
-
- run_next_test();
-});
-
-/**
- * Verify ICCIOHelper.processICCIOGetResponse for EF_TYPE_TRANSPARENT.
- */
-add_test(function test_icc_io_get_response_for_transparent_structure() {
- let worker = newUint8Worker();
- let context = worker.ContextPool._contexts[0];
- let buf = context.Buf;
- let iccioHelper = context.ICCIOHelper;
- let pduHelper = context.GsmPDUHelper;
-
- let responseArray = [
- // SIM response.
- [0x00, 0x00, 0x00, 0x0A, 0x2F, 0xE2, 0x04, 0x00, 0x0A, 0xA0, 0xAA, 0x00,
- 0x02, 0x00, 0x00],
- // USIM response.
- [0x62, 0x22, 0x82, 0x02, 0x41, 0x21, 0x83, 0x02, 0x2F, 0xE2, 0xA5, 0x09,
- 0xC1, 0x04, 0x40, 0x0F, 0xF5, 0x55, 0x92, 0x01, 0x00, 0x8A, 0x01, 0x05,
- 0x8B, 0x03, 0x2F, 0x06, 0x0B, 0x80, 0x02, 0x00, 0x0A, 0x88, 0x01, 0x10]
- ];
-
- for (let i = 0; i < responseArray.length; i++) {
- let strLen = responseArray[i].length * 2;
- buf.writeInt32(strLen);
- for (let j = 0; j < responseArray[i].length; j++) {
- pduHelper.writeHexOctet(responseArray[i][j]);
- }
- buf.writeStringDelimiter(strLen);
-
- let options = {fileId: ICC_EF_ICCID,
- structure: EF_STRUCTURE_TRANSPARENT};
- iccioHelper.processICCIOGetResponse(options);
-
- equal(options.fileSize, 0x0A);
- }
-
- run_next_test();
-});
-
-/**
- * Verify ICCIOHelper.processICCIOGetResponse for EF_TYPE_LINEAR_FIXED.
- */
-add_test(function test_icc_io_get_response_for_linear_fixed_structure() {
- let worker = newUint8Worker();
- let context = worker.ContextPool._contexts[0];
- let buf = context.Buf;
- let iccioHelper = context.ICCIOHelper;
- let pduHelper = context.GsmPDUHelper;
-
- let responseArray = [
- // SIM response.
- [0x00, 0x00, 0x00, 0x1A, 0x6F, 0x40, 0x04, 0x00, 0x11, 0xA0, 0xAA, 0x00,
- 0x02, 0x01, 0x1A],
- // USIM response.
- [0x62, 0x1E, 0x82, 0x05, 0x42, 0x21, 0x00, 0x1A, 0x01, 0x83, 0x02, 0x6F,
- 0x40, 0xA5, 0x03, 0x92, 0x01, 0x00, 0x8A, 0x01, 0x07, 0x8B, 0x03, 0x6F,
- 0x06, 0x02, 0x80, 0x02, 0x00, 0x1A, 0x88, 0x00]
- ];
-
- for (let i = 0; i < responseArray.length; i++) {
- let strLen = responseArray[i].length * 2;
- buf.writeInt32(strLen);
- for (let j = 0; j < responseArray[i].length; j++) {
- pduHelper.writeHexOctet(responseArray[i][j]);
- }
- buf.writeStringDelimiter(strLen);
-
- let options = {fileId: ICC_EF_MSISDN,
- structure: EF_STRUCTURE_LINEAR_FIXED};
- iccioHelper.processICCIOGetResponse(options);
-
- equal(options.fileSize, 0x1A);
- equal(options.recordSize, 0x1A);
- equal(options.totalRecords, 0x01);
- }
-
- run_next_test();
-});
-
diff --git a/dom/system/gonk/tests/test_ril_worker_icc_ICCPDUHelper.js b/dom/system/gonk/tests/test_ril_worker_icc_ICCPDUHelper.js
deleted file mode 100644
index 91495b1b7c..0000000000
--- a/dom/system/gonk/tests/test_ril_worker_icc_ICCPDUHelper.js
+++ /dev/null
@@ -1,652 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-subscriptLoader.loadSubScript("resource://gre/modules/ril_consts.js", this);
-
-function run_test() {
- run_next_test();
-}
-
-/**
- * Verify ICCPDUHelper#readICCUCS2String()
- */
-add_test(function test_read_icc_ucs2_string() {
- let worker = newUint8Worker();
- let context = worker.ContextPool._contexts[0];
- let helper = context.GsmPDUHelper;
- let iccHelper = context.ICCPDUHelper;
-
- // 0x80
- let text = "TEST";
- helper.writeUCS2String(text);
- // Also write two unused octets.
- let ffLen = 2;
- for (let i = 0; i < ffLen; i++) {
- helper.writeHexOctet(0xff);
- }
- equal(iccHelper.readICCUCS2String(0x80, (2 * text.length) + ffLen), text);
-
- // 0x81
- let array = [0x08, 0xd2, 0x4d, 0x6f, 0x7a, 0x69, 0x6c, 0x6c, 0x61, 0xca,
- 0xff, 0xff];
- let len = array.length;
- for (let i = 0; i < len; i++) {
- helper.writeHexOctet(array[i]);
- }
- equal(iccHelper.readICCUCS2String(0x81, len), "Mozilla\u694a");
-
- // 0x82
- let array2 = [0x08, 0x69, 0x00, 0x4d, 0x6f, 0x7a, 0x69, 0x6c, 0x6c, 0x61,
- 0xca, 0xff, 0xff];
- let len2 = array2.length;
- for (let i = 0; i < len2; i++) {
- helper.writeHexOctet(array2[i]);
- }
- equal(iccHelper.readICCUCS2String(0x82, len2), "Mozilla\u694a");
-
- run_next_test();
-});
-
-/**
- * Verify ICCPDUHelper#writeICCUCS2String()
- */
-add_test(function test_write_icc_ucs2_string() {
- let worker = newUint8Worker();
- let context = worker.ContextPool._contexts[0];
- let helper = context.GsmPDUHelper;
- let iccHelper = context.ICCPDUHelper;
- let alphaLen = 18;
- let test_data = [
- {
- encode: 0x80,
- // string only contain one character.
- data: "\u82b3"
- }, {
- encode: 0x80,
- // 2 UCS2 character not located in the same half-page.
- data: "Fire \u82b3\u8233"
- }, {
- encode: 0x80,
- // 2 UCS2 character not located in the same half-page.
- data: "\u694a\u704a"
- }, {
- encode: 0x81,
- // 2 UCS2 character within same half-page.
- data: "Fire \u6901\u697f"
- }, {
- encode: 0x81,
- // 2 UCS2 character within same half-page.
- data: "Fire \u6980\u69ff"
- }, {
- encode: 0x82,
- // 2 UCS2 character within same half-page, but bit 8 is different.
- data: "Fire \u0514\u0593"
- }, {
- encode: 0x82,
- // 2 UCS2 character over 0x81 can encode range.
- data: "Fire \u8000\u8001"
- }, {
- encode: 0x82,
- // 2 UCS2 character over 0x81 can encode range.
- data: "Fire \ufffd\ufffe"
- }];
-
- for (let i = 0; i < test_data.length; i++) {
- let test = test_data[i];
- let writtenStr = iccHelper.writeICCUCS2String(alphaLen, test.data);
- equal(writtenStr, test.data);
- equal(helper.readHexOctet(), test.encode);
- equal(iccHelper.readICCUCS2String(test.encode, alphaLen - 1), test.data);
- }
-
- // This string use 0x80 encoded and the maximum capacity is 17 octets.
- // Each alphabet takes 2 octets, thus the first 8 alphabets can be written.
- let str = "Mozilla \u82b3\u8233 On Fire";
- let writtenStr = iccHelper.writeICCUCS2String(alphaLen, str);
- equal(writtenStr, str.substring(0, 8));
- equal(helper.readHexOctet(), 0x80);
- equal(iccHelper.readICCUCS2String(0x80, alphaLen - 1), str.substring(0, 8));
-
- // This string use 0x81 encoded and the maximum capacity is 15 octets.
- // Each alphabet takes 1 octets, thus the first 15 alphabets can be written.
- str = "Mozilla \u6901\u697f On Fire";
- writtenStr = iccHelper.writeICCUCS2String(alphaLen, str);
- equal(writtenStr, str.substring(0, 15));
- equal(helper.readHexOctet(), 0x81);
- equal(iccHelper.readICCUCS2String(0x81, alphaLen - 1), str.substring(0, 15));
-
- // This string use 0x82 encoded and the maximum capacity is 14 octets.
- // Each alphabet takes 1 octets, thus the first 14 alphabets can be written.
- str = "Mozilla \u0514\u0593 On Fire";
- writtenStr = iccHelper.writeICCUCS2String(alphaLen, str);
- equal(writtenStr, str.substring(0, 14));
- equal(helper.readHexOctet(), 0x82);
- equal(iccHelper.readICCUCS2String(0x82, alphaLen - 1), str.substring(0, 14));
-
- run_next_test();
-});
-/**
- * Verify ICCPDUHelper#readDiallingNumber
- */
-add_test(function test_read_dialling_number() {
- let worker = newUint8Worker();
- let context = worker.ContextPool._contexts[0];
- let helper = context.GsmPDUHelper;
- let iccHelper = context.ICCPDUHelper;
- let str = "123456789";
-
- helper.readHexOctet = function() {
- return 0x81;
- };
-
- helper.readSwappedNibbleExtendedBcdString = function(len) {
- return str.substring(0, len);
- };
-
- for (let i = 0; i < str.length; i++) {
- equal(str.substring(0, i - 1), // -1 for the TON
- iccHelper.readDiallingNumber(i));
- }
-
- run_next_test();
-});
-
-/**
- * Verify ICCPDUHelper#read8BitUnpackedToString
- */
-add_test(function test_read_8bit_unpacked_to_string() {
- let worker = newUint8Worker();
- let context = worker.ContextPool._contexts[0];
- let helper = context.GsmPDUHelper;
- let iccHelper = context.ICCPDUHelper;
- const langTable = PDU_NL_LOCKING_SHIFT_TABLES[PDU_NL_IDENTIFIER_DEFAULT];
- const langShiftTable = PDU_NL_SINGLE_SHIFT_TABLES[PDU_NL_IDENTIFIER_DEFAULT];
-
- // Test 1: Read GSM alphabets.
- // Write alphabets before ESCAPE.
- for (let i = 0; i < PDU_NL_EXTENDED_ESCAPE; i++) {
- helper.writeHexOctet(i);
- }
-
- // Write two ESCAPEs to make it become ' '.
- helper.writeHexOctet(PDU_NL_EXTENDED_ESCAPE);
- helper.writeHexOctet(PDU_NL_EXTENDED_ESCAPE);
-
- for (let i = PDU_NL_EXTENDED_ESCAPE + 1; i < langTable.length; i++) {
- helper.writeHexOctet(i);
- }
-
- // Also write two unused fields.
- let ffLen = 2;
- for (let i = 0; i < ffLen; i++) {
- helper.writeHexOctet(0xff);
- }
-
- equal(iccHelper.read8BitUnpackedToString(PDU_NL_EXTENDED_ESCAPE),
- langTable.substring(0, PDU_NL_EXTENDED_ESCAPE));
- equal(iccHelper.read8BitUnpackedToString(2), " ");
- equal(iccHelper.read8BitUnpackedToString(langTable.length -
- PDU_NL_EXTENDED_ESCAPE - 1 + ffLen),
- langTable.substring(PDU_NL_EXTENDED_ESCAPE + 1));
-
- // Test 2: Read GSM extended alphabets.
- for (let i = 0; i < langShiftTable.length; i++) {
- helper.writeHexOctet(PDU_NL_EXTENDED_ESCAPE);
- helper.writeHexOctet(i);
- }
-
- // Read string before RESERVED_CONTROL.
- equal(iccHelper.read8BitUnpackedToString(PDU_NL_RESERVED_CONTROL * 2),
- langShiftTable.substring(0, PDU_NL_RESERVED_CONTROL));
- // ESCAPE + RESERVED_CONTROL will become ' '.
- equal(iccHelper.read8BitUnpackedToString(2), " ");
- // Read string between RESERVED_CONTROL and EXTENDED_ESCAPE.
- equal(iccHelper.read8BitUnpackedToString(
- (PDU_NL_EXTENDED_ESCAPE - PDU_NL_RESERVED_CONTROL - 1) * 2),
- langShiftTable.substring(PDU_NL_RESERVED_CONTROL + 1,
- PDU_NL_EXTENDED_ESCAPE));
- // ESCAPE + ESCAPE will become ' '.
- equal(iccHelper.read8BitUnpackedToString(2), " ");
- // Read remaining string.
- equal(iccHelper.read8BitUnpackedToString(
- (langShiftTable.length - PDU_NL_EXTENDED_ESCAPE - 1) * 2),
- langShiftTable.substring(PDU_NL_EXTENDED_ESCAPE + 1));
-
- run_next_test();
-});
-
-/**
- * Verify ICCPDUHelper#writeStringTo8BitUnpacked.
- *
- * Test writing GSM 8 bit alphabets.
- */
-add_test(function test_write_string_to_8bit_unpacked() {
- let worker = newUint8Worker();
- let context = worker.ContextPool._contexts[0];
- let helper = context.GsmPDUHelper;
- let iccHelper = context.ICCPDUHelper;
- const langTable = PDU_NL_LOCKING_SHIFT_TABLES[PDU_NL_IDENTIFIER_DEFAULT];
- const langShiftTable = PDU_NL_SINGLE_SHIFT_TABLES[PDU_NL_IDENTIFIER_DEFAULT];
- // Length of trailing 0xff.
- let ffLen = 2;
- let str;
-
- // Test 1, write GSM alphabets.
- let writtenStr = iccHelper.writeStringTo8BitUnpacked(langTable.length + ffLen, langTable);
- equal(writtenStr, langTable);
-
- for (let i = 0; i < langTable.length; i++) {
- equal(helper.readHexOctet(), i);
- }
-
- for (let i = 0; i < ffLen; i++) {
- equal(helper.readHexOctet(), 0xff);
- }
-
- // Test 2, write GSM extended alphabets.
- str = "\u000c\u20ac";
- writtenStr = iccHelper.writeStringTo8BitUnpacked(4, str);
- equal(writtenStr, str);
- equal(iccHelper.read8BitUnpackedToString(4), str);
-
- // Test 3, write GSM and GSM extended alphabets.
- // \u000c, \u20ac are from gsm extended alphabets.
- // \u00a3 is from gsm alphabet.
- str = "\u000c\u20ac\u00a3";
-
- // 2 octets * 2 = 4 octets for 2 gsm extended alphabets,
- // 1 octet for 1 gsm alphabet,
- // 2 octes for trailing 0xff.
- // "Totally 7 octets are to be written."
- writtenStr = iccHelper.writeStringTo8BitUnpacked(7, str);
- equal(writtenStr, str);
- equal(iccHelper.read8BitUnpackedToString(7), str);
-
- run_next_test();
-});
-
-/**
- * Verify ICCPDUHelper#writeStringTo8BitUnpacked with maximum octets written.
- */
-add_test(function test_write_string_to_8bit_unpacked_with_max_octets_written() {
- let worker = newUint8Worker();
- let context = worker.ContextPool._contexts[0];
- let helper = context.GsmPDUHelper;
- let iccHelper = context.ICCPDUHelper;
- const langTable = PDU_NL_LOCKING_SHIFT_TABLES[PDU_NL_IDENTIFIER_DEFAULT];
- const langShiftTable = PDU_NL_SINGLE_SHIFT_TABLES[PDU_NL_IDENTIFIER_DEFAULT];
-
- // The maximum of the number of octets that can be written is 3.
- // Only 3 characters shall be written even the length of the string is 4.
- let writtenStr = iccHelper.writeStringTo8BitUnpacked(3, langTable.substring(0, 4));
- equal(writtenStr, langTable.substring(0, 3));
- helper.writeHexOctet(0xff); // dummy octet.
- for (let i = 0; i < 3; i++) {
- equal(helper.readHexOctet(), i);
- }
- ok(helper.readHexOctet() != 4);
-
- // \u000c is GSM extended alphabet, 2 octets.
- // \u00a3 is GSM alphabet, 1 octet.
- let str = "\u000c\u00a3";
- writtenStr = iccHelper.writeStringTo8BitUnpacked(3, str);
- equal(writtenStr, str.substring(0, 2));
- equal(iccHelper.read8BitUnpackedToString(3), str);
-
- str = "\u00a3\u000c";
- writtenStr = iccHelper.writeStringTo8BitUnpacked(3, str);
- equal(writtenStr, str.substring(0, 2));
- equal(iccHelper.read8BitUnpackedToString(3), str);
-
- // 2 GSM extended alphabets cost 4 octets, but maximum is 3, so only the 1st
- // alphabet can be written.
- str = "\u000c\u000c";
- writtenStr = iccHelper.writeStringTo8BitUnpacked(3, str);
- helper.writeHexOctet(0xff); // dummy octet.
- equal(writtenStr, str.substring(0, 1));
- equal(iccHelper.read8BitUnpackedToString(4), str.substring(0, 1));
-
- run_next_test();
-});
-
-/**
- * Verify ICCPDUHelper.readAlphaIdentifier
- */
-add_test(function test_read_alpha_identifier() {
- let worker = newUint8Worker();
- let context = worker.ContextPool._contexts[0];
- let helper = context.GsmPDUHelper;
- let iccHelper = context.ICCPDUHelper;
-
- // UCS2: 0x80
- let text = "TEST";
- helper.writeHexOctet(0x80);
- helper.writeUCS2String(text);
- // Also write two unused octets.
- let ffLen = 2;
- for (let i = 0; i < ffLen; i++) {
- helper.writeHexOctet(0xff);
- }
- equal(iccHelper.readAlphaIdentifier(1 + (2 * text.length) + ffLen), text);
-
- // UCS2: 0x81
- let array = [0x81, 0x08, 0xd2, 0x4d, 0x6f, 0x7a, 0x69, 0x6c, 0x6c, 0x61, 0xca, 0xff, 0xff];
- for (let i = 0; i < array.length; i++) {
- helper.writeHexOctet(array[i]);
- }
- equal(iccHelper.readAlphaIdentifier(array.length), "Mozilla\u694a");
-
- // UCS2: 0x82
- let array2 = [0x82, 0x08, 0x69, 0x00, 0x4d, 0x6f, 0x7a, 0x69, 0x6c, 0x6c, 0x61, 0xca, 0xff, 0xff];
- for (let i = 0; i < array2.length; i++) {
- helper.writeHexOctet(array2[i]);
- }
- equal(iccHelper.readAlphaIdentifier(array2.length), "Mozilla\u694a");
-
- // GSM 8 Bit Unpacked
- const langTable = PDU_NL_LOCKING_SHIFT_TABLES[PDU_NL_IDENTIFIER_DEFAULT];
- for (let i = 0; i < PDU_NL_EXTENDED_ESCAPE; i++) {
- helper.writeHexOctet(i);
- }
- equal(iccHelper.readAlphaIdentifier(PDU_NL_EXTENDED_ESCAPE),
- langTable.substring(0, PDU_NL_EXTENDED_ESCAPE));
-
- run_next_test();
-});
-
-/**
- * Verify ICCPDUHelper.writeAlphaIdentifier
- */
-add_test(function test_write_alpha_identifier() {
- let worker = newUint8Worker();
- let context = worker.ContextPool._contexts[0];
- let helper = context.GsmPDUHelper;
- let iccHelper = context.ICCPDUHelper;
- // Length of trailing 0xff.
- let ffLen = 2;
-
- // Removal
- let writenAlphaId = iccHelper.writeAlphaIdentifier(10, null);
- equal(writenAlphaId, "");
- equal(iccHelper.readAlphaIdentifier(10), "");
-
- // GSM 8 bit
- let str = "Mozilla";
- writenAlphaId = iccHelper.writeAlphaIdentifier(str.length + ffLen, str);
- equal(writenAlphaId , str);
- equal(iccHelper.readAlphaIdentifier(str.length + ffLen), str);
-
- // UCS2
- str = "Mozilla\u8000";
- writenAlphaId = iccHelper.writeAlphaIdentifier(str.length * 2 + ffLen, str);
- equal(writenAlphaId , str);
- // * 2 for each character will be encoded to UCS2 alphabets.
- equal(iccHelper.readAlphaIdentifier(str.length * 2 + ffLen), str);
-
- // Test with maximum octets written.
- // 1 coding scheme (0x80) and 1 UCS2 character, total 3 octets.
- str = "\u694a";
- writenAlphaId = iccHelper.writeAlphaIdentifier(3, str);
- equal(writenAlphaId , str);
- equal(iccHelper.readAlphaIdentifier(3), str);
-
- // 1 coding scheme (0x80) and 2 UCS2 characters, total 5 octets.
- // numOctets is limited to 4, so only 1 UCS2 character can be written.
- str = "\u694a\u69ca";
- writenAlphaId = iccHelper.writeAlphaIdentifier(4, str);
- helper.writeHexOctet(0xff); // dummy octet.
- equal(writenAlphaId , str.substring(0, 1));
- equal(iccHelper.readAlphaIdentifier(5), str.substring(0, 1));
-
- // Write 0 octet.
- writenAlphaId = iccHelper.writeAlphaIdentifier(0, "1");
- helper.writeHexOctet(0xff); // dummy octet.
- equal(writenAlphaId, "");
- equal(iccHelper.readAlphaIdentifier(1), "");
-
- run_next_test();
-});
-
-/**
- * Verify ICCPDUHelper.readAlphaIdDiallingNumber
- */
-add_test(function test_read_alpha_id_dialling_number() {
- let worker = newUint8Worker();
- let context = worker.ContextPool._contexts[0];
- let helper = context.GsmPDUHelper;
- let iccHelper = context.ICCPDUHelper;
- let buf = context.Buf;
- const recordSize = 32;
-
- function testReadAlphaIdDiallingNumber(contact) {
- iccHelper.readAlphaIdentifier = function() {
- return contact.alphaId;
- };
-
- iccHelper.readNumberWithLength = function() {
- return contact.number;
- };
-
- let strLen = recordSize * 2;
- buf.writeInt32(strLen); // fake length
- helper.writeHexOctet(0xff); // fake CCP
- helper.writeHexOctet(0xff); // fake EXT1
- buf.writeStringDelimiter(strLen);
-
- let contactR = iccHelper.readAlphaIdDiallingNumber(recordSize);
- if (contact.alphaId == "" && contact.number == "") {
- equal(contactR, null);
- } else {
- equal(contactR.alphaId, contact.alphaId);
- equal(contactR.number, contact.number);
- }
- }
-
- testReadAlphaIdDiallingNumber({alphaId: "AlphaId", number: "0987654321"});
- testReadAlphaIdDiallingNumber({alphaId: "", number: ""});
-
- run_next_test();
-});
-
-/**
- * Verify ICCPDUHelper.writeAlphaIdDiallingNumber
- */
-add_test(function test_write_alpha_id_dialling_number() {
- let worker = newUint8Worker();
- let context = worker.ContextPool._contexts[0];
- let helper = context.ICCPDUHelper;
- const recordSize = 32;
-
- // Write a normal contact.
- let contactW = {
- alphaId: "Mozilla",
- number: "1234567890"
- };
-
- let writtenContact = helper.writeAlphaIdDiallingNumber(recordSize,
- contactW.alphaId,
- contactW.number, 0xff);
-
- let contactR = helper.readAlphaIdDiallingNumber(recordSize);
- equal(writtenContact.alphaId, contactR.alphaId);
- equal(writtenContact.number, contactR.number);
- equal(0xff, contactR.extRecordNumber);
-
- // Write a contact with alphaId encoded in UCS2 and number has '+'.
- let contactUCS2 = {
- alphaId: "火狐",
- number: "+1234567890"
- };
-
- writtenContact = helper.writeAlphaIdDiallingNumber(recordSize,
- contactUCS2.alphaId,
- contactUCS2.number, 0xff);
- contactR = helper.readAlphaIdDiallingNumber(recordSize);
- equal(writtenContact.alphaId, contactR.alphaId);
- equal(writtenContact.number, contactR.number);
- equal(0xff, contactR.extRecordNumber);
-
- // Write a null contact (Removal).
- writtenContact = helper.writeAlphaIdDiallingNumber(recordSize);
- contactR = helper.readAlphaIdDiallingNumber(recordSize);
- equal(contactR, null);
- equal(writtenContact.alphaId, "");
- equal(writtenContact.number, "");
-
- // Write a longer alphaId/dialling number
- // Dialling Number : Maximum 20 digits(10 octets).
- // Alpha Identifier: 32(recordSize) - 14 (10 octets for Dialling Number, 1
- // octet for TON/NPI, 1 for number length octet, and 2 for
- // Ext) = Maximum 18 octets.
- let longContact = {
- alphaId: "AAAAAAAAABBBBBBBBBCCCCCCCCC",
- number: "123456789012345678901234567890",
- };
-
- writtenContact = helper.writeAlphaIdDiallingNumber(recordSize,
- longContact.alphaId,
- longContact.number, 0xff);
- contactR = helper.readAlphaIdDiallingNumber(recordSize);
- equal(writtenContact.alphaId, contactR.alphaId);
- equal(writtenContact.number, contactR.number);
- equal(0xff, contactR.extRecordNumber);
-
- // Add '+' to number and test again.
- longContact.number = "+123456789012345678901234567890";
- writtenContact = helper.writeAlphaIdDiallingNumber(recordSize,
- longContact.alphaId,
- longContact.number, 0xff);
- contactR = helper.readAlphaIdDiallingNumber(recordSize);
- equal(writtenContact.alphaId, contactR.alphaId);
- equal(writtenContact.number, contactR.number);
- equal(0xff, contactR.extRecordNumber);
-
- run_next_test();
-});
-
-/**
- * Verify ICCPDUHelper.writeDiallingNumber
- */
-add_test(function test_write_dialling_number() {
- let worker = newUint8Worker();
- let context = worker.ContextPool._contexts[0];
- let helper = context.ICCPDUHelper;
-
- // with +
- let number = "+123456";
- let len = 4;
- helper.writeDiallingNumber(number);
- equal(helper.readDiallingNumber(len), number);
-
- // without +
- number = "987654";
- len = 4;
- helper.writeDiallingNumber(number);
- equal(helper.readDiallingNumber(len), number);
-
- number = "9876543";
- len = 5;
- helper.writeDiallingNumber(number);
- equal(helper.readDiallingNumber(len), number);
-
- run_next_test();
-});
-
-/**
- * Verify ICCPDUHelper.readNumberWithLength
- */
-add_test(function test_read_number_with_length() {
- let worker = newUint8Worker();
- let context = worker.ContextPool._contexts[0];
- let helper = context.GsmPDUHelper;
- let iccHelper = context.ICCPDUHelper;
-
- let numbers = [
- {
- number: "123456789",
- expectedNumber: "123456789"
- },
- {
- number: "",
- expectedNumber: ""
- },
- // Invalid length of BCD number/SSC contents
- {
- number: "12345678901234567890123",
- expectedNumber: ""
- },
- ];
-
- // To avoid obtaining wrong buffer content.
- context.Buf.seekIncoming = function(offset) {
- };
-
- function do_test(aNumber, aExpectedNumber) {
- iccHelper.readDiallingNumber = function(numLen) {
- return aNumber.substring(0, numLen);
- };
-
- if (aNumber) {
- helper.writeHexOctet(aNumber.length + 1);
- } else {
- helper.writeHexOctet(0xff);
- }
-
- equal(iccHelper.readNumberWithLength(), aExpectedNumber);
- }
-
- for (let i = 0; i < numbers.length; i++) {
- do_test(numbers[i].number, numbers[i].expectedNumber);
- }
-
- run_next_test();
-});
-
-/**
- * Verify ICCPDUHelper.writeNumberWithLength
- */
-add_test(function test_write_number_with_length() {
- let worker = newUint8Worker();
- let context = worker.ContextPool._contexts[0];
- let helper = context.GsmPDUHelper;
- let iccHelper = context.ICCPDUHelper;
-
- function test(number, expectedNumber) {
- expectedNumber = expectedNumber || number;
- let writeNumber = iccHelper.writeNumberWithLength(number);
- equal(writeNumber, expectedNumber);
- let numLen = helper.readHexOctet();
- equal(expectedNumber, iccHelper.readDiallingNumber(numLen));
- for (let i = 0; i < (ADN_MAX_BCD_NUMBER_BYTES - numLen); i++) {
- equal(0xff, helper.readHexOctet());
- }
- }
-
- // without +
- test("123456789");
-
- // with +
- test("+987654321");
-
- // extended BCD coding
- test("1*2#3,4*5#6,");
-
- // with + and extended BCD coding
- test("+1*2#3,4*5#6,");
-
- // non-supported characters should not be written.
- test("(1)23-456+789", "123456789");
-
- test("++(01)2*3-4#5,6+7(8)9*0#1,", "+012*34#5,6789*0#1,");
-
- // over maximum 20 digits should be truncated.
- test("012345678901234567890123456789", "01234567890123456789");
-
- // null
- iccHelper.writeNumberWithLength(null);
- for (let i = 0; i < (ADN_MAX_BCD_NUMBER_BYTES + 1); i++) {
- equal(0xff, helper.readHexOctet());
- }
-
- run_next_test();
-});
diff --git a/dom/system/gonk/tests/test_ril_worker_icc_ICCRecordHelper.js b/dom/system/gonk/tests/test_ril_worker_icc_ICCRecordHelper.js
deleted file mode 100644
index 00c55873de..0000000000
--- a/dom/system/gonk/tests/test_ril_worker_icc_ICCRecordHelper.js
+++ /dev/null
@@ -1,1080 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-subscriptLoader.loadSubScript("resource://gre/modules/ril_consts.js", this);
-
-function run_test() {
- run_next_test();
-}
-
-/**
- * Verify ICCRecordHelper.readPBR
- */
-add_test(function test_read_pbr() {
- let worker = newUint8Worker();
- let context = worker.ContextPool._contexts[0];
- let helper = context.GsmPDUHelper;
- let record = context.ICCRecordHelper;
- let buf = context.Buf;
- let io = context.ICCIOHelper;
-
- io.loadLinearFixedEF = function fakeLoadLinearFixedEF(options) {
- let pbr_1 = [
- 0xa8, 0x05, 0xc0, 0x03, 0x4f, 0x3a, 0x01
- ];
-
- // Write data size
- buf.writeInt32(pbr_1.length * 2);
-
- // Write pbr
- for (let i = 0; i < pbr_1.length; i++) {
- helper.writeHexOctet(pbr_1[i]);
- }
-
- // Write string delimiter
- buf.writeStringDelimiter(pbr_1.length * 2);
-
- options.totalRecords = 2;
- if (options.callback) {
- options.callback(options);
- }
- };
-
- io.loadNextRecord = function fakeLoadNextRecord(options) {
- let pbr_2 = [
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
- ];
-
- options.p1++;
- if (options.callback) {
- options.callback(options);
- }
- };
-
- let successCb = function successCb(pbrs) {
- equal(pbrs[0].adn.fileId, 0x4f3a);
- equal(pbrs.length, 1);
- };
-
- let errorCb = function errorCb(errorMsg) {
- do_print("Reading EF_PBR failed, msg = " + errorMsg);
- ok(false);
- };
-
- record.readPBR(successCb, errorCb);
-
- // Check cache pbrs when 2nd call
- let ifLoadEF = false;
- io.loadLinearFixedEF = function fakeLoadLinearFixedEF(options) {
- ifLoadEF = true;
- }
- record.readPBR(successCb, errorCb);
- ok(!ifLoadEF);
-
- run_next_test();
-});
-
-/**
- * Verify ICCRecordHelper.readEmail
- */
-add_test(function test_read_email() {
- let worker = newUint8Worker();
- let context = worker.ContextPool._contexts[0];
- let helper = context.GsmPDUHelper;
- let record = context.ICCRecordHelper;
- let buf = context.Buf;
- let io = context.ICCIOHelper;
- let recordSize;
-
- io.loadLinearFixedEF = function fakeLoadLinearFixedEF(options) {
- let email_1 = [
- 0x65, 0x6D, 0x61, 0x69, 0x6C,
- 0x00, 0x6D, 0x6F, 0x7A, 0x69,
- 0x6C, 0x6C, 0x61, 0x2E, 0x63,
- 0x6F, 0x6D, 0x02, 0x23];
-
- // Write data size
- buf.writeInt32(email_1.length * 2);
-
- // Write email
- for (let i = 0; i < email_1.length; i++) {
- helper.writeHexOctet(email_1[i]);
- }
-
- // Write string delimiter
- buf.writeStringDelimiter(email_1.length * 2);
-
- recordSize = email_1.length;
- options.recordSize = recordSize;
- if (options.callback) {
- options.callback(options);
- }
- };
-
- function doTestReadEmail(type, expectedResult) {
- let fileId = 0x6a75;
- let recordNumber = 1;
-
- // fileId and recordNumber are dummy arguments.
- record.readEmail(fileId, type, recordNumber, function(email) {
- equal(email, expectedResult);
- });
- };
-
- doTestReadEmail(ICC_USIM_TYPE1_TAG, "email@mozilla.com$#");
- doTestReadEmail(ICC_USIM_TYPE2_TAG, "email@mozilla.com");
- equal(record._emailRecordSize, recordSize);
-
- run_next_test();
-});
-
-/**
- * Verify ICCRecordHelper.updateEmail
- */
-add_test(function test_update_email() {
- const recordSize = 0x20;
- const recordNumber = 1;
- const fileId = 0x4f50;
- const NUM_TESTS = 2;
- let worker = newUint8Worker();
- let context = worker.ContextPool._contexts[0];
- let pduHelper = context.GsmPDUHelper;
- let iccHelper = context.ICCPDUHelper;
- let ril = context.RIL;
- ril.appType = CARD_APPTYPE_USIM;
- let recordHelper = context.ICCRecordHelper;
- let buf = context.Buf;
- let ioHelper = context.ICCIOHelper;
- let pbr = {email: {fileId: fileId, fileType: ICC_USIM_TYPE1_TAG},
- adn: {sfi: 1}};
- let count = 0;
-
- // Override.
- ioHelper.updateLinearFixedEF = function(options) {
- options.pathId = context.ICCFileHelper.getEFPath(options.fileId);
- options.command = ICC_COMMAND_UPDATE_RECORD;
- options.p1 = options.recordNumber;
- options.p2 = READ_RECORD_ABSOLUTE_MODE;
- options.p3 = recordSize;
- ril.iccIO(options);
- };
-
- function do_test(pbr, expectedEmail, expectedAdnRecordId) {
- buf.sendParcel = function() {
- count++;
-
- // Request Type.
- equal(this.readInt32(), REQUEST_SIM_IO);
-
- // Token : we don't care
- this.readInt32();
-
- // command.
- equal(this.readInt32(), ICC_COMMAND_UPDATE_RECORD);
-
- // fileId.
- equal(this.readInt32(), fileId);
-
- // pathId.
- equal(this.readString(),
- EF_PATH_MF_SIM + EF_PATH_DF_TELECOM + EF_PATH_DF_PHONEBOOK);
-
- // p1.
- equal(this.readInt32(), recordNumber);
-
- // p2.
- equal(this.readInt32(), READ_RECORD_ABSOLUTE_MODE);
-
- // p3.
- equal(this.readInt32(), recordSize);
-
- // data.
- let strLen = this.readInt32();
- let email;
- if (pbr.email.fileType === ICC_USIM_TYPE1_TAG) {
- email = iccHelper.read8BitUnpackedToString(recordSize);
- } else {
- email = iccHelper.read8BitUnpackedToString(recordSize - 2);
- equal(pduHelper.readHexOctet(), pbr.adn.sfi);
- equal(pduHelper.readHexOctet(), expectedAdnRecordId);
- }
- this.readStringDelimiter(strLen);
- equal(email, expectedEmail);
-
- // pin2.
- equal(this.readString(), null);
-
- // AID. Ignore because it's from modem.
- this.readInt32();
-
- if (count == NUM_TESTS) {
- run_next_test();
- }
- };
- recordHelper.updateEmail(pbr, recordNumber, expectedEmail, expectedAdnRecordId);
- }
-
- do_test(pbr, "test@mail.com");
- pbr.email.fileType = ICC_USIM_TYPE2_TAG;
- do_test(pbr, "test@mail.com", 1);
-});
-
-/**
- * Verify ICCRecordHelper.readANR
- */
-add_test(function test_read_anr() {
- let worker = newUint8Worker();
- let context = worker.ContextPool._contexts[0];
- let helper = context.GsmPDUHelper;
- let record = context.ICCRecordHelper;
- let buf = context.Buf;
- let io = context.ICCIOHelper;
- let recordSize;
-
- io.loadLinearFixedEF = function fakeLoadLinearFixedEF(options) {
- let anr_1 = [
- 0x01, 0x05, 0x81, 0x10, 0x32,
- 0x54, 0xF6, 0xFF, 0xFF];
-
- // Write data size
- buf.writeInt32(anr_1.length * 2);
-
- // Write anr
- for (let i = 0; i < anr_1.length; i++) {
- helper.writeHexOctet(anr_1[i]);
- }
-
- // Write string delimiter
- buf.writeStringDelimiter(anr_1.length * 2);
-
- recordSize = anr_1.length;
- options.recordSize = recordSize;
- if (options.callback) {
- options.callback(options);
- }
- };
-
- function doTestReadAnr(fileType, expectedResult) {
- let fileId = 0x4f11;
- let recordNumber = 1;
-
- // fileId and recordNumber are dummy arguments.
- record.readANR(fileId, fileType, recordNumber, function(anr) {
- equal(anr, expectedResult);
- });
- };
-
- doTestReadAnr(ICC_USIM_TYPE1_TAG, "0123456");
- equal(record._anrRecordSize, recordSize);
-
- run_next_test();
-});
-
-/**
- * Verify ICCRecordHelper.updateANR
- */
-add_test(function test_update_anr() {
- const recordSize = 0x20;
- const recordNumber = 1;
- const fileId = 0x4f11;
- const NUM_TESTS = 2;
- let worker = newUint8Worker();
- let context = worker.ContextPool._contexts[0];
- let pduHelper = context.GsmPDUHelper;
- let iccHelper = context.ICCPDUHelper;
- let ril = context.RIL;
- ril.appType = CARD_APPTYPE_USIM;
- let recordHelper = context.ICCRecordHelper;
- let buf = context.Buf;
- let ioHelper = context.ICCIOHelper;
- let pbr = {anr0: {fileId: fileId, fileType: ICC_USIM_TYPE1_TAG},
- adn: {sfi: 1}};
- let count = 0;
-
- // Override.
- ioHelper.updateLinearFixedEF = function(options) {
- options.pathId = context.ICCFileHelper.getEFPath(options.fileId);
- options.command = ICC_COMMAND_UPDATE_RECORD;
- options.p1 = options.recordNumber;
- options.p2 = READ_RECORD_ABSOLUTE_MODE;
- options.p3 = recordSize;
- ril.iccIO(options);
- };
-
- function do_test(pbr, expectedANR, expectedAdnRecordId) {
- buf.sendParcel = function() {
- count++;
-
- // Request Type.
- equal(this.readInt32(), REQUEST_SIM_IO);
-
- // Token : we don't care
- this.readInt32();
-
- // command.
- equal(this.readInt32(), ICC_COMMAND_UPDATE_RECORD);
-
- // fileId.
- equal(this.readInt32(), fileId);
-
- // pathId.
- equal(this.readString(),
- EF_PATH_MF_SIM + EF_PATH_DF_TELECOM + EF_PATH_DF_PHONEBOOK);
-
- // p1.
- equal(this.readInt32(), recordNumber);
-
- // p2.
- equal(this.readInt32(), READ_RECORD_ABSOLUTE_MODE);
-
- // p3.
- equal(this.readInt32(), recordSize);
-
- // data.
- let strLen = this.readInt32();
- // EF_AAS, ignore.
- pduHelper.readHexOctet();
- equal(iccHelper.readNumberWithLength(), expectedANR);
- // EF_CCP, ignore.
- pduHelper.readHexOctet();
- // EF_EXT1, ignore.
- pduHelper.readHexOctet();
- if (pbr.anr0.fileType === ICC_USIM_TYPE2_TAG) {
- equal(pduHelper.readHexOctet(), pbr.adn.sfi);
- equal(pduHelper.readHexOctet(), expectedAdnRecordId);
- }
- this.readStringDelimiter(strLen);
-
- // pin2.
- equal(this.readString(), null);
-
- // AID. Ignore because it's from modem.
- this.readInt32();
-
- if (count == NUM_TESTS) {
- run_next_test();
- }
- };
- recordHelper.updateANR(pbr, recordNumber, expectedANR, expectedAdnRecordId);
- }
-
- do_test(pbr, "+123456789");
- pbr.anr0.fileType = ICC_USIM_TYPE2_TAG;
- do_test(pbr, "123456789", 1);
-});
-
-/**
- * Verify ICCRecordHelper.readIAP
- */
-add_test(function test_read_iap() {
- let worker = newUint8Worker();
- let context = worker.ContextPool._contexts[0];
- let helper = context.GsmPDUHelper;
- let record = context.ICCRecordHelper;
- let buf = context.Buf;
- let io = context.ICCIOHelper;
- let recordSize;
-
- io.loadLinearFixedEF = function fakeLoadLinearFixedEF(options) {
- let iap_1 = [0x01, 0x02];
-
- // Write data size/
- buf.writeInt32(iap_1.length * 2);
-
- // Write iap.
- for (let i = 0; i < iap_1.length; i++) {
- helper.writeHexOctet(iap_1[i]);
- }
-
- // Write string delimiter.
- buf.writeStringDelimiter(iap_1.length * 2);
-
- recordSize = iap_1.length;
- options.recordSize = recordSize;
- if (options.callback) {
- options.callback(options);
- }
- };
-
- function doTestReadIAP(expectedIAP) {
- const fileId = 0x4f17;
- const recordNumber = 1;
-
- let successCb = function successCb(iap) {
- for (let i = 0; i < iap.length; i++) {
- equal(expectedIAP[i], iap[i]);
- }
- run_next_test();
- }.bind(this);
-
- let errorCb = function errorCb(errorMsg) {
- do_print(errorMsg);
- ok(false);
- run_next_test();
- }.bind(this);
-
- record.readIAP(fileId, recordNumber, successCb, errorCb);
- };
-
- doTestReadIAP([1, 2]);
-});
-
-/**
- * Verify ICCRecordHelper.updateIAP
- */
-add_test(function test_update_iap() {
- const recordSize = 2;
- const recordNumber = 1;
- const fileId = 0x4f17;
- let worker = newUint8Worker();
- let context = worker.ContextPool._contexts[0];
- let pduHelper = context.GsmPDUHelper;
- let ril = context.RIL;
- ril.appType = CARD_APPTYPE_USIM;
- let recordHelper = context.ICCRecordHelper;
- let buf = context.Buf;
- let ioHelper = context.ICCIOHelper;
- let count = 0;
-
- // Override.
- ioHelper.updateLinearFixedEF = function(options) {
- options.pathId = context.ICCFileHelper.getEFPath(options.fileId);
- options.command = ICC_COMMAND_UPDATE_RECORD;
- options.p1 = options.recordNumber;
- options.p2 = READ_RECORD_ABSOLUTE_MODE;
- options.p3 = recordSize;
- ril.iccIO(options);
- };
-
- function do_test(expectedIAP) {
- buf.sendParcel = function() {
- // Request Type.
- equal(this.readInt32(), REQUEST_SIM_IO);
-
- // Token : we don't care
- this.readInt32();
-
- // command.
- equal(this.readInt32(), ICC_COMMAND_UPDATE_RECORD);
-
- // fileId.
- equal(this.readInt32(), fileId);
-
- // pathId.
- equal(this.readString(),
- EF_PATH_MF_SIM + EF_PATH_DF_TELECOM + EF_PATH_DF_PHONEBOOK);
-
- // p1.
- equal(this.readInt32(), recordNumber);
-
- // p2.
- equal(this.readInt32(), READ_RECORD_ABSOLUTE_MODE);
-
- // p3.
- equal(this.readInt32(), recordSize);
-
- // data.
- let strLen = this.readInt32();
- for (let i = 0; i < recordSize; i++) {
- equal(expectedIAP[i], pduHelper.readHexOctet());
- }
- this.readStringDelimiter(strLen);
-
- // pin2.
- equal(this.readString(), null);
-
- // AID. Ignore because it's from modem.
- this.readInt32();
-
- run_next_test();
- };
- recordHelper.updateIAP(fileId, recordNumber, expectedIAP);
- }
-
- do_test([1, 2]);
-});
-
-/**
- * Verify ICCRecordHelper.readADNLike.
- */
-add_test(function test_read_adn_like() {
- const RECORD_SIZE = 0x20;
-
- let worker = newUint8Worker();
- let context = worker.ContextPool._contexts[0];
- let helper = context.GsmPDUHelper;
- let record = context.ICCRecordHelper;
- let buf = context.Buf;
- let io = context.ICCIOHelper;
- let ril = context.RIL;
-
- function do_test(extFileId, rawEF, expectedExtRecordNumber, expectedNumber) {
- io.loadLinearFixedEF = function fakeLoadLinearFixedEF(options) {
- // Write data size
- buf.writeInt32(rawEF.length * 2);
-
- // Write adn
- for (let i = 0; i < rawEF.length; i += 2) {
- helper.writeHexOctet(parseInt(rawEF.substr(i, 2), 16));
- }
-
- // Write string delimiter
- buf.writeStringDelimiter(rawEF.length * 2);
-
- options.p1 = 1;
- options.recordSize = RECORD_SIZE;
- options.totalRecords = 1;
- if (options.callback) {
- options.callback(options);
- }
- };
-
- record.readExtension = function(fileId, recordNumber, onsuccess, onerror) {
- onsuccess("1234");
- }
-
- let successCb = function successCb(contacts) {
- ok(contacts[0].number == expectedNumber);
- };
-
- let errorCb = function errorCb(errorMsg) {
- do_print("Reading ADNLike failed, msg = " + errorMsg);
- ok(false);
- };
-
- record.readADNLike(ICC_EF_ADN, extFileId, successCb, errorCb);
- }
-
- ril.appType = CARD_APPTYPE_SIM;
- // Valid extension
- do_test(ICC_EF_EXT1,"436f6e74616374303031ffffffffffffffff0b8199887766554433221100ff01",
- 0x01,"998877665544332211001234");
- // Empty extension
- do_test(ICC_EF_EXT1,"436f6e74616374303031ffffffffffffffff0b8199887766554433221100ffff",
- 0xff, "99887766554433221100");
- // Unsupport extension
- do_test(null,"436f6e74616374303031ffffffffffffffff0b8199887766554433221100ffff",
- 0xff, "99887766554433221100");
- // Empty dialling number contact
- do_test(null,"436f6e74616374303031ffffffffffffffffffffffffffffffffffffffffffff",
- 0xff, "");
-
- run_next_test();
-});
-
-/**
- * Verify ICCRecordHelper.updateADNLike.
- */
-add_test(function test_update_adn_like() {
- let worker = newUint8Worker();
- let context = worker.ContextPool._contexts[0];
- let ril = context.RIL;
- let record = context.ICCRecordHelper;
- let io = context.ICCIOHelper;
- let pdu = context.ICCPDUHelper;
- let buf = context.Buf;
-
- ril.appType = CARD_APPTYPE_SIM;
- const recordSize = 0x20;
- let fileId;
-
- // Override.
- io.updateLinearFixedEF = function(options) {
- options.pathId = context.ICCFileHelper.getEFPath(options.fileId);
- options.command = ICC_COMMAND_UPDATE_RECORD;
- options.p1 = options.recordNumber;
- options.p2 = READ_RECORD_ABSOLUTE_MODE;
- options.p3 = recordSize;
- ril.iccIO(options);
- };
-
- buf.sendParcel = function() {
- // Request Type.
- equal(this.readInt32(), REQUEST_SIM_IO);
-
- // Token : we don't care
- this.readInt32();
-
- // command.
- equal(this.readInt32(), ICC_COMMAND_UPDATE_RECORD);
-
- // fileId.
- equal(this.readInt32(), fileId);
-
- // pathId.
- equal(this.readString(), EF_PATH_MF_SIM + EF_PATH_DF_TELECOM);
-
- // p1.
- equal(this.readInt32(), 1);
-
- // p2.
- equal(this.readInt32(), READ_RECORD_ABSOLUTE_MODE);
-
- // p3.
- equal(this.readInt32(), 0x20);
-
- // data.
- let contact = pdu.readAlphaIdDiallingNumber(0x20);
- equal(contact.alphaId, "test");
- equal(contact.number, "123456");
- equal(contact.extRecordNumber, "0xff");
-
- // pin2.
- if (fileId == ICC_EF_ADN) {
- equal(this.readString(), null);
- } else {
- equal(this.readString(), "1111");
- }
-
- // AID. Ignore because it's from modem.
- this.readInt32();
-
- if (fileId == ICC_EF_FDN) {
- run_next_test();
- }
- };
-
- fileId = ICC_EF_ADN;
- record.updateADNLike(fileId, 0xff,
- {recordId: 1, alphaId: "test", number: "123456"});
-
- fileId = ICC_EF_FDN;
- record.updateADNLike(fileId, 0xff,
- {recordId: 1, alphaId: "test", number: "123456"},
- "1111");
-});
-
-/**
- * Verify ICCRecordHelper.findFreeRecordId.
- */
-add_test(function test_find_free_record_id() {
- let worker = newUint8Worker();
- let context = worker.ContextPool._contexts[0];
- let pduHelper = context.GsmPDUHelper;
- let recordHelper = context.ICCRecordHelper;
- let buf = context.Buf;
- let io = context.ICCIOHelper;
- let ril = context.RIL;
-
- function writeRecord(record) {
- // Write data size
- buf.writeInt32(record.length * 2);
-
- for (let i = 0; i < record.length; i++) {
- pduHelper.writeHexOctet(record[i]);
- }
-
- // Write string delimiter
- buf.writeStringDelimiter(record.length * 2);
- }
-
- io.loadLinearFixedEF = function fakeLoadLinearFixedEF(options) {
- // Some random data.
- let record = [0x12, 0x34, 0x56, 0x78, 0x90];
- options.p1 = 1;
- options.totalRecords = 2;
- writeRecord(record);
- if (options.callback) {
- options.callback(options);
- }
- };
-
- ril.iccIO = function fakeIccIO(options) {
- // Unused bytes.
- let record = [0xff, 0xff, 0xff, 0xff, 0xff];
- writeRecord(record);
- if (options.callback) {
- options.callback(options);
- }
- };
-
- let fileId = 0x0000; // Dummy.
- recordHelper.findFreeRecordId(
- fileId,
- function(recordId) {
- equal(recordId, 2);
- run_next_test();
- }.bind(this),
- function(errorMsg) {
- do_print(errorMsg);
- ok(false);
- run_next_test();
- }.bind(this));
-});
-
-/**
- * Verify ICCRecordHelper.fetchICCRecords.
- */
-add_test(function test_fetch_icc_recodes() {
- let worker = newWorker();
- let context = worker.ContextPool._contexts[0];
- let RIL = context.RIL;
- let iccRecord = context.ICCRecordHelper;
- let simRecord = context.SimRecordHelper;
- let ruimRecord = context.RuimRecordHelper;
- let fetchTag = 0x00;
-
- simRecord.fetchSimRecords = function() {
- fetchTag = 0x01;
- };
-
- ruimRecord.fetchRuimRecords = function() {
- fetchTag = 0x02;
- };
-
- RIL.appType = CARD_APPTYPE_SIM;
- iccRecord.fetchICCRecords();
- equal(fetchTag, 0x01);
-
- RIL.appType = CARD_APPTYPE_RUIM;
- iccRecord.fetchICCRecords();
- equal(fetchTag, 0x02);
-
- RIL.appType = CARD_APPTYPE_USIM;
- iccRecord.fetchICCRecords();
- equal(fetchTag, 0x01);
-
- run_next_test();
-});
-
-/**
- * Verify reading EF_ICCID.
- */
-add_test(function test_handling_iccid() {
- let worker = newUint8Worker();
- let context = worker.ContextPool._contexts[0];
- let record = context.ICCRecordHelper;
- let helper = context.GsmPDUHelper;
- let ril = context.RIL;
- let buf = context.Buf;
- let io = context.ICCIOHelper;
-
- ril.reportStkServiceIsRunning = function fakeReportStkServiceIsRunning() {
- };
-
- function do_test(rawICCID, expectedICCID) {
- io.loadTransparentEF = function fakeLoadTransparentEF(options) {
- // Write data size
- buf.writeInt32(rawICCID.length);
-
- // Write data
- for (let i = 0; i < rawICCID.length; i += 2) {
- helper.writeHexOctet(parseInt(rawICCID.substr(i, 2), 16));
- }
-
- // Write string delimiter
- buf.writeStringDelimiter(rawICCID.length);
-
- if (options.callback) {
- options.callback(options);
- }
- };
-
- record.readICCID();
-
- equal(ril.iccInfo.iccid, expectedICCID);
- }
-
- // Invalid value 0xE at high nibbile + low nibbile contains 0xF.
- do_test("9868002E90909F001519", "89860020909");
- // Invalid value 0xD at low nibbile.
- do_test("986800D2909090001519", "8986002090909005191");
- // Invalid value 0xC at low nibbile.
- do_test("986800C2909090001519", "8986002090909005191");
- // Invalid value 0xB at low nibbile.
- do_test("986800B2909090001519", "8986002090909005191");
- // Invalid value 0xA at low nibbile.
- do_test("986800A2909090001519", "8986002090909005191");
- // Valid ICCID.
- do_test("98101430121181157002", "89014103211118510720");
-
- run_next_test();
-});
-
-/**
- * Verify ICCRecordHelper.readExtension
- */
-add_test(function test_read_extension() {
- let worker = newUint8Worker();
- let context = worker.ContextPool._contexts[0];
- let helper = context.GsmPDUHelper;
- let record = context.ICCRecordHelper;
- let buf = context.Buf;
- let io = context.ICCIOHelper;
-
- function do_test(rawExtension, expectedExtensionNumber) {
- io.loadLinearFixedEF = function fakeLoadLinearFixedEF(options) {
- // Write data size
- buf.writeInt32(rawExtension.length * 2);
-
- // Write ext
- for (let i = 0; i < rawExtension.length; i += 2) {
- helper.writeHexOctet(parseInt(rawExtension.substr(i, 2), 16));
- }
-
- // Write string delimiter
- buf.writeStringDelimiter(rawExtension.length);
-
- if (options.callback) {
- options.callback(options);
- }
- };
-
- let successCb = function successCb(number) {
- do_print("extension number:" + number);
- equal(number, expectedExtensionNumber);
- };
-
- let errorCb = function errorCb() {
- ok(expectedExtensionNumber == null);
- };
-
- record.readExtension(0x6f4a, 1, successCb, errorCb);
- }
-
- // Test unsupported record type 0x01
- do_test("010a10325476981032547698ff", "");
- // Test invalid length 0xc1
- do_test("020c10325476981032547698ff", null);
- // Test extension chain which we don't support
- do_test("020a1032547698103254769802", "01234567890123456789");
- // Test valid Extension
- do_test("020a10325476981032547698ff", "01234567890123456789");
- // Test valid Extension
- do_test("0209103254769810325476ffff", "012345678901234567");
- // Test empty Extension
- do_test("02ffffffffffffffffffffffff", "");
-
- run_next_test();
-});
-
-/**
- * Verify ICCRecordHelper.updateExtension
- */
-add_test(function test_update_extension() {
- const RECORD_SIZE = 13;
- const RECORD_NUMBER = 1;
-
- let worker = newUint8Worker();
- let context = worker.ContextPool._contexts[0];
- let pduHelper = context.GsmPDUHelper;
- let ril = context.RIL;
- let recordHelper = context.ICCRecordHelper;
- let buf = context.Buf;
- let ioHelper = context.ICCIOHelper;
-
- // Override.
- ioHelper.updateLinearFixedEF = function(options) {
- options.pathId = context.ICCFileHelper.getEFPath(options.fileId);
- options.command = ICC_COMMAND_UPDATE_RECORD;
- options.p1 = options.recordNumber;
- options.p2 = READ_RECORD_ABSOLUTE_MODE;
- options.p3 = RECORD_SIZE;
- ril.iccIO(options);
- };
-
- function do_test(fileId, number, expectedNumber) {
- buf.sendParcel = function() {
- // Request Type.
- equal(this.readInt32(), REQUEST_SIM_IO);
-
- // Token : we don't care
- this.readInt32();
-
- // command.
- equal(this.readInt32(), ICC_COMMAND_UPDATE_RECORD);
-
- // fileId.
- equal(this.readInt32(), fileId);
-
- // pathId.
- if (ril.appType == CARD_APPTYPE_SIM || ril.appType == CARD_APPTYPE_RUIM) {
- equal(this.readString(),
- EF_PATH_MF_SIM + EF_PATH_DF_TELECOM);
- } else{
- equal(this.readString(),
- EF_PATH_MF_SIM + EF_PATH_DF_TELECOM + EF_PATH_DF_PHONEBOOK);
- }
-
- // p1.
- equal(this.readInt32(), RECORD_NUMBER);
-
- // p2.
- equal(this.readInt32(), READ_RECORD_ABSOLUTE_MODE);
-
- // p3.
- equal(this.readInt32(), RECORD_SIZE);
-
- // data.
- let strLen = this.readInt32();
- // Extension record
- let recordType = pduHelper.readHexOctet();
-
- equal(recordType, 0x02);
- equal(pduHelper.readHexOctet(), 10);
- equal(
- pduHelper.readSwappedNibbleExtendedBcdString(EXT_MAX_NUMBER_DIGITS - 1),
- expectedNumber);
-
- this.readStringDelimiter(strLen);
-
- // pin2.
- equal(this.readString(), null);
-
- // AID. Ignore because it's from modem.
- this.readInt32();
- };
-
- recordHelper.updateExtension(fileId, RECORD_NUMBER, number);
- }
-
- ril.appType = CARD_APPTYPE_SIM;
- do_test(ICC_EF_EXT1, "01234567890123456789", "01234567890123456789");
- // We don't support extension chain.
- do_test(ICC_EF_EXT1, "012345678901234567891234", "01234567890123456789");
-
- ril.appType = CARD_APPTYPE_USIM;
- do_test(ICC_EF_EXT1, "01234567890123456789", "01234567890123456789");
-
- ril.appType = CARD_APPTYPE_RUIM;
- do_test(ICC_EF_EXT1, "01234567890123456789", "01234567890123456789");
-
- run_next_test();
-});
-
-/**
- * Verify ICCRecordHelper.cleanEFRecord
- */
-add_test(function test_clean_ef_record() {
- const RECORD_SIZE = 13;
- const RECORD_NUMBER = 1;
-
- let worker = newUint8Worker();
- let context = worker.ContextPool._contexts[0];
- let pduHelper = context.GsmPDUHelper;
- let ril = context.RIL;
- let recordHelper = context.ICCRecordHelper;
- let buf = context.Buf;
- let ioHelper = context.ICCIOHelper;
-
- // Override.
- ioHelper.updateLinearFixedEF = function(options) {
- options.pathId = context.ICCFileHelper.getEFPath(options.fileId);
- options.command = ICC_COMMAND_UPDATE_RECORD;
- options.p1 = options.recordNumber;
- options.p2 = READ_RECORD_ABSOLUTE_MODE;
- options.p3 = RECORD_SIZE;
- ril.iccIO(options);
- };
-
- function do_test(fileId) {
- buf.sendParcel = function() {
- // Request Type.
- equal(this.readInt32(), REQUEST_SIM_IO);
-
- // Token : we don't care
- this.readInt32();
-
- // command.
- equal(this.readInt32(), ICC_COMMAND_UPDATE_RECORD);
-
- // fileId.
- equal(this.readInt32(), fileId);
-
- // pathId.
- if (ril.appType == CARD_APPTYPE_SIM || ril.appType == CARD_APPTYPE_RUIM) {
- equal(this.readString(),
- EF_PATH_MF_SIM + EF_PATH_DF_TELECOM);
- } else{
- equal(this.readString(),
- EF_PATH_MF_SIM + EF_PATH_DF_TELECOM + EF_PATH_DF_PHONEBOOK);
- }
-
- // p1.
- equal(this.readInt32(), RECORD_NUMBER);
-
- // p2.
- equal(this.readInt32(), READ_RECORD_ABSOLUTE_MODE);
-
- // p3.
- equal(this.readInt32(), RECORD_SIZE);
-
- // data.
- let strLen = this.readInt32();
- // Extension record
- for (let i = 0; i < RECORD_SIZE; i++) {
- equal(pduHelper.readHexOctet(), 0xff);
- }
-
- this.readStringDelimiter(strLen);
-
- // pin2.
- equal(this.readString(), null);
-
- // AID. Ignore because it's from modem.
- this.readInt32();
- };
-
- recordHelper.cleanEFRecord(fileId, RECORD_NUMBER);
- }
-
- ril.appType = CARD_APPTYPE_SIM;
- do_test(ICC_EF_EXT1);
-
- run_next_test();
-});
-
-/**
- * Verify ICCRecordHelper.getADNLikeExtensionRecordNumber
- */
-add_test(function test_get_adn_like_extension_record_number() {
- const RECORD_SIZE = 0x20;
-
- let worker = newUint8Worker();
- let context = worker.ContextPool._contexts[0];
- let helper = context.GsmPDUHelper;
- let record = context.ICCRecordHelper;
- let buf = context.Buf;
- let io = context.ICCIOHelper;
-
- function do_test(rawEF, expectedRecordNumber) {
- io.loadLinearFixedEF = function fakeLoadLinearFixedEF(options) {
- // Write data size
- buf.writeInt32(rawEF.length * 2);
-
- // Write ext
- for (let i = 0; i < rawEF.length; i += 2) {
- helper.writeHexOctet(parseInt(rawEF.substr(i, 2), 16));
- }
-
- // Write string delimiter
- buf.writeStringDelimiter(rawEF.length);
- options.recordSize = RECORD_SIZE;
- if (options.callback) {
- options.callback(options);
- }
- };
-
- let isSuccess = false;
- let successCb = function successCb(number) {
- equal(number, expectedRecordNumber);
- isSuccess = true;
- };
-
- let errorCb = function errorCb(errorMsg) {
- do_print("Reading ADNLike failed, msg = " + errorMsg);
- ok(false);
- };
-
- record.getADNLikeExtensionRecordNumber(ICC_EF_ADN, 1, successCb, errorCb);
- ok(isSuccess);
- }
-
- // Valid Extension, Alpha Id(Encoded with GSM 8 bit): "Contact001",
- // Dialling Number: 99887766554433221100, Ext1: 0x01
- do_test("436f6e74616374303031ffffffffffffffff0b8199887766554433221100ff01", 0x01);
- // Empty Extension, Alpha Id(Encoded with GSM 8 bit): "Contact001", Ext1: 0xff
- do_test("436f6e74616374303031ffffffffffffffffffffffffffffffffffffffffffff", 0xff);
-
- run_next_test();
-});
diff --git a/dom/system/gonk/tests/test_ril_worker_icc_ICCUtilsHelper.js b/dom/system/gonk/tests/test_ril_worker_icc_ICCUtilsHelper.js
deleted file mode 100644
index b23d0b598f..0000000000
--- a/dom/system/gonk/tests/test_ril_worker_icc_ICCUtilsHelper.js
+++ /dev/null
@@ -1,326 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-subscriptLoader.loadSubScript("resource://gre/modules/ril_consts.js", this);
-
-function run_test() {
- run_next_test();
-}
-
-/**
- * Verify ICCUtilsHelper.isICCServiceAvailable.
- */
-add_test(function test_is_icc_service_available() {
- let worker = newUint8Worker();
- let context = worker.ContextPool._contexts[0];
- let ICCUtilsHelper = context.ICCUtilsHelper;
- let RIL = context.RIL;
-
- function test_table(sst, geckoService, simEnabled, usimEnabled) {
- RIL.iccInfoPrivate.sst = sst;
- RIL.appType = CARD_APPTYPE_SIM;
- equal(ICCUtilsHelper.isICCServiceAvailable(geckoService), simEnabled);
- RIL.appType = CARD_APPTYPE_USIM;
- equal(ICCUtilsHelper.isICCServiceAvailable(geckoService), usimEnabled);
- }
-
- test_table([0x08], "ADN", true, false);
- test_table([0x08], "FDN", false, false);
- test_table([0x08], "SDN", false, true);
-
- run_next_test();
-});
-
-/**
- * Verify ICCUtilsHelper.isGsm8BitAlphabet
- */
-add_test(function test_is_gsm_8bit_alphabet() {
- let worker = newUint8Worker();
- let context = worker.ContextPool._contexts[0];
- let ICCUtilsHelper = context.ICCUtilsHelper;
- const langTable = PDU_NL_LOCKING_SHIFT_TABLES[PDU_NL_IDENTIFIER_DEFAULT];
- const langShiftTable = PDU_NL_SINGLE_SHIFT_TABLES[PDU_NL_IDENTIFIER_DEFAULT];
-
- equal(ICCUtilsHelper.isGsm8BitAlphabet(langTable), true);
- equal(ICCUtilsHelper.isGsm8BitAlphabet(langShiftTable), true);
- equal(ICCUtilsHelper.isGsm8BitAlphabet("\uaaaa"), false);
-
- run_next_test();
-});
-
-/**
- * Verify ICCUtilsHelper.parsePbrTlvs
- */
-add_test(function test_parse_pbr_tlvs() {
- let worker = newUint8Worker();
- let context = worker.ContextPool._contexts[0];
- let buf = context.Buf;
-
- let pbrTlvs = [
- {tag: ICC_USIM_TYPE1_TAG,
- length: 0x0F,
- value: [{tag: ICC_USIM_EFADN_TAG,
- length: 0x03,
- value: [0x4F, 0x3A, 0x02]},
- {tag: ICC_USIM_EFIAP_TAG,
- length: 0x03,
- value: [0x4F, 0x25, 0x01]},
- {tag: ICC_USIM_EFPBC_TAG,
- length: 0x03,
- value: [0x4F, 0x09, 0x04]}]
- },
- {tag: ICC_USIM_TYPE2_TAG,
- length: 0x05,
- value: [{tag: ICC_USIM_EFEMAIL_TAG,
- length: 0x03,
- value: [0x4F, 0x50, 0x0B]},
- {tag: ICC_USIM_EFANR_TAG,
- length: 0x03,
- value: [0x4F, 0x11, 0x02]},
- {tag: ICC_USIM_EFANR_TAG,
- length: 0x03,
- value: [0x4F, 0x12, 0x03]}]
- },
- {tag: ICC_USIM_TYPE3_TAG,
- length: 0x0A,
- value: [{tag: ICC_USIM_EFCCP1_TAG,
- length: 0x03,
- value: [0x4F, 0x3D, 0x0A]},
- {tag: ICC_USIM_EFEXT1_TAG,
- length: 0x03,
- value: [0x4F, 0x4A, 0x03]}]
- },
- ];
-
- let pbr = context.ICCUtilsHelper.parsePbrTlvs(pbrTlvs);
- equal(pbr.adn.fileId, 0x4F3a);
- equal(pbr.iap.fileId, 0x4F25);
- equal(pbr.pbc.fileId, 0x4F09);
- equal(pbr.email.fileId, 0x4F50);
- equal(pbr.anr0.fileId, 0x4f11);
- equal(pbr.anr1.fileId, 0x4f12);
- equal(pbr.ccp1.fileId, 0x4F3D);
- equal(pbr.ext1.fileId, 0x4F4A);
-
- run_next_test();
-});
-
-/**
- * Verify MCC and MNC parsing
- */
-add_test(function test_mcc_mnc_parsing() {
- let worker = newUint8Worker();
- let context = worker.ContextPool._contexts[0];
- let helper = context.ICCUtilsHelper;
-
- function do_test(imsi, mncLength, expectedMcc, expectedMnc) {
- let result = helper.parseMccMncFromImsi(imsi, mncLength);
-
- if (!imsi) {
- equal(result, null);
- return;
- }
-
- equal(result.mcc, expectedMcc);
- equal(result.mnc, expectedMnc);
- }
-
- // Test the imsi is null.
- do_test(null, null, null, null);
-
- // Test MCC is Taiwan
- do_test("466923202422409", 0x02, "466", "92");
- do_test("466923202422409", 0x03, "466", "923");
- do_test("466923202422409", null, "466", "92");
-
- // Test MCC is US
- do_test("310260542718417", 0x02, "310", "26");
- do_test("310260542718417", 0x03, "310", "260");
- do_test("310260542718417", null, "310", "260");
-
- run_next_test();
-});
-
-add_test(function test_get_network_name_from_icc() {
- let worker = newUint8Worker();
- let context = worker.ContextPool._contexts[0];
- let RIL = context.RIL;
- let ICCUtilsHelper = context.ICCUtilsHelper;
-
- function testGetNetworkNameFromICC(operatorData, expectedResult) {
- let result = ICCUtilsHelper.getNetworkNameFromICC(operatorData.mcc,
- operatorData.mnc,
- operatorData.lac);
-
- if (expectedResult == null) {
- equal(result, expectedResult);
- } else {
- equal(result.fullName, expectedResult.longName);
- equal(result.shortName, expectedResult.shortName);
- }
- }
-
- // Before EF_OPL and EF_PNN have been loaded.
- testGetNetworkNameFromICC({mcc: "123", mnc: "456", lac: 0x1000}, null);
- testGetNetworkNameFromICC({mcc: "321", mnc: "654", lac: 0x2000}, null);
-
- // Set HPLMN
- RIL.iccInfo.mcc = "123";
- RIL.iccInfo.mnc = "456";
-
- RIL.voiceRegistrationState = {
- cell: {
- gsmLocationAreaCode: 0x1000
- }
- };
- RIL.operator = {};
-
- // Set EF_PNN
- RIL.iccInfoPrivate = {
- PNN: [
- {"fullName": "PNN1Long", "shortName": "PNN1Short"},
- {"fullName": "PNN2Long", "shortName": "PNN2Short"},
- {"fullName": "PNN3Long", "shortName": "PNN3Short"},
- {"fullName": "PNN4Long", "shortName": "PNN4Short"},
- {"fullName": "PNN5Long", "shortName": "PNN5Short"},
- {"fullName": "PNN6Long", "shortName": "PNN6Short"},
- {"fullName": "PNN7Long", "shortName": "PNN7Short"},
- {"fullName": "PNN8Long", "shortName": "PNN8Short"}
- ]
- };
-
- // EF_OPL isn't available
- ICCUtilsHelper.isICCServiceAvailable = function fakeIsICCServiceAvailable(service) {
- return false;
- };
-
- // EF_OPL isn't available and current isn't in HPLMN,
- testGetNetworkNameFromICC({mcc: "321", mnc: "654", lac: 0x1000}, null);
-
- // EF_OPL isn't available and current is in HPLMN,
- // the first record of PNN should be returned.
- testGetNetworkNameFromICC({mcc: "123", mnc: "456", lac: 0x1000},
- {longName: "PNN1Long", shortName: "PNN1Short"});
-
- // EF_OPL is available
- ICCUtilsHelper.isICCServiceAvailable = function fakeIsICCServiceAvailable(service) {
- return service === "OPL";
- };
-
- // Set EF_OPL
- RIL.iccInfoPrivate.OPL = [
- {
- "mcc": "123",
- "mnc": "456",
- "lacTacStart": 0,
- "lacTacEnd": 0xFFFE,
- "pnnRecordId": 4
- },
- {
- "mcc": "321",
- "mnc": "654",
- "lacTacStart": 0,
- "lacTacEnd": 0x0010,
- "pnnRecordId": 3
- },
- {
- "mcc": "321",
- "mnc": "654",
- "lacTacStart": 0x0100,
- "lacTacEnd": 0x1010,
- "pnnRecordId": 2
- },
- {
- "mcc": ";;;",
- "mnc": "01",
- "lacTacStart": 0,
- "lacTacEnd": 0xFFFE,
- "pnnRecordId": 5
- },
- {
- "mcc": "00;",
- "mnc": "02",
- "lacTacStart": 0,
- "lacTacEnd": 0xFFFE,
- "pnnRecordId": 6
- },
- {
- "mcc": "001",
- "mnc": ";;",
- "lacTacStart": 0,
- "lacTacEnd": 0xFFFE,
- "pnnRecordId": 7
- },
- {
- "mcc": "002",
- "mnc": "0;",
- "lacTacStart": 0,
- "lacTacEnd": 0xFFFE,
- "pnnRecordId": 8
- }
- ];
-
- // Both EF_PNN and EF_OPL are presented, and current PLMN is HPLMN,
- testGetNetworkNameFromICC({mcc: "123", mnc: "456", lac: 0x1000},
- {longName: "PNN4Long", shortName: "PNN4Short"});
-
- // Current PLMN is not HPLMN, and according to LAC, we should get
- // the second PNN record.
- testGetNetworkNameFromICC({mcc: "321", mnc: "654", lac: 0x1000},
- {longName: "PNN2Long", shortName: "PNN2Short"});
-
- // Current PLMN is not HPLMN, and according to LAC, we should get
- // the thrid PNN record.
- testGetNetworkNameFromICC({mcc: "321", mnc: "654", lac: 0x0001},
- {longName: "PNN3Long", shortName: "PNN3Short"});
-
- // Current PLMN is not HPLMN, and according to LAC, we should get
- // the 5th PNN record after wild char (ie: ';') handling.
- testGetNetworkNameFromICC({mcc: "001", mnc: "01", lac: 0x0001},
- {longName: "PNN5Long", shortName: "PNN5Short"});
-
- // Current PLMN is not HPLMN, and according to LAC, we should get
- // the 6th PNN record after wild char (ie: ';') handling.
- testGetNetworkNameFromICC({mcc: "001", mnc: "02", lac: 0x0001},
- {longName: "PNN6Long", shortName: "PNN6Short"});
-
- // Current PLMN is not HPLMN, and according to LAC, we should get
- // the 7th PNN record after wild char (ie: ';') handling.
- testGetNetworkNameFromICC({mcc: "001", mnc: "03", lac: 0x0001},
- {longName: "PNN7Long", shortName: "PNN7Short"});
-
- // Current PLMN is not HPLMN, and according to LAC, we should get
- // the 8th PNN record after wild char (ie: ';') handling.
- testGetNetworkNameFromICC({mcc: "002", mnc: "03", lac: 0x0001},
- {longName: "PNN8Long", shortName: "PNN8Short"});
-
- run_next_test();
-});
-
-/**
- * Verify ICCUtilsHelper.isCphsServiceAvailable.
- */
-add_test(function test_is_cphs_service_available() {
- let worker = newUint8Worker();
- let context = worker.ContextPool._contexts[0];
- let ICCUtilsHelper = context.ICCUtilsHelper;
- let RIL = context.RIL;
- RIL.iccInfoPrivate.cphsSt = new Uint8Array(2);
-
- function test_table(cphsSt, geckoService) {
- RIL.iccInfoPrivate.cphsSt.set(cphsSt);
-
- for (let service in GECKO_ICC_SERVICES.cphs) {
- equal(ICCUtilsHelper.isCphsServiceAvailable(service),
- geckoService == service);
- }
- }
-
- test_table([0x03, 0x00], "CSP");
- test_table([0x0C, 0x00], "SST");
- test_table([0x30, 0x00], "MBN");
- test_table([0xC0, 0x00], "ONSF");
- test_table([0x00, 0x03], "INFO_NUM");
-
- run_next_test();
-});
diff --git a/dom/system/gonk/tests/test_ril_worker_icc_IconLoader.js b/dom/system/gonk/tests/test_ril_worker_icc_IconLoader.js
deleted file mode 100644
index 8bcd26ffea..0000000000
--- a/dom/system/gonk/tests/test_ril_worker_icc_IconLoader.js
+++ /dev/null
@@ -1,771 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-subscriptLoader.loadSubScript("resource://gre/modules/ril_consts.js", this);
-
-function run_test() {
- run_next_test();
-}
-
-/**
- * Verify IconLoader.loadIcons with recordNumbers array length being 1.
- * Query images of one record at a time.
- */
-add_test(function test_load_icon_basic() {
- let worker = newUint8Worker();
- let context = worker.ContextPool._contexts[0];
- let ril = context.RIL;
- let iconLoader = context.IconLoader;
- let simRecordHelper = context.SimRecordHelper;
-
- let test_data = [
- {rawData: [
- {codingScheme: ICC_IMG_CODING_SCHEME_BASIC,
- width: 0x10,
- height: 0x10,
- body: [0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00,
- 0x00, 0x9d, 0xe9, 0xa1, 0x2d, 0xa1, 0x2d, 0xa1, 0x2b,
- 0xa1, 0x2b, 0x9d, 0xe9, 0x00, 0x00, 0xff, 0xff, 0xff,
- 0xff, 0x00, 0x00, 0xff, 0xff]}],
- expected: [
- {width: 0x10,
- height: 0x10,
- pixels: [/* 1st byte of body: 0xff */
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0xffffffff,
- /* 2nd byte of body: 0xff */
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0xffffffff,
- /* 3rd byte of body: 0x00 */
- 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
- 0x000000ff, 0x000000ff, 0x000000ff,
- /* 4th byte of body: 0x00 */
- 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
- 0x000000ff, 0x000000ff, 0x000000ff,
- /* 5th byte of body: 0xff */
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0xffffffff,
- /* 6th byte of body: 0xff */
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0xffffffff,
- /* 7th byte of body: 0xff */
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0xffffffff,
- /* 8th byte of body: 0xff */
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0xffffffff,
- /* 9th byte of body: 0x00 */
- 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
- 0x000000ff, 0x000000ff, 0x000000ff,
- /* 10th byte of body: 0x00 */
- 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
- 0x000000ff, 0x000000ff, 0x000000ff,
- /* 11th byte of body: 0x9d */
- 0xffffffff, 0x000000ff, 0x000000ff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0x000000ff, 0xffffffff,
- /* 12th byte of body: 0xe9 */
- 0xffffffff, 0xffffffff, 0xffffffff, 0x000000ff, 0xffffffff,
- 0x000000ff, 0x000000ff, 0xffffffff,
- /* 13th byte of body: 0xa1 */
- 0xffffffff, 0x000000ff, 0xffffffff, 0x000000ff, 0x000000ff,
- 0x000000ff, 0x000000ff, 0xffffffff,
- /* 14th byte of body: 0x2d */
- 0x000000ff, 0x000000ff, 0xffffffff, 0x000000ff, 0xffffffff,
- 0xffffffff, 0x000000ff, 0xffffffff,
- /* 15th byte of body: 0xa1 */
- 0xffffffff, 0x000000ff, 0xffffffff, 0x000000ff, 0x000000ff,
- 0x000000ff, 0x000000ff, 0xffffffff,
- /* 16th byte of body: 0x2d */
- 0x000000ff, 0x000000ff, 0xffffffff, 0x000000ff, 0xffffffff,
- 0xffffffff, 0x000000ff, 0xffffffff,
- /* 17th byte of body: 0xa1 */
- 0xffffffff, 0x000000ff, 0xffffffff, 0x000000ff, 0x000000ff,
- 0x000000ff, 0x000000ff, 0xffffffff,
- /* 18th byte of body: 0x2b */
- 0x000000ff, 0x000000ff, 0xffffffff, 0x000000ff, 0xffffffff,
- 0x000000ff, 0xffffffff, 0xffffffff,
- /* 19th byte of body: 0xa1 */
- 0xffffffff, 0x000000ff, 0xffffffff, 0x000000ff, 0x000000ff,
- 0x000000ff, 0x000000ff, 0xffffffff,
- /* 20th byte of body: 0x2b */
- 0x000000ff, 0x000000ff, 0xffffffff, 0x000000ff, 0xffffffff,
- 0x000000ff, 0xffffffff, 0xffffffff,
- /* 21th byte of body: 0x9d */
- 0xffffffff, 0x000000ff, 0x000000ff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0x000000ff, 0xffffffff,
- /* 22th byte of body: 0xe9 */
- 0xffffffff, 0xffffffff, 0xffffffff, 0x000000ff, 0xffffffff,
- 0x000000ff, 0x000000ff, 0xffffffff,
- /* 23th byte of body: 0x00 */
- 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
- 0x000000ff, 0x000000ff, 0x000000ff,
- /* 24th byte of body: 0x00 */
- 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
- 0x000000ff, 0x000000ff, 0x000000ff,
- /* 25th byte of body: 0xff */
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0xffffffff,
- /* 26th byte of body: 0xff */
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0xffffffff,
- /* 27th byte of body: 0xff */
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0xffffffff,
- /* 28th byte of body: 0xff */
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0xffffffff,
- /* 29th byte of body: 0x00 */
- 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
- 0x000000ff, 0x000000ff, 0x000000ff,
- /* 30th byte of body: 0x00 */
- 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
- 0x000000ff, 0x000000ff, 0x000000ff,
- /* 31th byte of body: 0xff */
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0xffffffff,
- /* 32th byte of body: 0xff */
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0xffffffff]}]},
- {rawData: [
- {codingScheme: ICC_IMG_CODING_SCHEME_COLOR,
- width: 0x10,
- height: 0x10,
- bitsPerImgPoint: 0x04,
- numOfClutEntries: 0x10,
- body: [0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xaa, 0xaa,
- 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
- 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xcf, 0xfc, 0xcc, 0xfc, 0xcc,
- 0xcf, 0xcf, 0xfc, 0xcf, 0xcf, 0xff, 0xfc, 0xff, 0xcf,
- 0xcc, 0xfc, 0xcf, 0xcf, 0xff, 0xfc, 0xff, 0xcf, 0xcc,
- 0xfc, 0xcf, 0xcf, 0xff, 0xfc, 0xff, 0xcf, 0xcf, 0xcc,
- 0xcf, 0xcf, 0xff, 0xfc, 0xff, 0xcf, 0xcf, 0xcc, 0xcf,
- 0xfc, 0xcc, 0xfc, 0xcc, 0xcf, 0xcf, 0xfc, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xaa, 0xaa, 0xaa,
- 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
- 0xaa, 0xaa, 0xaa, 0xaa, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
- 0x99, 0x99],
- clut: [0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00,
- 0x80, 0x80, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x80,
- 0x00, 0x80, 0x80, 0xc0, 0xc0, 0xc0, 0x80, 0x80, 0x80,
- 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0xff, 0x00,
- 0x00, 0x00, 0xff, 0xff, 0x00, 0xff, 0x00, 0xff, 0xff,
- 0xff, 0xff, 0xff]}],
- expected: [
- {width: 0x10,
- height: 0x10,
- pixels: [0xff0000ff, 0xff0000ff, 0xff0000ff, 0xff0000ff, 0xff0000ff,
- 0xff0000ff, 0xff0000ff, 0xff0000ff, 0xff0000ff, 0xff0000ff,
- 0xff0000ff, 0xff0000ff, 0xff0000ff, 0xff0000ff, 0xff0000ff,
- 0xff0000ff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff,
- 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff,
- 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff,
- 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff,
- 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff,
- 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff,
- 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0x0000ffff, 0xffffffff, 0xffffffff, 0x0000ffff, 0x0000ffff,
- 0x0000ffff, 0xffffffff, 0x0000ffff, 0x0000ffff, 0x0000ffff,
- 0x0000ffff, 0xffffffff, 0x0000ffff, 0xffffffff, 0xffffffff,
- 0x0000ffff, 0x0000ffff, 0xffffffff, 0x0000ffff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0xffffffff, 0x0000ffff, 0xffffffff,
- 0xffffffff, 0x0000ffff, 0xffffffff, 0x0000ffff, 0x0000ffff,
- 0xffffffff, 0x0000ffff, 0x0000ffff, 0xffffffff, 0x0000ffff,
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0000ffff,
- 0xffffffff, 0xffffffff, 0x0000ffff, 0xffffffff, 0x0000ffff,
- 0x0000ffff, 0xffffffff, 0x0000ffff, 0x0000ffff, 0xffffffff,
- 0x0000ffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0x0000ffff, 0xffffffff, 0xffffffff, 0x0000ffff, 0xffffffff,
- 0x0000ffff, 0xffffffff, 0x0000ffff, 0x0000ffff, 0x0000ffff,
- 0xffffffff, 0x0000ffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0x0000ffff, 0xffffffff, 0xffffffff, 0x0000ffff,
- 0xffffffff, 0x0000ffff, 0xffffffff, 0x0000ffff, 0x0000ffff,
- 0x0000ffff, 0xffffffff, 0xffffffff, 0x0000ffff, 0x0000ffff,
- 0x0000ffff, 0xffffffff, 0x0000ffff, 0x0000ffff, 0x0000ffff,
- 0x0000ffff, 0xffffffff, 0x0000ffff, 0xffffffff, 0xffffffff,
- 0x0000ffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff,
- 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff,
- 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff,
- 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff,
- 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff,
- 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff,
- 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xff0000ff, 0xff0000ff, 0xff0000ff, 0xff0000ff, 0xff0000ff,
- 0xff0000ff, 0xff0000ff, 0xff0000ff, 0xff0000ff, 0xff0000ff,
- 0xff0000ff, 0xff0000ff, 0xff0000ff, 0xff0000ff, 0xff0000ff,
- 0xff0000ff]}]},
- {rawData: [
- {codingScheme: ICC_IMG_CODING_SCHEME_COLOR,
- width: 0x03,
- height: 0x03,
- bitsPerImgPoint: 0x05,
- numOfClutEntries: 0x20,
- body: [0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88],
- clut: [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
- 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11,
- 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a,
- 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23,
- 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c,
- 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
- 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e,
- 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
- 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50,
- 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
- 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f]},
- {codingScheme: ICC_IMG_CODING_SCHEME_BASIC,
- width: 0x10,
- height: 0x10,
- body: [0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00,
- 0x00, 0x9d, 0xe9, 0xa1, 0x2d, 0xa1, 0x2d, 0xa1, 0x2b,
- 0xa1, 0x2b, 0x9d, 0xe9, 0x00, 0x00, 0xff, 0xff, 0xff,
- 0xff, 0x00, 0x00, 0xff, 0xff]}],
- expected: [
- {width: 0x03,
- height: 0x03,
- pixels: [0x000102ff, 0x060708ff, 0x0c0d0eff, 0x121314ff, 0x18191aff,
- 0x1e1f20ff, 0x242526ff, 0x2a2b2cff, 0x333435ff]},
- {width: 0x10,
- height: 0x10,
- pixels: [/* 1st byte of body: 0xff */
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0xffffffff,
- /* 2nd byte of body: 0xff */
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0xffffffff,
- /* 3rd byte of body: 0x00 */
- 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
- 0x000000ff, 0x000000ff, 0x000000ff,
- /* 4th byte of body: 0x00 */
- 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
- 0x000000ff, 0x000000ff, 0x000000ff,
- /* 5th byte of body: 0xff */
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0xffffffff,
- /* 6th byte of body: 0xff */
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0xffffffff,
- /* 7th byte of body: 0xff */
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0xffffffff,
- /* 8th byte of body: 0xff */
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0xffffffff,
- /* 9th byte of body: 0x00 */
- 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
- 0x000000ff, 0x000000ff, 0x000000ff,
- /* 10th byte of body: 0x00 */
- 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
- 0x000000ff, 0x000000ff, 0x000000ff,
- /* 11th byte of body: 0x9d */
- 0xffffffff, 0x000000ff, 0x000000ff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0x000000ff, 0xffffffff,
- /* 12th byte of body: 0xe9 */
- 0xffffffff, 0xffffffff, 0xffffffff, 0x000000ff, 0xffffffff,
- 0x000000ff, 0x000000ff, 0xffffffff,
- /* 13th byte of body: 0xa1 */
- 0xffffffff, 0x000000ff, 0xffffffff, 0x000000ff, 0x000000ff,
- 0x000000ff, 0x000000ff, 0xffffffff,
- /* 14th byte of body: 0x2d */
- 0x000000ff, 0x000000ff, 0xffffffff, 0x000000ff, 0xffffffff,
- 0xffffffff, 0x000000ff, 0xffffffff,
- /* 15th byte of body: 0xa1 */
- 0xffffffff, 0x000000ff, 0xffffffff, 0x000000ff, 0x000000ff,
- 0x000000ff, 0x000000ff, 0xffffffff,
- /* 16th byte of body: 0x2d */
- 0x000000ff, 0x000000ff, 0xffffffff, 0x000000ff, 0xffffffff,
- 0xffffffff, 0x000000ff, 0xffffffff,
- /* 17th byte of body: 0xa1 */
- 0xffffffff, 0x000000ff, 0xffffffff, 0x000000ff, 0x000000ff,
- 0x000000ff, 0x000000ff, 0xffffffff,
- /* 18th byte of body: 0x2b */
- 0x000000ff, 0x000000ff, 0xffffffff, 0x000000ff, 0xffffffff,
- 0x000000ff, 0xffffffff, 0xffffffff,
- /* 19th byte of body: 0xa1 */
- 0xffffffff, 0x000000ff, 0xffffffff, 0x000000ff, 0x000000ff,
- 0x000000ff, 0x000000ff, 0xffffffff,
- /* 20th byte of body: 0x2b */
- 0x000000ff, 0x000000ff, 0xffffffff, 0x000000ff, 0xffffffff,
- 0x000000ff, 0xffffffff, 0xffffffff,
- /* 21th byte of body: 0x9d */
- 0xffffffff, 0x000000ff, 0x000000ff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0x000000ff, 0xffffffff,
- /* 22th byte of body: 0xe9 */
- 0xffffffff, 0xffffffff, 0xffffffff, 0x000000ff, 0xffffffff,
- 0x000000ff, 0x000000ff, 0xffffffff,
- /* 23th byte of body: 0x00 */
- 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
- 0x000000ff, 0x000000ff, 0x000000ff,
- /* 24th byte of body: 0x00 */
- 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
- 0x000000ff, 0x000000ff, 0x000000ff,
- /* 25th byte of body: 0xff */
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0xffffffff,
- /* 26th byte of body: 0xff */
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0xffffffff,
- /* 27th byte of body: 0xff */
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0xffffffff,
- /* 28th byte of body: 0xff */
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0xffffffff,
- /* 29th byte of body: 0x00 */
- 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
- 0x000000ff, 0x000000ff, 0x000000ff,
- /* 30th byte of body: 0x00 */
- 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
- 0x000000ff, 0x000000ff, 0x000000ff,
- /* 31th byte of body: 0xff */
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0xffffffff,
- /* 32th byte of body: 0xff */
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0xffffffff]}]},
- {rawData: [
- {codingScheme: ICC_IMG_CODING_SCHEME_COLOR_TRANSPARENCY,
- width: 0x04,
- height: 0x04,
- bitsPerImgPoint: 0x04,
- numOfClutEntries: 0x10,
- body: [0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa, 0x99, 0x88],
- clut: [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
- 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11,
- 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a,
- 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23,
- 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c,
- 0x2d, 0x2e, 0x2f]}],
- expected: [
- {width: 0x04,
- height: 0x04,
- pixels: [0x00000000, 0x00000000, 0x2a2b2cff, 0x2a2b2cff, 0x272829ff,
- 0x272829ff, 0x242526ff, 0x242526ff, 0x212223ff, 0x212223ff,
- 0x1e1f20ff, 0x1e1f20ff, 0x1b1c1dff, 0x1b1c1dff, 0x18191aff,
- 0x18191aff]}]}];
-
- function do_test(test_data, expected) {
- simRecordHelper.readIMG = function fakeReadIMG(recordNumber, onsuccess, onerror) {
- onsuccess(test_data);
- };
-
- let onsuccess = function(icons) {
- // Query one record at a time.
- equal(icons.length, 1);
- equal(icons[0].length, expected.length);
- for (let i = 0; i < icons[0].length; i++) {
- // Read the i_th image of the record.
- let icon = icons[0][i];
- let exp = expected[i];
- equal(icon.width, exp.width);
- equal(icon.height, exp.height);
- equal(icon.pixels.length, exp.pixels.length);
- for (let j = 0; j < icon.pixels.length; j++) {
- equal(icon.pixels[j], exp.pixels[j]);
- }
- }
- };
-
- iconLoader.loadIcons([0], onsuccess);
- }
-
- for (let i = 0; i < test_data.length; i++) {
- do_test(test_data[i].rawData, test_data[i].expected);
- }
-
- run_next_test();
-});
-
-/**
- * Verify IconLoader.loadIcons.
- */
-add_test(function test_load_icons() {
- let worker = newUint8Worker();
- let context = worker.ContextPool._contexts[0];
- let ril = context.RIL;
- let iconLoader = context.IconLoader;
- let simRecordHelper = context.SimRecordHelper;
-
- let test_data = {
- rawData: [
- // Record 1.
- [{codingScheme: ICC_IMG_CODING_SCHEME_BASIC,
- width: 0x10,
- height: 0x10,
- body: [0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00,
- 0x00, 0x9d, 0xe9, 0xa1, 0x2d, 0xa1, 0x2d, 0xa1, 0x2b,
- 0xa1, 0x2b, 0x9d, 0xe9, 0x00, 0x00, 0xff, 0xff, 0xff,
- 0xff, 0x00, 0x00, 0xff, 0xff]}],
- // Record 2.
- [{codingScheme: ICC_IMG_CODING_SCHEME_COLOR,
- width: 0x10,
- height: 0x10,
- bitsPerImgPoint: 0x04,
- numOfClutEntries: 0x10,
- body: [0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xaa, 0xaa,
- 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
- 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xcf, 0xfc, 0xcc, 0xfc, 0xcc,
- 0xcf, 0xcf, 0xfc, 0xcf, 0xcf, 0xff, 0xfc, 0xff, 0xcf,
- 0xcc, 0xfc, 0xcf, 0xcf, 0xff, 0xfc, 0xff, 0xcf, 0xcc,
- 0xfc, 0xcf, 0xcf, 0xff, 0xfc, 0xff, 0xcf, 0xcf, 0xcc,
- 0xcf, 0xcf, 0xff, 0xfc, 0xff, 0xcf, 0xcf, 0xcc, 0xcf,
- 0xfc, 0xcc, 0xfc, 0xcc, 0xcf, 0xcf, 0xfc, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xaa, 0xaa, 0xaa,
- 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
- 0xaa, 0xaa, 0xaa, 0xaa, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
- 0x99, 0x99],
- clut: [0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00,
- 0x80, 0x80, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x80,
- 0x00, 0x80, 0x80, 0xc0, 0xc0, 0xc0, 0x80, 0x80, 0x80,
- 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0xff, 0x00,
- 0x00, 0x00, 0xff, 0xff, 0x00, 0xff, 0x00, 0xff, 0xff,
- 0xff, 0xff, 0xff]}],
- // Record 3.
- [{codingScheme: ICC_IMG_CODING_SCHEME_COLOR,
- width: 0x03,
- height: 0x03,
- bitsPerImgPoint: 0x05,
- numOfClutEntries: 0x20,
- body: [0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88],
- clut: [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
- 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11,
- 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a,
- 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23,
- 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c,
- 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
- 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e,
- 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
- 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50,
- 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
- 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f]},
- {codingScheme: ICC_IMG_CODING_SCHEME_BASIC,
- width: 0x10,
- height: 0x10,
- body: [0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00,
- 0x00, 0x9d, 0xe9, 0xa1, 0x2d, 0xa1, 0x2d, 0xa1, 0x2b,
- 0xa1, 0x2b, 0x9d, 0xe9, 0x00, 0x00, 0xff, 0xff, 0xff,
- 0xff, 0x00, 0x00, 0xff, 0xff]}],
- // Record 4.
- [{codingScheme: ICC_IMG_CODING_SCHEME_COLOR_TRANSPARENCY,
- width: 0x04,
- height: 0x04,
- bitsPerImgPoint: 0x04,
- numOfClutEntries: 0x10,
- body: [0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa, 0x99, 0x88],
- clut: [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
- 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11,
- 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a,
- 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23,
- 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c,
- 0x2d, 0x2e, 0x2f]}]],
- expected: [
- // Record 1.
- [{width: 0x10,
- height: 0x10,
- pixels: [/* 1st byte of body: 0xff */
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0xffffffff,
- /* 2nd byte of body: 0xff */
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0xffffffff,
- /* 3rd byte of body: 0x00 */
- 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
- 0x000000ff, 0x000000ff, 0x000000ff,
- /* 4th byte of body: 0x00 */
- 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
- 0x000000ff, 0x000000ff, 0x000000ff,
- /* 5th byte of body: 0xff */
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0xffffffff,
- /* 6th byte of body: 0xff */
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0xffffffff,
- /* 7th byte of body: 0xff */
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0xffffffff,
- /* 8th byte of body: 0xff */
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0xffffffff,
- /* 9th byte of body: 0x00 */
- 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
- 0x000000ff, 0x000000ff, 0x000000ff,
- /* 10th byte of body: 0x00 */
- 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
- 0x000000ff, 0x000000ff, 0x000000ff,
- /* 11th byte of body: 0x9d */
- 0xffffffff, 0x000000ff, 0x000000ff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0x000000ff, 0xffffffff,
- /* 12th byte of body: 0xe9 */
- 0xffffffff, 0xffffffff, 0xffffffff, 0x000000ff, 0xffffffff,
- 0x000000ff, 0x000000ff, 0xffffffff,
- /* 13th byte of body: 0xa1 */
- 0xffffffff, 0x000000ff, 0xffffffff, 0x000000ff, 0x000000ff,
- 0x000000ff, 0x000000ff, 0xffffffff,
- /* 14th byte of body: 0x2d */
- 0x000000ff, 0x000000ff, 0xffffffff, 0x000000ff, 0xffffffff,
- 0xffffffff, 0x000000ff, 0xffffffff,
- /* 15th byte of body: 0xa1 */
- 0xffffffff, 0x000000ff, 0xffffffff, 0x000000ff, 0x000000ff,
- 0x000000ff, 0x000000ff, 0xffffffff,
- /* 16th byte of body: 0x2d */
- 0x000000ff, 0x000000ff, 0xffffffff, 0x000000ff, 0xffffffff,
- 0xffffffff, 0x000000ff, 0xffffffff,
- /* 17th byte of body: 0xa1 */
- 0xffffffff, 0x000000ff, 0xffffffff, 0x000000ff, 0x000000ff,
- 0x000000ff, 0x000000ff, 0xffffffff,
- /* 18th byte of body: 0x2b */
- 0x000000ff, 0x000000ff, 0xffffffff, 0x000000ff, 0xffffffff,
- 0x000000ff, 0xffffffff, 0xffffffff,
- /* 19th byte of body: 0xa1 */
- 0xffffffff, 0x000000ff, 0xffffffff, 0x000000ff, 0x000000ff,
- 0x000000ff, 0x000000ff, 0xffffffff,
- /* 20th byte of body: 0x2b */
- 0x000000ff, 0x000000ff, 0xffffffff, 0x000000ff, 0xffffffff,
- 0x000000ff, 0xffffffff, 0xffffffff,
- /* 21th byte of body: 0x9d */
- 0xffffffff, 0x000000ff, 0x000000ff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0x000000ff, 0xffffffff,
- /* 22th byte of body: 0xe9 */
- 0xffffffff, 0xffffffff, 0xffffffff, 0x000000ff, 0xffffffff,
- 0x000000ff, 0x000000ff, 0xffffffff,
- /* 23th byte of body: 0x00 */
- 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
- 0x000000ff, 0x000000ff, 0x000000ff,
- /* 24th byte of body: 0x00 */
- 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
- 0x000000ff, 0x000000ff, 0x000000ff,
- /* 25th byte of body: 0xff */
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0xffffffff,
- /* 26th byte of body: 0xff */
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0xffffffff,
- /* 27th byte of body: 0xff */
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0xffffffff,
- /* 28th byte of body: 0xff */
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0xffffffff,
- /* 29th byte of body: 0x00 */
- 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
- 0x000000ff, 0x000000ff, 0x000000ff,
- /* 30th byte of body: 0x00 */
- 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
- 0x000000ff, 0x000000ff, 0x000000ff,
- /* 31th byte of body: 0xff */
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0xffffffff,
- /* 32th byte of body: 0xff */
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0xffffffff]}],
- // Record 2.
- [{width: 0x10,
- height: 0x10,
- pixels: [0xff0000ff, 0xff0000ff, 0xff0000ff, 0xff0000ff, 0xff0000ff,
- 0xff0000ff, 0xff0000ff, 0xff0000ff, 0xff0000ff, 0xff0000ff,
- 0xff0000ff, 0xff0000ff, 0xff0000ff, 0xff0000ff, 0xff0000ff,
- 0xff0000ff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff,
- 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff,
- 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff,
- 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff,
- 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff,
- 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff,
- 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0x0000ffff, 0xffffffff, 0xffffffff, 0x0000ffff, 0x0000ffff,
- 0x0000ffff, 0xffffffff, 0x0000ffff, 0x0000ffff, 0x0000ffff,
- 0x0000ffff, 0xffffffff, 0x0000ffff, 0xffffffff, 0xffffffff,
- 0x0000ffff, 0x0000ffff, 0xffffffff, 0x0000ffff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0xffffffff, 0x0000ffff, 0xffffffff,
- 0xffffffff, 0x0000ffff, 0xffffffff, 0x0000ffff, 0x0000ffff,
- 0xffffffff, 0x0000ffff, 0x0000ffff, 0xffffffff, 0x0000ffff,
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0000ffff,
- 0xffffffff, 0xffffffff, 0x0000ffff, 0xffffffff, 0x0000ffff,
- 0x0000ffff, 0xffffffff, 0x0000ffff, 0x0000ffff, 0xffffffff,
- 0x0000ffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0x0000ffff, 0xffffffff, 0xffffffff, 0x0000ffff, 0xffffffff,
- 0x0000ffff, 0xffffffff, 0x0000ffff, 0x0000ffff, 0x0000ffff,
- 0xffffffff, 0x0000ffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0x0000ffff, 0xffffffff, 0xffffffff, 0x0000ffff,
- 0xffffffff, 0x0000ffff, 0xffffffff, 0x0000ffff, 0x0000ffff,
- 0x0000ffff, 0xffffffff, 0xffffffff, 0x0000ffff, 0x0000ffff,
- 0x0000ffff, 0xffffffff, 0x0000ffff, 0x0000ffff, 0x0000ffff,
- 0x0000ffff, 0xffffffff, 0x0000ffff, 0xffffffff, 0xffffffff,
- 0x0000ffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff,
- 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff,
- 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff,
- 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff,
- 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff,
- 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff,
- 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xff0000ff, 0xff0000ff, 0xff0000ff, 0xff0000ff, 0xff0000ff,
- 0xff0000ff, 0xff0000ff, 0xff0000ff, 0xff0000ff, 0xff0000ff,
- 0xff0000ff, 0xff0000ff, 0xff0000ff, 0xff0000ff, 0xff0000ff,
- 0xff0000ff]}],
- // Record 3.
- [{width: 0x03,
- height: 0x03,
- pixels: [0x000102ff, 0x060708ff, 0x0c0d0eff, 0x121314ff, 0x18191aff,
- 0x1e1f20ff, 0x242526ff, 0x2a2b2cff, 0x333435ff]},
- {width: 0x10,
- height: 0x10,
- pixels: [/* 1st byte of body: 0xff */
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0xffffffff,
- /* 2nd byte of body: 0xff */
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0xffffffff,
- /* 3rd byte of body: 0x00 */
- 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
- 0x000000ff, 0x000000ff, 0x000000ff,
- /* 4th byte of body: 0x00 */
- 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
- 0x000000ff, 0x000000ff, 0x000000ff,
- /* 5th byte of body: 0xff */
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0xffffffff,
- /* 6th byte of body: 0xff */
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0xffffffff,
- /* 7th byte of body: 0xff */
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0xffffffff,
- /* 8th byte of body: 0xff */
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0xffffffff,
- /* 9th byte of body: 0x00 */
- 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
- 0x000000ff, 0x000000ff, 0x000000ff,
- /* 10th byte of body: 0x00 */
- 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
- 0x000000ff, 0x000000ff, 0x000000ff,
- /* 11th byte of body: 0x9d */
- 0xffffffff, 0x000000ff, 0x000000ff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0x000000ff, 0xffffffff,
- /* 12th byte of body: 0xe9 */
- 0xffffffff, 0xffffffff, 0xffffffff, 0x000000ff, 0xffffffff,
- 0x000000ff, 0x000000ff, 0xffffffff,
- /* 13th byte of body: 0xa1 */
- 0xffffffff, 0x000000ff, 0xffffffff, 0x000000ff, 0x000000ff,
- 0x000000ff, 0x000000ff, 0xffffffff,
- /* 14th byte of body: 0x2d */
- 0x000000ff, 0x000000ff, 0xffffffff, 0x000000ff, 0xffffffff,
- 0xffffffff, 0x000000ff, 0xffffffff,
- /* 15th byte of body: 0xa1 */
- 0xffffffff, 0x000000ff, 0xffffffff, 0x000000ff, 0x000000ff,
- 0x000000ff, 0x000000ff, 0xffffffff,
- /* 16th byte of body: 0x2d */
- 0x000000ff, 0x000000ff, 0xffffffff, 0x000000ff, 0xffffffff,
- 0xffffffff, 0x000000ff, 0xffffffff,
- /* 17th byte of body: 0xa1 */
- 0xffffffff, 0x000000ff, 0xffffffff, 0x000000ff, 0x000000ff,
- 0x000000ff, 0x000000ff, 0xffffffff,
- /* 18th byte of body: 0x2b */
- 0x000000ff, 0x000000ff, 0xffffffff, 0x000000ff, 0xffffffff,
- 0x000000ff, 0xffffffff, 0xffffffff,
- /* 19th byte of body: 0xa1 */
- 0xffffffff, 0x000000ff, 0xffffffff, 0x000000ff, 0x000000ff,
- 0x000000ff, 0x000000ff, 0xffffffff,
- /* 20th byte of body: 0x2b */
- 0x000000ff, 0x000000ff, 0xffffffff, 0x000000ff, 0xffffffff,
- 0x000000ff, 0xffffffff, 0xffffffff,
- /* 21th byte of body: 0x9d */
- 0xffffffff, 0x000000ff, 0x000000ff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0x000000ff, 0xffffffff,
- /* 22th byte of body: 0xe9 */
- 0xffffffff, 0xffffffff, 0xffffffff, 0x000000ff, 0xffffffff,
- 0x000000ff, 0x000000ff, 0xffffffff,
- /* 23th byte of body: 0x00 */
- 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
- 0x000000ff, 0x000000ff, 0x000000ff,
- /* 24th byte of body: 0x00 */
- 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
- 0x000000ff, 0x000000ff, 0x000000ff,
- /* 25th byte of body: 0xff */
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0xffffffff,
- /* 26th byte of body: 0xff */
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0xffffffff,
- /* 27th byte of body: 0xff */
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0xffffffff,
- /* 28th byte of body: 0xff */
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0xffffffff,
- /* 29th byte of body: 0x00 */
- 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
- 0x000000ff, 0x000000ff, 0x000000ff,
- /* 30th byte of body: 0x00 */
- 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
- 0x000000ff, 0x000000ff, 0x000000ff,
- /* 31th byte of body: 0xff */
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0xffffffff,
- /* 32th byte of body: 0xff */
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0xffffffff]}],
- // Record 4.
- [{width: 0x04,
- height: 0x04,
- pixels: [0x00000000, 0x00000000, 0x2a2b2cff, 0x2a2b2cff, 0x272829ff,
- 0x272829ff, 0x242526ff, 0x242526ff, 0x212223ff, 0x212223ff,
- 0x1e1f20ff, 0x1e1f20ff, 0x1b1c1dff, 0x1b1c1dff, 0x18191aff,
- 0x18191aff]}]]};
-
- function do_test() {
- simRecordHelper.readIMG = function fakeReadIMG(recordNumber, onsuccess, onerror) {
- onsuccess(test_data.rawData[recordNumber]);
- };
-
- let onsuccess = function(icons) {
- equal(icons.length, test_data.expected.length);
- for (let i = 0; i < icons.length; i++) {
- for (let j = 0; j < icons[i].length; j++) {
- // Read the j_th image from the i_th record.
- let icon = icons[i][j];
- let expected = test_data.expected[i][j];
- equal(icon.width, expected.width);
- equal(icon.height, expected.height);
- equal(icon.pixels.length, expected.pixels.length);
- for (let k = 0; k < icon.pixels.length; k++) {
- equal(icon.pixels[k], expected.pixels[k]);
- }
- }
- }
- };
-
- let recordNumbers = [0, 1, 2, 3];
- iconLoader.loadIcons(recordNumbers, onsuccess);
- }
-
- do_test();
- run_next_test();
-});
diff --git a/dom/system/gonk/tests/test_ril_worker_icc_SimRecordHelper.js b/dom/system/gonk/tests/test_ril_worker_icc_SimRecordHelper.js
deleted file mode 100644
index 6500cc663a..0000000000
--- a/dom/system/gonk/tests/test_ril_worker_icc_SimRecordHelper.js
+++ /dev/null
@@ -1,1648 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-subscriptLoader.loadSubScript("resource://gre/modules/ril_consts.js", this);
-
-function run_test() {
- run_next_test();
-}
-
-/**
- * Verify reading EF_AD and parsing MCC/MNC
- */
-add_test(function test_reading_ad_and_parsing_mcc_mnc() {
- let worker = newUint8Worker();
- let context = worker.ContextPool._contexts[0];
- let record = context.SimRecordHelper;
- let helper = context.GsmPDUHelper;
- let ril = context.RIL;
- let buf = context.Buf;
- let io = context.ICCIOHelper;
-
- function do_test(mncLengthInEf, imsi, expectedMcc, expectedMnc) {
- ril.iccInfoPrivate.imsi = imsi;
-
- io.loadTransparentEF = function fakeLoadTransparentEF(options) {
- let ad = [0x00, 0x00, 0x00];
- if (typeof mncLengthInEf === 'number') {
- ad.push(mncLengthInEf);
- }
-
- // Write data size
- buf.writeInt32(ad.length * 2);
-
- // Write data
- for (let i = 0; i < ad.length; i++) {
- helper.writeHexOctet(ad[i]);
- }
-
- // Write string delimiter
- buf.writeStringDelimiter(ad.length * 2);
-
- if (options.callback) {
- options.callback(options);
- }
- };
-
- record.readAD();
-
- equal(ril.iccInfo.mcc, expectedMcc);
- equal(ril.iccInfo.mnc, expectedMnc);
- }
-
- do_test(undefined, "466923202422409", "466", "92" );
- do_test(0x00, "466923202422409", "466", "92" );
- do_test(0x01, "466923202422409", "466", "92" );
- do_test(0x02, "466923202422409", "466", "92" );
- do_test(0x03, "466923202422409", "466", "923");
- do_test(0x04, "466923202422409", "466", "92" );
- do_test(0xff, "466923202422409", "466", "92" );
-
- do_test(undefined, "310260542718417", "310", "260");
- do_test(0x00, "310260542718417", "310", "260");
- do_test(0x01, "310260542718417", "310", "260");
- do_test(0x02, "310260542718417", "310", "26" );
- do_test(0x03, "310260542718417", "310", "260");
- do_test(0x04, "310260542718417", "310", "260");
- do_test(0xff, "310260542718417", "310", "260");
-
- run_next_test();
-});
-
-add_test(function test_reading_optional_efs() {
- let worker = newUint8Worker();
- let context = worker.ContextPool._contexts[0];
- let record = context.SimRecordHelper;
- let gsmPdu = context.GsmPDUHelper;
- let ril = context.RIL;
- let buf = context.Buf;
- let io = context.ICCIOHelper;
-
- function buildSST(supportedEf) {
- let sst = [];
- let len = supportedEf.length;
- for (let i = 0; i < len; i++) {
- let index, bitmask, iccService;
- if (ril.appType === CARD_APPTYPE_SIM) {
- iccService = GECKO_ICC_SERVICES.sim[supportedEf[i]];
- iccService -= 1;
- index = Math.floor(iccService / 4);
- bitmask = 2 << ((iccService % 4) << 1);
- } else if (ril.appType === CARD_APPTYPE_USIM){
- iccService = GECKO_ICC_SERVICES.usim[supportedEf[i]];
- iccService -= 1;
- index = Math.floor(iccService / 8);
- bitmask = 1 << ((iccService % 8) << 0);
- }
-
- if (sst) {
- sst[index] |= bitmask;
- }
- }
- return sst;
- }
-
- ril.updateCellBroadcastConfig = function fakeUpdateCellBroadcastConfig() {
- // Ignore updateCellBroadcastConfig after reading SST
- };
-
- function do_test(sst, supportedEf) {
- // Clone supportedEf to local array for testing
- let testEf = supportedEf.slice(0);
-
- record.readMSISDN = function fakeReadMSISDN() {
- testEf.splice(testEf.indexOf("MSISDN"), 1);
- };
-
- record.readMBDN = function fakeReadMBDN() {
- testEf.splice(testEf.indexOf("MDN"), 1);
- };
-
- record.readMWIS = function fakeReadMWIS() {
- testEf.splice(testEf.indexOf("MWIS"), 1);
- };
-
- io.loadTransparentEF = function fakeLoadTransparentEF(options) {
- // Write data size
- buf.writeInt32(sst.length * 2);
-
- // Write data
- for (let i = 0; i < sst.length; i++) {
- gsmPdu.writeHexOctet(sst[i] || 0);
- }
-
- // Write string delimiter
- buf.writeStringDelimiter(sst.length * 2);
-
- if (options.callback) {
- options.callback(options);
- }
-
- if (testEf.length !== 0) {
- do_print("Un-handled EF: " + JSON.stringify(testEf));
- ok(false);
- }
- };
-
- record.readSST();
- }
-
- // TODO: Add all necessary optional EFs eventually
- let supportedEf = ["MSISDN", "MDN", "MWIS"];
- ril.appType = CARD_APPTYPE_SIM;
- do_test(buildSST(supportedEf), supportedEf);
- ril.appType = CARD_APPTYPE_USIM;
- do_test(buildSST(supportedEf), supportedEf);
-
- run_next_test();
-});
-
-/**
- * Verify fetchSimRecords.
- */
-add_test(function test_fetch_sim_records() {
- let worker = newWorker();
- let context = worker.ContextPool._contexts[0];
- let RIL = context.RIL;
- let iccRecord = context.ICCRecordHelper;
- let simRecord = context.SimRecordHelper;
-
- function testFetchSimRecordes(expectCalled, expectCphsSuccess) {
- let ifCalled = [];
-
- RIL.getIMSI = function() {
- ifCalled.push("getIMSI");
- };
-
- simRecord.readAD = function() {
- ifCalled.push("readAD");
- };
-
- simRecord.readCphsInfo = function(onsuccess, onerror) {
- ifCalled.push("readCphsInfo");
- if (expectCphsSuccess) {
- onsuccess();
- } else {
- onerror();
- }
- };
-
- simRecord.readSST = function() {
- ifCalled.push("readSST");
- };
-
- simRecord.fetchSimRecords();
-
- for (let i = 0; i < expectCalled.length; i++ ) {
- if (ifCalled[i] != expectCalled[i]) {
- do_print(expectCalled[i] + " is not called.");
- ok(false);
- }
- }
- }
-
- let expectCalled = ["getIMSI", "readAD", "readCphsInfo", "readSST"];
- testFetchSimRecordes(expectCalled, true);
- testFetchSimRecordes(expectCalled, false);
-
- run_next_test();
-});
-
-/**
- * Verify SimRecordHelper.readMWIS
- */
-add_test(function test_read_mwis() {
- let worker = newUint8Worker();
- let context = worker.ContextPool._contexts[0];
- let helper = context.GsmPDUHelper;
- let recordHelper = context.SimRecordHelper;
- let buf = context.Buf;
- let io = context.ICCIOHelper;
- let mwisData;
- let postedMessage;
-
- worker.postMessage = function fakePostMessage(message) {
- postedMessage = message;
- };
-
- io.loadLinearFixedEF = function fakeLoadLinearFixedEF(options) {
- if (mwisData) {
- // Write data size
- buf.writeInt32(mwisData.length * 2);
-
- // Write MWIS
- for (let i = 0; i < mwisData.length; i++) {
- helper.writeHexOctet(mwisData[i]);
- }
-
- // Write string delimiter
- buf.writeStringDelimiter(mwisData.length * 2);
-
- options.recordSize = mwisData.length;
- if (options.callback) {
- options.callback(options);
- }
- } else {
- do_print("mwisData[] is not set.");
- }
- };
-
- function buildMwisData(isActive, msgCount) {
- if (msgCount < 0 || msgCount === GECKO_VOICEMAIL_MESSAGE_COUNT_UNKNOWN) {
- msgCount = 0;
- } else if (msgCount > 255) {
- msgCount = 255;
- }
-
- mwisData = [ (isActive) ? 0x01 : 0x00,
- msgCount,
- 0xFF, 0xFF, 0xFF ];
- }
-
- function do_test(isActive, msgCount) {
- buildMwisData(isActive, msgCount);
- recordHelper.readMWIS();
-
- equal("iccmwis", postedMessage.rilMessageType);
- equal(isActive, postedMessage.mwi.active);
- equal((isActive) ? msgCount : 0, postedMessage.mwi.msgCount);
- }
-
- do_test(true, GECKO_VOICEMAIL_MESSAGE_COUNT_UNKNOWN);
- do_test(true, 1);
- do_test(true, 255);
-
- do_test(false, 0);
- do_test(false, 255); // Test the corner case when mwi is disable with incorrect msgCount.
-
- run_next_test();
-});
-
-/**
- * Verify SimRecordHelper.updateMWIS
- */
-add_test(function test_update_mwis() {
- let worker = newUint8Worker();
- let context = worker.ContextPool._contexts[0];
- let pduHelper = context.GsmPDUHelper;
- let ril = context.RIL;
- ril.appType = CARD_APPTYPE_USIM;
- ril.iccInfoPrivate.mwis = [0x00, 0x00, 0x00, 0x00, 0x00];
- let recordHelper = context.SimRecordHelper;
- let buf = context.Buf;
- let ioHelper = context.ICCIOHelper;
- let recordSize = ril.iccInfoPrivate.mwis.length;
- let recordNum = 1;
-
- ioHelper.updateLinearFixedEF = function(options) {
- options.pathId = context.ICCFileHelper.getEFPath(options.fileId);
- options.command = ICC_COMMAND_UPDATE_RECORD;
- options.p1 = options.recordNumber;
- options.p2 = READ_RECORD_ABSOLUTE_MODE;
- options.p3 = recordSize;
- ril.iccIO(options);
- };
-
- function do_test(isActive, count) {
- let mwis = ril.iccInfoPrivate.mwis;
- let isUpdated = false;
-
- function buildMwisData() {
- let result = mwis.slice(0);
- result[0] = isActive? (mwis[0] | 0x01) : (mwis[0] & 0xFE);
- result[1] = (count === GECKO_VOICEMAIL_MESSAGE_COUNT_UNKNOWN) ? 0 : count;
-
- return result;
- }
-
- buf.sendParcel = function() {
- isUpdated = true;
-
- // Request Type.
- equal(this.readInt32(), REQUEST_SIM_IO);
-
- // Token : we don't care
- this.readInt32();
-
- // command.
- equal(this.readInt32(), ICC_COMMAND_UPDATE_RECORD);
-
- // fileId.
- equal(this.readInt32(), ICC_EF_MWIS);
-
- // pathId.
- equal(this.readString(),
- EF_PATH_MF_SIM + ((ril.appType === CARD_APPTYPE_USIM) ? EF_PATH_ADF_USIM : EF_PATH_DF_GSM));
-
- // p1.
- equal(this.readInt32(), recordNum);
-
- // p2.
- equal(this.readInt32(), READ_RECORD_ABSOLUTE_MODE);
-
- // p3.
- equal(this.readInt32(), recordSize);
-
- // data.
- let strLen = this.readInt32();
- equal(recordSize * 2, strLen);
- let expectedMwis = buildMwisData();
- for (let i = 0; i < recordSize; i++) {
- equal(expectedMwis[i], pduHelper.readHexOctet());
- }
- this.readStringDelimiter(strLen);
-
- // pin2.
- equal(this.readString(), null);
-
- // AID. Ignore because it's from modem.
- this.readInt32();
- };
-
- ok(!isUpdated);
-
- recordHelper.updateMWIS({ active: isActive,
- msgCount: count });
-
- ok((ril.iccInfoPrivate.mwis) ? isUpdated : !isUpdated);
- }
-
- do_test(true, GECKO_VOICEMAIL_MESSAGE_COUNT_UNKNOWN);
- do_test(true, 1);
- do_test(true, 255);
-
- do_test(false, 0);
-
- // Test if Path ID is correct for SIM.
- ril.appType = CARD_APPTYPE_SIM;
- do_test(false, 0);
-
- // Test if loadLinearFixedEF() is not invoked in updateMWIS() when
- // EF_MWIS is not loaded/available.
- delete ril.iccInfoPrivate.mwis;
- do_test(false, 0);
-
- run_next_test();
-});
-
-/**
- * Verify the call flow of receiving Class 2 SMS stored in SIM:
- * 1. UNSOLICITED_RESPONSE_NEW_SMS_ON_SIM.
- * 2. SimRecordHelper.readSMS().
- * 3. sendChromeMessage() with rilMessageType == "sms-received".
- */
-add_test(function test_read_new_sms_on_sim() {
- // Instead of reusing newUint8Worker defined in this file,
- // we define our own worker to fake the methods in WorkerBuffer dynamically.
- function newSmsOnSimWorkerHelper() {
- let _postedMessage;
- let _worker = newWorker({
- postRILMessage: function(data) {
- },
- postMessage: function(message) {
- _postedMessage = message;
- }
- });
-
- _worker.debug = do_print;
-
- return {
- get postedMessage() {
- return _postedMessage;
- },
- get worker() {
- return _worker;
- },
- fakeWokerBuffer: function() {
- let context = _worker.ContextPool._contexts[0];
- let index = 0; // index for read
- let buf = [];
- context.Buf.writeUint8 = function(value) {
- buf.push(value);
- };
- context.Buf.readUint8 = function() {
- return buf[index++];
- };
- context.Buf.seekIncoming = function(offset) {
- index += offset;
- };
- context.Buf.getReadAvailable = function() {
- return buf.length - index;
- };
- }
- };
- }
-
- let workerHelper = newSmsOnSimWorkerHelper();
- let worker = workerHelper.worker;
- let context = worker.ContextPool._contexts[0];
-
- context.ICCIOHelper.loadLinearFixedEF = function fakeLoadLinearFixedEF(options) {
- // SimStatus: Unread, SMSC:+0123456789, Sender: +9876543210, Text: How are you?
- let SimSmsPduHex = "0306911032547698040A9189674523010000208062917314080CC8F71D14969741F977FD07"
- // In 4.2.25 EF_SMS Short Messages of 3GPP TS 31.102:
- // 1. Record length == 176 bytes.
- // 2. Any bytes in the record following the TPDU shall be filled with 'FF'.
- + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
- + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
- + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
- + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF";
-
- workerHelper.fakeWokerBuffer();
-
- context.Buf.writeString(SimSmsPduHex);
-
- options.recordSize = 176; // Record length is fixed to 176 bytes.
- if (options.callback) {
- options.callback(options);
- }
- };
-
- function newSmsOnSimParcel() {
- let data = new Uint8Array(4 + 4); // Int32List with 1 element.
- let offset = 0;
-
- function writeInt(value) {
- data[offset++] = value & 0xFF;
- data[offset++] = (value >> 8) & 0xFF;
- data[offset++] = (value >> 16) & 0xFF;
- data[offset++] = (value >> 24) & 0xFF;
- }
-
- writeInt(1); // Length of Int32List
- writeInt(1); // RecordNum = 1.
-
- return newIncomingParcel(-1,
- RESPONSE_TYPE_UNSOLICITED,
- UNSOLICITED_RESPONSE_NEW_SMS_ON_SIM,
- data);
- }
-
- function do_test() {
- worker.onRILMessage(0, newSmsOnSimParcel());
-
- let postedMessage = workerHelper.postedMessage;
-
- equal("sms-received", postedMessage.rilMessageType);
- equal("+0123456789", postedMessage.SMSC);
- equal("+9876543210", postedMessage.sender);
- equal("How are you?", postedMessage.body);
- }
-
- do_test();
-
- run_next_test();
-});
-
-/**
- * Verify the result of updateDisplayCondition after reading EF_SPDI | EF_SPN.
- */
-add_test(function test_update_display_condition() {
- let worker = newUint8Worker();
- let context = worker.ContextPool._contexts[0];
- let record = context.SimRecordHelper;
- let helper = context.GsmPDUHelper;
- let ril = context.RIL;
- let buf = context.Buf;
- let io = context.ICCIOHelper;
-
- function do_test_spdi() {
- // No EF_SPN, but having EF_SPDI.
- // It implies "ril.iccInfoPrivate.spnDisplayCondition = undefined;".
- io.loadTransparentEF = function fakeLoadTransparentEF(options) {
- // PLMN lists are : 234-136 and 466-92.
- let spdi = [0xA3, 0x0B, 0x80, 0x09, 0x32, 0x64, 0x31, 0x64, 0x26, 0x9F,
- 0xFF, 0xFF, 0xFF];
-
- // Write data size.
- buf.writeInt32(spdi.length * 2);
-
- // Write data.
- for (let i = 0; i < spdi.length; i++) {
- helper.writeHexOctet(spdi[i]);
- }
-
- // Write string delimiter.
- buf.writeStringDelimiter(spdi.length * 2);
-
- if (options.callback) {
- options.callback(options);
- }
- };
-
- record.readSPDI();
-
- equal(ril.iccInfo.isDisplayNetworkNameRequired, true);
- equal(ril.iccInfo.isDisplaySpnRequired, false);
- }
-
- function do_test_spn(displayCondition,
- expectedPlmnNameDisplay,
- expectedSpnDisplay) {
- io.loadTransparentEF = function fakeLoadTransparentEF(options) {
- // "Android" as Service Provider Name.
- let spn = [0x41, 0x6E, 0x64, 0x72, 0x6F, 0x69, 0x64];
- if (typeof displayCondition === 'number') {
- spn.unshift(displayCondition);
- }
-
- // Write data size.
- buf.writeInt32(spn.length * 2);
-
- // Write data.
- for (let i = 0; i < spn.length; i++) {
- helper.writeHexOctet(spn[i]);
- }
-
- // Write string delimiter.
- buf.writeStringDelimiter(spn.length * 2);
-
- if (options.callback) {
- options.callback(options);
- }
- };
-
- record.readSPN();
-
- equal(ril.iccInfo.isDisplayNetworkNameRequired, expectedPlmnNameDisplay);
- equal(ril.iccInfo.isDisplaySpnRequired, expectedSpnDisplay);
- }
-
- // Create empty operator object.
- ril.operator = {};
- // Setup SIM MCC-MNC to 310-260 as home network.
- ril.iccInfo.mcc = 310;
- ril.iccInfo.mnc = 260;
-
- do_test_spdi();
-
- // No network.
- do_test_spn(0x00, true, true);
- do_test_spn(0x01, true, true);
- do_test_spn(0x02, true, false);
- do_test_spn(0x03, true, false);
-
- // Home network.
- ril.operator.mcc = 310;
- ril.operator.mnc = 260;
- do_test_spn(0x00, false, true);
- do_test_spn(0x01, true, true);
- do_test_spn(0x02, false, true);
- do_test_spn(0x03, true, true);
-
- // Not HPLMN but in PLMN list.
- ril.iccInfoPrivate.SPDI = [{"mcc":"234","mnc":"136"},{"mcc":"466","mnc":"92"}];
- ril.operator.mcc = 466;
- ril.operator.mnc = 92;
- do_test_spn(0x00, false, true);
- do_test_spn(0x01, true, true);
- do_test_spn(0x02, false, true);
- do_test_spn(0x03, true, true);
- ril.iccInfoPrivate.SPDI = null; // reset SPDI to null;
-
- // Non-Home network.
- ril.operator.mcc = 466;
- ril.operator.mnc = 01;
- do_test_spn(0x00, true, true);
- do_test_spn(0x01, true, true);
- do_test_spn(0x02, true, false);
- do_test_spn(0x03, true, false);
-
- run_next_test();
-});
-
-/**
- * Verify reading EF_IMG and EF_IIDF with ICC_IMG_CODING_SCHEME_BASIC
- */
-add_test(function test_reading_img_basic() {
- let worker = newUint8Worker();
- let context = worker.ContextPool._contexts[0];
- let record = context.SimRecordHelper;
- let helper = context.GsmPDUHelper;
- let ril = context.RIL;
- let buf = context.Buf;
- let io = context.ICCIOHelper;
-
- let test_data = [
- {img: [0x01, 0x05, 0x05, 0x11, 0x4f, 0x00, 0x00, 0x00, 0x00, 0x06],
- iidf: [
- [/* Header */
- 0x05, 0x05,
- /* Image body */
- 0x11, 0x33, 0x55, 0xfe]],
- expected: [
- {width: 0x05,
- height: 0x05,
- codingScheme: ICC_IMG_CODING_SCHEME_BASIC,
- body: [0x11, 0x33, 0x55, 0xfe]}]},
- {img: [0x01, 0x05, 0x05, 0x11, 0x4f, 0x00, 0x00, 0x00, 0x00, 0x06,
- /* Padding */
- 0xff, 0xff],
- iidf: [
- [/* Header */
- 0x05, 0x05,
- /* Image body */
- 0x11, 0x33, 0x55, 0xfe]],
- expected: [
- {width: 0x05,
- height: 0x05,
- codingScheme: ICC_IMG_CODING_SCHEME_BASIC,
- body: [0x11, 0x33, 0x55, 0xfe]}]},
- {img: [0x02, 0x10, 0x01, 0x11, 0x4f, 0x04, 0x00, 0x05, 0x00, 0x04, 0x10,
- 0x01, 0x11, 0x4f, 0x05, 0x00, 0x05, 0x00, 0x04],
- iidf: [
- [/* Data offset */
- 0xff, 0xff, 0xff, 0xff, 0xff,
- /* Header */
- 0x10, 0x01,
- /* Image body */
- 0x11, 0x99,
- /* Trailing data */
- 0xff, 0xff, 0xff],
- [/* Data offset */
- 0xff, 0xff, 0xff, 0xff, 0xff,
- /* Header */
- 0x10, 0x01,
- /* Image body */
- 0x99, 0x11]],
- expected: [
- {width: 0x10,
- height: 0x01,
- codingScheme: ICC_IMG_CODING_SCHEME_BASIC,
- body: [0x11, 0x99]},
- {width: 0x10,
- height: 0x01,
- codingScheme: ICC_IMG_CODING_SCHEME_BASIC,
- body: [0x99, 0x11]}]},
- {img: [0x01, 0x28, 0x20, 0x11, 0x4f, 0xac, 0x00, 0x0b, 0x00, 0xa2],
- iidf: [
- [/* Data offset */
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- /* Header */
- 0x28, 0x20,
- /* Image body */
- 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
- 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15,
- 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20,
- 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b,
- 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36,
- 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41,
- 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c,
- 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
- 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x00, 0x01, 0x02,
- 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d,
- 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
- 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23,
- 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e,
- 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
- 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f]],
- expected: [
- {width: 0x28,
- height: 0x20,
- codingScheme: ICC_IMG_CODING_SCHEME_BASIC,
- body: [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
- 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13,
- 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d,
- 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
- 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31,
- 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b,
- 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45,
- 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
- 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
- 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x00, 0x01, 0x02, 0x03,
- 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d,
- 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
- 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21,
- 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b,
- 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
- 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f]}]}];
-
- function do_test(img, iidf, expected) {
- io.loadLinearFixedEF = function fakeLoadLinearFixedEF(options) {
- // Write data size
- buf.writeInt32(img.length * 2);
-
- // Write data
- for (let i = 0; i < img.length; i++) {
- helper.writeHexOctet(img[i]);
- }
-
- // Write string delimiter
- buf.writeStringDelimiter(img.length * 2);
-
- if (options.callback) {
- options.callback(options);
- }
- };
-
- let instanceIndex = 0;
- io.loadTransparentEF = function fakeLoadTransparentEF(options) {
- // Write data size
- buf.writeInt32(iidf[instanceIndex].length * 2);
-
- // Write data
- for (let i = 0; i < iidf[instanceIndex].length; i++) {
- helper.writeHexOctet(iidf[instanceIndex][i]);
- }
-
- // Write string delimiter
- buf.writeStringDelimiter(iidf[instanceIndex].length * 2);
-
- instanceIndex++;
-
- if (options.callback) {
- options.callback(options);
- }
- };
-
- let onsuccess = function(icons) {
- equal(icons.length, expected.length);
- for (let i = 0; i < icons.length; i++) {
- let icon = icons[i];
- let exp = expected[i];
- equal(icon.width, exp.width);
- equal(icon.height, exp.height);
- equal(icon.codingScheme, exp.codingScheme);
-
- equal(icon.body.length, exp.body.length);
- for (let j = 0; j < icon.body.length; j++) {
- equal(icon.body[j], exp.body[j]);
- }
- }
- };
- record.readIMG(0, onsuccess);
- }
-
- for (let i = 0; i< test_data.length; i++) {
- do_test(test_data[i].img, test_data[i].iidf, test_data[i].expected);
- }
- run_next_test();
-});
-
-/**
- * Verify reading EF_IMG and EF_IIDF with the case data length is not enough
- */
-add_test(function test_reading_img_length_error() {
- let worker = newUint8Worker();
- let context = worker.ContextPool._contexts[0];
- let record = context.SimRecordHelper;
- let helper = context.GsmPDUHelper;
- let ril = context.RIL;
- let buf = context.Buf;
- let io = context.ICCIOHelper;
-
- let test_data = [
- {/* Offset length not enough, should be 4. */
- img: [0x01, 0x05, 0x05, 0x11, 0x4f, 0x00, 0x00, 0x04, 0x00, 0x06],
- iidf: [0xff, 0xff, 0xff, // Offset.
- 0x05, 0x05, 0x11, 0x22, 0x33, 0xfe]},
- {/* iidf data length not enough, should be 6. */
- img: [0x01, 0x05, 0x05, 0x11, 0x4f, 0x00, 0x00, 0x00, 0x00, 0x06],
- iidf: [0x05, 0x05, 0x11, 0x22, 0x33]}];
-
- function do_test(img, iidf) {
- io.loadLinearFixedEF = function fakeLoadLinearFixedEF(options) {
- // Write data size
- buf.writeInt32(img.length * 2);
-
- // Write data
- for (let i = 0; i < img.length; i++) {
- helper.writeHexOctet(img[i]);
- }
-
- // Write string delimiter
- buf.writeStringDelimiter(img.length * 2);
-
- if (options.callback) {
- options.callback(options);
- }
- };
-
- io.loadTransparentEF = function fakeLoadTransparentEF(options) {
- // Write data size
- buf.writeInt32(iidf.length * 2);
-
- // Write data
- for (let i = 0; i < iidf.length; i++) {
- helper.writeHexOctet(iidf[i]);
- }
-
- // Write string delimiter
- buf.writeStringDelimiter(iidf.length * 2);
-
- if (options.callback) {
- options.callback(options);
- }
- };
-
- let onsuccess = function() {
- do_print("onsuccess shouldn't be called.");
- ok(false);
- };
-
- let onerror = function() {
- do_print("onerror called as expected.");
- ok(true);
- };
-
- record.readIMG(0, onsuccess, onerror);
- }
-
- for (let i = 0; i < test_data.length; i++) {
- do_test(test_data[i].img, test_data[i].iidf);
- }
- run_next_test();
-});
-
-/**
- * Verify reading EF_IMG and EF_IIDF with an invalid fileId
- */
-add_test(function test_reading_img_invalid_fileId() {
- let worker = newUint8Worker();
- let context = worker.ContextPool._contexts[0];
- let record = context.SimRecordHelper;
- let helper = context.GsmPDUHelper;
- let ril = context.RIL;
- let buf = context.Buf;
- let io = context.ICCIOHelper;
-
- // Test invalid fileId: 0x5f00.
- let img_test = [0x01, 0x05, 0x05, 0x11, 0x5f, 0x00, 0x00, 0x00, 0x00, 0x06];
- let iidf_test = [0x05, 0x05, 0x11, 0x22, 0x33, 0xfe];
-
- io.loadLinearFixedEF = function fakeLoadLinearFixedEF(options) {
- // Write data size
- buf.writeInt32(img_test.length * 2);
-
- // Write data
- for (let i = 0; i < img_test.length; i++) {
- helper.writeHexOctet(img_test[i]);
- }
-
- // Write string delimiter
- buf.writeStringDelimiter(img_test.length * 2);
-
- if (options.callback) {
- options.callback(options);
- }
- };
-
- io.loadTransparentEF = function fakeLoadTransparentEF(options) {
- // Write data size
- buf.writeInt32(iidf_test.length * 2);
-
- // Write data
- for (let i = 0; i < iidf_test.length; i++) {
- helper.writeHexOctet(iidf_test[i]);
- }
-
- // Write string delimiter
- buf.writeStringDelimiter(iidf_test.length * 2);
-
- if (options.callback) {
- options.callback(options);
- }
- };
-
- let onsuccess = function() {
- do_print("onsuccess shouldn't be called.");
- ok(false);
- };
-
- let onerror = function() {
- do_print("onerror called as expected.");
- ok(true);
- };
-
- record.readIMG(0, onsuccess, onerror);
-
- run_next_test();
-});
-
-/**
- * Verify reading EF_IMG with a wrong record length
- */
-add_test(function test_reading_img_wrong_record_length() {
- let worker = newUint8Worker();
- let context = worker.ContextPool._contexts[0];
- let record = context.SimRecordHelper;
- let helper = context.GsmPDUHelper;
- let ril = context.RIL;
- let buf = context.Buf;
- let io = context.ICCIOHelper;
-
- let test_data = [
- [0x01, 0x05, 0x05, 0x11, 0x4f, 0x00, 0x00, 0x00],
- [0x02, 0x05, 0x05, 0x11, 0x4f, 0x00, 0x00, 0x00, 0x00, 0x06]];
-
- function do_test(img) {
- io.loadLinearFixedEF = function fakeLoadLinearFixedEF(options) {
- // Write data size
- buf.writeInt32(img.length * 2);
-
- // Write data
- for (let i = 0; i < img.length; i++) {
- helper.writeHexOctet(img[i]);
- }
-
- // Write string delimiter
- buf.writeStringDelimiter(img.length * 2);
-
- if (options.callback) {
- options.callback(options);
- }
- };
-
- let onsuccess = function() {
- do_print("onsuccess shouldn't be called.");
- ok(false);
- };
-
- let onerror = function() {
- do_print("onerror called as expected.");
- ok(true);
- };
-
- record.readIMG(0, onsuccess, onerror);
- }
-
- for (let i = 0; i < test_data.length; i++) {
- do_test(test_data[i]);
- }
- run_next_test();
-});
-
-/**
- * Verify reading EF_IMG and EF_IIDF with ICC_IMG_CODING_SCHEME_COLOR
- */
-add_test(function test_reading_img_color() {
- let worker = newUint8Worker();
- let context = worker.ContextPool._contexts[0];
- let record = context.SimRecordHelper;
- let helper = context.GsmPDUHelper;
- let ril = context.RIL;
- let buf = context.Buf;
- let io = context.ICCIOHelper;
-
- let test_data = [
- {img: [0x01, 0x05, 0x05, 0x21, 0x4f, 0x11, 0x00, 0x00, 0x00, 0x13],
- iidf: [
- [/* Header */
- 0x05, 0x05, 0x03, 0x08, 0x00, 0x13,
- /* Image body */
- 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, 0x90, 0xa0,
- 0xb0, 0xc0, 0xd0,
- /* Clut entries */
- 0x00, 0x01, 0x02,
- 0x10, 0x11, 0x12,
- 0x20, 0x21, 0x22,
- 0x30, 0x31, 0x32,
- 0x40, 0x41, 0x42,
- 0x50, 0x51, 0x52,
- 0x60, 0x61, 0x62,
- 0x70, 0x71, 0x72]],
- expected: [
- {width: 0x05,
- height: 0x05,
- codingScheme: ICC_IMG_CODING_SCHEME_COLOR,
- bitsPerImgPoint: 0x03,
- numOfClutEntries: 0x08,
- body: [0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, 0x90, 0xa0, 0xb0,
- 0xc0, 0xd0],
- clut: [0x00, 0x01, 0x02,
- 0x10, 0x11, 0x12,
- 0x20, 0x21, 0x22,
- 0x30, 0x31, 0x32,
- 0x40, 0x41, 0x42,
- 0x50, 0x51, 0x52,
- 0x60, 0x61, 0x62,
- 0x70, 0x71, 0x72]}]},
- {img: [0x02, 0x01, 0x06, 0x21, 0x4f, 0x33, 0x00, 0x02, 0x00, 0x08, 0x01,
- 0x06, 0x21, 0x4f, 0x44, 0x00, 0x02, 0x00, 0x08],
- iidf: [
- [/* Data offset */
- 0xff, 0xff,
- /* Header */
- 0x01, 0x06, 0x02, 0x04, 0x00, 0x0d,
- /* Image body */
- 0x40, 0x50,
- /* Clut offset */
- 0xaa, 0xbb, 0xcc,
- /* Clut entries */
- 0x01, 0x03, 0x05,
- 0x21, 0x23, 0x25,
- 0x41, 0x43, 0x45,
- 0x61, 0x63, 0x65],
- [/* Data offset */
- 0xff, 0xff,
- /* Header */
- 0x01, 0x06, 0x02, 0x04, 0x00, 0x0d,
- /* Image body */
- 0x4f, 0x5f,
- /* Clut offset */
- 0xaa, 0xbb, 0xcc,
- /* Clut entries */
- 0x11, 0x13, 0x15,
- 0x21, 0x23, 0x25,
- 0x41, 0x43, 0x45,
- 0x61, 0x63, 0x65]],
- expected: [
- {width: 0x01,
- height: 0x06,
- codingScheme: ICC_IMG_CODING_SCHEME_COLOR,
- bitsPerImgPoint: 0x02,
- numOfClutEntries: 0x04,
- body: [0x40, 0x50],
- clut: [0x01, 0x03, 0x05,
- 0x21, 0x23, 0x25,
- 0x41, 0x43, 0x45,
- 0x61, 0x63, 0x65]},
- {width: 0x01,
- height: 0x06,
- codingScheme: ICC_IMG_CODING_SCHEME_COLOR,
- bitsPerImgPoint: 0x02,
- numOfClutEntries: 0x04,
- body: [0x4f, 0x5f],
- clut: [0x11, 0x13, 0x15,
- 0x21, 0x23, 0x25,
- 0x41, 0x43, 0x45,
- 0x61, 0x63, 0x65]}]}];
-
- function do_test(img, iidf, expected) {
- io.loadLinearFixedEF = function fakeLoadLinearFixedEF(options) {
- // Write data size
- buf.writeInt32(img.length * 2);
-
- // Write data
- for (let i = 0; i < img.length; i++) {
- helper.writeHexOctet(img[i]);
- }
-
- // Write string delimiter
- buf.writeStringDelimiter(img.length * 2);
-
- if (options.callback) {
- options.callback(options);
- }
- };
-
- let instanceIndex = 0;
- io.loadTransparentEF = function fakeLoadTransparentEF(options) {
- // Write data size
- buf.writeInt32(iidf[instanceIndex].length * 2);
-
- // Write data
- for (let i = 0; i < iidf[instanceIndex].length; i++) {
- helper.writeHexOctet(iidf[instanceIndex][i]);
- }
-
- // Write string delimiter
- buf.writeStringDelimiter(iidf[instanceIndex].length * 2);
-
- instanceIndex++;
-
- if (options.callback) {
- options.callback(options);
- }
- };
-
- let onsuccess = function(icons) {
- equal(icons.length, expected.length);
- for (let i = 0; i < icons.length; i++) {
- let icon = icons[i];
- let exp = expected[i];
- equal(icon.width, exp.width);
- equal(icon.height, exp.height);
- equal(icon.codingScheme, exp.codingScheme);
-
- equal(icon.body.length, exp.body.length);
- for (let j = 0; j < icon.body.length; j++) {
- equal(icon.body[j], exp.body[j]);
- }
-
- equal(icon.clut.length, exp.clut.length);
- for (let j = 0; j < icon.clut.length; j++) {
- equal(icon.clut[j], exp.clut[j]);
- }
- }
- };
-
- record.readIMG(0, onsuccess);
- }
-
- for (let i = 0; i< test_data.length; i++) {
- do_test(test_data[i].img, test_data[i].iidf, test_data[i].expected);
- }
- run_next_test();
-});
-
-/**
- * Verify reading EF_IMG and EF_IIDF with
- * ICC_IMG_CODING_SCHEME_COLOR_TRANSPARENCY
- */
-add_test(function test_reading_img_color() {
- let worker = newUint8Worker();
- let context = worker.ContextPool._contexts[0];
- let record = context.SimRecordHelper;
- let helper = context.GsmPDUHelper;
- let ril = context.RIL;
- let buf = context.Buf;
- let io = context.ICCIOHelper;
-
- let test_data = [
- {img: [0x01, 0x05, 0x05, 0x22, 0x4f, 0x11, 0x00, 0x00, 0x00, 0x13],
- iidf: [
- [/* Header */
- 0x05, 0x05, 0x03, 0x08, 0x00, 0x13,
- /* Image body */
- 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, 0x90, 0xa0,
- 0xb0, 0xc0, 0xd0,
- /* Clut entries */
- 0x00, 0x01, 0x02,
- 0x10, 0x11, 0x12,
- 0x20, 0x21, 0x22,
- 0x30, 0x31, 0x32,
- 0x40, 0x41, 0x42,
- 0x50, 0x51, 0x52,
- 0x60, 0x61, 0x62,
- 0x70, 0x71, 0x72]],
- expected: [
- {width: 0x05,
- height: 0x05,
- codingScheme: ICC_IMG_CODING_SCHEME_COLOR_TRANSPARENCY,
- bitsPerImgPoint: 0x03,
- numOfClutEntries: 0x08,
- body: [0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, 0x90,
- 0xa0, 0xb0, 0xc0, 0xd0],
- clut: [0x00, 0x01, 0x02,
- 0x10, 0x11, 0x12,
- 0x20, 0x21, 0x22,
- 0x30, 0x31, 0x32,
- 0x40, 0x41, 0x42,
- 0x50, 0x51, 0x52,
- 0x60, 0x61, 0x62,
- 0x70, 0x71, 0x72]}]},
- {img: [0x02, 0x01, 0x06, 0x22, 0x4f, 0x33, 0x00, 0x02, 0x00, 0x08, 0x01,
- 0x06, 0x22, 0x4f, 0x33, 0x00, 0x02, 0x00, 0x08],
- iidf: [
- [/* Data offset */
- 0xff, 0xff,
- /* Header */
- 0x01, 0x06, 0x02, 0x04, 0x00, 0x0d,
- /* Image body */
- 0x40, 0x50,
- /* Clut offset */
- 0x0a, 0x0b, 0x0c,
- /* Clut entries */
- 0x01, 0x03, 0x05,
- 0x21, 0x23, 0x25,
- 0x41, 0x43, 0x45,
- 0x61, 0x63, 0x65],
- [/* Data offset */
- 0xff, 0xff,
- /* Header */
- 0x01, 0x06, 0x02, 0x04, 0x00, 0x0d,
- /* Image body */
- 0x4f, 0x5f,
- /* Clut offset */
- 0x0a, 0x0b, 0x0c,
- /* Clut entries */
- 0x11, 0x13, 0x15,
- 0x21, 0x23, 0x25,
- 0x41, 0x43, 0x45,
- 0x61, 0x63, 0x65]],
- expected: [
- {width: 0x01,
- height: 0x06,
- codingScheme: ICC_IMG_CODING_SCHEME_COLOR_TRANSPARENCY,
- bitsPerImgPoint: 0x02,
- numOfClutEntries: 0x04,
- body: [0x40, 0x50],
- clut: [0x01, 0x03, 0x05,
- 0x21, 0x23, 0x25,
- 0x41, 0x43, 0x45,
- 0x61, 0x63, 0x65]},
- {width: 0x01,
- height: 0x06,
- codingScheme: ICC_IMG_CODING_SCHEME_COLOR_TRANSPARENCY,
- bitsPerImgPoint: 0x02,
- numOfClutEntries: 0x04,
- body: [0x4f, 0x5f],
- clut: [0x11, 0x13, 0x15,
- 0x21, 0x23, 0x25,
- 0x41, 0x43, 0x45,
- 0x61, 0x63, 0x65]}]}];
-
- function do_test(img, iidf, expected) {
- io.loadLinearFixedEF = function fakeLoadLinearFixedEF(options) {
- // Write data size
- buf.writeInt32(img.length * 2);
-
- // Write data
- for (let i = 0; i < img.length; i++) {
- helper.writeHexOctet(img[i]);
- }
-
- // Write string delimiter
- buf.writeStringDelimiter(img.length * 2);
-
- if (options.callback) {
- options.callback(options);
- }
- };
-
- let instanceIndex = 0;
- io.loadTransparentEF = function fakeLoadTransparentEF(options) {
- // Write data size
- buf.writeInt32(iidf[instanceIndex].length * 2);
-
- // Write data
- for (let i = 0; i < iidf[instanceIndex].length; i++) {
- helper.writeHexOctet(iidf[instanceIndex][i]);
- }
-
- // Write string delimiter
- buf.writeStringDelimiter(iidf[instanceIndex].length * 2);
-
- instanceIndex++;
-
- if (options.callback) {
- options.callback(options);
- }
- };
-
- let onsuccess = function(icons) {
- equal(icons.length, expected.length);
- for (let i = 0; i < icons.length; i++) {
- let icon = icons[i];
- let exp = expected[i];
- equal(icon.width, exp.width);
- equal(icon.height, exp.height);
- equal(icon.codingScheme, exp.codingScheme);
-
- equal(icon.body.length, exp.body.length);
- for (let j = 0; j < icon.body.length; j++) {
- equal(icon.body[j], exp.body[j]);
- }
-
- equal(icon.clut.length, exp.clut.length);
- for (let j = 0; j < icon.clut.length; j++) {
- equal(icon.clut[j], exp.clut[j]);
- }
- }
- };
-
- record.readIMG(0, onsuccess);
- }
-
- for (let i = 0; i< test_data.length; i++) {
- do_test(test_data[i].img, test_data[i].iidf, test_data[i].expected);
- }
- run_next_test();
-});
-
-/**
- * Verify SimRecordHelper.readCphsInfo
- */
-add_test(function test_read_cphs_info() {
- let worker = newUint8Worker();
- let context = worker.ContextPool._contexts[0];
- let RIL = context.RIL;
- let pduHelper = context.GsmPDUHelper;
- let recordHelper = context.SimRecordHelper;
- let buf = context.Buf;
- let io = context.ICCIOHelper;
- let cphsPDU = new Uint8Array(3);
-
- io.loadTransparentEF = function(options) {
- if (cphsPDU) {
- // Write data size
- buf.writeInt32(cphsPDU.length * 2);
-
- // Write CPHS INFO
- for (let i = 0; i < cphsPDU.length; i++) {
- pduHelper.writeHexOctet(cphsPDU[i]);
- }
-
- // Write string delimiter
- buf.writeStringDelimiter(cphsPDU.length * 2);
-
- if (options.callback) {
- options.callback(options);
- }
- } else {
- do_print("cphsPDU[] is not set.");
- }
- };
-
- function do_test(cphsInfo, cphsSt) {
- let onsuccess = false;
- let onerror = false;
-
- delete RIL.iccInfoPrivate.cphsSt;
- cphsPDU.set(cphsInfo);
- recordHelper.readCphsInfo(() => { onsuccess = true; },
- () => { onerror = true; });
-
- ok((cphsSt) ? onsuccess : onerror);
- ok(!((cphsSt) ? onerror : onsuccess));
- if (cphsSt) {
- equal(RIL.iccInfoPrivate.cphsSt.length, cphsSt.length);
- for (let i = 0; i < cphsSt.length; i++) {
- equal(RIL.iccInfoPrivate.cphsSt[i], cphsSt[i]);
- }
- } else {
- equal(RIL.iccInfoPrivate.cphsSt, cphsSt);
- }
- }
-
- do_test([
- 0x01, // Phase 1
- 0xFF, // All available & activated
- 0x03 // All available & activated
- ],
- [
- 0x3F, // All services except ONSF(bit 8-7) are available and activated.
- 0x00 // INFO_NUM shall not be available & activated.
- ]);
-
- do_test([
- 0x02, // Phase 2
- 0xFF, // All available & activated
- 0x03 // All available & activated
- ],
- [
- 0xF3, // All services except ONSF are available and activated.
- 0x03 // INFO_NUM shall not be available & activated.
- ]);
-
- do_test([
- 0x03, // Phase 3
- 0xFF, // All available & activated
- 0x03 // All available & activated
- ],
- undefined); // RIL.iccInfoPrivate.cphsSt shall be remained as 'undefined'.
-
- run_next_test();
-});
-
-/**
- * Verify SimRecordHelper.readMBDN/SimRecordHelper.readCphsMBN
- */
-add_test(function test_read_voicemail_number() {
- let worker = newUint8Worker();
- let context = worker.ContextPool._contexts[0];
- let RIL = context.RIL;
- let pduHelper = context.GsmPDUHelper;
- let recordHelper = context.SimRecordHelper;
- let buf = context.Buf;
- let io = context.ICCIOHelper;
- let postedMessage;
-
- worker.postMessage = function(message) {
- postedMessage = message;
- };
-
- io.loadLinearFixedEF = function(options) {
- let mbnData = [
- 0x56, 0x6F, 0x69, 0x63, 0x65, 0x6D, 0x61, 0x69,
- 0x6C, 0xFF, // Alpha Identifier: Voicemail
- 0x03, // Length of BCD number: 3
- 0x80, // TOA: Unknown
- 0x11, 0xF1, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xFF, // Dialing Number: 111
- 0xFF, // Capability/Configuration Record Identifier
- 0xFF // Extension Record Identifier
- ];
-
- // Write data size
- buf.writeInt32(mbnData.length * 2);
-
- // Write MBN
- for (let i = 0; i < mbnData.length; i++) {
- pduHelper.writeHexOctet(mbnData[i]);
- }
-
- // Write string delimiter
- buf.writeStringDelimiter(mbnData.length * 2);
-
- options.recordSize = mbnData.length;
- if (options.callback) {
- options.callback(options);
- }
- };
-
- function do_test(funcName, msgCount) {
- postedMessage = null;
- delete RIL.iccInfoPrivate.mbdn;
- recordHelper[funcName]();
-
- equal("iccmbdn", postedMessage.rilMessageType);
- equal("Voicemail", postedMessage.alphaId);
- equal("111", postedMessage.number);
- }
-
- do_test("readMBDN");
- do_test("readCphsMBN");
-
- run_next_test();
-});
-
-/**
- * Verify the recovery from SimRecordHelper.readCphsMBN() if MBDN is not valid
- * or is empty after SimRecordHelper.readMBDN().
- */
-add_test(function test_read_mbdn_recovered_from_cphs_mbn() {
- let worker = newUint8Worker();
- let context = worker.ContextPool._contexts[0];
- let RIL = context.RIL;
- let pduHelper = context.GsmPDUHelper;
- let recordHelper = context.SimRecordHelper;
- let iccUtilsHelper = context.ICCUtilsHelper;
- let buf = context.Buf;
- let io = context.ICCIOHelper;
-
- io.loadLinearFixedEF = function(options) {
- let mbnData = [
- 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
- ];
-
- // Write data size
- buf.writeInt32(mbnData.length * 2);
-
- // Write MBN
- for (let i = 0; i < mbnData.length; i++) {
- pduHelper.writeHexOctet(mbnData[i]);
- }
-
- // Write string delimiter
- buf.writeStringDelimiter(mbnData.length * 2);
-
- options.recordSize = mbnData.length;
- if (options.callback) {
- options.callback(options);
- }
- };
-
- iccUtilsHelper.isCphsServiceAvailable = function(geckoService) {
- return geckoService == "MBN";
- };
-
- let isRecovered = false;
- recordHelper.readCphsMBN = function(onComplete) {
- isRecovered = true;
- };
-
- recordHelper.readMBDN();
-
- equal(RIL.iccInfoPrivate.mbdn, undefined);
- ok(isRecovered);
-
- run_next_test();
-});
-
-/**
- * Verify reading EF_PNN with different coding scheme.
- */
-add_test(function test_pnn_with_different_coding_scheme() {
- let worker = newUint8Worker();
- let context = worker.ContextPool._contexts[0];
- let record = context.SimRecordHelper;
- let pduHelper = context.GsmPDUHelper;
- let ril = context.RIL;
- let buf = context.Buf;
- let io = context.ICCIOHelper;
-
- let test_data = [{
- // Cell Broadcast data coding scheme - "Test1"
- pnn: [0x43, 0x06, 0x85, 0xD4, 0xF2, 0x9C, 0x1E, 0x03],
- expectedResult: "Test1"
- },{
- // UCS2 with 0x80 - "Test1"
- pnn: [0x43, 0x0C, 0x90, 0x80, 0x00, 0x54, 0x00, 0x65, 0x00, 0x73, 0x00, 0x74, 0x00, 0x31],
- expectedResult: "Test1"
- },{
- // UCS2 with 0x81 - "Mozilla\u694a"
- pnn: [0x43, 0x0E, 0x90, 0x81, 0x08, 0xd2, 0x4d, 0x6f, 0x7a, 0x69, 0x6c, 0x6c, 0x61, 0xca, 0xff, 0xff],
- expectedResult: "Mozilla\u694a"
- },{
- // UCS2 with 0x82 - "Mozilla\u694a"
- pnn: [0x43, 0x0F, 0x90, 0x82, 0x08, 0x69, 0x00, 0x4d, 0x6f, 0x7a, 0x69, 0x6c, 0x6c, 0x61, 0xca, 0xff, 0xff],
- expectedResult: "Mozilla\u694a"
- }];
-
- function do_test_pnn(pnn, expectedResult) {
- io.loadLinearFixedEF = function fakeLoadLinearFixedEF(options) {
- // Write data size.
- buf.writeInt32(pnn.length * 2);
-
- // Write data.
- for (let i = 0; i < pnn.length; i++) {
- pduHelper.writeHexOctet(pnn[i]);
- }
-
- // Write string delimiter.
- buf.writeStringDelimiter(pnn.length * 2);
-
- if (options.callback) {
- options.callback(options);
- }
- };
-
- record.readPNN();
-
- equal(ril.iccInfoPrivate.PNN[0].fullName, expectedResult);
- // Reset PNN info for next test
- ril.iccInfoPrivate.PNN = null;
- }
-
- ril.appType = CARD_APPTYPE_SIM;
- for (let i = 0; i < test_data.length; i++) {
- do_test_pnn(test_data[i].pnn, test_data[i].expectedResult);
- }
-
- run_next_test();
-});
-
-/**
- * Verify reading EF_PNN with different content.
- */
-add_test(function test_pnn_with_different_content() {
- let worker = newUint8Worker();
- let context = worker.ContextPool._contexts[0];
- let record = context.SimRecordHelper;
- let pduHelper = context.GsmPDUHelper;
- let ril = context.RIL;
- let buf = context.Buf;
- let io = context.ICCIOHelper;
-
- let test_data = [{
- // [0]: {"fullName":"Test1","shortName":"Test1"}
- pnn: [0x43, 0x06, 0x85, 0xD4, 0xF2, 0x9C, 0x1E, 0x03,
- 0x45, 0x06, 0x85, 0xD4, 0xF2, 0x9C, 0x1E, 0x03],
- expectedResult: {"fullName": "Test1","shortName": "Test1"}
- },{
- // [1]: {"fullName":"Test2"}
- pnn: [0x43, 0x06, 0x85, 0xD4, 0xF2, 0x9C, 0x2E, 0x03],
- expectedResult: {"fullName": "Test2"}
- },{
- // [2]: undefined
- pnn: [0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF],
- },{
- // [3]: {"fullName": "Test4"}
- pnn: [0x43, 0x06, 0x85, 0xD4, 0xF2, 0x9C, 0x4E, 0x03],
- expectedResult: {"fullName": "Test4"}
- },{
- // [4]: undefined
- pnn: [0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF],
- }];
-
- function do_test_pnn() {
- ril.iccIO = function fakeIccIO(options) {
- let index = options.p1 - 1;
- let pnn = test_data[index].pnn;
-
- // Write data size.
- buf.writeInt32(pnn.length * 2);
-
- // Write data.
- for (let i = 0; i < pnn.length; i++) {
- pduHelper.writeHexOctet(pnn[i]);
- }
-
- // Write string delimiter.
- buf.writeStringDelimiter(pnn.length * 2);
-
- if (options.callback) {
- options.callback(options);
- }
- };
-
- io.loadLinearFixedEF = function fakeLoadLinearFixedEF(options) {
- options.p1 = 1;
- options.totalRecords = test_data.length;
-
- ril.iccIO(options);
- };
-
- record.readPNN();
-
- equal(test_data.length, ril.iccInfoPrivate.PNN.length);
- for (let i = 0; i < test_data.length; i++) {
- if (test_data[i].expectedResult) {
- equal(test_data[i].expectedResult.fullName,
- ril.iccInfoPrivate.PNN[i].fullName);
- equal(test_data[i].expectedResult.shortName,
- ril.iccInfoPrivate.PNN[i].shortName);
- } else {
- equal(test_data[i].expectedResult, ril.iccInfoPrivate.PNN[i]);
- }
- }
- }
-
- ril.appType = CARD_APPTYPE_SIM;
- do_test_pnn();
-
- run_next_test();
-});
diff --git a/dom/system/gonk/tests/test_ril_worker_ruim.js b/dom/system/gonk/tests/test_ril_worker_ruim.js
deleted file mode 100644
index 0ddc10f296..0000000000
--- a/dom/system/gonk/tests/test_ril_worker_ruim.js
+++ /dev/null
@@ -1,328 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-subscriptLoader.loadSubScript("resource://gre/modules/ril_consts.js", this);
-
-function run_test() {
- run_next_test();
-}
-
-/**
- * Verify RUIM Service.
- */
-add_test(function test_is_ruim_service_available() {
- let worker = newWorker();
- let context = worker.ContextPool._contexts[0];
- context.RIL._isCdma = true;
- context.RIL.appType = CARD_APPTYPE_RUIM;
-
- function test_table(cst, geckoService, enabled) {
- context.RIL.iccInfoPrivate.cst = cst;
- equal(context.ICCUtilsHelper.isICCServiceAvailable(geckoService),
- enabled);
- }
-
- test_table([0x0, 0x0, 0x0, 0x0, 0x03], "SPN", true);
- test_table([0x0, 0x0, 0x0, 0x03, 0x0], "SPN", false);
- test_table([0x0, 0x0C, 0x0, 0x0, 0x0], "ENHANCED_PHONEBOOK", true);
- test_table([0x0, 0x0, 0x0, 0x0, 0x0], "ENHANCED_PHONEBOOK", false);
-
- run_next_test();
-});
-
-/**
- * Verify EF_PATH for RUIM file.
- */
-add_test(function test_ruim_file_path_id() {
- let worker = newWorker();
- let context = worker.ContextPool._contexts[0];
- let RIL = context.RIL;
- let ICCFileHelper = context.ICCFileHelper;
-
- RIL.appType = CARD_APPTYPE_RUIM;
- equal(ICCFileHelper.getEFPath(ICC_EF_CSIM_CST),
- EF_PATH_MF_SIM + EF_PATH_DF_CDMA);
-
- run_next_test();
-});
-
-add_test(function test_fetch_ruim_recodes() {
- let worker = newWorker();
- let context = worker.ContextPool._contexts[0];
- let RIL = context.RIL;
- let ruimHelper = context.RuimRecordHelper;
-
- function testFetchRuimRecordes(expectCalled) {
- let ifCalled = [];
-
- ruimHelper.getIMSI_M = function() {
- ifCalled.push("getIMSI_M");
- };
-
- ruimHelper.readCST = function() {
- ifCalled.push("readCST");
- };
-
- ruimHelper.readCDMAHome = function() {
- ifCalled.push("readCDMAHome");
- };
-
- RIL.getCdmaSubscription = function() {
- ifCalled.push("getCdmaSubscription");
- };
-
- ruimHelper.fetchRuimRecords();
-
- for (let i = 0; i < expectCalled.length; i++ ) {
- if (ifCalled[i] != expectCalled[i]) {
- do_print(expectCalled[i] + " is not called.");
- ok(false);
- }
- }
- }
-
- let expectCalled = ["getIMSI_M", "readCST", "readCDMAHome",
- "getCdmaSubscription"];
- testFetchRuimRecordes(expectCalled);
-
- run_next_test();
-});
-
-/**
- * Verify RuimRecordHelper.decodeIMSIValue
- */
-add_test(function test_decode_imsi_value() {
- let worker = newUint8Worker();
- let context = worker.ContextPool._contexts[0];
-
- function testDecodeImsiValue(encoded, length, expect) {
- let decoded = context.RuimRecordHelper.decodeIMSIValue(encoded, length);
-
- equal(expect, decoded);
- }
-
- testDecodeImsiValue( 99, 2, "00");
- testDecodeImsiValue( 90, 2, "01");
- testDecodeImsiValue( 19, 2, "20");
- testDecodeImsiValue( 23, 2, "34");
- testDecodeImsiValue(999, 3, "000");
- testDecodeImsiValue(990, 3, "001");
- testDecodeImsiValue(909, 3, "010");
- testDecodeImsiValue( 99, 3, "100");
- testDecodeImsiValue(901, 3, "012");
- testDecodeImsiValue( 19, 3, "120");
- testDecodeImsiValue( 91, 3, "102");
- testDecodeImsiValue(199, 3, "200");
- testDecodeImsiValue(123, 3, "234");
- testDecodeImsiValue(578, 3, "689");
-
- run_next_test();
-});
-
-/**
- * Verify RuimRecordHelper.getIMSI_M
- */
-add_test(function test_get_imsi_m() {
- let worker = newUint8Worker();
- let context = worker.ContextPool._contexts[0];
- let helper = context.GsmPDUHelper;
- let buf = context.Buf;
- let io = context.ICCIOHelper;
-
- function testDecodeImsi(encodedImsi, expectedImsi) {
- io.loadTransparentEF = function fakeLoadTransparentEF(options) {
- // Write data size
- buf.writeInt32(encodedImsi.length * 2);
-
- // Write imsi
- for (let i = 0; i < encodedImsi.length; i++) {
- helper.writeHexOctet(encodedImsi[i]);
- }
-
- // Write string delimiter
- buf.writeStringDelimiter(encodedImsi.length * 2);
-
- if (options.callback) {
- options.callback(options);
- }
- };
-
- context.RuimRecordHelper.getIMSI_M();
- let imsi = context.RIL.iccInfoPrivate.imsi;
-
- equal(expectedImsi, imsi)
- }
-
- let imsi_1 = "466050081062861";
- testDecodeImsi([0x0, 0xe5, 0x03, 0xee, 0xca, 0x17, 0x5e, 0x80, 0x63, 0x01], imsi_1);
-
- let imsi_2 = "460038351175976";
- testDecodeImsi([0x0, 0xd4, 0x02, 0x61, 0x97, 0x01, 0x5c, 0x80, 0x67, 0x01], imsi_2);
-
- run_next_test();
-});
-
-/**
- * Verify RuimRecordHelper.readCDMAHome
- */
-add_test(function test_read_cdmahome() {
- let worker = newUint8Worker();
- let context = worker.ContextPool._contexts[0];
- let helper = context.GsmPDUHelper;
- let buf = context.Buf;
- let io = context.ICCIOHelper;
-
- io.loadLinearFixedEF = function fakeLoadLinearFixedEF(options) {
- let cdmaHome = [0xc1, 0x34, 0xff, 0xff, 0x00];
-
- // Write data size
- buf.writeInt32(cdmaHome.length * 2);
-
- // Write cdma home file.
- for (let i = 0; i < cdmaHome.length; i++) {
- helper.writeHexOctet(cdmaHome[i]);
- }
-
- // Write string delimiter
- buf.writeStringDelimiter(cdmaHome.length * 2);
-
- // We just have 1 test record.
-
- options.totalRecords = 1;
- if (options.callback) {
- options.callback(options);
- }
- };
-
- function testCdmaHome(expectedSystemIds, expectedNetworkIds) {
- context.RuimRecordHelper.readCDMAHome();
- let cdmaHome = context.RIL.cdmaHome;
- for (let i = 0; i < expectedSystemIds.length; i++) {
- equal(cdmaHome.systemId[i], expectedSystemIds[i]);
- equal(cdmaHome.networkId[i], expectedNetworkIds[i]);
- }
- equal(cdmaHome.systemId.length, expectedSystemIds.length);
- equal(cdmaHome.networkId.length, expectedNetworkIds.length);
- }
-
- testCdmaHome([13505], [65535]);
-
- run_next_test();
-});
-
-/**
- * Verify reading CDMA EF_SPN
- */
-add_test(function test_read_cdmaspn() {
- let worker = newUint8Worker();
- let context = worker.ContextPool._contexts[0];
- let helper = context.GsmPDUHelper;
- let buf = context.Buf;
- let io = context.ICCIOHelper;
-
- function testReadSpn(file, expectedSpn, expectedDisplayCondition) {
- io.loadTransparentEF = function fakeLoadTransparentEF(options) {
- // Write data size
- buf.writeInt32(file.length * 2);
-
- // Write file.
- for (let i = 0; i < file.length; i++) {
- helper.writeHexOctet(file[i]);
- }
-
- // Write string delimiter
- buf.writeStringDelimiter(file.length * 2);
-
- if (options.callback) {
- options.callback(options);
- }
- };
-
- context.RuimRecordHelper.readSPN();
- equal(context.RIL.iccInfo.spn, expectedSpn);
- equal(context.RIL.iccInfoPrivate.spnDisplayCondition,
- expectedDisplayCondition);
- }
-
- testReadSpn([0x01, 0x04, 0x06, 0x4e, 0x9e, 0x59, 0x2a, 0x96,
- 0xfb, 0x4f, 0xe1, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff],
- String.fromCharCode(0x4e9e) +
- String.fromCharCode(0x592a) +
- String.fromCharCode(0x96fb) +
- String.fromCharCode(0x4fe1),
- 0x1);
-
- // Test when there's no tailing 0xff in spn string.
- testReadSpn([0x01, 0x04, 0x06, 0x4e, 0x9e, 0x59, 0x2a, 0x96,
- 0xfb, 0x4f, 0xe1],
- String.fromCharCode(0x4e9e) +
- String.fromCharCode(0x592a) +
- String.fromCharCode(0x96fb) +
- String.fromCharCode(0x4fe1),
- 0x1);
-
- run_next_test();
-});
-
-/**
- * Verify display condition for CDMA.
- */
-add_test(function test_cdma_spn_display_condition() {
- let worker = newWorker({
- postRILMessage: function(data) {
- // Do nothing
- },
- postMessage: function(message) {
- // Do nothing
- }
- });
- let context = worker.ContextPool._contexts[0];
- let RIL = context.RIL;
- let ICCUtilsHelper = context.ICCUtilsHelper;
-
- // Set cdma.
- RIL._isCdma = true;
-
- // Test updateDisplayCondition runs before any of SIM file is ready.
- equal(ICCUtilsHelper.updateDisplayCondition(), true);
- equal(RIL.iccInfo.isDisplayNetworkNameRequired, true);
- equal(RIL.iccInfo.isDisplaySpnRequired, false);
-
- // Test with value.
- function testDisplayCondition(ruimDisplayCondition,
- homeSystemIds, homeNetworkIds,
- currentSystemId, currentNetworkId,
- expectUpdateDisplayCondition,
- expectIsDisplaySPNRequired) {
- RIL.iccInfoPrivate.spnDisplayCondition = ruimDisplayCondition;
- RIL.cdmaHome = {
- systemId: homeSystemIds,
- networkId: homeNetworkIds
- };
- RIL.voiceRegistrationState.cell = {
- cdmaSystemId: currentSystemId,
- cdmaNetworkId: currentNetworkId
- };
-
- equal(ICCUtilsHelper.updateDisplayCondition(), expectUpdateDisplayCondition);
- equal(RIL.iccInfo.isDisplayNetworkNameRequired, false);
- equal(RIL.iccInfo.isDisplaySpnRequired, expectIsDisplaySPNRequired);
- };
-
- // SPN is not required when ruimDisplayCondition is false.
- testDisplayCondition(0x0, [123], [345], 123, 345, true, false);
-
- // System id and network id are all match.
- testDisplayCondition(0x1, [123], [345], 123, 345, true, true);
-
- // Network is 65535, we should only need to match system id.
- testDisplayCondition(0x1, [123], [65535], 123, 345, false, true);
-
- // Not match.
- testDisplayCondition(0x1, [123], [456], 123, 345, true, false);
-
- run_next_test();
-});
diff --git a/dom/system/gonk/tests/test_ril_worker_sms.js b/dom/system/gonk/tests/test_ril_worker_sms.js
deleted file mode 100644
index 7c1b972a74..0000000000
--- a/dom/system/gonk/tests/test_ril_worker_sms.js
+++ /dev/null
@@ -1,273 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-subscriptLoader.loadSubScript("resource://gre/modules/ril_consts.js", this);
-
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-
-XPCOMUtils.defineLazyGetter(this, "gSmsSegmentHelper", function() {
- let ns = {};
- Cu.import("resource://gre/modules/SmsSegmentHelper.jsm", ns);
- return ns.SmsSegmentHelper;
-});
-
-const ESCAPE = "\uffff";
-const RESCTL = "\ufffe";
-
-function run_test() {
- run_next_test();
-}
-
-/**
- * Verify receiving SMS-DELIVERY messages
- */
-
-function hexToNibble(nibble) {
- nibble &= 0x0f;
- if (nibble < 10) {
- nibble += 48; // ASCII '0'
- } else {
- nibble += 55; // ASCII 'A'
- }
- return nibble;
-}
-
-function pduToParcelData(pdu) {
- let dataLength = 4 + pdu.length * 4 + 4;
- let data = new Uint8Array(dataLength);
- let offset = 0;
-
- // String length
- data[offset++] = pdu.length & 0xFF;
- data[offset++] = (pdu.length >> 8) & 0xFF;
- data[offset++] = (pdu.length >> 16) & 0xFF;
- data[offset++] = (pdu.length >> 24) & 0xFF;
-
- // PDU data
- for (let i = 0; i < pdu.length; i++) {
- let hi = (pdu[i] >>> 4) & 0x0F;
- let lo = pdu[i] & 0x0F;
-
- data[offset++] = hexToNibble(hi);
- data[offset++] = 0;
- data[offset++] = hexToNibble(lo);
- data[offset++] = 0;
- }
-
- // String delimitor
- data[offset++] = 0;
- data[offset++] = 0;
- data[offset++] = 0;
- data[offset++] = 0;
-
- return data;
-}
-
-function compose7bitPdu(lst, sst, data, septets) {
- if ((lst == 0) && (sst == 0)) {
- return [0x00, // SMSC
- PDU_MTI_SMS_DELIVER, // firstOctet
- 1, 0x00, 0, // senderAddress
- 0x00, // protocolIdentifier
- PDU_DCS_MSG_CODING_7BITS_ALPHABET, // dataCodingScheme
- 0, 0, 0, 0, 0, 0, 0, // y m d h m s tz
- septets] // userDataLength
- .concat(data);
- }
-
- return [0x00, // SMSC
- PDU_MTI_SMS_DELIVER | PDU_UDHI, // firstOctet
- 1, 0x00, 0, // senderAddress
- 0x00, // protocolIdentifier
- PDU_DCS_MSG_CODING_7BITS_ALPHABET, // dataCodingScheme
- 0, 0, 0, 0, 0, 0, 0, // y m d h m s tz
- 8 + septets, // userDataLength
- 6, // user data header length
- PDU_IEI_NATIONAL_LANGUAGE_LOCKING_SHIFT, 1, lst, // PDU_IEI_NATIONAL_LANGUAGE_LOCKING_SHIFT
- PDU_IEI_NATIONAL_LANGUAGE_SINGLE_SHIFT, 1, sst] // PDU_IEI_NATIONAL_LANGUAGE_SINGLE_SHIFT
- .concat(data);
-}
-
-function composeUcs2Pdu(rawBytes) {
- return [0x00, // SMSC
- PDU_MTI_SMS_DELIVER, // firstOctet
- 1, 0x00, 0, // senderAddress
- 0x00, // protocolIdentifier
- PDU_DCS_MSG_CODING_16BITS_ALPHABET, // dataCodingScheme
- 0, 0, 0, 0, 0, 0, 0, // y m d h m s tz
- rawBytes.length] // userDataLength
- .concat(rawBytes);
-}
-
-function newSmsParcel(pdu) {
- return newIncomingParcel(-1,
- RESPONSE_TYPE_UNSOLICITED,
- UNSOLICITED_RESPONSE_NEW_SMS,
- pduToParcelData(pdu));
-}
-
-function removeSpecialChar(str, needle) {
- for (let i = 0; i < needle.length; i++) {
- let pos;
- while ((pos = str.indexOf(needle[i])) >= 0) {
- str = str.substring(0, pos) + str.substring(pos + 1);
- }
- }
- return str;
-}
-
-function newWriteHexOctetAsUint8Worker() {
- let worker = newWorker({
- postRILMessage: function(data) {
- // Do nothing
- },
- postMessage: function(message) {
- // Do nothing
- }
- });
-
- let context = worker.ContextPool._contexts[0];
- context.GsmPDUHelper.writeHexOctet = function(value) {
- context.Buf.writeUint8(value);
- };
-
- return worker;
-}
-
-function add_test_receiving_sms(expected, pdu) {
- add_test(function test_receiving_sms() {
- let worker = newWorker({
- postRILMessage: function(data) {
- // Do nothing
- },
- postMessage: function(message) {
- do_print("fullBody: " + message.fullBody);
- equal(expected, message.fullBody)
- }
- });
-
- do_print("expect: " + expected);
- do_print("pdu: " + pdu);
- worker.onRILMessage(0, newSmsParcel(pdu));
-
- run_next_test();
- });
-}
-
-var test_receiving_7bit_alphabets__worker;
-function test_receiving_7bit_alphabets(lst, sst) {
- if (!test_receiving_7bit_alphabets__worker) {
- test_receiving_7bit_alphabets__worker = newWriteHexOctetAsUint8Worker();
- }
- let worker = test_receiving_7bit_alphabets__worker;
- let context = worker.ContextPool._contexts[0];
- let helper = context.GsmPDUHelper;
- let buf = context.Buf;
-
- function get7bitRawBytes(expected) {
- buf.outgoingIndex = 0;
- helper.writeStringAsSeptets(expected, 0, lst, sst);
-
- let subArray = buf.outgoingBytes.subarray(0, buf.outgoingIndex);
- return Array.slice(subArray);
- }
-
- let langTable = PDU_NL_LOCKING_SHIFT_TABLES[lst];
- let langShiftTable = PDU_NL_SINGLE_SHIFT_TABLES[sst];
-
- let text = removeSpecialChar(langTable + langShiftTable, ESCAPE + RESCTL);
- for (let i = 0; i < text.length;) {
- let len = Math.min(70, text.length - i);
- let expected = text.substring(i, i + len);
- let septets =
- gSmsSegmentHelper.countGsm7BitSeptets(expected, langTable, langShiftTable);
- let rawBytes = get7bitRawBytes(expected);
- let pdu = compose7bitPdu(lst, sst, rawBytes, septets);
- add_test_receiving_sms(expected, pdu);
-
- i += len;
- }
-}
-
-function test_receiving_ucs2_alphabets(text) {
- let worker = test_receiving_7bit_alphabets__worker;
- let context = worker.ContextPool._contexts[0];
- let buf = context.Buf;
-
- function getUCS2RawBytes(expected) {
- buf.outgoingIndex = 0;
- context.GsmPDUHelper.writeUCS2String(expected);
-
- let subArray = buf.outgoingBytes.subarray(0, buf.outgoingIndex);
- return Array.slice(subArray);
- }
-
- for (let i = 0; i < text.length;) {
- let len = Math.min(70, text.length - i);
- let expected = text.substring(i, i + len);
- let rawBytes = getUCS2RawBytes(expected);
- let pdu = composeUcs2Pdu(rawBytes);
- add_test_receiving_sms(expected, pdu);
-
- i += len;
- }
-}
-
-var ucs2str = "";
-for (let lst = 0; lst < PDU_NL_LOCKING_SHIFT_TABLES.length; lst++) {
- ucs2str += PDU_NL_LOCKING_SHIFT_TABLES[lst];
- for (let sst = 0; sst < PDU_NL_SINGLE_SHIFT_TABLES.length; sst++) {
- test_receiving_7bit_alphabets(lst, sst);
-
- if (lst == 0) {
- ucs2str += PDU_NL_SINGLE_SHIFT_TABLES[sst];
- }
- }
-}
-test_receiving_ucs2_alphabets(ucs2str);
-
-// Bug 820220: B2G SMS: wrong order and truncated content in multi-part messages
-add_test(function test_sendSMS_UCS2_without_langIndex_langShiftIndex_defined() {
- let worker = newWriteHexOctetAsUint8Worker();
- let context = worker.ContextPool._contexts[0];
-
- context.Buf.sendParcel = function() {
- // Each sendParcel() call represents one outgoing segment of a multipart
- // SMS message. Here, we have the first segment send, so it's "Hello "
- // only.
- //
- // 4(parcel size) + 4(request type) + 4(token)
- // + 4(two messages) + 4(null SMSC) + 4(message string length)
- // + 1(first octet) + 1(message reference)
- // + 2(DA len, TOA) + 4(addr)
- // + 1(pid) + 1(dcs)
- // + 1(UDL) + 6(UDHL, type, len, ref, max, seq)
- // + 12(2 * strlen("Hello "))
- // + 4(two delimitors) = 57
- //
- // If we have additional 6(type, len, langIndex, type len, langShiftIndex)
- // octets here, then bug 809553 is not fixed.
- equal(this.outgoingIndex, 57);
-
- run_next_test();
- };
-
- context.RIL.sendSMS({
- number: "1",
- segmentMaxSeq: 2,
- fullBody: "Hello World!",
- dcs: PDU_DCS_MSG_CODING_16BITS_ALPHABET,
- segmentRef16Bit: false,
- userDataHeaderLength: 5,
- requestStatusReport: true,
- segments: [
- {
- body: "Hello ",
- encodedBodyLength: 12,
- }, {
- body: "World!",
- encodedBodyLength: 12,
- }
- ],
- });
-});
diff --git a/dom/system/gonk/tests/test_ril_worker_sms_cdma.js b/dom/system/gonk/tests/test_ril_worker_sms_cdma.js
deleted file mode 100644
index 85d0b6e0c9..0000000000
--- a/dom/system/gonk/tests/test_ril_worker_sms_cdma.js
+++ /dev/null
@@ -1,298 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-subscriptLoader.loadSubScript("resource://gre/modules/ril_consts.js", this);
-
-function run_test() {
- run_next_test();
-}
-
-/*
- * Helper function to covert a HEX string to a byte array.
- *
- * @param hexString
- * A hexadecimal string of which the length is even.
- */
-function hexStringToBytes(hexString) {
- let bytes = [];
-
- let length = hexString.length;
-
- for (let i = 0; i < length; i += 2) {
- bytes.push(Number.parseInt(hexString.substr(i, 2), 16));
- }
-
- return bytes;
-}
-
-/*
- * Helper function to covert a byte array to a HEX string.
- *
- * @param bytes
- * Could be a regular byte array or Uint8Array.
- */
-function bytesToHexString(bytes) {
- let hexString = "";
- let hex;
-
- for (let i = 0; i < bytes.length; i++) {
- hex = bytes[i].toString(16).toUpperCase();
- if (hex.length === 1) {
- hexString += "0";
- }
- hexString += hex;
- }
-
- return hexString;
-}
-
-/*
- * Helper function to ecode Opaque UserData
- *
- * @param msg_type
- * PDU_CDMA_MSG_TYPE_SUBMIT or PDU_CDMA_MSG_TYPE_DELIVER
- * @param data
- * The byte array of opaque data to be encoded.
- */
-function encodeOpaqueUserData(bitBufferHelper, options) {
- let bearerDataBuffer = [];
- bitBufferHelper.startWrite(bearerDataBuffer);
-
- // Msg-Id
- bitBufferHelper.writeBits(PDU_CDMA_MSG_USERDATA_MSG_ID, 8);
- bitBufferHelper.writeBits(3, 8);
- bitBufferHelper.writeBits(options.msg_type, 4); // MSG_TYPE
- bitBufferHelper.writeBits(1, 16); // MSG_ID
- bitBufferHelper.flushWithPadding(); // HEADER_IND (1) + RESERVED (3)
-
- // User Data
- bitBufferHelper.writeBits(PDU_CDMA_MSG_USERDATA_BODY, 8);
- let dataLength = options.data.length;
- bitBufferHelper.writeBits(2 + dataLength, 8); // 2 bytes for MSG_ENCODING, NUM_FIELDS
- bitBufferHelper.writeBits(PDU_CDMA_MSG_CODING_OCTET, 5); //MSG_ENCODING
- // MSG_TYPE is omitted if MSG_ENCODING is CODING_OCTET
- bitBufferHelper.writeBits(dataLength, 8); // NUM_FIELDS
- for (let i = 0; i < dataLength; i++) { // CHARi
- bitBufferHelper.writeBits(options.data[i], 8);
- }
- bitBufferHelper.flushWithPadding(); // RESERVED (3 filling bits)
-
- return bearerDataBuffer;
-}
-
-function newSmsParcel(cdmaPduHelper, pdu) {
- return newIncomingParcel(-1,
- RESPONSE_TYPE_UNSOLICITED,
- UNSOLICITED_RESPONSE_CDMA_NEW_SMS,
- pduToParcelData(cdmaPduHelper, pdu));
-}
-
-/*
- * Helper function to encode PDU into Parcel.
- * See ril_cdma_sms.h for the structure definition of RIL_CDMA_SMS_Message
- *
- * @param teleservice
- * The Teleservice-Id of this PDU.
- * See PDU_CDMA_MSG_TELESERIVCIE_ID_XXX in ril_const.js.
- * @param address
- * The Orginating or Destinating address.
- * @param bearerData
- * The byte array of the encoded bearer data.
- */
-function pduToParcelData(cdmaPduHelper, pdu) {
-
- let addrInfo = cdmaPduHelper.encodeAddr(pdu.address);
- // Teleservice, isServicePresent, ServiceCategory,
- // addrInfo {digitMode, numberMode, numberType, numberPlan, address.length, address}
- // Sub Address
- // bearerData length, bearerData.
- let dataLength = 4 + 4 + 4
- + (5 + addrInfo.address.length) * 4
- + 3 * 4
- + 4 + pdu.bearerData.length * 4;
-
- let data = new Uint8Array(dataLength);
- let offset = 0;
-
- function writeInt(value) {
- data[offset++] = value & 0xFF;
- data[offset++] = (value >> 8) & 0xFF;
- data[offset++] = (value >> 16) & 0xFF;
- data[offset++] = (value >> 24) & 0xFF;
- }
-
- function writeByte(value) {
- data[offset++] = value & 0xFF;
- data[offset++] = 0;
- data[offset++] = 0;
- data[offset++] = 0;
- }
-
- // Teleservice
- writeInt(pdu.teleservice);
-
- // isServicePresent
- writeByte(0);
-
- // ServiceCategory
- writeInt(PDU_CDMA_MSG_CATEGORY_UNSPEC);
-
- // AddrInfo
- writeByte(addrInfo.digitMode);
- writeByte(addrInfo.numberMode);
- writeByte(addrInfo.numberType);
- writeByte(addrInfo.numberPlan);
- let addressLength = addrInfo.address.length;
- writeByte(addressLength);
- for (let i = 0; i < addressLength; i++) {
- writeByte(addrInfo.address[i]);
- }
-
- // Subaddress
- writeByte(0);
- writeByte(0);
- writeByte(0);
-
- // Bearer Data Length
- dataLength = pdu.bearerData.length;
- writeByte(dataLength);
-
- // Bearer Data
- for (let i = 0; i < dataLength; i++) {
- writeByte(pdu.bearerData[i]);
- }
-
- return data;
-}
-
-/**
- * Verify CDMA SMS Delivery ACK Message.
- */
-add_test(function test_processCdmaSmsStatusReport() {
- let workerHelper = newInterceptWorker();
- let worker = workerHelper.worker;
- let context = worker.ContextPool._contexts[0];
-
- function test_StatusReport(errorClass, msgStatus) {
- let msgId = 0;
- let sentSmsMap = context.RIL._pendingSentSmsMap;
-
- sentSmsMap[msgId] = {};
-
- let message = {
- SMSC: "",
- mti: 0,
- udhi: 0,
- sender: "0987654321",
- recipient: null,
- pid: PDU_PID_DEFAULT,
- epid: PDU_PID_DEFAULT,
- dcs: 0,
- mwi: null,
- replace: false,
- header: null,
- body: "Status: Sent, Dest: 0987654321",
- data: null,
- timestamp: new Date().valueOf(),
- language: null,
- status: null,
- scts: null,
- dt: null,
- encoding: PDU_CDMA_MSG_CODING_7BITS_ASCII,
- messageClass: GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_NORMAL],
- messageType: PDU_CDMA_MSG_TYPE_P2P,
- serviceCategory: 0,
- subMsgType: PDU_CDMA_MSG_TYPE_DELIVER_ACK,
- msgId: msgId,
- errorClass: errorClass,
- msgStatus: msgStatus
- };
-
- context.RIL._processCdmaSmsStatusReport(message);
-
- let postedMessage = workerHelper.postedMessage;
-
- // Check if pending token is removed.
- ok((errorClass === 2) ? !!sentSmsMap[msgId] : !sentSmsMap[msgId]);
-
- // Check the response message accordingly.
- if (errorClass === -1) {
- // Check if the report is treated as normal incoming SMS
- equal("sms-received", postedMessage.rilMessageType);
- } else if (errorClass === 2) {
- // Do nothing.
- } else {
- // Check Delivery Status
- if (errorClass === 0) {
- equal(postedMessage.deliveryStatus, GECKO_SMS_DELIVERY_STATUS_SUCCESS);
- } else {
- equal(postedMessage.deliveryStatus, GECKO_SMS_DELIVERY_STATUS_ERROR);
- }
- }
- }
-
- test_StatusReport(-1, -1); // Message Status Sub-parameter is absent.
- test_StatusReport(0, 0); // 00|000000: no error|Message accepted
- test_StatusReport(2, 4); // 10|000100: temporary condition|Network congestion
- test_StatusReport(3, 5); // 11|000101: permanent condition|Network error
-
- run_next_test();
-});
-
-/**
- * Verify WAP Push over CDMA SMS Message.
- */
-add_test(function test_processCdmaSmsWapPush() {
- let workerHelper = newInterceptWorker(),
- worker = workerHelper.worker,
- context = worker.ContextPool._contexts[0],
- bitBufferHelper = context.BitBufferHelper,
- cdmaPduHelper = context.CdmaPDUHelper;
-
- function test_CdmaSmsWapPdu(wdpData, reversed) {
- let orig_address = "0987654321",
- hexString,
- fullDataHexString = "";
-
- for (let i = 0; i < wdpData.length; i++) {
- let dataIndex = (reversed) ? (wdpData.length - i - 1) : i;
- hexString = "00"; // MSG_TYPE
- hexString += bytesToHexString([wdpData.length]); // TOTAL_SEG
- hexString += bytesToHexString([dataIndex]); // SEG_NUM (zero-based)
- if ((dataIndex === 0)) {
- hexString += "23F00B84"; // SOURCE_PORT, DEST_PORT for 1st segment
- }
- hexString += wdpData[dataIndex]; // WDP DATA
-
- do_print("hexString: " + hexString);
-
- fullDataHexString += wdpData[i];
-
- let pdu = {
- teleservice: PDU_CDMA_MSG_TELESERIVCIE_ID_WAP,
- address: orig_address,
- bearerData: encodeOpaqueUserData(bitBufferHelper,
- { msg_type: PDU_CDMA_MSG_TYPE_DELIVER,
- data: hexStringToBytes(hexString) })
- };
-
- worker.onRILMessage(0, newSmsParcel(cdmaPduHelper, pdu));
- }
-
- let postedMessage = workerHelper.postedMessage;
-
- do_print("fullDataHexString: " + fullDataHexString);
-
- equal("sms-received", postedMessage.rilMessageType);
- equal(PDU_CDMA_MSG_TELESERIVCIE_ID_WAP, postedMessage.teleservice);
- equal(orig_address, postedMessage.sender);
- equal(0x23F0, postedMessage.header.originatorPort);
- equal(0x0B84, postedMessage.header.destinationPort);
- equal(fullDataHexString, bytesToHexString(postedMessage.data));
- }
-
- // Verify Single WAP PDU
- test_CdmaSmsWapPdu(["000102030405060708090A0B0C0D0E0F"]);
-
- run_next_test();
-});
diff --git a/dom/system/gonk/tests/test_ril_worker_sms_cdmapduhelper.js b/dom/system/gonk/tests/test_ril_worker_sms_cdmapduhelper.js
deleted file mode 100644
index 276728f2fb..0000000000
--- a/dom/system/gonk/tests/test_ril_worker_sms_cdmapduhelper.js
+++ /dev/null
@@ -1,210 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-subscriptLoader.loadSubScript("resource://gre/modules/ril_consts.js", this);
-
-function run_test() {
- run_next_test();
-}
-
-/**
- * Verify CdmaPDUHelper#encodeUserDataReplyOption.
- */
-add_test(function test_CdmaPDUHelper_encodeUserDataReplyOption() {
- let worker = newWorker({
- postRILMessage: function(data) {
- // Do nothing
- },
- postMessage: function(message) {
- // Do nothing
- }
- });
- let context = worker.ContextPool._contexts[0];
-
- let testDataBuffer = [];
- context.BitBufferHelper.startWrite(testDataBuffer);
-
- let helper = context.CdmaPDUHelper;
- helper.encodeUserDataReplyOption({requestStatusReport: true});
-
- let expectedDataBuffer = [PDU_CDMA_MSG_USERDATA_REPLY_OPTION, 0x01, 0x40];
-
- equal(testDataBuffer.length, expectedDataBuffer.length);
-
- for (let i = 0; i < expectedDataBuffer.length; i++) {
- equal(testDataBuffer[i], expectedDataBuffer[i]);
- }
-
- run_next_test();
-});
-
-/**
- * Verify CdmaPDUHelper#cdma_decodeUserDataMsgStatus.
- */
-add_test(function test_CdmaPDUHelper_decodeUserDataMsgStatus() {
- let worker = newWorker({
- postRILMessage: function(data) {
- // Do nothing
- },
- postMessage: function(message) {
- // Do nothing
- }
- });
- let context = worker.ContextPool._contexts[0];
-
- let helper = context.CdmaPDUHelper;
- function test_MsgStatus(octet) {
- let testDataBuffer = [octet];
- context.BitBufferHelper.startRead(testDataBuffer);
- let result = helper.decodeUserDataMsgStatus();
-
- equal(result.errorClass, octet >>> 6);
- equal(result.msgStatus, octet & 0x3F);
- }
-
- // 00|000000: no error|Message accepted
- test_MsgStatus(0x00);
-
- // 10|000100: temporary condition|Network congestion
- test_MsgStatus(0x84);
-
- // 11|000101: permanent condition|Network error
- test_MsgStatus(0xC5);
-
- run_next_test();
-});
-
-/**
- * Verify CdmaPDUHelper#decodeCdmaPDUMsg.
- * - encoding by shift-jis
- */
-add_test(function test_CdmaPDUHelper_decodeCdmaPDUMsg_Shift_jis() {
- let worker = newWorker({
- postRILMessage: function(data) {
- // Do nothing
- },
- postMessage: function(message) {
- // Do nothing
- }
- });
- let context = worker.ContextPool._contexts[0];
-
- let helper = context.CdmaPDUHelper;
- function test_decodePDUMsg(testDataBuffer, expected, encoding, msgType, msgBodySize) {
- context.BitBufferHelper.startRead(testDataBuffer);
- let result = helper.decodeCdmaPDUMsg(encoding, msgType, msgBodySize);
- equal(result, expected);
- }
-
- // Shift-JIS has 1 byte and 2 byte code for one character and has some types of characters:
- // Hiragana, Kanji, Katakana(fullwidth, halfwidth)...
- // This test is a combination of 1 byte and 2 byte code and types of characters.
-
- // test case 1
- let testDataBuffer1 = [0x82, 0x58, 0x33, 0x41, 0x61, 0x33, 0x82, 0x60,
- 0x82, 0x81, 0x33, 0xB1, 0xAF, 0x33, 0x83, 0x41,
- 0x83, 0x96, 0x33, 0x82, 0xA0, 0x33, 0x93, 0xFA,
- 0x33, 0x3A, 0x3C, 0x33, 0x81, 0x80, 0x81, 0x8E,
- 0x33, 0x31, 0x82, 0x51, 0x41, 0x61, 0x82, 0x51,
- 0x82, 0x60, 0x82, 0x81, 0x82, 0x51, 0xB1, 0xAF,
- 0x82, 0x51, 0x83, 0x41, 0x83, 0x96, 0x82, 0x51,
- 0x82, 0xA0, 0x82, 0x51, 0x93, 0xFA, 0x82, 0x51,
- 0x3A, 0x3C, 0x82, 0x51, 0x81, 0x80, 0x81, 0x8E,
- 0x82, 0x51];
-
- test_decodePDUMsg(
- testDataBuffer1,
- "\uFF19\u0033\u0041\u0061\u0033\uFF21\uFF41\u0033\uFF71\uFF6F\u0033\u30A2\u30F6\u0033\u3042\u0033\u65E5\u0033\u003A\u003C\u0033\u00F7\u2103\u0033\u0031\uFF12\u0041\u0061\uFF12\uFF21\uFF41\uFF12\uFF71\uFF6F\uFF12\u30A2\u30F6\uFF12\u3042\uFF12\u65E5\uFF12\u003A\u003C\uFF12\u00F7\u2103\uFF12",
- PDU_CDMA_MSG_CODING_SHIFT_JIS,
- undefined,
- testDataBuffer1.length
- );
-
- // test case 2
- let testDataBuffer2 = [0x31, 0x51, 0x63, 0x82, 0x58, 0x51, 0x63, 0x82,
- 0x60, 0x82, 0x81, 0x51, 0x63, 0xB1, 0xAF, 0x51,
- 0x63, 0x83, 0x41, 0x83, 0x96, 0x51, 0x63, 0x82,
- 0xA0, 0x51, 0x63, 0x93, 0xFA, 0x51, 0x63, 0x3A,
- 0x3C, 0x51, 0x63, 0x81, 0x80, 0x81, 0x8E, 0x51,
- 0x63, 0x31, 0x82, 0x70, 0x82, 0x85, 0x82, 0x58,
- 0x82, 0x70, 0x82, 0x85, 0x41, 0x61, 0x82, 0x70,
- 0x82, 0x85, 0xB1, 0xAF, 0x82, 0x70, 0x82, 0x85,
- 0x83, 0x41, 0x83, 0x96, 0x82, 0x70, 0x82, 0x85,
- 0x82, 0xA0, 0x82, 0x70, 0x82, 0x85, 0x93, 0xFA,
- 0x82, 0x70, 0x82, 0x85, 0x3A, 0x3C, 0x82, 0x70,
- 0x82, 0x85, 0x81, 0x80, 0x81, 0x8E, 0x82, 0x70,
- 0x82, 0x85];
-
- test_decodePDUMsg(
- testDataBuffer2,
- "\u0031\u0051\u0063\uFF19\u0051\u0063\uFF21\uFF41\u0051\u0063\uFF71\uFF6F\u0051\u0063\u30A2\u30F6\u0051\u0063\u3042\u0051\u0063\u65E5\u0051\u0063\u003A\u003C\u0051\u0063\u00F7\u2103\u0051\u0063\u0031\uFF31\uFF45\uFF19\uFF31\uFF45\u0041\u0061\uFF31\uFF45\uFF71\uFF6F\uFF31\uFF45\u30A2\u30F6\uFF31\uFF45\u3042\uFF31\uFF45\u65E5\uFF31\uFF45\u003A\u003C\uFF31\uFF45\u00F7\u2103\uFF31\uFF45",
- PDU_CDMA_MSG_CODING_SHIFT_JIS,
- undefined,
- testDataBuffer2.length
- );
-
- // test case 3
- let testDataBuffer3 = [0x31, 0xC2, 0xDF, 0x82, 0x58, 0xC2, 0xDF, 0x41,
- 0x61, 0xC2, 0xDF, 0x82, 0x60, 0x82, 0x81, 0xC2,
- 0xDF, 0x83, 0x41, 0x83, 0x96, 0xC2, 0xDF, 0x82,
- 0xA0, 0xC2, 0xDF, 0x93, 0xFA, 0xC2, 0xDF, 0x3A,
- 0x3C, 0xC2, 0xDF, 0x81, 0x80, 0x81, 0x8E, 0xC2,
- 0xDF, 0x31, 0x83, 0x51, 0x83, 0x87, 0x82, 0x58,
- 0x83, 0x51, 0x83, 0x87, 0x41, 0x61, 0x83, 0x51,
- 0x83, 0x87, 0x82, 0x60, 0x82, 0x81, 0x83, 0x51,
- 0x83, 0x87, 0xB1, 0xAF, 0x83, 0x51, 0x83, 0x87,
- 0x82, 0xA0, 0x83, 0x51, 0x83, 0x87, 0x93, 0xFA,
- 0x83, 0x51, 0x83, 0x87, 0x3A, 0x3C, 0x83, 0x51,
- 0x83, 0x87, 0x81, 0x80, 0x81, 0x8E, 0x83, 0x51,
- 0x83, 0x87];
-
- test_decodePDUMsg(
- testDataBuffer3,
- "\u0031\uFF82\uFF9F\uFF19\uFF82\uFF9F\u0041\u0061\uFF82\uFF9F\uFF21\uFF41\uFF82\uFF9F\u30A2\u30F6\uFF82\uFF9F\u3042\uFF82\uFF9F\u65E5\uFF82\uFF9F\u003A\u003C\uFF82\uFF9F\u00F7\u2103\uFF82\uFF9F\u0031\u30B2\u30E7\uFF19\u30B2\u30E7\u0041\u0061\u30B2\u30E7\uFF21\uFF41\u30B2\u30E7\uFF71\uFF6F\u30B2\u30E7\u3042\u30B2\u30E7\u65E5\u30B2\u30E7\u003A\u003C\u30B2\u30E7\u00F7\u2103\u30B2\u30E7",
- PDU_CDMA_MSG_CODING_SHIFT_JIS,
- undefined,
- testDataBuffer3.length
- );
-
- // test case 4
- let testDataBuffer4 = [0x31, 0x82, 0xB0, 0x82, 0x58, 0x82, 0xB0, 0x41,
- 0x61, 0x82, 0xB0, 0x82, 0x60, 0x82, 0x81, 0x82,
- 0xB0, 0xB1, 0xAF, 0x82, 0xB0, 0x83, 0x41, 0x83,
- 0x96, 0x82, 0xB0, 0x93, 0xFA, 0x82, 0xB0, 0x3A,
- 0x3C, 0x82, 0xB0, 0x81, 0x80, 0x81, 0x8E, 0x82,
- 0xB0, 0x31, 0x88, 0xA4, 0x82, 0x58, 0x88, 0xA4,
- 0x41, 0x61, 0x88, 0xA4, 0x82, 0x60, 0x82, 0x81,
- 0x88, 0xA4, 0xB1, 0xAF, 0x88, 0xA4, 0x83, 0x41,
- 0x83, 0x96, 0x88, 0xA4, 0x82, 0xA0, 0x88, 0xA4,
- 0x3A, 0x3C, 0x88, 0xA4, 0x81, 0x80, 0x81, 0x8E,
- 0x88, 0xA4];
-
- test_decodePDUMsg(
- testDataBuffer4,
- "\u0031\u3052\uFF19\u3052\u0041\u0061\u3052\uFF21\uFF41\u3052\uFF71\uFF6F\u3052\u30A2\u30F6\u3052\u65E5\u3052\u003A\u003C\u3052\u00F7\u2103\u3052\u0031\u611B\uFF19\u611B\u0041\u0061\u611B\uFF21\uFF41\u611B\uFF71\uFF6F\u611B\u30A2\u30F6\u611B\u3042\u611B\u003A\u003C\u611B\u00F7\u2103\u611B",
- PDU_CDMA_MSG_CODING_SHIFT_JIS,
- undefined,
- testDataBuffer4.length
- );
-
- // test case 5
- let testDataBuffer5 = [0x31, 0x40, 0x82, 0x58, 0x40, 0x41, 0x61, 0x40,
- 0x82, 0x60, 0x82, 0x81, 0x40, 0xB1, 0xAF, 0x40,
- 0x83, 0x41, 0x83, 0x96, 0x40, 0x82, 0xA0, 0x40,
- 0x93, 0xFA, 0x40, 0x81, 0x80, 0x81, 0x8E, 0x40,
- 0x31, 0x81, 0x9B, 0x82, 0x58, 0x81, 0x9B, 0x41,
- 0x61, 0x81, 0x9B, 0x82, 0x60, 0x82, 0x81, 0x81,
- 0x9B, 0xB1, 0xAF, 0x81, 0x9B, 0x83, 0x41, 0x83,
- 0x96, 0x81, 0x9B, 0x82, 0xA0, 0x81, 0x9B, 0x93,
- 0xFA, 0x81, 0x9B, 0x3A, 0x3C, 0x81, 0x9B];
-
- test_decodePDUMsg(
- testDataBuffer5,
- "\u0031\u0040\uFF19\u0040\u0041\u0061\u0040\uFF21\uFF41\u0040\uFF71\uFF6F\u0040\u30A2\u30F6\u0040\u3042\u0040\u65E5\u0040\u00F7\u2103\u0040\u0031\u25CB\uFF19\u25CB\u0041\u0061\u25CB\uFF21\uFF41\u25CB\uFF71\uFF6F\u25CB\u30A2\u30F6\u25CB\u3042\u25CB\u65E5\u25CB\u003A\u003C\u25CB",
- PDU_CDMA_MSG_CODING_SHIFT_JIS,
- undefined,
- testDataBuffer5.length
- );
-
- run_next_test();
-});
diff --git a/dom/system/gonk/tests/test_ril_worker_sms_gsmpduhelper.js b/dom/system/gonk/tests/test_ril_worker_sms_gsmpduhelper.js
deleted file mode 100644
index f52c64cf85..0000000000
--- a/dom/system/gonk/tests/test_ril_worker_sms_gsmpduhelper.js
+++ /dev/null
@@ -1,282 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-subscriptLoader.loadSubScript("resource://gre/modules/ril_consts.js", this);
-
-function run_test() {
- run_next_test();
-}
-
-/**
- * Verify GsmPDUHelper#readDataCodingScheme.
- */
-add_test(function test_GsmPDUHelper_readDataCodingScheme() {
- let worker = newWorker({
- postRILMessage: function(data) {
- // Do nothing
- },
- postMessage: function(message) {
- // Do nothing
- }
- });
-
- let context = worker.ContextPool._contexts[0];
- let helper = context.GsmPDUHelper;
- function test_dcs(dcs, encoding, messageClass, mwi) {
- helper.readHexOctet = function() {
- return dcs;
- }
-
- let msg = {};
- helper.readDataCodingScheme(msg);
-
- equal(msg.dcs, dcs);
- equal(msg.encoding, encoding);
- equal(msg.messageClass, messageClass);
- equal(msg.mwi == null, mwi == null);
- if (mwi != null) {
- equal(msg.mwi.active, mwi.active);
- equal(msg.mwi.discard, mwi.discard);
- equal(msg.mwi.msgCount, mwi.msgCount);
- }
- }
-
- // Group 00xx
- // Bit 3 and 2 indicate the character set being used.
- test_dcs(0x00, PDU_DCS_MSG_CODING_7BITS_ALPHABET,
- GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_NORMAL]);
- test_dcs(0x04, PDU_DCS_MSG_CODING_8BITS_ALPHABET,
- GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_NORMAL]);
- test_dcs(0x08, PDU_DCS_MSG_CODING_16BITS_ALPHABET,
- GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_NORMAL]);
- test_dcs(0x0C, PDU_DCS_MSG_CODING_7BITS_ALPHABET,
- GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_NORMAL]);
- // Bit 4, if set to 0, indicates that bits 1 to 0 are reserved and have no
- // message class meaning.
- test_dcs(0x01, PDU_DCS_MSG_CODING_7BITS_ALPHABET,
- GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_NORMAL]);
- test_dcs(0x02, PDU_DCS_MSG_CODING_7BITS_ALPHABET,
- GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_NORMAL]);
- test_dcs(0x03, PDU_DCS_MSG_CODING_7BITS_ALPHABET,
- GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_NORMAL]);
- // Bit 4, if set to 1, indicates that bits 1 to 0 have a message class meaning.
- test_dcs(0x10, PDU_DCS_MSG_CODING_7BITS_ALPHABET,
- GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_0]);
- test_dcs(0x11, PDU_DCS_MSG_CODING_7BITS_ALPHABET,
- GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_1]);
- test_dcs(0x12, PDU_DCS_MSG_CODING_7BITS_ALPHABET,
- GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_2]);
- test_dcs(0x13, PDU_DCS_MSG_CODING_7BITS_ALPHABET,
- GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_3]);
-
- // Group 01xx
- test_dcs(0x50, PDU_DCS_MSG_CODING_7BITS_ALPHABET,
- GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_0]);
-
- // Group 1000..1011: reserved
- test_dcs(0x8F, PDU_DCS_MSG_CODING_7BITS_ALPHABET,
- GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_NORMAL]);
- test_dcs(0x9F, PDU_DCS_MSG_CODING_7BITS_ALPHABET,
- GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_NORMAL]);
- test_dcs(0xAF, PDU_DCS_MSG_CODING_7BITS_ALPHABET,
- GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_NORMAL]);
- test_dcs(0xBF, PDU_DCS_MSG_CODING_7BITS_ALPHABET,
- GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_NORMAL]);
-
- // Group 1100: Message Waiting Indication Group: Discard Message
- // Bit 3 indicates Indication Sense:
- test_dcs(0xC0, PDU_DCS_MSG_CODING_7BITS_ALPHABET,
- GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_NORMAL],
- {active: false, discard: true, msgCount: 0});
- test_dcs(0xC8, PDU_DCS_MSG_CODING_7BITS_ALPHABET,
- GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_NORMAL],
- {active: true, discard: true, msgCount: -1});
- // Bit 2 is reserved, and set to 0:
- test_dcs(0xCC, PDU_DCS_MSG_CODING_7BITS_ALPHABET,
- GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_NORMAL],
- {active: true, discard: true, msgCount: -1});
-
- // Group 1101: Message Waiting Indication Group: Store Message
- // Bit 3 indicates Indication Sense:
- test_dcs(0xD0, PDU_DCS_MSG_CODING_7BITS_ALPHABET,
- GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_NORMAL],
- {active: false, discard: false, msgCount: 0});
- test_dcs(0xD8, PDU_DCS_MSG_CODING_7BITS_ALPHABET,
- GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_NORMAL],
- {active: true, discard: false, msgCount: -1});
- // Bit 2 is reserved, and set to 0:
- test_dcs(0xDC, PDU_DCS_MSG_CODING_7BITS_ALPHABET,
- GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_NORMAL],
- {active: true, discard: false, msgCount: -1});
-
- // Group 1110: Message Waiting Indication Group: Store Message, UCS2
- // Bit 3 indicates Indication Sense:
- test_dcs(0xE0, PDU_DCS_MSG_CODING_16BITS_ALPHABET,
- GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_NORMAL],
- {active: false, discard: false, msgCount: 0});
- test_dcs(0xE8, PDU_DCS_MSG_CODING_16BITS_ALPHABET,
- GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_NORMAL],
- {active: true, discard: false, msgCount: -1});
- // Bit 2 is reserved, and set to 0:
- test_dcs(0xEC, PDU_DCS_MSG_CODING_16BITS_ALPHABET,
- GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_NORMAL],
- {active: true, discard: false, msgCount: -1});
-
- // Group 1111
- test_dcs(0xF0, PDU_DCS_MSG_CODING_7BITS_ALPHABET,
- GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_0]);
- test_dcs(0xF1, PDU_DCS_MSG_CODING_7BITS_ALPHABET,
- GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_1]);
- test_dcs(0xF2, PDU_DCS_MSG_CODING_7BITS_ALPHABET,
- GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_2]);
- test_dcs(0xF3, PDU_DCS_MSG_CODING_7BITS_ALPHABET,
- GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_3]);
- test_dcs(0xF4, PDU_DCS_MSG_CODING_8BITS_ALPHABET,
- GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_0]);
- test_dcs(0xF5, PDU_DCS_MSG_CODING_8BITS_ALPHABET,
- GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_1]);
- test_dcs(0xF6, PDU_DCS_MSG_CODING_8BITS_ALPHABET,
- GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_2]);
- test_dcs(0xF7, PDU_DCS_MSG_CODING_8BITS_ALPHABET,
- GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_3]);
- // Bit 3 is reserved and should be set to 0, but if it doesn't we should
- // ignore it.
- test_dcs(0xF8, PDU_DCS_MSG_CODING_7BITS_ALPHABET,
- GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_0]);
-
- run_next_test();
-});
-
-/**
- * Verify GsmPDUHelper#writeStringAsSeptets() padding bits handling.
- */
-add_test(function test_GsmPDUHelper_writeStringAsSeptets() {
- let worker = newWorker({
- postRILMessage: function(data) {
- // Do nothing
- },
- postMessage: function(message) {
- // Do nothing
- }
- });
-
- let context = worker.ContextPool._contexts[0];
- let helper = context.GsmPDUHelper;
- helper.resetOctetWritten = function() {
- helper.octetsWritten = 0;
- };
- helper.writeHexOctet = function() {
- helper.octetsWritten++;
- };
-
- let base = "AAAAAAAA"; // Base string of 8 characters long
- for (let len = 0; len < 8; len++) {
- let str = base.substring(0, len);
-
- for (let paddingBits = 0; paddingBits < 8; paddingBits++) {
- do_print("Verifying GsmPDUHelper.writeStringAsSeptets("
- + str + ", " + paddingBits + ", <default>, <default>)");
- helper.resetOctetWritten();
- helper.writeStringAsSeptets(str, paddingBits, PDU_NL_IDENTIFIER_DEFAULT,
- PDU_NL_IDENTIFIER_DEFAULT);
- equal(Math.ceil(((len * 7) + paddingBits) / 8),
- helper.octetsWritten);
- }
- }
-
- run_next_test();
-});
-
-/**
- * Verify that encoding with Spanish locking shift table generates the same
- * septets as with GSM default alphabet table.
- *
- * Bug 1138841 - Incorrect Spanish national language locking shift table
- * definition.
- */
-add_test(function test_GsmPDUHelper_writeStringAsSeptets_spanish_fallback() {
- let worker = newWorker({
- postRILMessage: function(data) {
- // Do nothing
- },
- postMessage: function(message) {
- // Do nothing
- }
- });
-
- let context = worker.ContextPool._contexts[0];
- let helper = context.GsmPDUHelper;
- let buf = [];
- helper.writeHexOctet = function(octet) {
- buf.push(octet);
- }
-
- // Simple message string which is covered by GSM default alphabet.
- let msg = "The quick brown fox jumps over the lazy dog";
-
- // Encoded with GSM default alphabet.
- helper.writeStringAsSeptets(msg, 0 /* paddingBits */,
- PDU_NL_IDENTIFIER_DEFAULT, PDU_NL_IDENTIFIER_DEFAULT);
- let octetsWithDefaultTable = buf;
- buf = [];
-
- // Encoded with Spanish locking shift table.
- helper.writeStringAsSeptets(msg, 0 /* paddingBits */,
- PDU_NL_IDENTIFIER_SPANISH, PDU_NL_IDENTIFIER_SPANISH);
-
- // The length and content should be equal to what encoded with GSM default
- // alphabet.
- equal(octetsWithDefaultTable.length, buf.length);
- for (let i = 0; i < buf.length; i++) {
- equal(octetsWithDefaultTable[i], buf[i]);
- }
-
- run_next_test();
-});
-
-/**
- * Verify GsmPDUHelper#readAddress
- */
-add_test(function test_GsmPDUHelper_readAddress() {
- let worker = newWorker({
- postRILMessage: function(data) {
- // Do nothing
- },
- postMessage: function(message) {
- // Do nothing
- }
- });
-
- let context = worker.ContextPool._contexts[0];
- let helper = context.GsmPDUHelper;
- function test_address(addrHex, addrString) {
- let uint16Array = [];
- let ix = 0;
- for (let i = 0; i < addrHex.length; ++i) {
- uint16Array[i] = addrHex[i].charCodeAt();
- }
-
- context.Buf.readUint16 = function(){
- if(ix >= uint16Array.length) {
- do_throw("out of range in uint16Array");
- }
- return uint16Array[ix++];
- }
- let length = helper.readHexOctet();
- let parsedAddr = helper.readAddress(length);
- equal(parsedAddr, addrString);
- }
-
- // For AlphaNumeric
- test_address("04D01100", "_@");
- test_address("04D01000", "\u0394@");
-
- // Direct prepand
- test_address("0B914151245584F6", "+14154255486");
- test_address("0E914151245584B633", "+14154255486#33");
-
- // PDU_TOA_NATIONAL
- test_address("0BA14151245584F6", "14154255486");
-
- run_next_test();
-});
diff --git a/dom/system/gonk/tests/test_ril_worker_sms_nl_tables.js b/dom/system/gonk/tests/test_ril_worker_sms_nl_tables.js
deleted file mode 100644
index 32bc5dc2ae..0000000000
--- a/dom/system/gonk/tests/test_ril_worker_sms_nl_tables.js
+++ /dev/null
@@ -1,77 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-subscriptLoader.loadSubScript("resource://gre/modules/ril_consts.js", this);
-
-const ESCAPE = "\uffff";
-const RESCTL = "\ufffe";
-const LF = "\n";
-const CR = "\r";
-const SP = " ";
-const FF = "\u000c";
-
-function run_test() {
- run_next_test();
-}
-
-/**
- * Verify validity of the national language tables
- */
-add_test(function test_nl_locking_shift_tables_validity() {
- for (let lst = 0; lst < PDU_NL_LOCKING_SHIFT_TABLES.length; lst++) {
- do_print("Verifying PDU_NL_LOCKING_SHIFT_TABLES[" + lst + "]");
-
- let table = PDU_NL_LOCKING_SHIFT_TABLES[lst];
-
- // Make sure table length is 128, or it will break table lookup algorithm.
- equal(table.length, 128);
-
- // Make sure special values are preserved.
- equal(table[PDU_NL_EXTENDED_ESCAPE], ESCAPE);
- equal(table[PDU_NL_LINE_FEED], LF);
- equal(table[PDU_NL_CARRIAGE_RETURN], CR);
- equal(table[PDU_NL_SPACE], SP);
- }
-
- run_next_test();
-});
-
-add_test(function test_nl_single_shift_tables_validity() {
- for (let sst = 0; sst < PDU_NL_SINGLE_SHIFT_TABLES.length; sst++) {
- do_print("Verifying PDU_NL_SINGLE_SHIFT_TABLES[" + sst + "]");
-
- let table = PDU_NL_SINGLE_SHIFT_TABLES[sst];
-
- // Make sure table length is 128, or it will break table lookup algorithm.
- equal(table.length, 128);
-
- // Make sure special values are preserved.
- equal(table[PDU_NL_EXTENDED_ESCAPE], ESCAPE);
- equal(table[PDU_NL_PAGE_BREAK], FF);
- equal(table[PDU_NL_RESERVED_CONTROL], RESCTL);
- }
-
- run_next_test();
-});
-
-add_test(function test_gsm_sms_strict_7bit_charmap_validity() {
- let defaultTable = PDU_NL_LOCKING_SHIFT_TABLES[PDU_NL_IDENTIFIER_DEFAULT];
- let defaultShiftTable = PDU_NL_SINGLE_SHIFT_TABLES[PDU_NL_IDENTIFIER_DEFAULT];
- for (let from in GSM_SMS_STRICT_7BIT_CHARMAP) {
- let to = GSM_SMS_STRICT_7BIT_CHARMAP[from];
- do_print("Verifying GSM_SMS_STRICT_7BIT_CHARMAP[\"\\u0x"
- + from.charCodeAt(0).toString(16) + "\"] => \"\\u"
- + to.charCodeAt(0).toString(16) + "\"");
-
- // Make sure "from" is not in default table
- equal(defaultTable.indexOf(from), -1);
- equal(defaultShiftTable.indexOf(from), -1);
- // Make sure "to" is in default table
- if ((defaultTable.indexOf(to) < 0)
- && (defaultShiftTable.indexOf(to) < 0)) {
- equal(false, true);
- }
- }
-
- run_next_test();
-});
diff --git a/dom/system/gonk/tests/test_ril_worker_sms_segment_info.js b/dom/system/gonk/tests/test_ril_worker_sms_segment_info.js
deleted file mode 100644
index 2b29ac60eb..0000000000
--- a/dom/system/gonk/tests/test_ril_worker_sms_segment_info.js
+++ /dev/null
@@ -1,115 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-subscriptLoader.loadSubScript("resource://gre/modules/ril_consts.js", this);
-
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-
-XPCOMUtils.defineLazyGetter(this, "gSmsSegmentHelper", function() {
- let ns = {};
- Cu.import("resource://gre/modules/SmsSegmentHelper.jsm", ns);
- return ns.SmsSegmentHelper;
-});
-
-const ESCAPE = "\uffff";
-const RESCTL = "\ufffe";
-
-function run_test() {
- run_next_test();
-}
-
-/**
- * Verify SmsSegmentHelper#countGsm7BitSeptets() and
- * GsmPDUHelper#writeStringAsSeptets() algorithm match each other.
- */
-add_test(function test_SmsSegmentHelper__countGsm7BitSeptets() {
- let worker = newWorker({
- postRILMessage: function(data) {
- // Do nothing
- },
- postMessage: function(message) {
- // Do nothing
- }
- });
-
- let context = worker.ContextPool._contexts[0];
- let helper = context.GsmPDUHelper;
- helper.resetOctetWritten = function() {
- helper.octetsWritten = 0;
- };
- helper.writeHexOctet = function() {
- helper.octetsWritten++;
- };
-
- function do_check_calc(str, expectedCalcLen, lst, sst, strict7BitEncoding, strToWrite) {
- equal(expectedCalcLen,
- gSmsSegmentHelper
- .countGsm7BitSeptets(str,
- PDU_NL_LOCKING_SHIFT_TABLES[lst],
- PDU_NL_SINGLE_SHIFT_TABLES[sst],
- strict7BitEncoding));
-
- helper.resetOctetWritten();
- strToWrite = strToWrite || str;
- helper.writeStringAsSeptets(strToWrite, 0, lst, sst);
- equal(Math.ceil(expectedCalcLen * 7 / 8), helper.octetsWritten);
- }
-
- // Test calculation encoded message length using both locking/single shift tables.
- for (let lst = 0; lst < PDU_NL_LOCKING_SHIFT_TABLES.length; lst++) {
- let langTable = PDU_NL_LOCKING_SHIFT_TABLES[lst];
-
- let str = langTable.substring(0, PDU_NL_EXTENDED_ESCAPE)
- + langTable.substring(PDU_NL_EXTENDED_ESCAPE + 1);
-
- for (let sst = 0; sst < PDU_NL_SINGLE_SHIFT_TABLES.length; sst++) {
- let langShiftTable = PDU_NL_SINGLE_SHIFT_TABLES[sst];
-
- // <escape>, <resctrl> should be ignored.
- do_check_calc(ESCAPE + RESCTL, 0, lst, sst);
-
- // Characters defined in locking shift table should be encoded directly.
- do_check_calc(str, str.length, lst, sst);
-
- let [str1, str2] = ["", ""];
- for (let i = 0; i < langShiftTable.length; i++) {
- if ((i == PDU_NL_EXTENDED_ESCAPE) || (i == PDU_NL_RESERVED_CONTROL)) {
- continue;
- }
-
- let c = langShiftTable[i];
- if (langTable.indexOf(c) >= 0) {
- str1 += c;
- } else {
- str2 += c;
- }
- }
-
- // Characters found in both locking/single shift tables should be
- // directly encoded.
- do_check_calc(str1, str1.length, lst, sst);
-
- // Characters found only in single shift tables should be encoded as
- // <escape><code>, therefore doubles its original length.
- do_check_calc(str2, str2.length * 2, lst, sst);
- }
- }
-
- // Bug 790192: support strict GSM SMS 7-Bit encoding
- let str = "", strToWrite = "", gsmLen = 0;
- for (let c in GSM_SMS_STRICT_7BIT_CHARMAP) {
- str += c;
- strToWrite += GSM_SMS_STRICT_7BIT_CHARMAP[c];
- if (PDU_NL_LOCKING_SHIFT_TABLES.indexOf(GSM_SMS_STRICT_7BIT_CHARMAP[c])) {
- gsmLen += 1;
- } else {
- gsmLen += 2;
- }
- }
- do_check_calc(str, gsmLen,
- PDU_NL_IDENTIFIER_DEFAULT, PDU_NL_IDENTIFIER_DEFAULT,
- true, strToWrite);
-
- run_next_test();
-});
-
diff --git a/dom/system/gonk/tests/test_ril_worker_smsc_address.js b/dom/system/gonk/tests/test_ril_worker_smsc_address.js
deleted file mode 100644
index c8c283b7c4..0000000000
--- a/dom/system/gonk/tests/test_ril_worker_smsc_address.js
+++ /dev/null
@@ -1,112 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-subscriptLoader.loadSubScript("resource://gre/modules/ril_consts.js", this);
-
-const SMSC_ATT = '+13123149810';
-const SMSC_ATT_TYPO = '+++1312@@@314$$$9,8,1,0';
-const SMSC_ATT_TEXT = '"+13123149810",145';
-const SMSC_ATT_TEXT_INCORRECT_TOA = '"+13123149810",129';
-const SMSC_ATT_PDU = '07913121139418F0';
-const SMSC_O2 = '+447802000332';
-const SMSC_O2_TEXT = '"+447802000332",145';
-const SMSC_O2_PDU = '0791448720003023';
-const SMSC_EMPTY = '';
-const SMSC_TON_UNKNOWN = '0407485455'
-const SMSC_TON_UNKNOWN_TEXT = '"0407485455",129';
-const SMSC_TON_UNKNOWN_TEXT_NO_TOA = '"0407485455"';
-const SMSC_TON_UNKNOWN_TEXT_INVALID_TOA = '"0407485455",abc';
-const SMSC_TON_UNKNOWN_PDU = '06814070844555';
-const SMSC_EMPTY_PDU = 'FFFFFFFFFFFFFFFFFFFFFFFF';
-const SMSC_EMPTY_TEXT = '';
-
-function run_test() {
- run_next_test();
-}
-
-function setSmsc(context, smsc, ton, npi, expected) {
- context.Buf.postRILMessage = function() {
- equal(this.readString(), expected);
- };
-
- context.RIL.setSmscAddress({
- smscAddress: smsc,
- typeOfNumber: ton,
- numberPlanIdentification: npi
- });
-}
-
-function getSmsc(worker, context, raw, smsc, ton, npi) {
- worker.postMessage = function(message) {
- equal(message.smscAddress, smsc);
- equal(message.typeOfNumber, ton);
- equal(message.numberPlanIdentification, npi);
- }
-
- context.Buf.writeString(raw);
- context.RIL[REQUEST_GET_SMSC_ADDRESS](0, { rilMessageType: "getSmscAddress"});
-}
-
-add_test(function test_setSmscAddress() {
- let worker = newUint8Worker();
- let context = worker.ContextPool._contexts[0];
- let parcelTypes = [];
- context.Buf.newParcel = (type, options) => parcelTypes.push(type);
-
- // Test text mode.
- worker.RILQUIRKS_SMSC_ADDRESS_FORMAT = "text";
-
- setSmsc(context, SMSC_ATT, 1, 1, SMSC_ATT_TEXT);
- equal(parcelTypes.pop(), REQUEST_SET_SMSC_ADDRESS);
-
- setSmsc(context, SMSC_O2, 1, 1, SMSC_O2_TEXT);
- equal(parcelTypes.pop(), REQUEST_SET_SMSC_ADDRESS);
-
- setSmsc(context, SMSC_ATT_TYPO, 1, 1, SMSC_ATT_TEXT);
- equal(parcelTypes.pop(), REQUEST_SET_SMSC_ADDRESS);
-
- setSmsc(context, SMSC_TON_UNKNOWN, 0, 1, SMSC_TON_UNKNOWN_TEXT);
- equal(parcelTypes.pop(), REQUEST_SET_SMSC_ADDRESS);
-
- // Test pdu mode.
- worker.RILQUIRKS_SMSC_ADDRESS_FORMAT = "pdu";
-
- setSmsc(context, SMSC_ATT, 1, 1, SMSC_ATT_PDU);
- equal(parcelTypes.pop(), REQUEST_SET_SMSC_ADDRESS);
-
- setSmsc(context, SMSC_O2, 1, 1, SMSC_O2_PDU);
- equal(parcelTypes.pop(), REQUEST_SET_SMSC_ADDRESS);
-
- setSmsc(context, SMSC_ATT_TYPO, 1, 1, SMSC_ATT_PDU);
- equal(parcelTypes.pop(), REQUEST_SET_SMSC_ADDRESS);
-
- setSmsc(context, SMSC_TON_UNKNOWN, 0, 1, SMSC_TON_UNKNOWN_PDU);
- equal(parcelTypes.pop(), REQUEST_SET_SMSC_ADDRESS);
-
- run_next_test();
-});
-
-add_test(function test_getSmscAddress() {
- let worker = newUint8Worker();
- let context = worker.ContextPool._contexts[0];
-
- // Test text mode.
- worker.RILQUIRKS_SMSC_ADDRESS_FORMAT = "text";
- getSmsc(worker, context, SMSC_ATT_TEXT, SMSC_ATT, 1, 1);
- getSmsc(worker, context, SMSC_ATT_TEXT_INCORRECT_TOA, SMSC_ATT, 1, 1);
- getSmsc(worker, context, SMSC_O2_TEXT, SMSC_O2, 1, 1);
- getSmsc(worker, context, SMSC_TON_UNKNOWN_TEXT, SMSC_TON_UNKNOWN, 0, 1);
- getSmsc(worker, context, SMSC_TON_UNKNOWN_TEXT_NO_TOA, SMSC_TON_UNKNOWN, 0, 1);
- getSmsc(worker, context, SMSC_TON_UNKNOWN_TEXT_INVALID_TOA, SMSC_TON_UNKNOWN,
- 0, 1);
- getSmsc(worker, context, SMSC_EMPTY_TEXT, SMSC_EMPTY, 0, 1);
-
- // Test pdu mode.
- worker.RILQUIRKS_SMSC_ADDRESS_FORMAT = "pdu";
- getSmsc(worker, context, SMSC_ATT_PDU, SMSC_ATT, 1, 1);
- getSmsc(worker, context, SMSC_O2_PDU, SMSC_O2, 1, 1);
- getSmsc(worker, context, SMSC_TON_UNKNOWN_PDU, SMSC_TON_UNKNOWN, 0, 1);
- getSmsc(worker, context, SMSC_EMPTY_PDU, SMSC_EMPTY, 0, 1);
-
- run_next_test();
-});
diff --git a/dom/system/gonk/tests/test_ril_worker_ssn.js b/dom/system/gonk/tests/test_ril_worker_ssn.js
deleted file mode 100644
index ea0a2a599b..0000000000
--- a/dom/system/gonk/tests/test_ril_worker_ssn.js
+++ /dev/null
@@ -1,104 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-subscriptLoader.loadSubScript("resource://gre/modules/ril_consts.js", this);
-
-function run_test() {
- run_next_test();
-}
-
-add_test(function test_notification() {
- let workerHelper = newInterceptWorker();
- let worker = workerHelper.worker;
- let context = worker.ContextPool._contexts[0];
-
- function Call(callIndex, number) {
- this.callIndex = callIndex;
- this.number = number;
- }
-
- Call.prototype = {
- // Should use CALL_STATE_ACTIVE.
- // Any new outgoing call (state = dialing or alerting) will be drop if there
- // is no pending outgoing call created before.
- state: CALL_STATE_ACTIVE,
- //callIndex: 0,
- toa: 0,
- isMpty: false,
- isMT: false,
- als: 0,
- isVoice: true,
- isVoicePrivacy: false,
- //number: null,
- numberPresentation: 0,
- name: null,
- namePresentation: 0,
- uusInfo: null
- };
-
- let oneCall = {
- 0: new Call(0, '00000')
- };
-
- let twoCalls = {
- 0: new Call(0, '00000'),
- 1: new Call(1, '11111')
- };
-
- function testNotification(calls, code, number, resultNotification) {
-
- let testInfo = {calls: calls, code: code, number: number,
- resultNotification: resultNotification};
- do_print('Test case info: ' + JSON.stringify(testInfo));
-
- // Set current calls.
- context.RIL.sendChromeMessage({
- rilMessageType: "currentCalls",
- calls: calls
- });
-
- let notificationInfo = {
- notificationType: 1, // MT
- code: code,
- index: 0,
- type: 0,
- number: number
- };
-
- context.RIL._processSuppSvcNotification(notificationInfo);
-
- let postedMessage = workerHelper.postedMessage;
- equal(postedMessage.rilMessageType, 'suppSvcNotification');
- equal(postedMessage.number, number);
- equal(postedMessage.notification, resultNotification);
-
- // Clear all existed calls.
- context.RIL.sendChromeMessage({
- rilMessageType: "currentCalls",
- calls: {}
- });
- }
-
- testNotification(oneCall, SUPP_SVC_NOTIFICATION_CODE2_PUT_ON_HOLD, null,
- GECKO_SUPP_SVC_NOTIFICATION_REMOTE_HELD);
-
- testNotification(oneCall, SUPP_SVC_NOTIFICATION_CODE2_RETRIEVED, null,
- GECKO_SUPP_SVC_NOTIFICATION_REMOTE_RESUMED);
-
- testNotification(twoCalls, SUPP_SVC_NOTIFICATION_CODE2_PUT_ON_HOLD, null,
- GECKO_SUPP_SVC_NOTIFICATION_REMOTE_HELD);
-
- testNotification(twoCalls, SUPP_SVC_NOTIFICATION_CODE2_RETRIEVED, null,
- GECKO_SUPP_SVC_NOTIFICATION_REMOTE_RESUMED);
-
- testNotification(twoCalls, SUPP_SVC_NOTIFICATION_CODE2_PUT_ON_HOLD, '00000',
- GECKO_SUPP_SVC_NOTIFICATION_REMOTE_HELD);
-
- testNotification(twoCalls, SUPP_SVC_NOTIFICATION_CODE2_PUT_ON_HOLD, '11111',
- GECKO_SUPP_SVC_NOTIFICATION_REMOTE_HELD);
-
- testNotification(twoCalls, SUPP_SVC_NOTIFICATION_CODE2_PUT_ON_HOLD, '22222',
- GECKO_SUPP_SVC_NOTIFICATION_REMOTE_HELD);
-
- run_next_test();
-});
diff --git a/dom/system/gonk/tests/test_ril_worker_stk.js b/dom/system/gonk/tests/test_ril_worker_stk.js
deleted file mode 100644
index 49b914e89e..0000000000
--- a/dom/system/gonk/tests/test_ril_worker_stk.js
+++ /dev/null
@@ -1,1698 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-subscriptLoader.loadSubScript("resource://gre/modules/ril_consts.js", this);
-
-function run_test() {
- run_next_test();
-}
-
-/**
- * Helper function.
- */
-function newUint8SupportOutgoingIndexWorker() {
- let worker = newWorker();
- let index = 4; // index for read
- let buf = [0, 0, 0, 0]; // Preserved parcel size
- let context = worker.ContextPool._contexts[0];
-
- context.Buf.writeUint8 = function(value) {
- if (context.Buf.outgoingIndex >= buf.length) {
- buf.push(value);
- } else {
- buf[context.Buf.outgoingIndex] = value;
- }
-
- context.Buf.outgoingIndex++;
- };
-
- context.Buf.readUint8 = function() {
- return buf[index++];
- };
-
- context.Buf.seekIncoming = function(offset) {
- index += offset;
- };
-
- worker.debug = do_print;
-
- return worker;
-}
-
-// Test RIL requests related to STK.
-/**
- * Verify if RIL.sendStkTerminalProfile be called.
- */
-add_test(function test_if_send_stk_terminal_profile() {
- let worker = newUint8Worker();
- let context = worker.ContextPool._contexts[0];
- let profileSend = false;
- context.RIL.sendStkTerminalProfile = function(data) {
- profileSend = true;
- };
-
- let iccStatus = {
- gsmUmtsSubscriptionAppIndex: 0,
- apps: [{
- app_state: CARD_APPSTATE_READY,
- app_type: CARD_APPTYPE_USIM
- }],
- };
- worker.RILQUIRKS_SEND_STK_PROFILE_DOWNLOAD = false;
-
- context.RIL._processICCStatus(iccStatus);
-
- equal(profileSend, false);
-
- run_next_test();
-});
-
-/**
- * Verify RIL.sendStkTerminalProfile
- */
-add_test(function test_send_stk_terminal_profile() {
- let worker = newUint8Worker();
- let context = worker.ContextPool._contexts[0];
- let ril = context.RIL;
- let buf = context.Buf;
-
- ril.sendStkTerminalProfile(STK_SUPPORTED_TERMINAL_PROFILE);
-
- buf.seekIncoming(8);
- let profile = buf.readString();
- for (let i = 0; i < STK_SUPPORTED_TERMINAL_PROFILE.length; i++) {
- equal(parseInt(profile.substring(2 * i, 2 * i + 2), 16),
- STK_SUPPORTED_TERMINAL_PROFILE[i]);
- }
-
- run_next_test();
-});
-
-/**
- * Verify STK terminal response
- */
-add_test(function test_stk_terminal_response() {
- let worker = newUint8SupportOutgoingIndexWorker();
- let context = worker.ContextPool._contexts[0];
- let buf = context.Buf;
- let pduHelper = context.GsmPDUHelper;
-
- buf.sendParcel = function() {
- // Type
- equal(this.readInt32(), REQUEST_STK_SEND_TERMINAL_RESPONSE);
-
- // Token : we don't care
- this.readInt32();
-
- // Data Size, 44 = 2 * (TLV_COMMAND_DETAILS_SIZE(5) +
- // TLV_DEVICE_ID_SIZE(4) +
- // TLV_RESULT_SIZE(3) +
- // TEXT LENGTH(10))
- equal(this.readInt32(), 44);
-
- // Command Details, Type-Length-Value
- equal(pduHelper.readHexOctet(), COMPREHENSIONTLV_TAG_COMMAND_DETAILS |
- COMPREHENSIONTLV_FLAG_CR);
- equal(pduHelper.readHexOctet(), 3);
- equal(pduHelper.readHexOctet(), 0x01);
- equal(pduHelper.readHexOctet(), STK_CMD_PROVIDE_LOCAL_INFO);
- equal(pduHelper.readHexOctet(), STK_LOCAL_INFO_NNA);
-
- // Device Identifies, Type-Length-Value(Source ID-Destination ID)
- equal(pduHelper.readHexOctet(), COMPREHENSIONTLV_TAG_DEVICE_ID);
- equal(pduHelper.readHexOctet(), 2);
- equal(pduHelper.readHexOctet(), STK_DEVICE_ID_ME);
- equal(pduHelper.readHexOctet(), STK_DEVICE_ID_SIM);
-
- // Result
- equal(pduHelper.readHexOctet(), COMPREHENSIONTLV_TAG_RESULT |
- COMPREHENSIONTLV_FLAG_CR);
- equal(pduHelper.readHexOctet(), 1);
- equal(pduHelper.readHexOctet(), STK_RESULT_OK);
-
- // Text
- equal(pduHelper.readHexOctet(), COMPREHENSIONTLV_TAG_TEXT_STRING |
- COMPREHENSIONTLV_FLAG_CR);
- equal(pduHelper.readHexOctet(), 8);
- equal(pduHelper.readHexOctet(), STK_TEXT_CODING_GSM_7BIT_PACKED);
- equal(pduHelper.readSeptetsToString(7, 0, PDU_NL_IDENTIFIER_DEFAULT,
- PDU_NL_IDENTIFIER_DEFAULT), "Mozilla");
-
- run_next_test();
- };
-
- let response = {
- command: {
- commandNumber: 0x01,
- typeOfCommand: STK_CMD_PROVIDE_LOCAL_INFO,
- commandQualifier: STK_LOCAL_INFO_NNA,
- options: {
- isPacked: true
- }
- },
- input: "Mozilla",
- resultCode: STK_RESULT_OK
- };
- context.RIL.sendStkTerminalResponse(response);
-});
-
-/**
- * Verify STK terminal response : GET INPUT with empty string.
- *
- * @See |TERMINAL RESPONSE: GET INPUT 1.9.1A| of 27.22.4.3.1 GET INPUT (normal)
- * in TS 102 384.
- */
-add_test(function test_stk_terminal_response_get_input_empty_string() {
- let worker = newUint8SupportOutgoingIndexWorker();
- let context = worker.ContextPool._contexts[0];
- let buf = context.Buf;
- let pduHelper = context.GsmPDUHelper;
-
- buf.sendParcel = function() {
- // Type
- equal(this.readInt32(), REQUEST_STK_SEND_TERMINAL_RESPONSE);
-
- // Token : we don't care
- this.readInt32();
-
- // Data Size, 30 = 2 * (TLV_COMMAND_DETAILS_SIZE(5) +
- // TLV_DEVICE_ID_SIZE(4) +
- // TLV_RESULT_SIZE(3) +
- // TEXT LENGTH(3))
- equal(this.readInt32(), 30);
-
- // Command Details, Type-Length-Value
- equal(pduHelper.readHexOctet(), COMPREHENSIONTLV_TAG_COMMAND_DETAILS |
- COMPREHENSIONTLV_FLAG_CR);
- equal(pduHelper.readHexOctet(), 3);
- equal(pduHelper.readHexOctet(), 0x01);
- equal(pduHelper.readHexOctet(), STK_CMD_GET_INPUT);
- equal(pduHelper.readHexOctet(), 0x00);
-
- // Device Identifies, Type-Length-Value(Source ID-Destination ID)
- equal(pduHelper.readHexOctet(), COMPREHENSIONTLV_TAG_DEVICE_ID);
- equal(pduHelper.readHexOctet(), 2);
- equal(pduHelper.readHexOctet(), STK_DEVICE_ID_ME);
- equal(pduHelper.readHexOctet(), STK_DEVICE_ID_SIM);
-
- // Result
- equal(pduHelper.readHexOctet(), COMPREHENSIONTLV_TAG_RESULT |
- COMPREHENSIONTLV_FLAG_CR);
- equal(pduHelper.readHexOctet(), 1);
- equal(pduHelper.readHexOctet(), STK_RESULT_OK);
-
- // Text
- equal(pduHelper.readHexOctet(), COMPREHENSIONTLV_TAG_TEXT_STRING |
- COMPREHENSIONTLV_FLAG_CR);
- equal(pduHelper.readHexOctet(), 1);
- equal(pduHelper.readHexOctet(), STK_TEXT_CODING_GSM_8BIT);
-
- run_next_test();
- };
-
- let response = {
- command: {
- commandNumber: 0x01,
- typeOfCommand: STK_CMD_GET_INPUT,
- commandQualifier: 0x00,
- options: {
- minLength: 0,
- maxLength: 1,
- defaultText: "<SEND>"
- }
- },
- input: "",
- resultCode: STK_RESULT_OK
- };
- context.RIL.sendStkTerminalResponse(response);
-});
-
-/**
- * Verify STK terminal response : GET INPUT with 160 unpacked characters.
- *
- * @See |TERMINAL RESPONSE: GET INPUT 1.8.1| of 27.22.4.3.1 GET INPUT (normal)
- * in TS 102 384.
- */
-add_test(function test_stk_terminal_response_get_input_160_unpacked_characters() {
- let worker = newUint8SupportOutgoingIndexWorker();
- let context = worker.ContextPool._contexts[0];
- let buf = context.Buf;
- let pduHelper = context.GsmPDUHelper;
- let iccPduHelper = context.ICCPDUHelper;
- let TEST_TEXT_STRING = "***1111111111###" +
- "***2222222222###" +
- "***3333333333###" +
- "***4444444444###" +
- "***5555555555###" +
- "***6666666666###" +
- "***7777777777###" +
- "***8888888888###" +
- "***9999999999###" +
- "***0000000000###";
-
- buf.sendParcel = function() {
- // Type
- equal(this.readInt32(), REQUEST_STK_SEND_TERMINAL_RESPONSE);
-
- // Token : we don't care
- this.readInt32();
-
- // Data Size, 352 = 2 * (TLV_COMMAND_DETAILS_SIZE(5) +
- // TLV_DEVICE_ID_SIZE(4) +
- // TLV_RESULT_SIZE(3) +
- // TEXT LENGTH(164))
- equal(this.readInt32(), 352);
-
- // Command Details, Type-Length-Value
- equal(pduHelper.readHexOctet(), COMPREHENSIONTLV_TAG_COMMAND_DETAILS |
- COMPREHENSIONTLV_FLAG_CR);
- equal(pduHelper.readHexOctet(), 3);
- equal(pduHelper.readHexOctet(), 0x01);
- equal(pduHelper.readHexOctet(), STK_CMD_GET_INPUT);
- equal(pduHelper.readHexOctet(), 0x00);
-
- // Device Identifies, Type-Length-Value(Source ID-Destination ID)
- equal(pduHelper.readHexOctet(), COMPREHENSIONTLV_TAG_DEVICE_ID);
- equal(pduHelper.readHexOctet(), 2);
- equal(pduHelper.readHexOctet(), STK_DEVICE_ID_ME);
- equal(pduHelper.readHexOctet(), STK_DEVICE_ID_SIM);
-
- // Result
- equal(pduHelper.readHexOctet(), COMPREHENSIONTLV_TAG_RESULT |
- COMPREHENSIONTLV_FLAG_CR);
- equal(pduHelper.readHexOctet(), 1);
- equal(pduHelper.readHexOctet(), STK_RESULT_OK);
-
- // Text
- equal(pduHelper.readHexOctet(), COMPREHENSIONTLV_TAG_TEXT_STRING |
- COMPREHENSIONTLV_FLAG_CR);
- // C-TLV Length Encoding: 161 = 0x81 0xA1
- equal(pduHelper.readHexOctet(), 0x81);
- equal(pduHelper.readHexOctet(), 0xA1);
- equal(pduHelper.readHexOctet(), STK_TEXT_CODING_GSM_8BIT);
- equal(iccPduHelper.read8BitUnpackedToString(160), TEST_TEXT_STRING);
-
- run_next_test();
- };
-
- let response = {
- command: {
- commandNumber: 0x01,
- typeOfCommand: STK_CMD_GET_INPUT,
- commandQualifier: 0x00,
- options: {
- minLength: 160,
- maxLength: 160,
- text: TEST_TEXT_STRING
- }
- },
- input: TEST_TEXT_STRING,
- resultCode: STK_RESULT_OK
- };
- context.RIL.sendStkTerminalResponse(response);
-});
-
-/**
- * Verify STK terminal response : GET_INKEY - NO_RESPONSE_FROM_USER with
- * duration provided.
- *
- * @See |27.22.4.2.8 GET INKEY (Variable Time out)| in TS 102 384.
- */
-add_test(function test_stk_terminal_response_get_inkey_no_response_from_user() {
- let worker = newUint8SupportOutgoingIndexWorker();
- let context = worker.ContextPool._contexts[0];
- let buf = context.Buf;
- let pduHelper = context.GsmPDUHelper;
-
- buf.sendParcel = function() {
- // Type
- equal(this.readInt32(), REQUEST_STK_SEND_TERMINAL_RESPONSE);
-
- // Token : we don't care
- this.readInt32();
-
- // Data Size, 32 = 2 * (TLV_COMMAND_DETAILS_SIZE(5) +
- // TLV_DEVICE_ID_SIZE(4) +
- // TLV_RESULT_SIZE(3) +
- // DURATION(4))
- equal(this.readInt32(), 32);
-
- // Command Details, Type-Length-Value
- equal(pduHelper.readHexOctet(), COMPREHENSIONTLV_TAG_COMMAND_DETAILS |
- COMPREHENSIONTLV_FLAG_CR);
- equal(pduHelper.readHexOctet(), 3);
- equal(pduHelper.readHexOctet(), 0x01);
- equal(pduHelper.readHexOctet(), STK_CMD_GET_INKEY);
- equal(pduHelper.readHexOctet(), 0x00);
-
- // Device Identifies, Type-Length-Value(Source ID-Destination ID)
- equal(pduHelper.readHexOctet(), COMPREHENSIONTLV_TAG_DEVICE_ID);
- equal(pduHelper.readHexOctet(), 2);
- equal(pduHelper.readHexOctet(), STK_DEVICE_ID_ME);
- equal(pduHelper.readHexOctet(), STK_DEVICE_ID_SIM);
-
- // Result
- equal(pduHelper.readHexOctet(), COMPREHENSIONTLV_TAG_RESULT |
- COMPREHENSIONTLV_FLAG_CR);
- equal(pduHelper.readHexOctet(), 1);
- equal(pduHelper.readHexOctet(), STK_RESULT_NO_RESPONSE_FROM_USER);
-
- // Duration, Type-Length-Value(Time unit, Time interval)
- equal(pduHelper.readHexOctet(), COMPREHENSIONTLV_TAG_DURATION);
- equal(pduHelper.readHexOctet(), 2);
- equal(pduHelper.readHexOctet(), STK_TIME_UNIT_SECOND);
- equal(pduHelper.readHexOctet(), 10);
-
- run_next_test();
- };
-
- let response = {
- command: {
- commandNumber: 0x01,
- typeOfCommand: STK_CMD_GET_INKEY,
- commandQualifier: 0x00,
- options: {
- duration: {
- timeUnit: STK_TIME_UNIT_SECOND,
- timeInterval: 10
- },
- text: 'Enter "+"'
- }
- },
- resultCode: STK_RESULT_NO_RESPONSE_FROM_USER
- };
- context.RIL.sendStkTerminalResponse(response);
-});
-
-/**
- * Verify STK terminal response : GET_INKEY - YES/NO request
- */
-add_test(function test_stk_terminal_response_get_inkey() {
- function do_test(isYesNo) {
- let worker = newUint8SupportOutgoingIndexWorker();
- let context = worker.ContextPool._contexts[0];
- let buf = context.Buf;
- let pduHelper = context.GsmPDUHelper;
-
- buf.sendParcel = function() {
- // Type
- equal(this.readInt32(), REQUEST_STK_SEND_TERMINAL_RESPONSE);
-
- // Token : we don't care
- this.readInt32();
-
- // Data Size, 32 = 2 * (TLV_COMMAND_DETAILS_SIZE(5) +
- // TLV_DEVICE_ID_SIZE(4) +
- // TLV_RESULT_SIZE(3) +
- // TEXT LENGTH(4))
- equal(this.readInt32(), 32);
-
- // Command Details, Type-Length-Value
- equal(pduHelper.readHexOctet(), COMPREHENSIONTLV_TAG_COMMAND_DETAILS |
- COMPREHENSIONTLV_FLAG_CR);
- equal(pduHelper.readHexOctet(), 3);
- equal(pduHelper.readHexOctet(), 0x01);
- equal(pduHelper.readHexOctet(), STK_CMD_GET_INKEY);
- equal(pduHelper.readHexOctet(), 0x04);
-
- // Device Identifies, Type-Length-Value(Source ID-Destination ID)
- equal(pduHelper.readHexOctet(), COMPREHENSIONTLV_TAG_DEVICE_ID);
- equal(pduHelper.readHexOctet(), 2);
- equal(pduHelper.readHexOctet(), STK_DEVICE_ID_ME);
- equal(pduHelper.readHexOctet(), STK_DEVICE_ID_SIM);
-
- // Result
- equal(pduHelper.readHexOctet(), COMPREHENSIONTLV_TAG_RESULT |
- COMPREHENSIONTLV_FLAG_CR);
- equal(pduHelper.readHexOctet(), 1);
- equal(pduHelper.readHexOctet(), STK_RESULT_OK);
-
- // Yes/No response
- equal(pduHelper.readHexOctet(), COMPREHENSIONTLV_TAG_TEXT_STRING |
- COMPREHENSIONTLV_FLAG_CR);
- equal(pduHelper.readHexOctet(), 2);
- equal(pduHelper.readHexOctet(), STK_TEXT_CODING_GSM_8BIT);
- equal(pduHelper.readHexOctet(), isYesNo ? 0x01 : 0x00);
- };
-
- let response = {
- command: {
- commandNumber: 0x01,
- typeOfCommand: STK_CMD_GET_INKEY,
- commandQualifier: 0x04,
- options: {
- isYesNoRequested: true
- }
- },
- isYesNo: isYesNo,
- resultCode: STK_RESULT_OK
- };
-
- context.RIL.sendStkTerminalResponse(response);
- };
-
- // Test "Yes" response
- do_test(true);
- // Test "No" response
- do_test(false);
-
- run_next_test();
-});
-
-/**
- * Verify STK terminal response with additional information.
- */
-add_test(function test_stk_terminal_response_with_additional_info() {
- function do_test(aInfo) {
- let worker = newUint8SupportOutgoingIndexWorker();
- let context = worker.ContextPool._contexts[0];
- let buf = context.Buf;
- let pduHelper = context.GsmPDUHelper;
-
- buf.sendParcel = function() {
- // Type
- equal(this.readInt32(), REQUEST_STK_SEND_TERMINAL_RESPONSE);
-
- // Token : we don't care
- this.readInt32();
-
- // Data Length 26 = 2 * (TLV_COMMAND_DETAILS_SIZE(5) +
- // TLV_DEVICE_ID_SIZE(4) +
- // TLV_RESULT_SIZE(4))
- equal(this.readInt32(), 26);
-
- // Command Details, Type-Length-Value(commandNumber, typeOfCommand, commandQualifier)
- equal(pduHelper.readHexOctet(), COMPREHENSIONTLV_TAG_COMMAND_DETAILS |
- COMPREHENSIONTLV_FLAG_CR);
- equal(pduHelper.readHexOctet(), 3);
- equal(pduHelper.readHexOctet(), 0x01);
- equal(pduHelper.readHexOctet(), STK_CMD_DISPLAY_TEXT);
- equal(pduHelper.readHexOctet(), 0x01);
-
- // Device Identifies, Type-Length-Value(Source ID-Destination ID)
- equal(pduHelper.readHexOctet(), COMPREHENSIONTLV_TAG_DEVICE_ID);
- equal(pduHelper.readHexOctet(), 2);
- equal(pduHelper.readHexOctet(), STK_DEVICE_ID_ME);
- equal(pduHelper.readHexOctet(), STK_DEVICE_ID_SIM);
-
- // Result, Type-Length-Value(General result, Additional information on result)
- equal(pduHelper.readHexOctet(), COMPREHENSIONTLV_TAG_RESULT |
- COMPREHENSIONTLV_FLAG_CR);
- equal(pduHelper.readHexOctet(), 2);
- equal(pduHelper.readHexOctet(), STK_RESULT_TERMINAL_CRNTLY_UNABLE_TO_PROCESS);
- equal(pduHelper.readHexOctet(), aInfo);
- };
-
- let response = {
- command: {
- commandNumber: 0x01,
- typeOfCommand: STK_CMD_DISPLAY_TEXT,
- commandQualifier: 0x01,
- options: {
- isHighPriority: true
- }
- },
- resultCode: STK_RESULT_TERMINAL_CRNTLY_UNABLE_TO_PROCESS,
- additionalInformation: aInfo
- };
-
- context.RIL.sendStkTerminalResponse(response);
- };
-
- do_test(0x01); // 'Screen is busy'
-
- run_next_test();
-});
-
-// Test ComprehensionTlvHelper
-
-/**
- * Verify ComprehensionTlvHelper.writeLocationInfoTlv
- */
-add_test(function test_write_location_info_tlv() {
- let worker = newUint8Worker();
- let context = worker.ContextPool._contexts[0];
- let pduHelper = context.GsmPDUHelper;
- let tlvHelper = context.ComprehensionTlvHelper;
-
- // Test with 2-digit mnc, and gsmCellId obtained from UMTS network.
- let loc = {
- mcc: "466",
- mnc: "92",
- gsmLocationAreaCode : 10291,
- gsmCellId: 19072823
- };
- tlvHelper.writeLocationInfoTlv(loc);
-
- let tag = pduHelper.readHexOctet();
- equal(tag, COMPREHENSIONTLV_TAG_LOCATION_INFO |
- COMPREHENSIONTLV_FLAG_CR);
-
- let length = pduHelper.readHexOctet();
- equal(length, 9);
-
- let mcc_mnc = pduHelper.readSwappedNibbleBcdString(3);
- equal(mcc_mnc, "46692");
-
- let lac = (pduHelper.readHexOctet() << 8) | pduHelper.readHexOctet();
- equal(lac, 10291);
-
- let cellId = (pduHelper.readHexOctet() << 24) |
- (pduHelper.readHexOctet() << 16) |
- (pduHelper.readHexOctet() << 8) |
- (pduHelper.readHexOctet());
- equal(cellId, 19072823);
-
- // Test with 1-digit mnc, and gsmCellId obtained from GSM network.
- loc = {
- mcc: "466",
- mnc: "02",
- gsmLocationAreaCode : 10291,
- gsmCellId: 65534
- };
- tlvHelper.writeLocationInfoTlv(loc);
-
- tag = pduHelper.readHexOctet();
- equal(tag, COMPREHENSIONTLV_TAG_LOCATION_INFO |
- COMPREHENSIONTLV_FLAG_CR);
-
- length = pduHelper.readHexOctet();
- equal(length, 7);
-
- mcc_mnc = pduHelper.readSwappedNibbleBcdString(3);
- equal(mcc_mnc, "46602");
-
- lac = (pduHelper.readHexOctet() << 8) | pduHelper.readHexOctet();
- equal(lac, 10291);
-
- cellId = (pduHelper.readHexOctet() << 8) | (pduHelper.readHexOctet());
- equal(cellId, 65534);
-
- // Test with 3-digit mnc, and gsmCellId obtained from GSM network.
- loc = {
- mcc: "466",
- mnc: "222",
- gsmLocationAreaCode : 10291,
- gsmCellId: 65534
- };
- tlvHelper.writeLocationInfoTlv(loc);
-
- tag = pduHelper.readHexOctet();
- equal(tag, COMPREHENSIONTLV_TAG_LOCATION_INFO |
- COMPREHENSIONTLV_FLAG_CR);
-
- length = pduHelper.readHexOctet();
- equal(length, 7);
-
- mcc_mnc = pduHelper.readSwappedNibbleBcdString(3);
- equal(mcc_mnc, "466222");
-
- lac = (pduHelper.readHexOctet() << 8) | pduHelper.readHexOctet();
- equal(lac, 10291);
-
- cellId = (pduHelper.readHexOctet() << 8) | (pduHelper.readHexOctet());
- equal(cellId, 65534);
-
- run_next_test();
-});
-
-/**
- * Verify ComprehensionTlvHelper.writeErrorNumber
- */
-add_test(function test_write_disconnecting_cause() {
- let worker = newUint8Worker();
- let context = worker.ContextPool._contexts[0];
- let pduHelper = context.GsmPDUHelper;
- let tlvHelper = context.ComprehensionTlvHelper;
-
- tlvHelper.writeCauseTlv(RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_BUSY]);
- let tag = pduHelper.readHexOctet();
- equal(tag, COMPREHENSIONTLV_TAG_CAUSE | COMPREHENSIONTLV_FLAG_CR);
- let len = pduHelper.readHexOctet();
- equal(len, 2); // We have one cause.
- let standard = pduHelper.readHexOctet();
- equal(standard, 0x60);
- let cause = pduHelper.readHexOctet();
- equal(cause, 0x80 | CALL_FAIL_BUSY);
-
- run_next_test();
-});
-
-/**
- * Verify ComprehensionTlvHelper.getSizeOfLengthOctets
- */
-add_test(function test_get_size_of_length_octets() {
- let worker = newUint8Worker();
- let context = worker.ContextPool._contexts[0];
- let tlvHelper = context.ComprehensionTlvHelper;
-
- let length = 0x70;
- equal(tlvHelper.getSizeOfLengthOctets(length), 1);
-
- length = 0x80;
- equal(tlvHelper.getSizeOfLengthOctets(length), 2);
-
- length = 0x180;
- equal(tlvHelper.getSizeOfLengthOctets(length), 3);
-
- length = 0x18000;
- equal(tlvHelper.getSizeOfLengthOctets(length), 4);
-
- run_next_test();
-});
-
-/**
- * Verify ComprehensionTlvHelper.writeLength
- */
-add_test(function test_write_length() {
- let worker = newUint8Worker();
- let context = worker.ContextPool._contexts[0];
- let pduHelper = context.GsmPDUHelper;
- let tlvHelper = context.ComprehensionTlvHelper;
-
- let length = 0x70;
- tlvHelper.writeLength(length);
- equal(pduHelper.readHexOctet(), length);
-
- length = 0x80;
- tlvHelper.writeLength(length);
- equal(pduHelper.readHexOctet(), 0x81);
- equal(pduHelper.readHexOctet(), length);
-
- length = 0x180;
- tlvHelper.writeLength(length);
- equal(pduHelper.readHexOctet(), 0x82);
- equal(pduHelper.readHexOctet(), (length >> 8) & 0xff);
- equal(pduHelper.readHexOctet(), length & 0xff);
-
- length = 0x18000;
- tlvHelper.writeLength(length);
- equal(pduHelper.readHexOctet(), 0x83);
- equal(pduHelper.readHexOctet(), (length >> 16) & 0xff);
- equal(pduHelper.readHexOctet(), (length >> 8) & 0xff);
- equal(pduHelper.readHexOctet(), length & 0xff);
-
- run_next_test();
-});
-
-// Test Proactive commands.
-
-function test_stk_proactive_command(aOptions) {
- let worker = newUint8Worker();
- let context = worker.ContextPool._contexts[0];
- let pduHelper = context.GsmPDUHelper;
- let berHelper = context.BerTlvHelper;
- let stkHelper = context.StkProactiveCmdHelper;
- let stkFactory = context.StkCommandParamsFactory;
-
- let testPdu = aOptions.pdu;
- let testTypeOfCommand = aOptions.typeOfCommand;
- let testIcons = aOptions.icons;
- let testFunc = aOptions.testFunc;
-
- if (testIcons) {
- let ril = context.RIL;
- ril.iccInfoPrivate.sst = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x30]; //IMG: 39
- ril.appType = CARD_APPTYPE_SIM;
-
- // skip asynchornous process in IconLoader.loadIcons().
- let iconLoader = context.IconLoader;
- iconLoader.loadIcons = (recordNumbers, onsuccess, onerror) => {
- onsuccess(testIcons);
- };
- }
-
- for(let i = 0 ; i < testPdu.length; i++) {
- pduHelper.writeHexOctet(testPdu[i]);
- }
-
- let berTlv = berHelper.decode(testPdu.length);
- let ctlvs = berTlv.value;
- let ctlv = stkHelper.searchForTag(COMPREHENSIONTLV_TAG_COMMAND_DETAILS, ctlvs);
- let cmdDetails = ctlv.value;
- equal(cmdDetails.typeOfCommand, testTypeOfCommand);
-
- stkFactory.createParam(cmdDetails, ctlvs, (aResult) => {
- cmdDetails.options = aResult;
- testFunc(context, cmdDetails, ctlvs);
- });
-}
-
-/**
- * Verify Proactive command helper : searchForSelectedTags
- */
-add_test(function test_stk_proactive_command_search_for_selected_tags() {
- let worker = newUint8Worker();
- let context = worker.ContextPool._contexts[0];
- let pduHelper = context.GsmPDUHelper;
- let berHelper = context.BerTlvHelper;
- let stkHelper = context.StkProactiveCmdHelper;
-
- let tag_test = [
- 0xD0,
- 0x3E,
- 0x85, 0x0A, 0x61, 0x6C, 0x70, 0x68, 0x61, 0x20, 0x69, 0x64, 0x20, 0x31,
- 0x85, 0x0A, 0x61, 0x6C, 0x70, 0x68, 0x61, 0x20, 0x69, 0x64, 0x20, 0x32,
- 0x85, 0x0A, 0x61, 0x6C, 0x70, 0x68, 0x61, 0x20, 0x69, 0x64, 0x20, 0x33,
- 0x85, 0x0A, 0x61, 0x6C, 0x70, 0x68, 0x61, 0x20, 0x69, 0x64, 0x20, 0x34,
- 0x85, 0x0A, 0x61, 0x6C, 0x70, 0x68, 0x61, 0x20, 0x69, 0x64, 0x20, 0x35,
- 0x85, 0x00];
-
- for (let i = 0; i < tag_test.length; i++) {
- pduHelper.writeHexOctet(tag_test[i]);
- }
-
- let berTlv = berHelper.decode(tag_test.length);
- let selectedCtlvs =
- stkHelper.searchForSelectedTags(berTlv.value, [COMPREHENSIONTLV_TAG_ALPHA_ID]);
- let tlv = selectedCtlvs.retrieve(COMPREHENSIONTLV_TAG_ALPHA_ID);
- equal(tlv.value.identifier, "alpha id 1");
-
- tlv = selectedCtlvs.retrieve(COMPREHENSIONTLV_TAG_ALPHA_ID);
- equal(tlv.value.identifier, "alpha id 2");
-
- tlv = selectedCtlvs.retrieve(COMPREHENSIONTLV_TAG_ALPHA_ID);
- equal(tlv.value.identifier, "alpha id 3");
-
- tlv = selectedCtlvs.retrieve(COMPREHENSIONTLV_TAG_ALPHA_ID);
- equal(tlv.value.identifier, "alpha id 4");
-
- tlv = selectedCtlvs.retrieve(COMPREHENSIONTLV_TAG_ALPHA_ID);
- equal(tlv.value.identifier, "alpha id 5");
-
- // emulate that the alpha identifier is provided and is a null data object,
- // which is converted to an empty string in ICCPDUHelper.
- tlv = selectedCtlvs.retrieve(COMPREHENSIONTLV_TAG_ALPHA_ID);
- strictEqual(tlv.value.identifier, "");
-
- // emulate that the alpha identifier is not provided
- tlv = selectedCtlvs.retrieve(COMPREHENSIONTLV_TAG_ALPHA_ID);
- strictEqual(tlv, undefined);
-
- run_next_test();
-});
-
-/**
- * Verify Proactive Command : Refresh
- */
-add_test(function test_stk_proactive_command_refresh() {
- test_stk_proactive_command({
- pdu: [
- 0xD0,
- 0x10,
- 0x81, 0x03, 0x01, 0x01, 0x01,
- 0x82, 0x02, 0x81, 0x82,
- 0x92, 0x05, 0x01, 0x3F, 0x00, 0x2F, 0xE2
- ],
- typeOfCommand: STK_CMD_REFRESH,
- icons: null,
- testFunc: (context, cmdDetails, ctlvs) => {
- let stkHelper = context.StkProactiveCmdHelper;
- let ctlv = stkHelper.searchForTag(COMPREHENSIONTLV_TAG_FILE_LIST, ctlvs);
- equal(ctlv.value.fileList, "3F002FE2");
- }
- });
-
- run_next_test();
-});
-
-/**
- * Verify Proactive Command : Play Tone
- */
-add_test(function test_stk_proactive_command_play_tone() {
- test_stk_proactive_command({
- pdu: [
- 0xD0,
- 0x1F,
- 0x81, 0x03, 0x01, 0x20, 0x00,
- 0x82, 0x02, 0x81, 0x03,
- 0x85, 0x09, 0x44, 0x69, 0x61, 0x6C, 0x20, 0x54, 0x6F, 0x6E, 0x65,
- 0x8E, 0x01, 0x01,
- 0x84, 0x02, 0x01, 0x05,
- 0x9E, 0x02, 0x00, 0x01
- ],
- typeOfCommand: STK_CMD_PLAY_TONE,
- icons: [1],
- testFunc: (context, cmdDetails, ctlvs) => {
- let playTone = cmdDetails.options;
-
- equal(playTone.text, "Dial Tone");
- equal(playTone.tone, STK_TONE_TYPE_DIAL_TONE);
- equal(playTone.duration.timeUnit, STK_TIME_UNIT_SECOND);
- equal(playTone.duration.timeInterval, 5);
- equal(playTone.iconSelfExplanatory, true);
- equal(playTone.icons, 1);
- }
- });
-
- run_next_test();
-});
-
-/**
- * Verify Proactive Command : Poll Interval
- */
-add_test(function test_stk_proactive_command_poll_interval() {
- test_stk_proactive_command({
- pdu: [
- 0xD0,
- 0x0D,
- 0x81, 0x03, 0x01, 0x03, 0x00,
- 0x82, 0x02, 0x81, 0x82,
- 0x84, 0x02, 0x01, 0x14
- ],
- typeOfCommand: STK_CMD_POLL_INTERVAL,
- icons: null,
- testFunc: (context, cmdDetails, ctlvs) => {
- let interval = cmdDetails.options;
-
- equal(interval.timeUnit, STK_TIME_UNIT_SECOND);
- equal(interval.timeInterval, 0x14);
- }
- });
-
- run_next_test();
-});
-
-/**
- * Verify Proactive Command: Display Text
- */
-add_test(function test_stk_proactive_command_display_text() {
- test_stk_proactive_command({
- pdu: [
- 0xd0,
- 0x2c,
- 0x81, 0x03, 0x01, 0x21, 0x80,
- 0x82, 0x02, 0x81, 0x02,
- 0x0d, 0x1d, 0x00, 0xd3, 0x30, 0x9b, 0xfc, 0x06, 0xc9, 0x5c, 0x30, 0x1a,
- 0xa8, 0xe8, 0x02, 0x59, 0xc3, 0xec, 0x34, 0xb9, 0xac, 0x07, 0xc9, 0x60,
- 0x2f, 0x58, 0xed, 0x15, 0x9b, 0xb9, 0x40,
- 0x9e, 0x02, 0x00, 0x01
- ],
- typeOfCommand: STK_CMD_DISPLAY_TEXT,
- icons: [1],
- testFunc: (context, cmdDetails, ctlvs) => {
- let textMsg = cmdDetails.options;
-
- equal(textMsg.text, "Saldo 2.04 E. Validez 20/05/13. ");
- equal(textMsg.iconSelfExplanatory, true);
- equal(textMsg.icons, 1);
- }
- });
-
- run_next_test();
-});
-
-/**
- * Verify Proactive Command: Set Up Event List.
- */
-add_test(function test_stk_proactive_command_event_list() {
- test_stk_proactive_command({
- pdu: [
- 0xD0,
- 0x0F,
- 0x81, 0x03, 0x01, 0x05, 0x00,
- 0x82, 0x02, 0x81, 0x82,
- 0x99, 0x04, 0x00, 0x01, 0x02, 0x03
- ],
- typeOfCommand: STK_CMD_SET_UP_EVENT_LIST,
- icons: null,
- testFunc: (context, cmdDetails, ctlvs) => {
- let event = cmdDetails.options;
-
- equal(Array.isArray(event.eventList), true);
-
- for (let i = 0; i < event.eventList.length; i++) {
- equal(event.eventList[i], i);
- }
- }
- });
-
- run_next_test();
-});
-
-/**
- * Verify Proactive Command : Get Input
- */
-add_test(function test_stk_proactive_command_get_input() {
- test_stk_proactive_command({
- pdu: [
- 0xD0,
- 0x22,
- 0x81, 0x03, 0x01, 0x23, 0x8F,
- 0x82, 0x02, 0x81, 0x82,
- 0x8D, 0x05, 0x04, 0x54, 0x65, 0x78, 0x74,
- 0x91, 0x02, 0x01, 0x10,
- 0x17, 0x08, 0x04, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6C, 0x74,
- 0x9E, 0x02, 0x00, 0x01
- ],
- typeOfCommand: STK_CMD_GET_INPUT,
- icons: [1],
- testFunc: (context, cmdDetails, ctlvs) => {
- let input = cmdDetails.options;
-
- equal(input.text, "Text");
- equal(input.isAlphabet, true);
- equal(input.isUCS2, true);
- equal(input.hideInput, true);
- equal(input.isPacked, true);
- equal(input.isHelpAvailable, true);
- equal(input.minLength, 0x01);
- equal(input.maxLength, 0x10);
- equal(input.defaultText, "Default");
- equal(input.iconSelfExplanatory, true);
- equal(input.icons, 1);
- }
- });
-
- test_stk_proactive_command({
- pdu: [
- 0xD0,
- 0x11,
- 0x81, 0x03, 0x01, 0x23, 0x00,
- 0x82, 0x02, 0x81, 0x82,
- 0x8D, 0x00,
- 0x91, 0x02, 0x01, 0x10,
- 0x17, 0x00
- ],
- typeOfCommand: STK_CMD_GET_INPUT,
- icons: null,
- testFunc: (context, cmdDetails, ctlvs) => {
- let input = cmdDetails.options;
-
- equal(input.text, null);
- equal(input.minLength, 0x01);
- equal(input.maxLength, 0x10);
- equal(input.defaultText, null);
- }
- });
-
- run_next_test();
-});
-
-/**
- * Verify Proactive Command : More Time
- */
-add_test(function test_stk_proactive_command_more_time() {
- let worker = newUint8Worker();
- let context = worker.ContextPool._contexts[0];
- let pduHelper = context.GsmPDUHelper;
- let berHelper = context.BerTlvHelper;
- let stkHelper = context.StkProactiveCmdHelper;
-
- let more_time_1 = [
- 0xD0,
- 0x09,
- 0x81, 0x03, 0x01, 0x02, 0x00,
- 0x82, 0x02, 0x81, 0x82];
-
- for(let i = 0 ; i < more_time_1.length; i++) {
- pduHelper.writeHexOctet(more_time_1[i]);
- }
-
- let berTlv = berHelper.decode(more_time_1.length);
- let ctlvs = berTlv.value;
- let tlv = stkHelper.searchForTag(COMPREHENSIONTLV_TAG_COMMAND_DETAILS, ctlvs);
- equal(tlv.value.commandNumber, 0x01);
- equal(tlv.value.typeOfCommand, STK_CMD_MORE_TIME);
- equal(tlv.value.commandQualifier, 0x00);
-
- run_next_test();
-});
-
-/**
- * Verify Proactive Command : Select Item
- */
-add_test(function test_stk_proactive_command_select_item() {
- test_stk_proactive_command({
- pdu: [
- 0xD0,
- 0x3D,
- 0x81, 0x03, 0x01, 0x24, 0x00,
- 0x82, 0x02, 0x81, 0x82,
- 0x85, 0x05, 0x54, 0x69, 0x74, 0x6C, 0x65,
- 0x8F, 0x07, 0x01, 0x69, 0x74, 0x65, 0x6D, 0x20, 0x31,
- 0x8F, 0x07, 0x02, 0x69, 0x74, 0x65, 0x6D, 0x20, 0x32,
- 0x8F, 0x07, 0x03, 0x69, 0x74, 0x65, 0x6D, 0x20, 0x33,
- 0x18, 0x03, 0x10, 0x15, 0x20,
- 0x90, 0x01, 0x01,
- 0x9E, 0x02, 0x00, 0x01,
- 0x9F, 0x04, 0x00, 0x01, 0x02, 0x03
- ],
- typeOfCommand: STK_CMD_SELECT_ITEM,
- icons: [1, 1, 2, 3],
- testFunc: (context, cmdDetails, ctlvs) => {
- let menu = cmdDetails.options;
-
- equal(menu.title, "Title");
- equal(menu.iconSelfExplanatory, true);
- equal(menu.icons, 1);
- equal(menu.items[0].identifier, 1);
- equal(menu.items[0].text, "item 1");
- equal(menu.items[0].iconSelfExplanatory, true);
- equal(menu.items[0].icons, 1);
- equal(menu.items[1].identifier, 2);
- equal(menu.items[1].text, "item 2");
- equal(menu.items[1].iconSelfExplanatory, true);
- equal(menu.items[1].icons, 2);
- equal(menu.items[2].identifier, 3);
- equal(menu.items[2].text, "item 3");
- equal(menu.items[2].iconSelfExplanatory, true);
- equal(menu.items[2].icons, 3);
- equal(menu.nextActionList[0], STK_CMD_SET_UP_CALL);
- equal(menu.nextActionList[1], STK_CMD_LAUNCH_BROWSER);
- equal(menu.nextActionList[2], STK_CMD_PLAY_TONE);
- equal(menu.defaultItem, 0x00);
- }
- });
-
- test_stk_proactive_command({
- pdu: [
- 0xD0,
- 0x33,
- 0x81, 0x03, 0x01, 0x24, 0x00,
- 0x82, 0x02, 0x81, 0x82,
- 0x85, 0x05, 0x54, 0x69, 0x74, 0x6C, 0x65,
- 0x8F, 0x07, 0x01, 0x69, 0x74, 0x65, 0x6D, 0x20, 0x31,
- 0x8F, 0x07, 0x02, 0x69, 0x74, 0x65, 0x6D, 0x20, 0x32,
- 0x8F, 0x07, 0x03, 0x69, 0x74, 0x65, 0x6D, 0x20, 0x33,
- 0x18, 0x03, 0x00, 0x15, 0x81,
- 0x90, 0x01, 0x03
- ],
- typeOfCommand: STK_CMD_SELECT_ITEM,
- icons: null,
- testFunc: (context, cmdDetails, ctlvs) => {
- let menu = cmdDetails.options;
-
- equal(menu.title, "Title");
- equal(menu.items[0].identifier, 1);
- equal(menu.items[0].text, "item 1");
- equal(menu.items[1].identifier, 2);
- equal(menu.items[1].text, "item 2");
- equal(menu.items[2].identifier, 3);
- equal(menu.items[2].text, "item 3");
- equal(menu.nextActionList[0], STK_NEXT_ACTION_NULL);
- equal(menu.nextActionList[1], STK_CMD_LAUNCH_BROWSER);
- equal(menu.nextActionList[2], STK_NEXT_ACTION_END_PROACTIVE_SESSION);
- equal(menu.defaultItem, 0x02);
- }
- });
-
- run_next_test();
-});
-
-/**
- * Verify Proactive Command : Set Up Menu
- */
-add_test(function test_stk_proactive_command_set_up_menu() {
- test_stk_proactive_command({
- pdu: [
- 0xD0,
- 0x3A,
- 0x81, 0x03, 0x01, 0x25, 0x00,
- 0x82, 0x02, 0x81, 0x82,
- 0x85, 0x05, 0x54, 0x69, 0x74, 0x6C, 0x65,
- 0x8F, 0x07, 0x01, 0x69, 0x74, 0x65, 0x6D, 0x20, 0x31,
- 0x8F, 0x07, 0x02, 0x69, 0x74, 0x65, 0x6D, 0x20, 0x32,
- 0x8F, 0x07, 0x03, 0x69, 0x74, 0x65, 0x6D, 0x20, 0x33,
- 0x18, 0x03, 0x10, 0x15, 0x20,
- 0x9E, 0x02, 0x00, 0x01,
- 0x9F, 0x04, 0x00, 0x01, 0x02, 0x03
- ],
- typeOfCommand: STK_CMD_SET_UP_MENU,
- icons: [1, 1, 2, 3],
- testFunc: (context, cmdDetails, ctlvs) => {
- let menu = cmdDetails.options;
-
- equal(menu.title, "Title");
- equal(menu.iconSelfExplanatory, true);
- equal(menu.icons, 1);
- equal(menu.items[0].identifier, 1);
- equal(menu.items[0].text, "item 1");
- equal(menu.items[0].iconSelfExplanatory, true);
- equal(menu.items[0].icons, 1);
- equal(menu.items[1].identifier, 2);
- equal(menu.items[1].text, "item 2");
- equal(menu.items[1].iconSelfExplanatory, true);
- equal(menu.items[1].icons, 2);
- equal(menu.items[2].identifier, 3);
- equal(menu.items[2].text, "item 3");
- equal(menu.items[2].iconSelfExplanatory, true);
- equal(menu.items[2].icons, 3);
- equal(menu.nextActionList[0], STK_CMD_SET_UP_CALL);
- equal(menu.nextActionList[1], STK_CMD_LAUNCH_BROWSER);
- equal(menu.nextActionList[2], STK_CMD_PLAY_TONE);
- }
- });
-
- test_stk_proactive_command({
- pdu: [
- 0xD0,
- 0x30,
- 0x81, 0x03, 0x01, 0x25, 0x00,
- 0x82, 0x02, 0x81, 0x82,
- 0x85, 0x05, 0x54, 0x69, 0x74, 0x6C, 0x65,
- 0x8F, 0x07, 0x01, 0x69, 0x74, 0x65, 0x6D, 0x20, 0x31,
- 0x8F, 0x07, 0x02, 0x69, 0x74, 0x65, 0x6D, 0x20, 0x32,
- 0x8F, 0x07, 0x03, 0x69, 0x74, 0x65, 0x6D, 0x20, 0x33,
- 0x18, 0x03, 0x81, 0x00, 0x00
- ],
- typeOfCommand: STK_CMD_SET_UP_MENU,
- icons: null,
- testFunc: (context, cmdDetails, ctlvs) => {
- let menu = cmdDetails.options;
-
- equal(menu.title, "Title");
- equal(menu.items[0].identifier, 1);
- equal(menu.items[0].text, "item 1");
- equal(menu.items[1].identifier, 2);
- equal(menu.items[1].text, "item 2");
- equal(menu.items[2].identifier, 3);
- equal(menu.items[2].text, "item 3");
- equal(menu.nextActionList[0], STK_NEXT_ACTION_END_PROACTIVE_SESSION);
- equal(menu.nextActionList[1], STK_NEXT_ACTION_NULL);
- equal(menu.nextActionList[2], STK_NEXT_ACTION_NULL);
- }
- });
-
- run_next_test();
-});
-
-/**
- * Verify Proactive Command : Set Up Call
- */
-add_test(function test_stk_proactive_command_set_up_call() {
- test_stk_proactive_command({
- pdu: [
- 0xD0,
- 0x31,
- 0x81, 0x03, 0x01, 0x10, 0x04,
- 0x82, 0x02, 0x81, 0x82,
- 0x05, 0x0A, 0x44, 0x69, 0x73, 0x63, 0x6F, 0x6E, 0x6E, 0x65, 0x63, 0x74,
- 0x86, 0x09, 0x81, 0x10, 0x32, 0x04, 0x21, 0x43, 0x65, 0x1C, 0x2C,
- 0x05, 0x07, 0x4D, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65,
- 0x9E, 0x02, 0x00, 0x01,
- 0x9E, 0x02, 0x01, 0x02
- ],
- typeOfCommand: STK_CMD_SET_UP_CALL,
- icons: [1, 2],
- testFunc: (context, cmdDetails, ctlvs) => {
- let setupCall = cmdDetails.options;
-
- equal(setupCall.address, "012340123456,1,2");
- equal(setupCall.confirmMessage.text, "Disconnect");
- equal(setupCall.confirmMessage.iconSelfExplanatory, true);
- equal(setupCall.confirmMessage.icons, 1);
- equal(setupCall.callMessage.text, "Message");
- equal(setupCall.callMessage.iconSelfExplanatory, false);
- equal(setupCall.callMessage.icons, 2);
- }
- });
-
- run_next_test();
-});
-
-/**
- * Verify Proactive Command : Timer Management
- */
-add_test(function test_stk_proactive_command_timer_management() {
- // Timer Management - Start
- test_stk_proactive_command({
- pdu: [
- 0xD0,
- 0x11,
- 0x81, 0x03, 0x01, 0x27, 0x00,
- 0x82, 0x02, 0x81, 0x82,
- 0xA4, 0x01, 0x01,
- 0xA5, 0x03, 0x10, 0x20, 0x30
- ],
- typeOfCommand: STK_CMD_TIMER_MANAGEMENT,
- icons: null,
- testFunc: (context, cmdDetails, ctlvs) => {
- equal(cmdDetails.commandQualifier, STK_TIMER_START);
-
- let timer = cmdDetails.options;
-
- equal(timer.timerId, 0x01);
- equal(timer.timerValue, (0x01 * 60 * 60) + (0x02 * 60) + 0x03);
- }
- });
-
- // Timer Management - Deactivate
- test_stk_proactive_command({
- pdu: [
- 0xD0,
- 0x0C,
- 0x81, 0x03, 0x01, 0x27, 0x01,
- 0x82, 0x02, 0x81, 0x82,
- 0xA4, 0x01, 0x01
- ],
- typeOfCommand: STK_CMD_TIMER_MANAGEMENT,
- icons: null,
- testFunc: (context, cmdDetails, ctlvs) => {
- equal(cmdDetails.commandQualifier, STK_TIMER_DEACTIVATE);
-
- let timer = cmdDetails.options;
-
- equal(timer.timerId, 0x01);
- ok(timer.timerValue === undefined);
- }
- });
-
- run_next_test();
-});
-
-/**
- * Verify Proactive Command : Provide Local Information
- */
-add_test(function test_stk_proactive_command_provide_local_information() {
- let worker = newUint8Worker();
- let context = worker.ContextPool._contexts[0];
- let pduHelper = context.GsmPDUHelper;
- let berHelper = context.BerTlvHelper;
- let stkHelper = context.StkProactiveCmdHelper;
- let stkCmdHelper = context.StkCommandParamsFactory;
-
- // Verify IMEI
- test_stk_proactive_command({
- pdu: [
- 0xD0,
- 0x09,
- 0x81, 0x03, 0x01, 0x26, 0x01,
- 0x82, 0x02, 0x81, 0x82
- ],
- typeOfCommand: STK_CMD_PROVIDE_LOCAL_INFO,
- icons: null,
- testFunc: (context, cmdDetails, ctlvs) => {
- equal(cmdDetails.commandQualifier, STK_LOCAL_INFO_IMEI);
-
- let provideLocalInfo = cmdDetails.options;
- equal(provideLocalInfo.localInfoType, STK_LOCAL_INFO_IMEI);
- }
- });
-
- // Verify Date and Time Zone
- test_stk_proactive_command({
- pdu: [
- 0xD0,
- 0x09,
- 0x81, 0x03, 0x01, 0x26, 0x03,
- 0x82, 0x02, 0x81, 0x82
- ],
- typeOfCommand: STK_CMD_PROVIDE_LOCAL_INFO,
- icons: null,
- testFunc: (context, cmdDetails, ctlvs) => {
- equal(cmdDetails.commandQualifier, STK_LOCAL_INFO_DATE_TIME_ZONE);
-
- let provideLocalInfo = cmdDetails.options;
- equal(provideLocalInfo.localInfoType, STK_LOCAL_INFO_DATE_TIME_ZONE);
- }
- });
-
- run_next_test();
-});
-
-/**
- * Verify Proactive command : BIP Messages
- */
-add_test(function test_stk_proactive_command_open_channel() {
- let worker = newUint8Worker();
- let context = worker.ContextPool._contexts[0];
- let pduHelper = context.GsmPDUHelper;
- let berHelper = context.BerTlvHelper;
- let stkHelper = context.StkProactiveCmdHelper;
- let stkCmdHelper = context.StkCommandParamsFactory;
-
- // Open Channel
- test_stk_proactive_command({
- pdu: [
- 0xD0,
- 0x0F,
- 0x81, 0x03, 0x01, 0x40, 0x00,
- 0x82, 0x02, 0x81, 0x82,
- 0x85, 0x04, 0x4F, 0x70, 0x65, 0x6E //alpha id: "Open"
- ],
- typeOfCommand: STK_CMD_OPEN_CHANNEL,
- icons: null,
- testFunc: (context, cmdDetails, ctlvs) => {
- let bipMsg = cmdDetails.options;
-
- equal(bipMsg.text, "Open");
- }
- });
-
- // Close Channel
- test_stk_proactive_command({
- pdu: [
- 0xD0,
- 0x10,
- 0x81, 0x03, 0x01, 0x41, 0x00,
- 0x82, 0x02, 0x81, 0x82,
- 0x85, 0x05, 0x43, 0x6C, 0x6F, 0x73, 0x65 //alpha id: "Close"
- ],
- typeOfCommand: STK_CMD_CLOSE_CHANNEL,
- icons: null,
- testFunc: (context, cmdDetails, ctlvs) => {
- let bipMsg = cmdDetails.options;
-
- equal(bipMsg.text, "Close");
- }
- });
-
- // Receive Data
- test_stk_proactive_command({
- pdu: [
- 0XD0,
- 0X12,
- 0x81, 0x03, 0x01, 0x42, 0x00,
- 0x82, 0x02, 0x81, 0x82,
- 0x85, 0x07, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65 //alpha id: "Receive"
- ],
- typeOfCommand: STK_CMD_RECEIVE_DATA,
- icons: null,
- testFunc: (context, cmdDetails, ctlvs) => {
- let bipMsg = cmdDetails.options;
-
- equal(bipMsg.text, "Receive");
- }
- });
-
- // Send Data
- test_stk_proactive_command({
- pdu: [
- 0xD0,
- 0x0F,
- 0x81, 0x03, 0x01, 0x43, 0x00,
- 0x82, 0x02, 0x81, 0x82,
- 0x85, 0x04, 0x53, 0x65, 0x6E, 0x64 //alpha id: "Send"
- ],
- typeOfCommand: STK_CMD_SEND_DATA,
- icons: null,
- testFunc: (context, cmdDetails, ctlvs) => {
- let bipMsg = cmdDetails.options;
-
- equal(bipMsg.text, "Send");
- }
- });
-
- run_next_test();
-});
-
-/**
- * Verify Event Download Command : Location Status
- */
-add_test(function test_stk_event_download_location_status() {
- let worker = newUint8SupportOutgoingIndexWorker();
- let context = worker.ContextPool._contexts[0];
- let buf = context.Buf;
- let pduHelper = context.GsmPDUHelper;
-
- buf.sendParcel = function() {
- // Type
- equal(this.readInt32(), REQUEST_STK_SEND_ENVELOPE_COMMAND);
-
- // Token : we don't care
- this.readInt32();
-
- // Data Size, 42 = 2 * (2 + TLV_DEVICE_ID_SIZE(4) +
- // TLV_EVENT_LIST_SIZE(3) +
- // TLV_LOCATION_STATUS_SIZE(3) +
- // TLV_LOCATION_INFO_GSM_SIZE(9))
- equal(this.readInt32(), 42);
-
- // BER tag
- equal(pduHelper.readHexOctet(), BER_EVENT_DOWNLOAD_TAG);
-
- // BER length, 19 = TLV_DEVICE_ID_SIZE(4) +
- // TLV_EVENT_LIST_SIZE(3) +
- // TLV_LOCATION_STATUS_SIZE(3) +
- // TLV_LOCATION_INFO_GSM_SIZE(9)
- equal(pduHelper.readHexOctet(), 19);
-
- // Event List, Type-Length-Value
- equal(pduHelper.readHexOctet(), COMPREHENSIONTLV_TAG_EVENT_LIST |
- COMPREHENSIONTLV_FLAG_CR);
- equal(pduHelper.readHexOctet(), 1);
- equal(pduHelper.readHexOctet(), STK_EVENT_TYPE_LOCATION_STATUS);
-
- // Device Identifies, Type-Length-Value(Source ID-Destination ID)
- equal(pduHelper.readHexOctet(), COMPREHENSIONTLV_TAG_DEVICE_ID |
- COMPREHENSIONTLV_FLAG_CR);
- equal(pduHelper.readHexOctet(), 2);
- equal(pduHelper.readHexOctet(), STK_DEVICE_ID_ME);
- equal(pduHelper.readHexOctet(), STK_DEVICE_ID_SIM);
-
- // Location Status, Type-Length-Value
- equal(pduHelper.readHexOctet(), COMPREHENSIONTLV_TAG_LOCATION_STATUS |
- COMPREHENSIONTLV_FLAG_CR);
- equal(pduHelper.readHexOctet(), 1);
- equal(pduHelper.readHexOctet(), STK_SERVICE_STATE_NORMAL);
-
- // Location Info, Type-Length-Value
- equal(pduHelper.readHexOctet(), COMPREHENSIONTLV_TAG_LOCATION_INFO |
- COMPREHENSIONTLV_FLAG_CR);
- equal(pduHelper.readHexOctet(), 7);
-
- equal(pduHelper.readHexOctet(), 0x21); // MCC + MNC
- equal(pduHelper.readHexOctet(), 0x63);
- equal(pduHelper.readHexOctet(), 0x54);
- equal(pduHelper.readHexOctet(), 0); // LAC
- equal(pduHelper.readHexOctet(), 0);
- equal(pduHelper.readHexOctet(), 0); // Cell ID
- equal(pduHelper.readHexOctet(), 0);
-
- run_next_test();
- };
-
- let event = {
- eventType: STK_EVENT_TYPE_LOCATION_STATUS,
- locationStatus: STK_SERVICE_STATE_NORMAL,
- locationInfo: {
- mcc: "123",
- mnc: "456",
- gsmLocationAreaCode: 0,
- gsmCellId: 0
- }
- };
- context.RIL.sendStkEventDownload({
- event: event
- });
-});
-
-// Test Event Download commands.
-
-/**
- * Verify Event Download Command : Language Selection
- */
-add_test(function test_stk_event_download_language_selection() {
- let worker = newUint8SupportOutgoingIndexWorker();
- let context = worker.ContextPool._contexts[0];
- let buf = context.Buf;
- let pduHelper = context.GsmPDUHelper;
- let iccHelper = context.ICCPDUHelper;
-
- buf.sendParcel = function() {
- // Type
- equal(this.readInt32(), REQUEST_STK_SEND_ENVELOPE_COMMAND);
-
- // Token : we don't care
- this.readInt32();
-
- // Data Size, 26 = 2 * (2 + TLV_DEVICE_ID_SIZE(4) +
- // TLV_EVENT_LIST_SIZE(3) +
- // TLV_LANGUAGE(4))
- equal(this.readInt32(), 26);
-
- // BER tag
- equal(pduHelper.readHexOctet(), BER_EVENT_DOWNLOAD_TAG);
-
- // BER length, 19 = TLV_DEVICE_ID_SIZE(4) +
- // TLV_EVENT_LIST_SIZE(3) +
- // TLV_LANGUAGE(4)
- equal(pduHelper.readHexOctet(), 11);
-
- // Event List, Type-Length-Value
- equal(pduHelper.readHexOctet(), COMPREHENSIONTLV_TAG_EVENT_LIST |
- COMPREHENSIONTLV_FLAG_CR);
- equal(pduHelper.readHexOctet(), 1);
- equal(pduHelper.readHexOctet(), STK_EVENT_TYPE_LANGUAGE_SELECTION);
-
- // Device Identifies, Type-Length-Value(Source ID-Destination ID)
- equal(pduHelper.readHexOctet(), COMPREHENSIONTLV_TAG_DEVICE_ID |
- COMPREHENSIONTLV_FLAG_CR);
- equal(pduHelper.readHexOctet(), 2);
- equal(pduHelper.readHexOctet(), STK_DEVICE_ID_ME);
- equal(pduHelper.readHexOctet(), STK_DEVICE_ID_SIM);
-
- // Language, Type-Length-Value
- equal(pduHelper.readHexOctet(), COMPREHENSIONTLV_TAG_LANGUAGE);
- equal(pduHelper.readHexOctet(), 2);
- equal(iccHelper.read8BitUnpackedToString(2), "zh");
-
- run_next_test();
- };
-
- let event = {
- eventType: STK_EVENT_TYPE_LANGUAGE_SELECTION,
- language: "zh"
- };
- context.RIL.sendStkEventDownload({
- event: event
- });
-});
-
-/**
- * Verify Event Download Command : User Activity
- */
-add_test(function test_stk_event_download_user_activity() {
- let worker = newUint8SupportOutgoingIndexWorker();
- let context = worker.ContextPool._contexts[0];
- let buf = context.Buf;
- let pduHelper = context.GsmPDUHelper;
-
- buf.sendParcel = function() {
- // Type
- equal(this.readInt32(), REQUEST_STK_SEND_ENVELOPE_COMMAND);
-
- // Token : we don't care
- this.readInt32();
-
- // Data Size, 18 = 2 * (2 + TLV_DEVICE_ID_SIZE(4) + TLV_EVENT_LIST_SIZE(3))
- equal(this.readInt32(), 18);
-
- // BER tag
- equal(pduHelper.readHexOctet(), BER_EVENT_DOWNLOAD_TAG);
-
- // BER length, 7 = TLV_DEVICE_ID_SIZE(4) + TLV_EVENT_LIST_SIZE(3)
- equal(pduHelper.readHexOctet(), 7);
-
- // Event List, Type-Length-Value
- equal(pduHelper.readHexOctet(), COMPREHENSIONTLV_TAG_EVENT_LIST |
- COMPREHENSIONTLV_FLAG_CR);
- equal(pduHelper.readHexOctet(), 1);
- equal(pduHelper.readHexOctet(), STK_EVENT_TYPE_USER_ACTIVITY);
-
- // Device Identities, Type-Length-Value(Source ID-Destination ID)
- equal(pduHelper.readHexOctet(), COMPREHENSIONTLV_TAG_DEVICE_ID |
- COMPREHENSIONTLV_FLAG_CR);
- equal(pduHelper.readHexOctet(), 2);
- equal(pduHelper.readHexOctet(), STK_DEVICE_ID_ME);
- equal(pduHelper.readHexOctet(), STK_DEVICE_ID_SIM);
-
- run_next_test();
- };
-
- let event = {
- eventType: STK_EVENT_TYPE_USER_ACTIVITY
- };
- context.RIL.sendStkEventDownload({
- event: event
- });
-});
-
-/**
- * Verify Event Download Command : Idle Screen Available
- */
-add_test(function test_stk_event_download_idle_screen_available() {
- let worker = newUint8SupportOutgoingIndexWorker();
- let context = worker.ContextPool._contexts[0];
- let buf = context.Buf;
- let pduHelper = context.GsmPDUHelper;
-
- buf.sendParcel = function() {
- // Type
- equal(this.readInt32(), REQUEST_STK_SEND_ENVELOPE_COMMAND);
-
- // Token : we don't care
- this.readInt32();
-
- // Data Size, 18 = 2 * (2 + TLV_DEVICE_ID_SIZE(4) + TLV_EVENT_LIST_SIZE(3))
- equal(this.readInt32(), 18);
-
- // BER tag
- equal(pduHelper.readHexOctet(), BER_EVENT_DOWNLOAD_TAG);
-
- // BER length, 7 = TLV_DEVICE_ID_SIZE(4) + TLV_EVENT_LIST_SIZE(3)
- equal(pduHelper.readHexOctet(), 7);
-
- // Event List, Type-Length-Value
- equal(pduHelper.readHexOctet(), COMPREHENSIONTLV_TAG_EVENT_LIST |
- COMPREHENSIONTLV_FLAG_CR);
- equal(pduHelper.readHexOctet(), 1);
- equal(pduHelper.readHexOctet(), STK_EVENT_TYPE_IDLE_SCREEN_AVAILABLE);
-
- // Device Identities, Type-Length-Value(Source ID-Destination ID)
- equal(pduHelper.readHexOctet(), COMPREHENSIONTLV_TAG_DEVICE_ID |
- COMPREHENSIONTLV_FLAG_CR);
- equal(pduHelper.readHexOctet(), 2);
- equal(pduHelper.readHexOctet(), STK_DEVICE_ID_DISPLAY);
- equal(pduHelper.readHexOctet(), STK_DEVICE_ID_SIM);
-
- run_next_test();
- };
-
- let event = {
- eventType: STK_EVENT_TYPE_IDLE_SCREEN_AVAILABLE
- };
- context.RIL.sendStkEventDownload({
- event: event
- });
-});
-
-/**
- * Verify Event Downloaded Command :Browser Termination
- */
-add_test(function test_stk_event_download_browser_termination() {
- let worker = newUint8SupportOutgoingIndexWorker();
- let context = worker.ContextPool._contexts[0];
- let buf = context.Buf;
- let pduHelper = context.GsmPDUHelper;
-
- buf.sendParcel = function() {
- // Type
- equal(this.readInt32(), REQUEST_STK_SEND_ENVELOPE_COMMAND);
-
- // Token : we don't care
- this.readInt32();
-
- // Data Size, 24 = 2 * ( 2+TLV_DEVICE_ID(4)+TLV_EVENT_LIST_SIZE(3)
- // +TLV_BROWSER_TERMINATION_CAUSE(3) )
- equal(this.readInt32(), 24);
-
- // BER tag
- equal(pduHelper.readHexOctet(), BER_EVENT_DOWNLOAD_TAG);
-
- // BER length, 10 = TLV_DEVICE_ID(4)+TLV_EVENT_LIST_SIZE(3)
- // ++TLV_BROWSER_TERMINATION_CAUSE(3)
- equal(pduHelper.readHexOctet(), 10);
-
- // Event List, Type-Length-Value
- equal(pduHelper.readHexOctet(), COMPREHENSIONTLV_TAG_EVENT_LIST |
- COMPREHENSIONTLV_FLAG_CR);
- equal(pduHelper.readHexOctet(), 1);
- equal(pduHelper.readHexOctet(), STK_EVENT_TYPE_BROWSER_TERMINATION);
-
- // Device Identities, Type-Length-Value(Source ID-Destination ID)
- equal(pduHelper.readHexOctet(), COMPREHENSIONTLV_TAG_DEVICE_ID |
- COMPREHENSIONTLV_FLAG_CR);
- equal(pduHelper.readHexOctet(), 2);
- equal(pduHelper.readHexOctet(), STK_DEVICE_ID_ME);
- equal(pduHelper.readHexOctet(), STK_DEVICE_ID_SIM);
-
- // Browser Termination Case, Type-Length-Value
- equal(pduHelper.readHexOctet(), COMPREHENSIONTLV_TAG_BROWSER_TERMINATION_CAUSE |
- COMPREHENSIONTLV_FLAG_CR);
- equal(pduHelper.readHexOctet(), 1);
- equal(pduHelper.readHexOctet(), STK_BROWSER_TERMINATION_CAUSE_USER);
-
- run_next_test();
- };
-
- let event = {
- eventType: STK_EVENT_TYPE_BROWSER_TERMINATION,
- terminationCause: STK_BROWSER_TERMINATION_CAUSE_USER
- };
- context.RIL.sendStkEventDownload({
- event: event
- });
-});
diff --git a/dom/system/gonk/tests/test_ril_worker_voiceprivacy.js b/dom/system/gonk/tests/test_ril_worker_voiceprivacy.js
deleted file mode 100644
index 21829da222..0000000000
--- a/dom/system/gonk/tests/test_ril_worker_voiceprivacy.js
+++ /dev/null
@@ -1,94 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-subscriptLoader.loadSubScript("resource://gre/modules/ril_consts.js", this);
-
-function run_test() {
- run_next_test();
-}
-
-add_test(function test_setVoicePrivacyMode_success() {
- let workerHelper = newInterceptWorker();
- let worker = workerHelper.worker;
- let context = worker.ContextPool._contexts[0];
-
- context.RIL.setVoicePrivacyMode = function fakeSetVoicePrivacyMode(options) {
- context.RIL[REQUEST_CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE](0, {});
- };
-
- context.RIL.setVoicePrivacyMode({
- enabled: true
- });
-
- let postedMessage = workerHelper.postedMessage;
-
- equal(postedMessage.errorMsg, undefined);
-
- run_next_test();
-});
-
-add_test(function test_setVoicePrivacyMode_generic_failure() {
- let workerHelper = newInterceptWorker();
- let worker = workerHelper.worker;
- let context = worker.ContextPool._contexts[0];
-
- context.RIL.setVoicePrivacyMode = function fakeSetVoicePrivacyMode(options) {
- context.RIL[REQUEST_CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE](0, {
- errorMsg: GECKO_ERROR_GENERIC_FAILURE
- });
- };
-
- context.RIL.setVoicePrivacyMode({
- enabled: true
- });
-
- let postedMessage = workerHelper.postedMessage;
-
- equal(postedMessage.errorMsg, GECKO_ERROR_GENERIC_FAILURE);
-
- run_next_test();
-});
-
-add_test(function test_queryVoicePrivacyMode_success_enabled_true() {
- let workerHelper = newInterceptWorker();
- let worker = workerHelper.worker;
- let context = worker.ContextPool._contexts[0];
-
- context.Buf.readInt32List = function fakeReadUint32List() {
- return [1];
- };
-
- context.RIL.queryVoicePrivacyMode = function fakeQueryVoicePrivacyMode(options) {
- context.RIL[REQUEST_CDMA_QUERY_PREFERRED_VOICE_PRIVACY_MODE](1, {});
- };
-
- context.RIL.queryVoicePrivacyMode();
-
- let postedMessage = workerHelper.postedMessage;
-
- equal(postedMessage.errorMsg, undefined);
- ok(postedMessage.enabled);
- run_next_test();
-});
-
-add_test(function test_queryVoicePrivacyMode_success_enabled_false() {
- let workerHelper = newInterceptWorker();
- let worker = workerHelper.worker;
- let context = worker.ContextPool._contexts[0];
-
- context.Buf.readInt32List = function fakeReadUint32List() {
- return [0];
- };
-
- context.RIL.queryVoicePrivacyMode = function fakeQueryVoicePrivacyMode(options) {
- context.RIL[REQUEST_CDMA_QUERY_PREFERRED_VOICE_PRIVACY_MODE](1, {});
- };
-
- context.RIL.queryVoicePrivacyMode();
-
- let postedMessage = workerHelper.postedMessage;
-
- equal(postedMessage.errorMsg, undefined);
- ok(!postedMessage.enabled);
- run_next_test();
-});
diff --git a/dom/system/gonk/tests/xpcshell.ini b/dom/system/gonk/tests/xpcshell.ini
deleted file mode 100644
index 1e8b798a39..0000000000
--- a/dom/system/gonk/tests/xpcshell.ini
+++ /dev/null
@@ -1,43 +0,0 @@
-[DEFAULT]
-head = header_helpers.js
-tail =
-
-[test_ril_worker_buf.js]
-[test_ril_worker_icc_CardLock.js]
-[test_ril_worker_icc_CardState.js]
-[test_ril_worker_icc_BerTlvHelper.js]
-[test_ril_worker_icc_GsmPDUHelper.js]
-[test_ril_worker_icc_ICCContactHelper.js]
-[test_ril_worker_icc_ICCIOHelper.js]
-[test_ril_worker_icc_ICCPDUHelper.js]
-[test_ril_worker_icc_ICCRecordHelper.js]
-[test_ril_worker_icc_IconLoader.js]
-[test_ril_worker_icc_ICCUtilsHelper.js]
-[test_ril_worker_icc_SimRecordHelper.js]
-[test_ril_worker_sms.js]
-# Bug 916067 - B2G RIL: test_ril_worker_sms.js takes too long to finish
-skip-if = true
-[test_ril_worker_sms_cdma.js]
-[test_ril_worker_sms_cdmapduhelper.js]
-[test_ril_worker_sms_nl_tables.js]
-[test_ril_worker_sms_gsmpduhelper.js]
-[test_ril_worker_sms_segment_info.js]
-[test_ril_worker_smsc_address.js]
-[test_ril_worker_cf.js]
-[test_ril_worker_cellbroadcast_config.js]
-[test_ril_worker_cellbroadcast_gsm.js]
-[test_ril_worker_cellbroadcast_umts.js]
-[test_ril_worker_ruim.js]
-[test_ril_worker_cw.js]
-[test_ril_worker_clir.js]
-[test_ril_worker_clip.js]
-[test_ril_worker_ssn.js]
-[test_ril_worker_voiceprivacy.js]
-[test_ril_worker_ecm.js]
-[test_ril_worker_stk.js]
-requesttimeoutfactor = 4
-[test_ril_worker_barring_password.js]
-[test_ril_worker_cdma_info_rec.js]
-[test_ril_system_messenger.js]
-# header_helpers.js is not needed for test_ril_system_messenger.js
-head =
diff --git a/dom/system/gonk/worker_buf.js b/dom/system/gonk/worker_buf.js
deleted file mode 100644
index 7064eeac5b..0000000000
--- a/dom/system/gonk/worker_buf.js
+++ /dev/null
@@ -1,623 +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/. */
-
-
-/**
- * This object contains helpers buffering incoming data & deconstructing it
- * into parcels as well as buffering outgoing data & constructing parcels.
- * For that it maintains two buffers and corresponding uint8 views, indexes.
- *
- * The incoming buffer is a circular buffer where we store incoming data.
- * As soon as a complete parcel is received, it is processed right away, so
- * the buffer only needs to be large enough to hold one parcel.
- *
- * The outgoing buffer is to prepare outgoing parcels. The index is reset
- * every time a parcel is sent.
- */
-
-var Buf = {
- INT32_MAX: 2147483647,
- UINT8_SIZE: 1,
- UINT16_SIZE: 2,
- UINT32_SIZE: 4,
- PARCEL_SIZE_SIZE: 4,
- PDU_HEX_OCTET_SIZE: 4,
-
- incomingBufferLength: 1024,
- incomingBuffer: null,
- incomingBytes: null,
- incomingWriteIndex: 0,
- incomingReadIndex: 0,
- readIncoming: 0,
- readAvailable: 0,
- currentParcelSize: 0,
-
- outgoingBufferLength: 1024,
- outgoingBuffer: null,
- outgoingBytes: null,
- outgoingIndex: 0,
- outgoingBufferCalSizeQueue: null,
-
- _init: function() {
- this.incomingBuffer = new ArrayBuffer(this.incomingBufferLength);
- this.outgoingBuffer = new ArrayBuffer(this.outgoingBufferLength);
-
- this.incomingBytes = new Uint8Array(this.incomingBuffer);
- this.outgoingBytes = new Uint8Array(this.outgoingBuffer);
-
- // Track where incoming data is read from and written to.
- this.incomingWriteIndex = 0;
- this.incomingReadIndex = 0;
-
- // Leave room for the parcel size for outgoing parcels.
- this.outgoingIndex = this.PARCEL_SIZE_SIZE;
-
- // How many bytes we've read for this parcel so far.
- this.readIncoming = 0;
-
- // How many bytes available as parcel data.
- this.readAvailable = 0;
-
- // Size of the incoming parcel. If this is zero, we're expecting a new
- // parcel.
- this.currentParcelSize = 0;
-
- // Queue for storing outgoing override points
- this.outgoingBufferCalSizeQueue = [];
- },
-
- /**
- * Mark current outgoingIndex as start point for calculation length of data
- * written to outgoingBuffer.
- * Mark can be nested for here uses queue to remember marks.
- *
- * @param writeFunction
- * Function to write data length into outgoingBuffer, this function is
- * also used to allocate buffer for data length.
- * Raw data size(in Uint8) is provided as parameter calling writeFunction.
- * If raw data size is not in proper unit for writing, user can adjust
- * the length value in writeFunction before writing.
- **/
- startCalOutgoingSize: function(writeFunction) {
- let sizeInfo = {index: this.outgoingIndex,
- write: writeFunction};
-
- // Allocate buffer for data lemgtj.
- writeFunction.call(0);
-
- // Get size of data length buffer for it is not counted into data size.
- sizeInfo.size = this.outgoingIndex - sizeInfo.index;
-
- // Enqueue size calculation information.
- this.outgoingBufferCalSizeQueue.push(sizeInfo);
- },
-
- /**
- * Calculate data length since last mark, and write it into mark position.
- **/
- stopCalOutgoingSize: function() {
- let sizeInfo = this.outgoingBufferCalSizeQueue.pop();
-
- // Remember current outgoingIndex.
- let currentOutgoingIndex = this.outgoingIndex;
- // Calculate data length, in uint8.
- let writeSize = this.outgoingIndex - sizeInfo.index - sizeInfo.size;
-
- // Write data length to mark, use same function for allocating buffer to make
- // sure there is no buffer overloading.
- this.outgoingIndex = sizeInfo.index;
- sizeInfo.write(writeSize);
-
- // Restore outgoingIndex.
- this.outgoingIndex = currentOutgoingIndex;
- },
-
- /**
- * Grow the incoming buffer.
- *
- * @param min_size
- * Minimum new size. The actual new size will be the the smallest
- * power of 2 that's larger than this number.
- */
- growIncomingBuffer: function(min_size) {
- if (DEBUG) {
- debug("Current buffer of " + this.incomingBufferLength +
- " can't handle incoming " + min_size + " bytes.");
- }
- let oldBytes = this.incomingBytes;
- this.incomingBufferLength =
- 2 << Math.floor(Math.log(min_size)/Math.log(2));
- if (DEBUG) debug("New incoming buffer size: " + this.incomingBufferLength);
- this.incomingBuffer = new ArrayBuffer(this.incomingBufferLength);
- this.incomingBytes = new Uint8Array(this.incomingBuffer);
- if (this.incomingReadIndex <= this.incomingWriteIndex) {
- // Read and write index are in natural order, so we can just copy
- // the old buffer over to the bigger one without having to worry
- // about the indexes.
- this.incomingBytes.set(oldBytes, 0);
- } else {
- // The write index has wrapped around but the read index hasn't yet.
- // Write whatever the read index has left to read until it would
- // circle around to the beginning of the new buffer, and the rest
- // behind that.
- let head = oldBytes.subarray(this.incomingReadIndex);
- let tail = oldBytes.subarray(0, this.incomingReadIndex);
- this.incomingBytes.set(head, 0);
- this.incomingBytes.set(tail, head.length);
- this.incomingReadIndex = 0;
- this.incomingWriteIndex += head.length;
- }
- if (DEBUG) {
- debug("New incoming buffer size is " + this.incomingBufferLength);
- }
- },
-
- /**
- * Grow the outgoing buffer.
- *
- * @param min_size
- * Minimum new size. The actual new size will be the the smallest
- * power of 2 that's larger than this number.
- */
- growOutgoingBuffer: function(min_size) {
- if (DEBUG) {
- debug("Current buffer of " + this.outgoingBufferLength +
- " is too small.");
- }
- let oldBytes = this.outgoingBytes;
- this.outgoingBufferLength =
- 2 << Math.floor(Math.log(min_size)/Math.log(2));
- this.outgoingBuffer = new ArrayBuffer(this.outgoingBufferLength);
- this.outgoingBytes = new Uint8Array(this.outgoingBuffer);
- this.outgoingBytes.set(oldBytes, 0);
- if (DEBUG) {
- debug("New outgoing buffer size is " + this.outgoingBufferLength);
- }
- },
-
- /**
- * Functions for reading data from the incoming buffer.
- *
- * These are all little endian, apart from readParcelSize();
- */
-
- /**
- * Ensure position specified is readable.
- *
- * @param index
- * Data position in incoming parcel, valid from 0 to
- * currentParcelSize.
- */
- ensureIncomingAvailable: function(index) {
- if (index >= this.currentParcelSize) {
- throw new Error("Trying to read data beyond the parcel end!");
- } else if (index < 0) {
- throw new Error("Trying to read data before the parcel begin!");
- }
- },
-
- /**
- * Seek in current incoming parcel.
- *
- * @param offset
- * Seek offset in relative to current position.
- */
- seekIncoming: function(offset) {
- // Translate to 0..currentParcelSize
- let cur = this.currentParcelSize - this.readAvailable;
-
- let newIndex = cur + offset;
- this.ensureIncomingAvailable(newIndex);
-
- // ... incomingReadIndex -->|
- // 0 new cur currentParcelSize
- // |================|=======|====================|
- // |<-- cur -->|<- readAvailable ->|
- // |<-- newIndex -->|<-- new readAvailable -->|
- this.readAvailable = this.currentParcelSize - newIndex;
-
- // Translate back:
- if (this.incomingReadIndex < cur) {
- // The incomingReadIndex is wrapped.
- newIndex += this.incomingBufferLength;
- }
- newIndex += (this.incomingReadIndex - cur);
- newIndex %= this.incomingBufferLength;
- this.incomingReadIndex = newIndex;
- },
-
- readUint8Unchecked: function() {
- let value = this.incomingBytes[this.incomingReadIndex];
- this.incomingReadIndex = (this.incomingReadIndex + 1) %
- this.incomingBufferLength;
- return value;
- },
-
- readUint8: function() {
- // Translate to 0..currentParcelSize
- let cur = this.currentParcelSize - this.readAvailable;
- this.ensureIncomingAvailable(cur);
-
- this.readAvailable--;
- return this.readUint8Unchecked();
- },
-
- readUint8Array: function(length) {
- // Translate to 0..currentParcelSize
- let last = this.currentParcelSize - this.readAvailable;
- last += (length - 1);
- this.ensureIncomingAvailable(last);
-
- let array = new Uint8Array(length);
- for (let i = 0; i < length; i++) {
- array[i] = this.readUint8Unchecked();
- }
-
- this.readAvailable -= length;
- return array;
- },
-
- readUint16: function() {
- return this.readUint8() | this.readUint8() << 8;
- },
-
- readInt32: function() {
- return this.readUint8() | this.readUint8() << 8 |
- this.readUint8() << 16 | this.readUint8() << 24;
- },
-
- readInt64: function() {
- // Avoid using bitwise operators as the operands of all bitwise operators
- // are converted to signed 32-bit integers.
- return this.readUint8() +
- this.readUint8() * Math.pow(2, 8) +
- this.readUint8() * Math.pow(2, 16) +
- this.readUint8() * Math.pow(2, 24) +
- this.readUint8() * Math.pow(2, 32) +
- this.readUint8() * Math.pow(2, 40) +
- this.readUint8() * Math.pow(2, 48) +
- this.readUint8() * Math.pow(2, 56);
- },
-
- readInt32List: function() {
- let length = this.readInt32();
- let ints = [];
- for (let i = 0; i < length; i++) {
- ints.push(this.readInt32());
- }
- return ints;
- },
-
- readString: function() {
- let string_len = this.readInt32();
- if (string_len < 0 || string_len >= this.INT32_MAX) {
- return null;
- }
- let s = "";
- for (let i = 0; i < string_len; i++) {
- s += String.fromCharCode(this.readUint16());
- }
- // Strings are \0\0 delimited, but that isn't part of the length. And
- // if the string length is even, the delimiter is two characters wide.
- // It's insane, I know.
- this.readStringDelimiter(string_len);
- return s;
- },
-
- readStringList: function() {
- let num_strings = this.readInt32();
- let strings = [];
- for (let i = 0; i < num_strings; i++) {
- strings.push(this.readString());
- }
- return strings;
- },
-
- readStringDelimiter: function(length) {
- let delimiter = this.readUint16();
- if (!(length & 1)) {
- delimiter |= this.readUint16();
- }
- if (DEBUG) {
- if (delimiter !== 0) {
- debug("Something's wrong, found string delimiter: " + delimiter);
- }
- }
- },
-
- readParcelSize: function() {
- return this.readUint8Unchecked() << 24 |
- this.readUint8Unchecked() << 16 |
- this.readUint8Unchecked() << 8 |
- this.readUint8Unchecked();
- },
-
- /**
- * Functions for writing data to the outgoing buffer.
- */
-
- /**
- * Ensure position specified is writable.
- *
- * @param index
- * Data position in outgoing parcel, valid from 0 to
- * outgoingBufferLength.
- */
- ensureOutgoingAvailable: function(index) {
- if (index >= this.outgoingBufferLength) {
- this.growOutgoingBuffer(index + 1);
- }
- },
-
- writeUint8: function(value) {
- this.ensureOutgoingAvailable(this.outgoingIndex);
-
- this.outgoingBytes[this.outgoingIndex] = value;
- this.outgoingIndex++;
- },
-
- writeUint16: function(value) {
- this.writeUint8(value & 0xff);
- this.writeUint8((value >> 8) & 0xff);
- },
-
- writeInt32: function(value) {
- this.writeUint8(value & 0xff);
- this.writeUint8((value >> 8) & 0xff);
- this.writeUint8((value >> 16) & 0xff);
- this.writeUint8((value >> 24) & 0xff);
- },
-
- writeString: function(value) {
- if (value == null) {
- this.writeInt32(-1);
- return;
- }
- this.writeInt32(value.length);
- for (let i = 0; i < value.length; i++) {
- this.writeUint16(value.charCodeAt(i));
- }
- // Strings are \0\0 delimited, but that isn't part of the length. And
- // if the string length is even, the delimiter is two characters wide.
- // It's insane, I know.
- this.writeStringDelimiter(value.length);
- },
-
- writeStringList: function(strings) {
- this.writeInt32(strings.length);
- for (let i = 0; i < strings.length; i++) {
- this.writeString(strings[i]);
- }
- },
-
- writeStringDelimiter: function(length) {
- this.writeUint16(0);
- if (!(length & 1)) {
- this.writeUint16(0);
- }
- },
-
- writeParcelSize: function(value) {
- /**
- * Parcel size will always be the first thing in the parcel byte
- * array, but the last thing written. Store the current index off
- * to a temporary to be reset after we write the size.
- */
- let currentIndex = this.outgoingIndex;
- this.outgoingIndex = 0;
- this.writeUint8((value >> 24) & 0xff);
- this.writeUint8((value >> 16) & 0xff);
- this.writeUint8((value >> 8) & 0xff);
- this.writeUint8(value & 0xff);
- this.outgoingIndex = currentIndex;
- },
-
- copyIncomingToOutgoing: function(length) {
- if (!length || (length < 0)) {
- return;
- }
-
- let translatedReadIndexEnd =
- this.currentParcelSize - this.readAvailable + length - 1;
- this.ensureIncomingAvailable(translatedReadIndexEnd);
-
- let translatedWriteIndexEnd = this.outgoingIndex + length - 1;
- this.ensureOutgoingAvailable(translatedWriteIndexEnd);
-
- let newIncomingReadIndex = this.incomingReadIndex + length;
- if (newIncomingReadIndex < this.incomingBufferLength) {
- // Reading won't cause wrapping, go ahead with builtin copy.
- this.outgoingBytes
- .set(this.incomingBytes.subarray(this.incomingReadIndex,
- newIncomingReadIndex),
- this.outgoingIndex);
- } else {
- // Not so lucky.
- newIncomingReadIndex %= this.incomingBufferLength;
- this.outgoingBytes
- .set(this.incomingBytes.subarray(this.incomingReadIndex,
- this.incomingBufferLength),
- this.outgoingIndex);
- if (newIncomingReadIndex) {
- let firstPartLength = this.incomingBufferLength - this.incomingReadIndex;
- this.outgoingBytes.set(this.incomingBytes.subarray(0, newIncomingReadIndex),
- this.outgoingIndex + firstPartLength);
- }
- }
-
- this.incomingReadIndex = newIncomingReadIndex;
- this.readAvailable -= length;
- this.outgoingIndex += length;
- },
-
- /**
- * Parcel management
- */
-
- /**
- * Write incoming data to the circular buffer.
- *
- * @param incoming
- * Uint8Array containing the incoming data.
- */
- writeToIncoming: function(incoming) {
- // We don't have to worry about the head catching the tail since
- // we process any backlog in parcels immediately, before writing
- // new data to the buffer. So the only edge case we need to handle
- // is when the incoming data is larger than the buffer size.
- let minMustAvailableSize = incoming.length + this.readIncoming;
- if (minMustAvailableSize > this.incomingBufferLength) {
- this.growIncomingBuffer(minMustAvailableSize);
- }
-
- // We can let the typed arrays do the copying if the incoming data won't
- // wrap around the edges of the circular buffer.
- let remaining = this.incomingBufferLength - this.incomingWriteIndex;
- if (remaining >= incoming.length) {
- this.incomingBytes.set(incoming, this.incomingWriteIndex);
- } else {
- // The incoming data would wrap around it.
- let head = incoming.subarray(0, remaining);
- let tail = incoming.subarray(remaining);
- this.incomingBytes.set(head, this.incomingWriteIndex);
- this.incomingBytes.set(tail, 0);
- }
- this.incomingWriteIndex = (this.incomingWriteIndex + incoming.length) %
- this.incomingBufferLength;
- },
-
- /**
- * Process incoming data.
- *
- * @param incoming
- * Uint8Array containing the incoming data.
- */
- processIncoming: function(incoming) {
- if (DEBUG) {
- debug("Received " + incoming.length + " bytes.");
- debug("Already read " + this.readIncoming);
- }
-
- this.writeToIncoming(incoming);
- this.readIncoming += incoming.length;
- while (true) {
- if (!this.currentParcelSize) {
- // We're expecting a new parcel.
- if (this.readIncoming < this.PARCEL_SIZE_SIZE) {
- // We don't know how big the next parcel is going to be, need more
- // data.
- if (DEBUG) debug("Next parcel size unknown, going to sleep.");
- return;
- }
- this.currentParcelSize = this.readParcelSize();
- if (DEBUG) {
- debug("New incoming parcel of size " + this.currentParcelSize);
- }
- // The size itself is not included in the size.
- this.readIncoming -= this.PARCEL_SIZE_SIZE;
- }
-
- if (this.readIncoming < this.currentParcelSize) {
- // We haven't read enough yet in order to be able to process a parcel.
- if (DEBUG) debug("Read " + this.readIncoming + ", but parcel size is "
- + this.currentParcelSize + ". Going to sleep.");
- return;
- }
-
- // Alright, we have enough data to process at least one whole parcel.
- // Let's do that.
- let expectedAfterIndex = (this.incomingReadIndex + this.currentParcelSize)
- % this.incomingBufferLength;
-
- if (DEBUG) {
- let parcel;
- if (expectedAfterIndex < this.incomingReadIndex) {
- let head = this.incomingBytes.subarray(this.incomingReadIndex);
- let tail = this.incomingBytes.subarray(0, expectedAfterIndex);
- parcel = Array.slice(head).concat(Array.slice(tail));
- } else {
- parcel = Array.slice(this.incomingBytes.subarray(
- this.incomingReadIndex, expectedAfterIndex));
- }
- debug("Parcel (size " + this.currentParcelSize + "): " + parcel);
- }
-
- if (DEBUG) debug("We have at least one complete parcel.");
- try {
- this.readAvailable = this.currentParcelSize;
- this.processParcel();
- } catch (ex) {
- if (DEBUG) debug("Parcel handling threw " + ex + "\n" + ex.stack);
- }
-
- // Ensure that the whole parcel was consumed.
- if (this.incomingReadIndex != expectedAfterIndex) {
- if (DEBUG) {
- debug("Parcel handler didn't consume whole parcel, " +
- Math.abs(expectedAfterIndex - this.incomingReadIndex) +
- " bytes left over");
- }
- this.incomingReadIndex = expectedAfterIndex;
- }
- this.readIncoming -= this.currentParcelSize;
- this.readAvailable = 0;
- this.currentParcelSize = 0;
- }
- },
-
- /**
- * Communicate with the IPC thread.
- */
- sendParcel: function() {
- // Compute the size of the parcel and write it to the front of the parcel
- // where we left room for it. Note that he parcel size does not include
- // the size itself.
- let parcelSize = this.outgoingIndex - this.PARCEL_SIZE_SIZE;
- this.writeParcelSize(parcelSize);
-
- // This assumes that postRILMessage will make a copy of the ArrayBufferView
- // right away!
- let parcel = this.outgoingBytes.subarray(0, this.outgoingIndex);
- if (DEBUG) debug("Outgoing parcel: " + Array.slice(parcel));
- this.onSendParcel(parcel);
- this.outgoingIndex = this.PARCEL_SIZE_SIZE;
- },
-
- getCurrentParcelSize: function() {
- return this.currentParcelSize;
- },
-
- getReadAvailable: function() {
- return this.readAvailable;
- }
-
- /**
- * Process one parcel.
- *
- * |processParcel| is an implementation provided incoming parcel processing
- * function invoked when we have received a complete parcel. Implementation
- * may call multiple read functions to extract data from the incoming buffer.
- */
- //processParcel: function() {
- // let something = this.readInt32();
- // ...
- //},
-
- /**
- * Write raw data out to underlying channel.
- *
- * |onSendParcel| is an implementation provided stream output function
- * invoked when we're really going to write something out. We assume the
- * data are completely copied to some output buffer in this call and may
- * be destroyed when it's done.
- *
- * @param parcel
- * An array of numeric octet data.
- */
- //onSendParcel: function(parcel) {
- // ...
- //}
-};
-
-module.exports = { Buf: Buf };
diff --git a/dom/system/moz.build b/dom/system/moz.build
index 3cff531b58..fc8cf533b0 100644
--- a/dom/system/moz.build
+++ b/dom/system/moz.build
@@ -12,8 +12,6 @@ elif toolkit == 'cocoa':
DIRS += ['mac']
elif toolkit == 'android':
DIRS += ['android']
-elif toolkit == 'gonk':
- DIRS += ['gonk']
elif toolkit in ('gtk2', 'gtk3'):
DIRS += ['linux']