1 /* 2 * Copyright 2009, The Android Open Source Project 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * * Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * * Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26 #include "config.h" 27 #include "bindings/modules/v8/V8Geolocation.h" 28 29 #include "bindings/modules/v8/V8PositionCallback.h" 30 #include "bindings/modules/v8/V8PositionErrorCallback.h" 31 #include "bindings/v8/V8Binding.h" 32 #include "bindings/v8/V8Callback.h" 33 #include "modules/geolocation/Geolocation.h" 34 35 using namespace WTF; 36 37 namespace WebCore { 38 39 static PositionOptions* createPositionOptions(v8::Local<v8::Value> value, v8::Isolate* isolate, bool& succeeded, ExceptionState& exceptionState) 40 { 41 succeeded = true; 42 43 // Create default options. 44 PositionOptions* options = PositionOptions::create(); 45 46 // Argument is optional (hence undefined is allowed), and null is allowed. 47 if (isUndefinedOrNull(value)) { 48 // Use default options. 49 return options; 50 } 51 52 // Given the above test, this will always yield an object. 53 v8::Local<v8::Object> object = value->ToObject(); 54 55 // For all three properties, we apply the following ... 56 // - If the getter or the property's valueOf method throws an exception, we 57 // quit so as not to risk overwriting the exception. 58 // - If the value is absent or undefined, we don't override the default. 59 v8::Local<v8::Value> enableHighAccuracyValue = object->Get(v8AtomicString(isolate, "enableHighAccuracy")); 60 if (enableHighAccuracyValue.IsEmpty()) { 61 succeeded = false; 62 return nullptr; 63 } 64 if (!enableHighAccuracyValue->IsUndefined()) { 65 v8::Local<v8::Boolean> enableHighAccuracyBoolean = enableHighAccuracyValue->ToBoolean(); 66 if (enableHighAccuracyBoolean.IsEmpty()) { 67 succeeded = false; 68 return nullptr; 69 } 70 options->setEnableHighAccuracy(enableHighAccuracyBoolean->Value()); 71 } 72 73 v8::Local<v8::Value> timeoutValue = object->Get(v8AtomicString(isolate, "timeout")); 74 if (timeoutValue.IsEmpty()) { 75 succeeded = false; 76 return nullptr; 77 } 78 if (!timeoutValue->IsUndefined()) { 79 v8::Local<v8::Number> timeoutNumber = timeoutValue->ToNumber(); 80 if (timeoutNumber.IsEmpty()) { 81 succeeded = false; 82 return nullptr; 83 } 84 if (timeoutNumber->Value() <= 0) 85 options->setTimeout(0); 86 else 87 options->setTimeout(toUInt32(timeoutValue, Clamp, exceptionState)); 88 } 89 90 v8::Local<v8::Value> maximumAgeValue = object->Get(v8AtomicString(isolate, "maximumAge")); 91 if (maximumAgeValue.IsEmpty()) { 92 succeeded = false; 93 return nullptr; 94 } 95 if (!maximumAgeValue->IsUndefined()) { 96 v8::Local<v8::Number> maximumAgeNumber = maximumAgeValue->ToNumber(); 97 if (maximumAgeNumber.IsEmpty()) { 98 succeeded = false; 99 return nullptr; 100 } 101 if (maximumAgeNumber->Value() <= 0) 102 options->setMaximumAge(0); 103 else 104 options->setMaximumAge(toUInt32(maximumAgeValue, Clamp, exceptionState)); 105 } 106 107 return options; 108 } 109 110 void V8Geolocation::getCurrentPositionMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& info) 111 { 112 bool succeeded = false; 113 114 ExceptionState exceptionState(ExceptionState::ExecutionContext, "getCurrentPosition", "Geolocation", info.Holder(), info.GetIsolate()); 115 116 OwnPtr<PositionCallback> positionCallback = createFunctionOnlyCallback<V8PositionCallback>(info[0], 1, succeeded, info.GetIsolate(), exceptionState); 117 if (!succeeded) 118 return; 119 ASSERT(positionCallback); 120 121 // Argument is optional (hence undefined is allowed), and null is allowed. 122 OwnPtr<PositionErrorCallback> positionErrorCallback = createFunctionOnlyCallback<V8PositionErrorCallback>(info[1], 2, succeeded, info.GetIsolate(), exceptionState, CallbackAllowUndefined | CallbackAllowNull); 123 if (!succeeded) 124 return; 125 126 PositionOptions* positionOptions = createPositionOptions(info[2], info.GetIsolate(), succeeded, exceptionState); 127 if (!succeeded) 128 return; 129 ASSERT(positionOptions); 130 131 Geolocation* geolocation = V8Geolocation::toNative(info.Holder()); 132 geolocation->getCurrentPosition(positionCallback.release(), positionErrorCallback.release(), positionOptions); 133 } 134 135 void V8Geolocation::watchPositionMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& info) 136 { 137 bool succeeded = false; 138 139 ExceptionState exceptionState(ExceptionState::ExecutionContext, "watchCurrentPosition", "Geolocation", info.Holder(), info.GetIsolate()); 140 141 OwnPtr<PositionCallback> positionCallback = createFunctionOnlyCallback<V8PositionCallback>(info[0], 1, succeeded, info.GetIsolate(), exceptionState); 142 if (!succeeded) 143 return; 144 ASSERT(positionCallback); 145 146 // Argument is optional (hence undefined is allowed), and null is allowed. 147 OwnPtr<PositionErrorCallback> positionErrorCallback = createFunctionOnlyCallback<V8PositionErrorCallback>(info[1], 2, succeeded, info.GetIsolate(), exceptionState, CallbackAllowUndefined | CallbackAllowNull); 148 if (!succeeded) 149 return; 150 151 PositionOptions* positionOptions = createPositionOptions(info[2], info.GetIsolate(), succeeded, exceptionState); 152 if (!succeeded) 153 return; 154 ASSERT(positionOptions); 155 156 Geolocation* geolocation = V8Geolocation::toNative(info.Holder()); 157 int watchId = geolocation->watchPosition(positionCallback.release(), positionErrorCallback.release(), positionOptions); 158 v8SetReturnValue(info, watchId); 159 } 160 161 } // namespace WebCore 162