diff options
Diffstat (limited to 'dom')
23 files changed, 1 insertions, 2293 deletions
diff --git a/dom/gamepad/cocoa/CocoaGamepad.cpp b/dom/gamepad/cocoa/CocoaGamepad.cpp deleted file mode 100644 index eb6eda9a17..0000000000 --- a/dom/gamepad/cocoa/CocoaGamepad.cpp +++ /dev/null @@ -1,590 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -// mostly derived from the Allegro source code at: -// http://alleg.svn.sourceforge.net/viewvc/alleg/allegro/branches/4.9/src/macosx/hidjoy.m?revision=13760&view=markup - -#include "mozilla/dom/Gamepad.h" -#include "mozilla/dom/GamepadPlatformService.h" -#include "mozilla/ArrayUtils.h" -#include "mozilla/Unused.h" -#include "nsThreadUtils.h" -#include <CoreFoundation/CoreFoundation.h> -#include <IOKit/hid/IOHIDBase.h> -#include <IOKit/hid/IOHIDKeys.h> -#include <IOKit/hid/IOHIDManager.h> - -#include <stdio.h> -#include <vector> - -namespace { - -using namespace mozilla; -using namespace mozilla::dom; -using std::vector; - -struct Button { - int id; - bool analog; - IOHIDElementRef element; - CFIndex min; - CFIndex max; - - Button(int aId, IOHIDElementRef aElement, CFIndex aMin, CFIndex aMax) : - id(aId), - analog((aMax - aMin) > 1), - element(aElement), - min(aMin), - max(aMax) {} -}; - -struct Axis { - int id; - IOHIDElementRef element; - uint32_t usagePage; - uint32_t usage; - CFIndex min; - CFIndex max; -}; - -typedef bool dpad_buttons[4]; - -// These values can be found in the USB HID Usage Tables: -// http://www.usb.org/developers/hidpage -const unsigned kDesktopUsagePage = 0x01; -const unsigned kSimUsagePage = 0x02; -const unsigned kAcceleratorUsage = 0xC4; -const unsigned kBrakeUsage = 0xC5; -const unsigned kJoystickUsage = 0x04; -const unsigned kGamepadUsage = 0x05; -const unsigned kAxisUsageMin = 0x30; -const unsigned kAxisUsageMax = 0x35; -const unsigned kDpadUsage = 0x39; -const unsigned kButtonUsagePage = 0x09; -const unsigned kConsumerPage = 0x0C; -const unsigned kHomeUsage = 0x223; -const unsigned kBackUsage = 0x224; - - -class Gamepad { - private: - IOHIDDeviceRef mDevice; - nsTArray<Button> buttons; - nsTArray<Axis> axes; - IOHIDElementRef mDpad; - dpad_buttons mDpadState; - - public: - Gamepad() : mDevice(nullptr), mDpad(nullptr), mSuperIndex(-1) {} - bool operator==(IOHIDDeviceRef device) const { return mDevice == device; } - bool empty() const { return mDevice == nullptr; } - void clear() - { - mDevice = nullptr; - buttons.Clear(); - axes.Clear(); - mDpad = nullptr; - mSuperIndex = -1; - } - void init(IOHIDDeviceRef device); - size_t numButtons() { return buttons.Length() + (mDpad ? 4 : 0); } - size_t numAxes() { return axes.Length(); } - - // Index given by our superclass. - uint32_t mSuperIndex; - - bool isDpad(IOHIDElementRef element) const - { - return element == mDpad; - } - - const dpad_buttons& getDpadState() const - { - return mDpadState; - } - - void setDpadState(const dpad_buttons& dpadState) - { - for (unsigned i = 0; i < ArrayLength(mDpadState); i++) { - mDpadState[i] = dpadState[i]; - } - } - - const Button* lookupButton(IOHIDElementRef element) const - { - for (unsigned i = 0; i < buttons.Length(); i++) { - if (buttons[i].element == element) - return &buttons[i]; - } - return nullptr; - } - - const Axis* lookupAxis(IOHIDElementRef element) const - { - for (unsigned i = 0; i < axes.Length(); i++) { - if (axes[i].element == element) - return &axes[i]; - } - return nullptr; - } -}; - -class AxisComparator { -public: - bool Equals(const Axis& a1, const Axis& a2) const - { - return a1.usagePage == a2.usagePage && a1.usage == a2.usage; - } - bool LessThan(const Axis& a1, const Axis& a2) const - { - if (a1.usagePage == a2.usagePage) { - return a1.usage < a2.usage; - } - return a1.usagePage < a2.usagePage; - } -}; - -void Gamepad::init(IOHIDDeviceRef device) -{ - clear(); - mDevice = device; - - CFArrayRef elements = IOHIDDeviceCopyMatchingElements(device, - nullptr, - kIOHIDOptionsTypeNone); - CFIndex n = CFArrayGetCount(elements); - for (CFIndex i = 0; i < n; i++) { - IOHIDElementRef element = (IOHIDElementRef)CFArrayGetValueAtIndex(elements, - i); - uint32_t usagePage = IOHIDElementGetUsagePage(element); - uint32_t usage = IOHIDElementGetUsage(element); - - if (usagePage == kDesktopUsagePage && - usage >= kAxisUsageMin && - usage <= kAxisUsageMax) - { - Axis axis = { int(axes.Length()), - element, - usagePage, - usage, - IOHIDElementGetLogicalMin(element), - IOHIDElementGetLogicalMax(element) }; - axes.AppendElement(axis); - } else if (usagePage == kDesktopUsagePage && usage == kDpadUsage && - // Don't know how to handle d-pads that return weird values. - IOHIDElementGetLogicalMax(element) - IOHIDElementGetLogicalMin(element) == 7) { - mDpad = element; - } else if ((usagePage == kSimUsagePage && - (usage == kAcceleratorUsage || - usage == kBrakeUsage)) || - (usagePage == kButtonUsagePage) || - (usagePage == kConsumerPage && - (usage == kHomeUsage || - usage == kBackUsage))) { - Button button(int(buttons.Length()), element, IOHIDElementGetLogicalMin(element), IOHIDElementGetLogicalMax(element)); - buttons.AppendElement(button); - } else { - //TODO: handle other usage pages - } - } - - AxisComparator comparator; - axes.Sort(comparator); - for (unsigned i = 0; i < axes.Length(); i++) { - axes[i].id = i; - } -} - -class DarwinGamepadService { - private: - IOHIDManagerRef mManager; - vector<Gamepad> mGamepads; - - //Workaround to support running in background thread - CFRunLoopRef mMonitorRunLoop; - nsCOMPtr<nsIThread> mMonitorThread; - - static void DeviceAddedCallback(void* data, IOReturn result, - void* sender, IOHIDDeviceRef device); - static void DeviceRemovedCallback(void* data, IOReturn result, - void* sender, IOHIDDeviceRef device); - static void InputValueChangedCallback(void* data, IOReturn result, - void* sender, IOHIDValueRef newValue); - - void DeviceAdded(IOHIDDeviceRef device); - void DeviceRemoved(IOHIDDeviceRef device); - void InputValueChanged(IOHIDValueRef value); - void StartupInternal(); - - public: - DarwinGamepadService(); - ~DarwinGamepadService(); - void Startup(); - void Shutdown(); - friend class DarwinGamepadServiceStartupRunnable; -}; - -class DarwinGamepadServiceStartupRunnable final : public Runnable -{ - private: - ~DarwinGamepadServiceStartupRunnable() {} - // This Runnable schedules startup of DarwinGamepadService - // in a new thread, pointer to DarwinGamepadService is only - // used by this Runnable within its thread. - DarwinGamepadService MOZ_NON_OWNING_REF *mService; - public: - explicit DarwinGamepadServiceStartupRunnable(DarwinGamepadService *service) - : mService(service) {} - NS_IMETHOD Run() override - { - MOZ_ASSERT(mService); - mService->StartupInternal(); - return NS_OK; - } -}; - -void -DarwinGamepadService::DeviceAdded(IOHIDDeviceRef device) -{ - RefPtr<GamepadPlatformService> service = - GamepadPlatformService::GetParentService(); - if (!service) { - return; - } - - size_t slot = size_t(-1); - for (size_t i = 0; i < mGamepads.size(); i++) { - if (mGamepads[i] == device) - return; - if (slot == size_t(-1) && mGamepads[i].empty()) - slot = i; - } - - if (slot == size_t(-1)) { - slot = mGamepads.size(); - mGamepads.push_back(Gamepad()); - } - mGamepads[slot].init(device); - - // Gather some identifying information - CFNumberRef vendorIdRef = - (CFNumberRef)IOHIDDeviceGetProperty(device, CFSTR(kIOHIDVendorIDKey)); - CFNumberRef productIdRef = - (CFNumberRef)IOHIDDeviceGetProperty(device, CFSTR(kIOHIDProductIDKey)); - CFStringRef productRef = - (CFStringRef)IOHIDDeviceGetProperty(device, CFSTR(kIOHIDProductKey)); - int vendorId, productId; - CFNumberGetValue(vendorIdRef, kCFNumberIntType, &vendorId); - CFNumberGetValue(productIdRef, kCFNumberIntType, &productId); - char product_name[128]; - CFStringGetCString(productRef, product_name, - sizeof(product_name), kCFStringEncodingASCII); - char buffer[256]; - sprintf(buffer, "%x-%x-%s", vendorId, productId, product_name); - uint32_t index = service->AddGamepad(buffer, - mozilla::dom::GamepadMappingType::_empty, - (int)mGamepads[slot].numButtons(), - (int)mGamepads[slot].numAxes()); - mGamepads[slot].mSuperIndex = index; -} - -void -DarwinGamepadService::DeviceRemoved(IOHIDDeviceRef device) -{ - RefPtr<GamepadPlatformService> service = - GamepadPlatformService::GetParentService(); - if (!service) { - return; - } - for (size_t i = 0; i < mGamepads.size(); i++) { - if (mGamepads[i] == device) { - service->RemoveGamepad(mGamepads[i].mSuperIndex); - mGamepads[i].clear(); - return; - } - } -} - -/* - * Given a value from a d-pad (POV hat in USB HID terminology), - * represent it as 4 buttons, one for each cardinal direction. - */ -static void -UnpackDpad(int dpad_value, int min, int max, dpad_buttons& buttons) -{ - const unsigned kUp = 0; - const unsigned kDown = 1; - const unsigned kLeft = 2; - const unsigned kRight = 3; - - // Different controllers have different ways of representing - // "nothing is pressed", but they're all outside the range of values. - if (dpad_value < min || dpad_value > max) { - // Nothing is pressed. - return; - } - - // Normalize value to start at 0. - int value = dpad_value - min; - - // Value will be in the range 0-7. The value represents the - // position of the d-pad around a circle, with 0 being straight up, - // 2 being right, 4 being straight down, and 6 being left. - if (value < 2 || value > 6) { - buttons[kUp] = true; - } - if (value > 2 && value < 6) { - buttons[kDown] = true; - } - if (value > 4) { - buttons[kLeft] = true; - } - if (value > 0 && value < 4) { - buttons[kRight] = true; - } -} - -void -DarwinGamepadService::InputValueChanged(IOHIDValueRef value) -{ - RefPtr<GamepadPlatformService> service = - GamepadPlatformService::GetParentService(); - if (!service) { - return; - } - - uint32_t value_length = IOHIDValueGetLength(value); - if (value_length > 4) { - // Workaround for bizarre issue with PS3 controllers that try to return - // massive (30+ byte) values and crash IOHIDValueGetIntegerValue - return; - } - IOHIDElementRef element = IOHIDValueGetElement(value); - IOHIDDeviceRef device = IOHIDElementGetDevice(element); - - for (unsigned i = 0; i < mGamepads.size(); i++) { - Gamepad &gamepad = mGamepads[i]; - if (gamepad == device) { - if (gamepad.isDpad(element)) { - const dpad_buttons& oldState = gamepad.getDpadState(); - dpad_buttons newState = { false, false, false, false }; - UnpackDpad(IOHIDValueGetIntegerValue(value), - IOHIDElementGetLogicalMin(element), - IOHIDElementGetLogicalMax(element), - newState); - const int numButtons = gamepad.numButtons(); - for (unsigned b = 0; b < ArrayLength(newState); b++) { - if (newState[b] != oldState[b]) { - service->NewButtonEvent(gamepad.mSuperIndex, - numButtons - 4 + b, - newState[b]); - } - } - gamepad.setDpadState(newState); - } else if (const Axis* axis = gamepad.lookupAxis(element)) { - double d = IOHIDValueGetIntegerValue(value); - double v = 2.0f * (d - axis->min) / - (double)(axis->max - axis->min) - 1.0f; - service->NewAxisMoveEvent(gamepad.mSuperIndex, axis->id, v); - } else if (const Button* button = gamepad.lookupButton(element)) { - int iv = IOHIDValueGetIntegerValue(value); - bool pressed = iv != 0; - double v = 0; - if (button->analog) { - double dv = iv; - v = (dv - button->min) / (double)(button->max - button->min); - } else { - v = pressed ? 1.0 : 0.0; - } - service->NewButtonEvent(gamepad.mSuperIndex, button->id, pressed, v); - } - return; - } - } -} - -void -DarwinGamepadService::DeviceAddedCallback(void* data, IOReturn result, - void* sender, IOHIDDeviceRef device) -{ - DarwinGamepadService* service = (DarwinGamepadService*)data; - service->DeviceAdded(device); -} - -void -DarwinGamepadService::DeviceRemovedCallback(void* data, IOReturn result, - void* sender, IOHIDDeviceRef device) -{ - DarwinGamepadService* service = (DarwinGamepadService*)data; - service->DeviceRemoved(device); -} - -void -DarwinGamepadService::InputValueChangedCallback(void* data, - IOReturn result, - void* sender, - IOHIDValueRef newValue) -{ - DarwinGamepadService* service = (DarwinGamepadService*)data; - service->InputValueChanged(newValue); -} - -static CFMutableDictionaryRef -MatchingDictionary(UInt32 inUsagePage, UInt32 inUsage) -{ - CFMutableDictionaryRef dict = - CFDictionaryCreateMutable(kCFAllocatorDefault, - 0, - &kCFTypeDictionaryKeyCallBacks, - &kCFTypeDictionaryValueCallBacks); - if (!dict) - return nullptr; - CFNumberRef number = CFNumberCreate(kCFAllocatorDefault, - kCFNumberIntType, - &inUsagePage); - if (!number) { - CFRelease(dict); - return nullptr; - } - CFDictionarySetValue(dict, CFSTR(kIOHIDDeviceUsagePageKey), number); - CFRelease(number); - - number = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &inUsage); - if (!number) { - CFRelease(dict); - return nullptr; - } - CFDictionarySetValue(dict, CFSTR(kIOHIDDeviceUsageKey), number); - CFRelease(number); - - return dict; -} - -DarwinGamepadService::DarwinGamepadService() : mManager(nullptr) {} - -DarwinGamepadService::~DarwinGamepadService() -{ - if (mManager != nullptr) - CFRelease(mManager); -} - -void -DarwinGamepadService::StartupInternal() -{ - if (mManager != nullptr) - return; - - IOHIDManagerRef manager = IOHIDManagerCreate(kCFAllocatorDefault, - kIOHIDOptionsTypeNone); - - CFMutableDictionaryRef criteria_arr[2]; - criteria_arr[0] = MatchingDictionary(kDesktopUsagePage, - kJoystickUsage); - if (!criteria_arr[0]) { - CFRelease(manager); - return; - } - - criteria_arr[1] = MatchingDictionary(kDesktopUsagePage, - kGamepadUsage); - if (!criteria_arr[1]) { - CFRelease(criteria_arr[0]); - CFRelease(manager); - return; - } - - CFArrayRef criteria = - CFArrayCreate(kCFAllocatorDefault, (const void**)criteria_arr, 2, nullptr); - if (!criteria) { - CFRelease(criteria_arr[1]); - CFRelease(criteria_arr[0]); - CFRelease(manager); - return; - } - - IOHIDManagerSetDeviceMatchingMultiple(manager, criteria); - CFRelease(criteria); - CFRelease(criteria_arr[1]); - CFRelease(criteria_arr[0]); - - IOHIDManagerRegisterDeviceMatchingCallback(manager, - DeviceAddedCallback, - this); - IOHIDManagerRegisterDeviceRemovalCallback(manager, - DeviceRemovedCallback, - this); - IOHIDManagerRegisterInputValueCallback(manager, - InputValueChangedCallback, - this); - IOHIDManagerScheduleWithRunLoop(manager, - CFRunLoopGetCurrent(), - kCFRunLoopDefaultMode); - IOReturn rv = IOHIDManagerOpen(manager, kIOHIDOptionsTypeNone); - if (rv != kIOReturnSuccess) { - CFRelease(manager); - return; - } - - mManager = manager; - - // We held the handle of the CFRunLoop to make sure we - // can shut it down explicitly by CFRunLoopStop in another - // thread. - mMonitorRunLoop = CFRunLoopGetCurrent(); - - // CFRunLoopRun() is a blocking message loop when it's called in - // non-main thread so this thread cannot receive any other runnables - // and nsITimer timeout events after it's called. - CFRunLoopRun(); -} - -void DarwinGamepadService::Startup() -{ - Unused << NS_NewThread(getter_AddRefs(mMonitorThread), - new DarwinGamepadServiceStartupRunnable(this)); -} - -void DarwinGamepadService::Shutdown() -{ - IOHIDManagerRef manager = (IOHIDManagerRef)mManager; - CFRunLoopStop(mMonitorRunLoop); - if (manager) { - IOHIDManagerClose(manager, 0); - CFRelease(manager); - mManager = nullptr; - } - mMonitorThread->Shutdown(); -} - -} // namespace - -namespace mozilla { -namespace dom { - -DarwinGamepadService* gService = nullptr; - -void StartGamepadMonitoring() -{ - if (gService) { - return; - } - - gService = new DarwinGamepadService(); - gService->Startup(); -} - -void StopGamepadMonitoring() -{ - if (!gService) { - return; - } - - gService->Shutdown(); - delete gService; - gService = nullptr; -} - -} // namespace dom -} // namespace mozilla diff --git a/dom/gamepad/moz.build b/dom/gamepad/moz.build index b8e3a855b2..15205e4c83 100644 --- a/dom/gamepad/moz.build +++ b/dom/gamepad/moz.build @@ -48,10 +48,6 @@ if CONFIG['MOZ_GAMEPAD']: SOURCES += [ 'fallback/FallbackGamepad.cpp' ] - elif CONFIG['MOZ_GAMEPAD_BACKEND'] == 'cocoa': - SOURCES += [ - 'cocoa/CocoaGamepad.cpp' - ] elif CONFIG['MOZ_GAMEPAD_BACKEND'] == 'windows': SOURCES += [ 'windows/WindowsGamepad.cpp' diff --git a/dom/geolocation/moz.build b/dom/geolocation/moz.build index 0230875223..d8ecf1ac17 100644 --- a/dom/geolocation/moz.build +++ b/dom/geolocation/moz.build @@ -29,10 +29,6 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'android': LOCAL_INCLUDES += [ '/dom/system/android', ] -elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa': - LOCAL_INCLUDES += [ - '/dom/system/mac', - ] elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows': LOCAL_INCLUDES += [ '/dom/system/windows', diff --git a/dom/media/standalone/moz.build b/dom/media/standalone/moz.build index 7ef15adaa9..5ec7e82c20 100644 --- a/dom/media/standalone/moz.build +++ b/dom/media/standalone/moz.build @@ -13,9 +13,6 @@ SOURCES += [ '../VideoSegment.cpp', ] -if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa': - UNIFIED_SOURCES += ['../systemservices/OSXRunLoopSingleton.cpp'] - LOCAL_INCLUDES += [ '/caps', '/dom/base', diff --git a/dom/media/systemservices/OSXRunLoopSingleton.cpp b/dom/media/systemservices/OSXRunLoopSingleton.cpp deleted file mode 100644 index 6211d5c127..0000000000 --- a/dom/media/systemservices/OSXRunLoopSingleton.cpp +++ /dev/null @@ -1,44 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-*/ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "OSXRunLoopSingleton.h" -#include <mozilla/StaticMutex.h> - -#include <AudioUnit/AudioUnit.h> -#include <CoreAudio/AudioHardware.h> -#include <CoreAudio/HostTime.h> -#include <CoreFoundation/CoreFoundation.h> - -static bool gRunLoopSet = false; -static mozilla::StaticMutex gMutex; - -void mozilla_set_coreaudio_notification_runloop_if_needed() -{ - mozilla::StaticMutexAutoLock lock(gMutex); - if (gRunLoopSet) { - return; - } - - /* This is needed so that AudioUnit listeners get called on this thread, and - * not the main thread. If we don't do that, they are not called, or a crash - * occur, depending on the OSX version. */ - AudioObjectPropertyAddress runloop_address = { - kAudioHardwarePropertyRunLoop, - kAudioObjectPropertyScopeGlobal, - kAudioObjectPropertyElementMaster - }; - - CFRunLoopRef run_loop = nullptr; - - OSStatus r; - r = AudioObjectSetPropertyData(kAudioObjectSystemObject, - &runloop_address, - 0, NULL, sizeof(CFRunLoopRef), &run_loop); - if (r != noErr) { - NS_WARNING("Could not make global CoreAudio notifications use their own thread."); - } - - gRunLoopSet = true; -} diff --git a/dom/media/systemservices/OSXRunLoopSingleton.h b/dom/media/systemservices/OSXRunLoopSingleton.h deleted file mode 100644 index d06365e146..0000000000 --- a/dom/media/systemservices/OSXRunLoopSingleton.h +++ /dev/null @@ -1,25 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-*/ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef OSXRUNLOOPSINGLETON_H_ -#define OSXRUNLOOPSINGLETON_H_ - -#include <mozilla/Types.h> - -#if defined(__cplusplus) -extern "C" { -#endif - -/* This function tells CoreAudio to use its own thread for device change - * notifications, and can be called from any thread without external - * synchronization. */ -void MOZ_EXPORT -mozilla_set_coreaudio_notification_runloop_if_needed(); - -#if defined(__cplusplus) -} -#endif - -#endif // OSXRUNLOOPSINGLETON_H_ diff --git a/dom/media/systemservices/moz.build b/dom/media/systemservices/moz.build index aa07b291a9..7d566c42ce 100644 --- a/dom/media/systemservices/moz.build +++ b/dom/media/systemservices/moz.build @@ -38,10 +38,6 @@ if CONFIG['OS_TARGET'] == 'Android': 'OpenSLESProvider.cpp', ] -if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa': - SOURCES += ['OSXRunLoopSingleton.cpp'] - EXPORTS += ['OSXRunLoopSingleton.h'] - if CONFIG['_MSC_VER']: DEFINES['__PRETTY_FUNCTION__'] = '__FUNCSIG__' diff --git a/dom/media/webspeech/synth/cocoa/OSXSpeechSynthesizerModule.cpp b/dom/media/webspeech/synth/cocoa/OSXSpeechSynthesizerModule.cpp deleted file mode 100644 index ef69170003..0000000000 --- a/dom/media/webspeech/synth/cocoa/OSXSpeechSynthesizerModule.cpp +++ /dev/null @@ -1,56 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "mozilla/ModuleUtils.h" -#include "nsIClassInfoImpl.h" - -#include "OSXSpeechSynthesizerService.h" - -using namespace mozilla::dom; - -#define OSXSPEECHSYNTHESIZERSERVICE_CID \ - {0x914e73b4, 0x6337, 0x4bef, {0x97, 0xf3, 0x4d, 0x06, 0x9e, 0x05, 0x3a, 0x12}} - -#define OSXSPEECHSYNTHESIZERSERVICE_CONTRACTID "@mozilla.org/synthsystem;1" - -// Defines OSXSpeechSynthesizerServiceConstructor -NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(OSXSpeechSynthesizerService, - OSXSpeechSynthesizerService::GetInstanceForService) - -// Defines kOSXSERVICE_CID -NS_DEFINE_NAMED_CID(OSXSPEECHSYNTHESIZERSERVICE_CID); - -static const mozilla::Module::CIDEntry kCIDs[] = { - { &kOSXSPEECHSYNTHESIZERSERVICE_CID, true, nullptr, OSXSpeechSynthesizerServiceConstructor }, - { nullptr } -}; - -static const mozilla::Module::ContractIDEntry kContracts[] = { - { OSXSPEECHSYNTHESIZERSERVICE_CONTRACTID, &kOSXSPEECHSYNTHESIZERSERVICE_CID }, - { nullptr } -}; - -static const mozilla::Module::CategoryEntry kCategories[] = { - { "speech-synth-started", "OSX Speech Synth", OSXSPEECHSYNTHESIZERSERVICE_CONTRACTID }, - { nullptr } -}; - -static void -UnloadOSXSpeechSynthesizerModule() -{ - OSXSpeechSynthesizerService::Shutdown(); -} - -static const mozilla::Module kModule = { - mozilla::Module::kVersion, - kCIDs, - kContracts, - kCategories, - nullptr, - nullptr, - UnloadOSXSpeechSynthesizerModule -}; - -NSMODULE_DEFN(osxsynth) = &kModule; diff --git a/dom/media/webspeech/synth/cocoa/OSXSpeechSynthesizerService.h b/dom/media/webspeech/synth/cocoa/OSXSpeechSynthesizerService.h deleted file mode 100644 index ba04f0fecb..0000000000 --- a/dom/media/webspeech/synth/cocoa/OSXSpeechSynthesizerService.h +++ /dev/null @@ -1,43 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef mozilla_dom_OsxSpeechSynthesizerService_h -#define mozilla_dom_OsxSpeechSynthesizerService_h - -#include "nsISpeechService.h" -#include "nsIObserver.h" -#include "mozilla/StaticPtr.h" - -namespace mozilla { -namespace dom { - -class OSXSpeechSynthesizerService final : public nsISpeechService - , public nsIObserver -{ -public: - NS_DECL_THREADSAFE_ISUPPORTS - NS_DECL_NSISPEECHSERVICE - NS_DECL_NSIOBSERVER - - bool Init(); - - static OSXSpeechSynthesizerService* GetInstance(); - static already_AddRefed<OSXSpeechSynthesizerService> GetInstanceForService(); - static void Shutdown(); - -private: - OSXSpeechSynthesizerService(); - virtual ~OSXSpeechSynthesizerService(); - - bool RegisterVoices(); - - bool mInitialized; - static mozilla::StaticRefPtr<OSXSpeechSynthesizerService> sSingleton; -}; - -} // namespace dom -} // namespace mozilla - -#endif diff --git a/dom/media/webspeech/synth/cocoa/OSXSpeechSynthesizerService.mm b/dom/media/webspeech/synth/cocoa/OSXSpeechSynthesizerService.mm deleted file mode 100644 index ec752e00f0..0000000000 --- a/dom/media/webspeech/synth/cocoa/OSXSpeechSynthesizerService.mm +++ /dev/null @@ -1,498 +0,0 @@ -/* -*- Mode: Objective-C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "nsISupports.h" -#include "nsServiceManagerUtils.h" -#include "nsObjCExceptions.h" -#include "nsCocoaUtils.h" -#include "nsThreadUtils.h" -#include "mozilla/dom/nsSynthVoiceRegistry.h" -#include "mozilla/dom/nsSpeechTask.h" -#include "mozilla/Preferences.h" -#include "mozilla/Assertions.h" -#include "OSXSpeechSynthesizerService.h" - -#import <Cocoa/Cocoa.h> - -// We can escape the default delimiters ("[[" and "]]") by temporarily -// changing the delimiters just before they appear, and changing them back -// just after. -#define DLIM_ESCAPE_START "[[dlim (( ))]]" -#define DLIM_ESCAPE_END "((dlim [[ ]]))" - -using namespace mozilla; - -class SpeechTaskCallback final : public nsISpeechTaskCallback -{ -public: - SpeechTaskCallback(nsISpeechTask* aTask, - NSSpeechSynthesizer* aSynth, - const nsTArray<size_t>& aOffsets) - : mTask(aTask) - , mSpeechSynthesizer(aSynth) - , mOffsets(aOffsets) - { - mStartingTime = TimeStamp::Now(); - } - - NS_DECL_CYCLE_COLLECTING_ISUPPORTS - NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(SpeechTaskCallback, nsISpeechTaskCallback) - - NS_DECL_NSISPEECHTASKCALLBACK - - void OnWillSpeakWord(uint32_t aIndex); - void OnError(uint32_t aIndex); - void OnDidFinishSpeaking(); - -private: - virtual ~SpeechTaskCallback() - { - [mSpeechSynthesizer release]; - } - - float GetTimeDurationFromStart(); - - nsCOMPtr<nsISpeechTask> mTask; - NSSpeechSynthesizer* mSpeechSynthesizer; - TimeStamp mStartingTime; - uint32_t mCurrentIndex; - nsTArray<size_t> mOffsets; -}; - -NS_IMPL_CYCLE_COLLECTION(SpeechTaskCallback, mTask); - -NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(SpeechTaskCallback) - NS_INTERFACE_MAP_ENTRY(nsISpeechTaskCallback) - NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsISpeechTaskCallback) -NS_INTERFACE_MAP_END - -NS_IMPL_CYCLE_COLLECTING_ADDREF(SpeechTaskCallback) -NS_IMPL_CYCLE_COLLECTING_RELEASE(SpeechTaskCallback) - -NS_IMETHODIMP -SpeechTaskCallback::OnCancel() -{ - NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT; - - [mSpeechSynthesizer stopSpeaking]; - return NS_OK; - - NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT; -} - -NS_IMETHODIMP -SpeechTaskCallback::OnPause() -{ - NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT; - - [mSpeechSynthesizer pauseSpeakingAtBoundary:NSSpeechImmediateBoundary]; - if (!mTask) { - // When calling pause() on child porcess, it may not receive end event - // from chrome process yet. - return NS_ERROR_FAILURE; - } - mTask->DispatchPause(GetTimeDurationFromStart(), mCurrentIndex); - return NS_OK; - - NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT; -} - -NS_IMETHODIMP -SpeechTaskCallback::OnResume() -{ - NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT; - - [mSpeechSynthesizer continueSpeaking]; - if (!mTask) { - // When calling resume() on child porcess, it may not receive end event - // from chrome process yet. - return NS_ERROR_FAILURE; - } - mTask->DispatchResume(GetTimeDurationFromStart(), mCurrentIndex); - return NS_OK; - - NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT; -} - -NS_IMETHODIMP -SpeechTaskCallback::OnVolumeChanged(float aVolume) -{ - NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT; - - [mSpeechSynthesizer setObject:[NSNumber numberWithFloat:aVolume] - forProperty:NSSpeechVolumeProperty error:nil]; - return NS_OK; - - NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT; -} - -float -SpeechTaskCallback::GetTimeDurationFromStart() -{ - TimeDuration duration = TimeStamp::Now() - mStartingTime; - return duration.ToMilliseconds(); -} - -void -SpeechTaskCallback::OnWillSpeakWord(uint32_t aIndex) -{ - mCurrentIndex = aIndex < mOffsets.Length() ? mOffsets[aIndex] : mCurrentIndex; - if (!mTask) { - return; - } - mTask->DispatchBoundary(NS_LITERAL_STRING("word"), - GetTimeDurationFromStart(), mCurrentIndex); -} - -void -SpeechTaskCallback::OnError(uint32_t aIndex) -{ - if (!mTask) { - return; - } - mTask->DispatchError(GetTimeDurationFromStart(), aIndex); -} - -void -SpeechTaskCallback::OnDidFinishSpeaking() -{ - mTask->DispatchEnd(GetTimeDurationFromStart(), mCurrentIndex); - // no longer needed - [mSpeechSynthesizer setDelegate:nil]; - mTask = nullptr; -} - -@interface SpeechDelegate : NSObject<NSSpeechSynthesizerDelegate> -{ -@private - SpeechTaskCallback* mCallback; -} - - - (id)initWithCallback:(SpeechTaskCallback*)aCallback; -@end - -@implementation SpeechDelegate -- (id)initWithCallback:(SpeechTaskCallback*)aCallback -{ - [super init]; - mCallback = aCallback; - return self; -} - -- (void)speechSynthesizer:(NSSpeechSynthesizer *)aSender - willSpeakWord:(NSRange)aRange ofString:(NSString*)aString -{ - mCallback->OnWillSpeakWord(aRange.location); -} - -- (void)speechSynthesizer:(NSSpeechSynthesizer *)aSender - didFinishSpeaking:(BOOL)aFinishedSpeaking -{ - mCallback->OnDidFinishSpeaking(); -} - -- (void)speechSynthesizer:(NSSpeechSynthesizer*)aSender - didEncounterErrorAtIndex:(NSUInteger)aCharacterIndex - ofString:(NSString*)aString - message:(NSString*)aMessage -{ - mCallback->OnError(aCharacterIndex); -} -@end - -namespace mozilla { -namespace dom { - -struct OSXVoice -{ - OSXVoice() : mIsDefault(false) - { - } - - nsString mUri; - nsString mName; - nsString mLocale; - bool mIsDefault; -}; - -class RegisterVoicesRunnable final : public Runnable -{ -public: - RegisterVoicesRunnable(OSXSpeechSynthesizerService* aSpeechService, - nsTArray<OSXVoice>& aList) - : mSpeechService(aSpeechService) - , mVoices(aList) - { - } - - NS_IMETHOD Run() override; - -private: - ~RegisterVoicesRunnable() - { - } - - // This runnable always use sync mode. It is unnecesarry to reference object - OSXSpeechSynthesizerService* mSpeechService; - nsTArray<OSXVoice>& mVoices; -}; - -NS_IMETHODIMP -RegisterVoicesRunnable::Run() -{ - nsresult rv; - nsCOMPtr<nsISynthVoiceRegistry> registry = - do_GetService(NS_SYNTHVOICEREGISTRY_CONTRACTID, &rv); - if (!registry) { - return rv; - } - - for (OSXVoice voice : mVoices) { - rv = registry->AddVoice(mSpeechService, voice.mUri, voice.mName, voice.mLocale, true, false); - if (NS_WARN_IF(NS_FAILED(rv))) { - continue; - } - - if (voice.mIsDefault) { - registry->SetDefaultVoice(voice.mUri, true); - } - } - - registry->NotifyVoicesChanged(); - - return NS_OK; -} - -class EnumVoicesRunnable final : public Runnable -{ -public: - explicit EnumVoicesRunnable(OSXSpeechSynthesizerService* aSpeechService) - : mSpeechService(aSpeechService) - { - } - - NS_IMETHOD Run() override; - -private: - ~EnumVoicesRunnable() - { - } - - RefPtr<OSXSpeechSynthesizerService> mSpeechService; -}; - -NS_IMETHODIMP -EnumVoicesRunnable::Run() -{ - NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT; - - AutoTArray<OSXVoice, 64> list; - - NSArray* voices = [NSSpeechSynthesizer availableVoices]; - NSString* defaultVoice = [NSSpeechSynthesizer defaultVoice]; - - for (NSString* voice in voices) { - OSXVoice item; - - NSDictionary* attr = [NSSpeechSynthesizer attributesForVoice:voice]; - - nsAutoString identifier; - nsCocoaUtils::GetStringForNSString([attr objectForKey:NSVoiceIdentifier], - identifier); - - nsCocoaUtils::GetStringForNSString([attr objectForKey:NSVoiceName], item.mName); - - nsCocoaUtils::GetStringForNSString( - [attr objectForKey:NSVoiceLocaleIdentifier], item.mLocale); - item.mLocale.ReplaceChar('_', '-'); - - item.mUri.AssignLiteral("urn:moz-tts:osx:"); - item.mUri.Append(identifier); - - if ([voice isEqualToString:defaultVoice]) { - item.mIsDefault = true; - } - - list.AppendElement(item); - } - - RefPtr<RegisterVoicesRunnable> runnable = new RegisterVoicesRunnable(mSpeechService, list); - NS_DispatchToMainThread(runnable, NS_DISPATCH_SYNC); - - return NS_OK; - - NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT; -} - -StaticRefPtr<OSXSpeechSynthesizerService> OSXSpeechSynthesizerService::sSingleton; - -NS_INTERFACE_MAP_BEGIN(OSXSpeechSynthesizerService) - NS_INTERFACE_MAP_ENTRY(nsISpeechService) - NS_INTERFACE_MAP_ENTRY(nsIObserver) - NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsISpeechService) -NS_INTERFACE_MAP_END - -NS_IMPL_ADDREF(OSXSpeechSynthesizerService) -NS_IMPL_RELEASE(OSXSpeechSynthesizerService) - -OSXSpeechSynthesizerService::OSXSpeechSynthesizerService() - : mInitialized(false) -{ -} - -OSXSpeechSynthesizerService::~OSXSpeechSynthesizerService() -{ -} - -bool -OSXSpeechSynthesizerService::Init() -{ - if (Preferences::GetBool("media.webspeech.synth.test") || - !Preferences::GetBool("media.webspeech.synth.enabled")) { - // When test is enabled, we shouldn't add OS backend (Bug 1160844) - return false; - } - - nsCOMPtr<nsIThread> thread; - if (NS_FAILED(NS_NewNamedThread("SpeechWorker", getter_AddRefs(thread)))) { - return false; - } - - // Get all the voices and register in the SynthVoiceRegistry - nsCOMPtr<nsIRunnable> runnable = new EnumVoicesRunnable(this); - thread->Dispatch(runnable, NS_DISPATCH_NORMAL); - - mInitialized = true; - return true; -} - -NS_IMETHODIMP -OSXSpeechSynthesizerService::Speak(const nsAString& aText, - const nsAString& aUri, - float aVolume, - float aRate, - float aPitch, - nsISpeechTask* aTask) -{ - NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT; - - MOZ_ASSERT(StringBeginsWith(aUri, NS_LITERAL_STRING("urn:moz-tts:osx:")), - "OSXSpeechSynthesizerService doesn't allow this voice URI"); - - NSSpeechSynthesizer* synth = [[NSSpeechSynthesizer alloc] init]; - // strlen("urn:moz-tts:osx:") == 16 - NSString* identifier = nsCocoaUtils::ToNSString(Substring(aUri, 16)); - [synth setVoice:identifier]; - - // default rate is 180-220 - [synth setObject:[NSNumber numberWithInt:aRate * 200] - forProperty:NSSpeechRateProperty error:nil]; - // volume allows 0.0-1.0 - [synth setObject:[NSNumber numberWithFloat:aVolume] - forProperty:NSSpeechVolumeProperty error:nil]; - // Use default pitch value to calculate this - NSNumber* defaultPitch = - [synth objectForProperty:NSSpeechPitchBaseProperty error:nil]; - if (defaultPitch) { - int newPitch = [defaultPitch intValue] * (aPitch / 2 + 0.5); - [synth setObject:[NSNumber numberWithInt:newPitch] - forProperty:NSSpeechPitchBaseProperty error:nil]; - } - - nsAutoString escapedText; - // We need to map the the offsets from the given text to the escaped text. - // The index of the offsets array is the position in the escaped text, - // the element value is the position in the user-supplied text. - nsTArray<size_t> offsets; - offsets.SetCapacity(aText.Length()); - - // This loop looks for occurances of "[[" or "]]", escapes them, and - // populates the offsets array to supply a map to the original offsets. - for (size_t i = 0; i < aText.Length(); i++) { - if (aText.Length() > i + 1 && - ((aText[i] == ']' && aText[i+1] == ']') || - (aText[i] == '[' && aText[i+1] == '['))) { - escapedText.AppendLiteral(DLIM_ESCAPE_START); - offsets.AppendElements(strlen(DLIM_ESCAPE_START)); - escapedText.Append(aText[i]); - offsets.AppendElement(i); - escapedText.Append(aText[++i]); - offsets.AppendElement(i); - escapedText.AppendLiteral(DLIM_ESCAPE_END); - offsets.AppendElements(strlen(DLIM_ESCAPE_END)); - } else { - escapedText.Append(aText[i]); - offsets.AppendElement(i); - } - } - - RefPtr<SpeechTaskCallback> callback = new SpeechTaskCallback(aTask, synth, offsets); - nsresult rv = aTask->Setup(callback, 0, 0, 0); - NS_ENSURE_SUCCESS(rv, rv); - - SpeechDelegate* delegate = [[SpeechDelegate alloc] initWithCallback:callback]; - [synth setDelegate:delegate]; - [delegate release ]; - - NSString* text = nsCocoaUtils::ToNSString(escapedText); - BOOL success = [synth startSpeakingString:text]; - NS_ENSURE_TRUE(success, NS_ERROR_FAILURE); - - aTask->DispatchStart(); - return NS_OK; - - NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT; -} - -NS_IMETHODIMP -OSXSpeechSynthesizerService::GetServiceType(SpeechServiceType* aServiceType) -{ - *aServiceType = nsISpeechService::SERVICETYPE_INDIRECT_AUDIO; - return NS_OK; -} - -NS_IMETHODIMP -OSXSpeechSynthesizerService::Observe(nsISupports* aSubject, const char* aTopic, - const char16_t* aData) -{ - return NS_OK; -} - -OSXSpeechSynthesizerService* -OSXSpeechSynthesizerService::GetInstance() -{ - MOZ_ASSERT(NS_IsMainThread()); - if (XRE_GetProcessType() != GeckoProcessType_Default) { - return nullptr; - } - - if (!sSingleton) { - RefPtr<OSXSpeechSynthesizerService> speechService = - new OSXSpeechSynthesizerService(); - if (speechService->Init()) { - sSingleton = speechService; - } - } - return sSingleton; -} - -already_AddRefed<OSXSpeechSynthesizerService> -OSXSpeechSynthesizerService::GetInstanceForService() -{ - RefPtr<OSXSpeechSynthesizerService> speechService = GetInstance(); - return speechService.forget(); -} - -void -OSXSpeechSynthesizerService::Shutdown() -{ - if (!sSingleton) { - return; - } - sSingleton = nullptr; -} - -} // namespace dom -} // namespace mozilla diff --git a/dom/media/webspeech/synth/cocoa/moz.build b/dom/media/webspeech/synth/cocoa/moz.build deleted file mode 100644 index 6953a81e95..0000000000 --- a/dom/media/webspeech/synth/cocoa/moz.build +++ /dev/null @@ -1,11 +0,0 @@ -# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- -# 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/. - -SOURCES += [ - 'OSXSpeechSynthesizerModule.cpp', - 'OSXSpeechSynthesizerService.mm' -] - -FINAL_LIBRARY = 'xul' diff --git a/dom/media/webspeech/synth/moz.build b/dom/media/webspeech/synth/moz.build index 6603689261..9784686dfe 100644 --- a/dom/media/webspeech/synth/moz.build +++ b/dom/media/webspeech/synth/moz.build @@ -32,9 +32,6 @@ SOURCES += [ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows': DIRS += ['windows'] -if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa': - DIRS += ['cocoa'] - if CONFIG['MOZ_SYNTH_SPEECHD']: DIRS += ['speechd'] diff --git a/dom/moz.build b/dom/moz.build index f02a4a5d6f..b324de2cb0 100644 --- a/dom/moz.build +++ b/dom/moz.build @@ -112,6 +112,6 @@ TEST_DIRS += [ 'imptests', ] -if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('gtk2', 'gtk3', 'cocoa', 'windows', 'android'): +if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('gtk2', 'gtk3', 'windows', 'android'): TEST_DIRS += ['plugins/test'] diff --git a/dom/plugins/base/moz.build b/dom/plugins/base/moz.build index 08f87d56a3..11649a8626 100644 --- a/dom/plugins/base/moz.build +++ b/dom/plugins/base/moz.build @@ -56,11 +56,6 @@ if CONFIG['OS_ARCH'] == 'WINNT': 'nsPluginNativeWindowWin.cpp', 'nsPluginsDirWin.cpp', ] -elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa': - SOURCES += [ - 'nsPluginNativeWindow.cpp', - 'nsPluginsDirDarwin.cpp', - ] else: SOURCES += [ 'nsPluginsDirUnix.cpp', @@ -82,7 +77,6 @@ LOCAL_INCLUDES += [ '/layout/xul', '/netwerk/base', '/widget', - '/widget/cocoa', '/xpcom/base', ] diff --git a/dom/plugins/base/nsPluginsDirDarwin.cpp b/dom/plugins/base/nsPluginsDirDarwin.cpp deleted file mode 100644 index 0085eec0d6..0000000000 --- a/dom/plugins/base/nsPluginsDirDarwin.cpp +++ /dev/null @@ -1,572 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* 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/. */ - -/* - nsPluginsDirDarwin.cpp - - Mac OS X implementation of the nsPluginsDir/nsPluginsFile classes. - - by Patrick C. Beard. - */ - -#include "GeckoChildProcessHost.h" -#include "base/process_util.h" - -#include "prlink.h" -#include "prnetdb.h" -#include "nsXPCOM.h" - -#include "nsPluginsDir.h" -#include "nsNPAPIPlugin.h" -#include "nsPluginsDirUtils.h" - -#include "nsILocalFileMac.h" -#include "mozilla/UniquePtr.h" - -#include "nsCocoaFeatures.h" - -#include <string.h> -#include <stdio.h> -#include <unistd.h> -#include <fcntl.h> - -#include <Carbon/Carbon.h> -#include <CoreServices/CoreServices.h> -#include <mach-o/loader.h> -#include <mach-o/fat.h> - -typedef NS_NPAPIPLUGIN_CALLBACK(const char *, NP_GETMIMEDESCRIPTION) (); -typedef NS_NPAPIPLUGIN_CALLBACK(OSErr, BP_GETSUPPORTEDMIMETYPES) (BPSupportedMIMETypes *mimeInfo, UInt32 flags); - -/* -** Returns a CFBundleRef if the path refers to a Mac OS X bundle directory. -** The caller is responsible for calling CFRelease() to deallocate. -*/ -static CFBundleRef getPluginBundle(const char* path) -{ - CFBundleRef bundle = nullptr; - CFStringRef pathRef = ::CFStringCreateWithCString(nullptr, path, - kCFStringEncodingUTF8); - if (pathRef) { - CFURLRef bundleURL = ::CFURLCreateWithFileSystemPath(nullptr, pathRef, - kCFURLPOSIXPathStyle, - true); - if (bundleURL) { - bundle = ::CFBundleCreate(nullptr, bundleURL); - ::CFRelease(bundleURL); - } - ::CFRelease(pathRef); - } - return bundle; -} - -static nsresult toCFURLRef(nsIFile* file, CFURLRef& outURL) -{ - nsCOMPtr<nsILocalFileMac> lfm = do_QueryInterface(file); - if (!lfm) - return NS_ERROR_FAILURE; - CFURLRef url; - nsresult rv = lfm->GetCFURL(&url); - if (NS_SUCCEEDED(rv)) - outURL = url; - - return rv; -} - -bool nsPluginsDir::IsPluginFile(nsIFile* file) -{ - nsCString fileName; - file->GetNativeLeafName(fileName); - /* - * Don't load the VDP fake plugin, to avoid tripping a bad bug in OS X - * 10.5.3 (see bug 436575). - */ - if (!strcmp(fileName.get(), "VerifiedDownloadPlugin.plugin")) { - NS_WARNING("Preventing load of VerifiedDownloadPlugin.plugin (see bug 436575)"); - return false; - } - return true; -} - -// Caller is responsible for freeing returned buffer. -static char* CFStringRefToUTF8Buffer(CFStringRef cfString) -{ - const char* buffer = ::CFStringGetCStringPtr(cfString, kCFStringEncodingUTF8); - if (buffer) { - return PL_strdup(buffer); - } - - int bufferLength = - ::CFStringGetMaximumSizeForEncoding(::CFStringGetLength(cfString), - kCFStringEncodingUTF8) + 1; - char* newBuffer = static_cast<char*>(moz_xmalloc(bufferLength)); - if (!newBuffer) { - return nullptr; - } - - if (!::CFStringGetCString(cfString, newBuffer, bufferLength, - kCFStringEncodingUTF8)) { - free(newBuffer); - return nullptr; - } - - newBuffer = static_cast<char*>(moz_xrealloc(newBuffer, - strlen(newBuffer) + 1)); - return newBuffer; -} - -class AutoCFTypeObject { -public: - explicit AutoCFTypeObject(CFTypeRef aObject) - { - mObject = aObject; - } - ~AutoCFTypeObject() - { - ::CFRelease(mObject); - } -private: - CFTypeRef mObject; -}; - -static Boolean MimeTypeEnabled(CFDictionaryRef mimeDict) { - if (!mimeDict) { - return true; - } - - CFTypeRef value; - if (::CFDictionaryGetValueIfPresent(mimeDict, CFSTR("WebPluginTypeEnabled"), &value)) { - if (value && ::CFGetTypeID(value) == ::CFBooleanGetTypeID()) { - return ::CFBooleanGetValue(static_cast<CFBooleanRef>(value)); - } - } - return true; -} - -static CFDictionaryRef ParsePlistForMIMETypesFilename(CFBundleRef bundle) -{ - CFTypeRef mimeFileName = ::CFBundleGetValueForInfoDictionaryKey(bundle, CFSTR("WebPluginMIMETypesFilename")); - if (!mimeFileName || ::CFGetTypeID(mimeFileName) != ::CFStringGetTypeID()) { - return nullptr; - } - - FSRef homeDir; - if (::FSFindFolder(kUserDomain, kCurrentUserFolderType, kDontCreateFolder, &homeDir) != noErr) { - return nullptr; - } - - CFURLRef userDirURL = ::CFURLCreateFromFSRef(kCFAllocatorDefault, &homeDir); - if (!userDirURL) { - return nullptr; - } - - AutoCFTypeObject userDirURLAutorelease(userDirURL); - CFStringRef mimeFilePath = ::CFStringCreateWithFormat(kCFAllocatorDefault, nullptr, CFSTR("Library/Preferences/%@"), static_cast<CFStringRef>(mimeFileName)); - if (!mimeFilePath) { - return nullptr; - } - - AutoCFTypeObject mimeFilePathAutorelease(mimeFilePath); - CFURLRef mimeFileURL = ::CFURLCreateWithFileSystemPathRelativeToBase(kCFAllocatorDefault, mimeFilePath, kCFURLPOSIXPathStyle, false, userDirURL); - if (!mimeFileURL) { - return nullptr; - } - - AutoCFTypeObject mimeFileURLAutorelease(mimeFileURL); - SInt32 errorCode = 0; - CFDataRef mimeFileData = nullptr; - Boolean result = ::CFURLCreateDataAndPropertiesFromResource(kCFAllocatorDefault, mimeFileURL, &mimeFileData, nullptr, nullptr, &errorCode); - if (!result) { - return nullptr; - } - - AutoCFTypeObject mimeFileDataAutorelease(mimeFileData); - if (errorCode != 0) { - return nullptr; - } - - CFPropertyListRef propertyList = ::CFPropertyListCreateFromXMLData(kCFAllocatorDefault, mimeFileData, kCFPropertyListImmutable, nullptr); - if (!propertyList) { - return nullptr; - } - - AutoCFTypeObject propertyListAutorelease(propertyList); - if (::CFGetTypeID(propertyList) != ::CFDictionaryGetTypeID()) { - return nullptr; - } - - CFTypeRef mimeTypes = ::CFDictionaryGetValue(static_cast<CFDictionaryRef>(propertyList), CFSTR("WebPluginMIMETypes")); - if (!mimeTypes || ::CFGetTypeID(mimeTypes) != ::CFDictionaryGetTypeID() || ::CFDictionaryGetCount(static_cast<CFDictionaryRef>(mimeTypes)) == 0) { - return nullptr; - } - - return static_cast<CFDictionaryRef>(::CFRetain(mimeTypes)); -} - -static void ParsePlistPluginInfo(nsPluginInfo& info, CFBundleRef bundle) -{ - CFDictionaryRef mimeDict = ParsePlistForMIMETypesFilename(bundle); - - if (!mimeDict) { - CFTypeRef mimeTypes = ::CFBundleGetValueForInfoDictionaryKey(bundle, CFSTR("WebPluginMIMETypes")); - if (!mimeTypes || ::CFGetTypeID(mimeTypes) != ::CFDictionaryGetTypeID() || ::CFDictionaryGetCount(static_cast<CFDictionaryRef>(mimeTypes)) == 0) - return; - mimeDict = static_cast<CFDictionaryRef>(::CFRetain(mimeTypes)); - } - - AutoCFTypeObject mimeDictAutorelease(mimeDict); - int mimeDictKeyCount = ::CFDictionaryGetCount(mimeDict); - - // Allocate memory for mime data - int mimeDataArraySize = mimeDictKeyCount * sizeof(char*); - info.fMimeTypeArray = static_cast<char**>(moz_xmalloc(mimeDataArraySize)); - if (!info.fMimeTypeArray) - return; - memset(info.fMimeTypeArray, 0, mimeDataArraySize); - info.fExtensionArray = static_cast<char**>(moz_xmalloc(mimeDataArraySize)); - if (!info.fExtensionArray) - return; - memset(info.fExtensionArray, 0, mimeDataArraySize); - info.fMimeDescriptionArray = static_cast<char**>(moz_xmalloc(mimeDataArraySize)); - if (!info.fMimeDescriptionArray) - return; - memset(info.fMimeDescriptionArray, 0, mimeDataArraySize); - - // Allocate memory for mime dictionary keys and values - mozilla::UniquePtr<CFTypeRef[]> keys(new CFTypeRef[mimeDictKeyCount]); - if (!keys) - return; - mozilla::UniquePtr<CFTypeRef[]> values(new CFTypeRef[mimeDictKeyCount]); - if (!values) - return; - - info.fVariantCount = 0; - - ::CFDictionaryGetKeysAndValues(mimeDict, keys.get(), values.get()); - for (int i = 0; i < mimeDictKeyCount; i++) { - CFTypeRef mimeString = keys[i]; - if (!mimeString || ::CFGetTypeID(mimeString) != ::CFStringGetTypeID()) { - continue; - } - CFTypeRef mimeDict = values[i]; - if (mimeDict && ::CFGetTypeID(mimeDict) == ::CFDictionaryGetTypeID()) { - if (!MimeTypeEnabled(static_cast<CFDictionaryRef>(mimeDict))) { - continue; - } - info.fMimeTypeArray[info.fVariantCount] = CFStringRefToUTF8Buffer(static_cast<CFStringRef>(mimeString)); - if (!info.fMimeTypeArray[info.fVariantCount]) { - continue; - } - CFTypeRef extensions = ::CFDictionaryGetValue(static_cast<CFDictionaryRef>(mimeDict), CFSTR("WebPluginExtensions")); - if (extensions && ::CFGetTypeID(extensions) == ::CFArrayGetTypeID()) { - int extensionCount = ::CFArrayGetCount(static_cast<CFArrayRef>(extensions)); - CFMutableStringRef extensionList = ::CFStringCreateMutable(kCFAllocatorDefault, 0); - for (int j = 0; j < extensionCount; j++) { - CFTypeRef extension = ::CFArrayGetValueAtIndex(static_cast<CFArrayRef>(extensions), j); - if (extension && ::CFGetTypeID(extension) == ::CFStringGetTypeID()) { - if (j > 0) - ::CFStringAppend(extensionList, CFSTR(",")); - ::CFStringAppend(static_cast<CFMutableStringRef>(extensionList), static_cast<CFStringRef>(extension)); - } - } - info.fExtensionArray[info.fVariantCount] = CFStringRefToUTF8Buffer(static_cast<CFStringRef>(extensionList)); - ::CFRelease(extensionList); - } - CFTypeRef description = ::CFDictionaryGetValue(static_cast<CFDictionaryRef>(mimeDict), CFSTR("WebPluginTypeDescription")); - if (description && ::CFGetTypeID(description) == ::CFStringGetTypeID()) - info.fMimeDescriptionArray[info.fVariantCount] = CFStringRefToUTF8Buffer(static_cast<CFStringRef>(description)); - } - info.fVariantCount++; - } -} - -nsPluginFile::nsPluginFile(nsIFile *spec) - : mPlugin(spec) -{ -} - -nsPluginFile::~nsPluginFile() {} - -nsresult nsPluginFile::LoadPlugin(PRLibrary **outLibrary) -{ - if (!mPlugin) - return NS_ERROR_NULL_POINTER; - - // 64-bit NSPR does not (yet) support bundles. So in 64-bit builds we need - // (for now) to load the bundle's executable. However this can cause - // problems: CFBundleCreate() doesn't run the bundle's executable's - // initialization code, while NSAddImage() and dlopen() do run it. So using - // NSPR's dyld loading mechanisms here (NSAddImage() or dlopen()) can cause - // a bundle's initialization code to run earlier than expected, and lead to - // crashes. See bug 577967. -#ifdef __LP64__ - char executablePath[PATH_MAX]; - executablePath[0] = '\0'; - nsAutoCString bundlePath; - mPlugin->GetNativePath(bundlePath); - CFStringRef pathRef = ::CFStringCreateWithCString(nullptr, bundlePath.get(), - kCFStringEncodingUTF8); - if (pathRef) { - CFURLRef bundleURL = ::CFURLCreateWithFileSystemPath(nullptr, pathRef, - kCFURLPOSIXPathStyle, - true); - if (bundleURL) { - CFBundleRef bundle = ::CFBundleCreate(nullptr, bundleURL); - if (bundle) { - CFURLRef executableURL = ::CFBundleCopyExecutableURL(bundle); - if (executableURL) { - if (!::CFURLGetFileSystemRepresentation(executableURL, true, (UInt8*)&executablePath, PATH_MAX)) - executablePath[0] = '\0'; - ::CFRelease(executableURL); - } - ::CFRelease(bundle); - } - ::CFRelease(bundleURL); - } - ::CFRelease(pathRef); - } -#else - nsAutoCString bundlePath; - mPlugin->GetNativePath(bundlePath); - const char *executablePath = bundlePath.get(); -#endif - - *outLibrary = PR_LoadLibrary(executablePath); - pLibrary = *outLibrary; - if (!pLibrary) { - return NS_ERROR_FAILURE; - } -#ifdef DEBUG - printf("[loaded plugin %s]\n", bundlePath.get()); -#endif - return NS_OK; -} - -static char* p2cstrdup(StringPtr pstr) -{ - int len = pstr[0]; - char* cstr = static_cast<char*>(moz_xmalloc(len + 1)); - if (cstr) { - memmove(cstr, pstr + 1, len); - cstr[len] = '\0'; - } - return cstr; -} - -static char* GetNextPluginStringFromHandle(Handle h, short *index) -{ - char *ret = p2cstrdup((unsigned char*)(*h + *index)); - *index += (ret ? strlen(ret) : 0) + 1; - return ret; -} - -static bool IsCompatibleArch(nsIFile *file) -{ - CFURLRef pluginURL = nullptr; - if (NS_FAILED(toCFURLRef(file, pluginURL))) - return false; - - bool isPluginFile = false; - - CFBundleRef pluginBundle = ::CFBundleCreate(kCFAllocatorDefault, pluginURL); - if (pluginBundle) { - UInt32 packageType, packageCreator; - ::CFBundleGetPackageInfo(pluginBundle, &packageType, &packageCreator); - if (packageType == 'BRPL' || packageType == 'IEPL' || packageType == 'NSPL') { - // Get path to plugin as a C string. - char executablePath[PATH_MAX]; - executablePath[0] = '\0'; - if (!::CFURLGetFileSystemRepresentation(pluginURL, true, (UInt8*)&executablePath, PATH_MAX)) { - executablePath[0] = '\0'; - } - - uint32_t pluginLibArchitectures; - nsresult rv = mozilla::ipc::GeckoChildProcessHost::GetArchitecturesForBinary(executablePath, &pluginLibArchitectures); - if (NS_FAILED(rv)) { - return false; - } - - uint32_t supportedArchitectures = -#ifdef __LP64__ - mozilla::ipc::GeckoChildProcessHost::GetSupportedArchitecturesForProcessType(GeckoProcessType_Plugin); -#else - base::GetCurrentProcessArchitecture(); -#endif - - // Consider the plugin architecture valid if there is any overlap in the masks. - isPluginFile = !!(supportedArchitectures & pluginLibArchitectures); - } - ::CFRelease(pluginBundle); - } - - ::CFRelease(pluginURL); - return isPluginFile; -} - -/** - * Obtains all of the information currently available for this plugin. - */ -nsresult nsPluginFile::GetPluginInfo(nsPluginInfo& info, PRLibrary **outLibrary) -{ - *outLibrary = nullptr; - - nsresult rv = NS_OK; - - if (!IsCompatibleArch(mPlugin)) { - return NS_ERROR_FAILURE; - } - - // clear out the info, except for the first field. - memset(&info, 0, sizeof(info)); - - // Try to get a bundle reference. - nsAutoCString path; - if (NS_FAILED(rv = mPlugin->GetNativePath(path))) - return rv; - CFBundleRef bundle = getPluginBundle(path.get()); - - // fill in full path - info.fFullPath = PL_strdup(path.get()); - - // fill in file name - nsAutoCString fileName; - if (NS_FAILED(rv = mPlugin->GetNativeLeafName(fileName))) - return rv; - info.fFileName = PL_strdup(fileName.get()); - - // Get fName - if (bundle) { - CFTypeRef name = ::CFBundleGetValueForInfoDictionaryKey(bundle, CFSTR("WebPluginName")); - if (name && ::CFGetTypeID(name) == ::CFStringGetTypeID()) - info.fName = CFStringRefToUTF8Buffer(static_cast<CFStringRef>(name)); - } - - // Get fDescription - if (bundle) { - CFTypeRef description = ::CFBundleGetValueForInfoDictionaryKey(bundle, CFSTR("WebPluginDescription")); - if (description && ::CFGetTypeID(description) == ::CFStringGetTypeID()) - info.fDescription = CFStringRefToUTF8Buffer(static_cast<CFStringRef>(description)); - } - - // Get fVersion - if (bundle) { - // Look for the release version first - CFTypeRef version = ::CFBundleGetValueForInfoDictionaryKey(bundle, CFSTR("CFBundleShortVersionString")); - if (!version) // try the build version - version = ::CFBundleGetValueForInfoDictionaryKey(bundle, kCFBundleVersionKey); - if (version && ::CFGetTypeID(version) == ::CFStringGetTypeID()) - info.fVersion = CFStringRefToUTF8Buffer(static_cast<CFStringRef>(version)); - } - - // The last thing we need to do is get MIME data - // fVariantCount, fMimeTypeArray, fExtensionArray, fMimeDescriptionArray - - // First look for data in a bundle plist - if (bundle) { - ParsePlistPluginInfo(info, bundle); - ::CFRelease(bundle); - if (info.fVariantCount > 0) - return NS_OK; - } - - // Don't load "fbplugin" or any plugins whose name starts with "fbplugin_" - // (Facebook plugins) if we're running on OS X 10.10 (Yosemite) or later. - // A "fbplugin" file crashes on load, in the call to LoadPlugin() below. - // See bug 1086977. - if (nsCocoaFeatures::OnYosemiteOrLater()) { - if (fileName.EqualsLiteral("fbplugin") || - StringBeginsWith(fileName, NS_LITERAL_CSTRING("fbplugin_"))) { - nsAutoCString msg; - msg.AppendPrintf("Preventing load of %s (see bug 1086977)", - fileName.get()); - NS_WARNING(msg.get()); - return NS_ERROR_FAILURE; - } - } - - // It's possible that our plugin has 2 entry points that'll give us mime type - // info. Quicktime does this to get around the need of having admin rights to - // change mime info in the resource fork. We need to use this info instead of - // the resource. See bug 113464. - - // Sadly we have to load the library for this to work. - rv = LoadPlugin(outLibrary); - if (NS_FAILED(rv)) - return rv; - - // Try to get data from NP_GetMIMEDescription - if (pLibrary) { - NP_GETMIMEDESCRIPTION pfnGetMimeDesc = (NP_GETMIMEDESCRIPTION)PR_FindFunctionSymbol(pLibrary, NP_GETMIMEDESCRIPTION_NAME); - if (pfnGetMimeDesc) - ParsePluginMimeDescription(pfnGetMimeDesc(), info); - if (info.fVariantCount) - return NS_OK; - } - - // We'll fill this in using BP_GetSupportedMIMETypes and/or resource fork data - BPSupportedMIMETypes mi = {kBPSupportedMIMETypesStructVers_1, nullptr, nullptr}; - - // Try to get data from BP_GetSupportedMIMETypes - if (pLibrary) { - BP_GETSUPPORTEDMIMETYPES pfnMime = (BP_GETSUPPORTEDMIMETYPES)PR_FindFunctionSymbol(pLibrary, "BP_GetSupportedMIMETypes"); - if (pfnMime && noErr == pfnMime(&mi, 0) && mi.typeStrings) { - info.fVariantCount = (**(short**)mi.typeStrings) / 2; - ::HLock(mi.typeStrings); - if (mi.infoStrings) // it's possible some plugins have infoStrings missing - ::HLock(mi.infoStrings); - } - } - - // Fill in the info struct based on the data in the BPSupportedMIMETypes struct - int variantCount = info.fVariantCount; - info.fMimeTypeArray = static_cast<char**>(moz_xmalloc(variantCount * sizeof(char*))); - if (!info.fMimeTypeArray) - return NS_ERROR_OUT_OF_MEMORY; - info.fExtensionArray = static_cast<char**>(moz_xmalloc(variantCount * sizeof(char*))); - if (!info.fExtensionArray) - return NS_ERROR_OUT_OF_MEMORY; - if (mi.infoStrings) { - info.fMimeDescriptionArray = static_cast<char**>(moz_xmalloc(variantCount * sizeof(char*))); - if (!info.fMimeDescriptionArray) - return NS_ERROR_OUT_OF_MEMORY; - } - short mimeIndex = 2; - short descriptionIndex = 2; - for (int i = 0; i < variantCount; i++) { - info.fMimeTypeArray[i] = GetNextPluginStringFromHandle(mi.typeStrings, &mimeIndex); - info.fExtensionArray[i] = GetNextPluginStringFromHandle(mi.typeStrings, &mimeIndex); - if (mi.infoStrings) - info.fMimeDescriptionArray[i] = GetNextPluginStringFromHandle(mi.infoStrings, &descriptionIndex); - } - - ::HUnlock(mi.typeStrings); - ::DisposeHandle(mi.typeStrings); - if (mi.infoStrings) { - ::HUnlock(mi.infoStrings); - ::DisposeHandle(mi.infoStrings); - } - - return NS_OK; -} - -nsresult nsPluginFile::FreePluginInfo(nsPluginInfo& info) -{ - free(info.fName); - free(info.fDescription); - int variantCount = info.fVariantCount; - for (int i = 0; i < variantCount; i++) { - free(info.fMimeTypeArray[i]); - free(info.fExtensionArray[i]); - free(info.fMimeDescriptionArray[i]); - } - free(info.fMimeTypeArray); - free(info.fMimeDescriptionArray); - free(info.fExtensionArray); - free(info.fFileName); - free(info.fFullPath); - free(info.fVersion); - - return NS_OK; -} diff --git a/dom/system/mac/CoreLocationLocationProvider.h b/dom/system/mac/CoreLocationLocationProvider.h deleted file mode 100644 index 979bc916d8..0000000000 --- a/dom/system/mac/CoreLocationLocationProvider.h +++ /dev/null @@ -1,59 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "nsCOMPtr.h" -#include "nsIGeolocationProvider.h" - - -/* - * The CoreLocationObjects class contains the CoreLocation objects - * we'll need. - * - * Declaring them directly in CoreLocationLocationProvider - * would require Objective-C++ syntax, which would contaminate all - * files that include this header and require them to be Objective-C++ - * as well. - * - * The solution then is to forward-declare CoreLocationObjects here and - * hold a pointer to it in CoreLocationLocationProvider, and only actually - * define it in CoreLocationLocationProvider.mm, thus making it safe - * for nsGeolocation.cpp, which is C++-only, to include this header. - */ -class CoreLocationObjects; -class MLSFallback; - -class CoreLocationLocationProvider - : public nsIGeolocationProvider -{ -public: - NS_DECL_ISUPPORTS - NS_DECL_NSIGEOLOCATIONPROVIDER - - CoreLocationLocationProvider(); - void NotifyError(uint16_t aErrorCode); - void Update(nsIDOMGeoPosition* aSomewhere); - void CreateMLSFallbackProvider(); - void CancelMLSFallbackProvider(); - -private: - virtual ~CoreLocationLocationProvider(); - - CoreLocationObjects* mCLObjects; - nsCOMPtr<nsIGeolocationUpdate> mCallback; - RefPtr<MLSFallback> mMLSFallbackProvider; - - class MLSUpdate : public nsIGeolocationUpdate - { - public: - NS_DECL_ISUPPORTS - NS_DECL_NSIGEOLOCATIONUPDATE - - explicit MLSUpdate(CoreLocationLocationProvider& parentProvider); - - private: - CoreLocationLocationProvider& mParentLocationProvider; - virtual ~MLSUpdate(); - }; -}; diff --git a/dom/system/mac/CoreLocationLocationProvider.mm b/dom/system/mac/CoreLocationLocationProvider.mm deleted file mode 100644 index 7a3feba97b..0000000000 --- a/dom/system/mac/CoreLocationLocationProvider.mm +++ /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 "nsAutoPtr.h" -#include "nsCOMPtr.h" -#include "nsGeoPosition.h" -#include "nsIConsoleService.h" -#include "nsServiceManagerUtils.h" -#include "nsIDOMGeoPositionError.h" -#include "CoreLocationLocationProvider.h" -#include "nsCocoaFeatures.h" -#include "prtime.h" -#include "MLSFallback.h" - -#include <CoreLocation/CLError.h> -#include <CoreLocation/CLLocation.h> -#include <CoreLocation/CLLocationManager.h> -#include <CoreLocation/CLLocationManagerDelegate.h> - -#include <objc/objc.h> -#include <objc/objc-runtime.h> - -#include "nsObjCExceptions.h" - -using namespace mozilla; - -static const CLLocationAccuracy kHIGH_ACCURACY = kCLLocationAccuracyBest; -static const CLLocationAccuracy kDEFAULT_ACCURACY = kCLLocationAccuracyNearestTenMeters; - -@interface LocationDelegate : NSObject <CLLocationManagerDelegate> -{ - CoreLocationLocationProvider* mProvider; -} - -- (id)init:(CoreLocationLocationProvider*)aProvider; -- (void)locationManager:(CLLocationManager*)aManager - didFailWithError:(NSError *)aError; -- (void)locationManager:(CLLocationManager*)aManager didUpdateLocations:(NSArray*)locations; - -@end - -@implementation LocationDelegate -- (id) init:(CoreLocationLocationProvider*) aProvider -{ - if ((self = [super init])) { - mProvider = aProvider; - } - - return self; -} - -- (void)locationManager:(CLLocationManager*)aManager - didFailWithError:(NSError *)aError -{ - nsCOMPtr<nsIConsoleService> console = - do_GetService(NS_CONSOLESERVICE_CONTRACTID); - - NS_ENSURE_TRUE_VOID(console); - - NSString* message = - [@"Failed to acquire position: " stringByAppendingString: [aError localizedDescription]]; - - console->LogStringMessage(NS_ConvertUTF8toUTF16([message UTF8String]).get()); - - if ([aError code] == kCLErrorDenied) { - mProvider->NotifyError(nsIDOMGeoPositionError::PERMISSION_DENIED); - return; - } - - // The CL provider does not fallback to GeoIP, so use NetworkGeolocationProvider for this. - // The concept here is: on error, hand off geolocation to MLS, which will then report - // back a location or error. We can't call this with no delay however, as this method - // is called with an error code of 0 in both failed geolocation cases, and also when - // geolocation is not immediately available. - // The 2 sec delay is arbitrarily large enough that CL has a reasonable head start and - // if it is likely to succeed, it should complete before the MLS provider. - // Take note that in locationManager:didUpdateLocations: the handoff to MLS is stopped. - mProvider->CreateMLSFallbackProvider(); -} - -- (void)locationManager:(CLLocationManager*)aManager didUpdateLocations:(NSArray*)aLocations -{ - if (aLocations.count < 1) { - return; - } - - mProvider->CancelMLSFallbackProvider(); - - CLLocation* location = [aLocations objectAtIndex:0]; - - nsCOMPtr<nsIDOMGeoPosition> geoPosition = - new nsGeoPosition(location.coordinate.latitude, - location.coordinate.longitude, - location.altitude, - location.horizontalAccuracy, - location.verticalAccuracy, - location.course, - location.speed, - PR_Now() / PR_USEC_PER_MSEC); - - mProvider->Update(geoPosition); -} -@end - -NS_IMPL_ISUPPORTS(CoreLocationLocationProvider::MLSUpdate, nsIGeolocationUpdate); - -CoreLocationLocationProvider::MLSUpdate::MLSUpdate(CoreLocationLocationProvider& parentProvider) - : mParentLocationProvider(parentProvider) -{ -} - -CoreLocationLocationProvider::MLSUpdate::~MLSUpdate() -{ -} - -NS_IMETHODIMP -CoreLocationLocationProvider::MLSUpdate::Update(nsIDOMGeoPosition *position) -{ - nsCOMPtr<nsIDOMGeoPositionCoords> coords; - position->GetCoords(getter_AddRefs(coords)); - if (!coords) { - return NS_ERROR_FAILURE; - } - mParentLocationProvider.Update(position); - return NS_OK; -} -NS_IMETHODIMP -CoreLocationLocationProvider::MLSUpdate::NotifyError(uint16_t error) -{ - mParentLocationProvider.NotifyError(error); - return NS_OK; -} -class CoreLocationObjects { -public: - nsresult Init(CoreLocationLocationProvider* aProvider) { - mLocationManager = [[CLLocationManager alloc] init]; - NS_ENSURE_TRUE(mLocationManager, NS_ERROR_NOT_AVAILABLE); - - mLocationDelegate = [[LocationDelegate alloc] init:aProvider]; - NS_ENSURE_TRUE(mLocationDelegate, NS_ERROR_NOT_AVAILABLE); - - mLocationManager.desiredAccuracy = kDEFAULT_ACCURACY; - mLocationManager.delegate = mLocationDelegate; - - return NS_OK; - } - - ~CoreLocationObjects() { - if (mLocationManager) { - [mLocationManager release]; - } - - if (mLocationDelegate) { - [mLocationDelegate release]; - } - } - - LocationDelegate* mLocationDelegate; - CLLocationManager* mLocationManager; -}; - -NS_IMPL_ISUPPORTS(CoreLocationLocationProvider, nsIGeolocationProvider) - -CoreLocationLocationProvider::CoreLocationLocationProvider() - : mCLObjects(nullptr), mMLSFallbackProvider(nullptr) -{ -} - -CoreLocationLocationProvider::~CoreLocationLocationProvider() -{ -} - -NS_IMETHODIMP -CoreLocationLocationProvider::Startup() -{ - if (!mCLObjects) { - nsAutoPtr<CoreLocationObjects> clObjs(new CoreLocationObjects()); - - nsresult rv = clObjs->Init(this); - NS_ENSURE_SUCCESS(rv, rv); - - mCLObjects = clObjs.forget(); - } - - // Must be stopped before starting or response (success or failure) is not guaranteed - [mCLObjects->mLocationManager stopUpdatingLocation]; - [mCLObjects->mLocationManager startUpdatingLocation]; - return NS_OK; -} - -NS_IMETHODIMP -CoreLocationLocationProvider::Watch(nsIGeolocationUpdate* aCallback) -{ - if (mCallback) { - return NS_OK; - } - - mCallback = aCallback; - return NS_OK; -} - -NS_IMETHODIMP -CoreLocationLocationProvider::Shutdown() -{ - NS_ENSURE_STATE(mCLObjects); - - [mCLObjects->mLocationManager stopUpdatingLocation]; - - delete mCLObjects; - mCLObjects = nullptr; - - if (mMLSFallbackProvider) { - mMLSFallbackProvider->Shutdown(); - mMLSFallbackProvider = nullptr; - } - - return NS_OK; -} - -NS_IMETHODIMP -CoreLocationLocationProvider::SetHighAccuracy(bool aEnable) -{ - NS_ENSURE_STATE(mCLObjects); - - mCLObjects->mLocationManager.desiredAccuracy = - (aEnable ? kHIGH_ACCURACY : kDEFAULT_ACCURACY); - - return NS_OK; -} - -void -CoreLocationLocationProvider::Update(nsIDOMGeoPosition* aSomewhere) -{ - if (aSomewhere && mCallback) { - mCallback->Update(aSomewhere); - } -} - -void -CoreLocationLocationProvider::NotifyError(uint16_t aErrorCode) -{ - mCallback->NotifyError(aErrorCode); -} - -void -CoreLocationLocationProvider::CreateMLSFallbackProvider() -{ - if (mMLSFallbackProvider) { - return; - } - - mMLSFallbackProvider = new MLSFallback(); - mMLSFallbackProvider->Startup(new MLSUpdate(*this)); -} - -void -CoreLocationLocationProvider::CancelMLSFallbackProvider() -{ - if (!mMLSFallbackProvider) { - return; - } - - mMLSFallbackProvider->Shutdown(); - mMLSFallbackProvider = nullptr; -} diff --git a/dom/system/mac/moz.build b/dom/system/mac/moz.build deleted file mode 100644 index 08b7c2151e..0000000000 --- a/dom/system/mac/moz.build +++ /dev/null @@ -1,14 +0,0 @@ -# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- -# 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/. - -SOURCES += ['CoreLocationLocationProvider.mm'] - -include('/ipc/chromium/chromium-config.mozbuild') - -FINAL_LIBRARY = 'xul' -LOCAL_INCLUDES += [ - '/dom/geolocation', -] - diff --git a/dom/system/moz.build b/dom/system/moz.build index bde685e4fc..fb41fd4f2d 100644 --- a/dom/system/moz.build +++ b/dom/system/moz.build @@ -7,8 +7,6 @@ toolkit = CONFIG['MOZ_WIDGET_TOOLKIT'] if toolkit == 'windows': DIRS += ['windows'] -elif toolkit == 'cocoa': - DIRS += ['mac'] elif toolkit == 'android': DIRS += ['android'] elif toolkit in ('gtk2', 'gtk3'): diff --git a/dom/xbl/builtin/mac/jar.mn b/dom/xbl/builtin/mac/jar.mn deleted file mode 100644 index 9f05c2dd6c..0000000000 --- a/dom/xbl/builtin/mac/jar.mn +++ /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/. - -toolkit.jar: -* content/global/platformHTMLBindings.xml (platformHTMLBindings.xml) diff --git a/dom/xbl/builtin/mac/moz.build b/dom/xbl/builtin/mac/moz.build deleted file mode 100644 index 635fa39c99..0000000000 --- a/dom/xbl/builtin/mac/moz.build +++ /dev/null @@ -1,6 +0,0 @@ -# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- -# 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/. - -JAR_MANIFESTS += ['jar.mn']
\ No newline at end of file diff --git a/dom/xbl/builtin/mac/platformHTMLBindings.xml b/dom/xbl/builtin/mac/platformHTMLBindings.xml deleted file mode 100644 index b705923999..0000000000 --- a/dom/xbl/builtin/mac/platformHTMLBindings.xml +++ /dev/null @@ -1,72 +0,0 @@ -<?xml version="1.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/. --> - - -<bindings id="htmlBindings" - xmlns="http://www.mozilla.org/xbl" - xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> - - <binding id="inputFields" bindToUntrustedContent="true"> - <handlers> - <handler event="keypress" key="c" modifiers="accel" command="cmd_copy"/> - <handler event="keypress" key="x" modifiers="accel" command="cmd_cut"/> - <handler event="keypress" key="v" modifiers="accel" command="cmd_paste"/> - <handler event="keypress" key="z" modifiers="accel" command="cmd_undo"/> - <handler event="keypress" key="z" modifiers="accel,shift" command="cmd_redo"/> - <handler event="keypress" key="a" modifiers="accel" command="cmd_selectAll"/> - </handlers> - </binding> - - <binding id="textAreas" bindToUntrustedContent="true"> - <handlers> - <handler event="keypress" key="c" modifiers="accel" command="cmd_copy"/> - <handler event="keypress" key="x" modifiers="accel" command="cmd_cut"/> - <handler event="keypress" key="v" modifiers="accel" command="cmd_paste"/> - <handler event="keypress" key="z" modifiers="accel" command="cmd_undo"/> - <handler event="keypress" key="z" modifiers="accel,shift" command="cmd_redo"/> - <handler event="keypress" key="a" modifiers="accel" command="cmd_selectAll"/> - </handlers> - </binding> - - <binding id="browser"> - <handlers> -#include ../browser-base.inc - <handler event="keypress" keycode="VK_PAGE_UP" command="cmd_scrollPageUp"/> - <handler event="keypress" keycode="VK_PAGE_DOWN" command="cmd_scrollPageDown"/> - <handler event="keypress" keycode="VK_HOME" command="cmd_scrollTop" /> - <handler event="keypress" keycode="VK_END" command="cmd_scrollBottom" /> - - <handler event="keypress" keycode="VK_LEFT" modifiers="alt" command="cmd_moveLeft2" /> - <handler event="keypress" keycode="VK_RIGHT" modifiers="alt" command="cmd_moveRight2" /> - <handler event="keypress" keycode="VK_LEFT" modifiers="alt,shift" command="cmd_selectLeft2" /> - <handler event="keypress" keycode="VK_RIGHT" modifiers="alt,shift" command="cmd_selectRight2" /> - <handler event="keypress" keycode="VK_LEFT" modifiers="shift" command="cmd_selectLeft" /> - <handler event="keypress" keycode="VK_RIGHT" modifiers="shift" command="cmd_selectRight" /> - <handler event="keypress" keycode="VK_UP" modifiers="alt,shift" command="cmd_selectUp2" /> - <handler event="keypress" keycode="VK_DOWN" modifiers="alt,shift" command="cmd_selectDown2" /> - <handler event="keypress" keycode="VK_UP" modifiers="shift" command="cmd_selectUp" /> - <handler event="keypress" keycode="VK_DOWN" modifiers="shift" command="cmd_selectDown" /> - <handler event="keypress" keycode="VK_UP" modifiers="accel" command="cmd_moveUp2"/> - <handler event="keypress" keycode="VK_DOWN" modifiers="accel" command="cmd_moveDown2"/> - </handlers> - </binding> - - <binding id="editor"> - <handlers> - <handler event="keypress" key=" " modifiers="shift" command="cmd_scrollPageUp" /> - <handler event="keypress" key=" " command="cmd_scrollPageDown" /> - - <handler event="keypress" key="z" command="cmd_undo" modifiers="accel"/> - <handler event="keypress" key="z" command="cmd_redo" modifiers="accel,shift" /> - <handler event="keypress" key="x" command="cmd_cut" modifiers="accel"/> - <handler event="keypress" key="c" command="cmd_copy" modifiers="accel"/> - <handler event="keypress" key="v" command="cmd_paste" modifiers="accel"/> - <handler event="keypress" key="v" command="cmd_pasteNoFormatting" modifiers="accel,shift"/> - <handler event="keypress" key="a" command="cmd_selectAll" modifiers="accel"/> - <handler event="keypress" key="v" command="cmd_pasteNoFormatting" modifiers="accel,alt,shift"/> - </handlers> - </binding> - -</bindings> diff --git a/dom/xbl/builtin/moz.build b/dom/xbl/builtin/moz.build index 23e3285d49..c51001b4c9 100644 --- a/dom/xbl/builtin/moz.build +++ b/dom/xbl/builtin/moz.build @@ -5,8 +5,6 @@ if CONFIG['OS_ARCH'] == 'WINNT': DIRS += ['win'] -elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa': - DIRS += ['mac'] elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'android': DIRS += ['android'] elif CONFIG['MOZ_WIDGET_TOOLKIT'] in ('gtk2', 'gtk3'): |