• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
createPositionOptions(v8::Local<v8::Value> value,v8::Isolate * isolate,bool & succeeded,ExceptionState & exceptionState)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 
getCurrentPositionMethodCustom(const v8::FunctionCallbackInfo<v8::Value> & info)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 
watchPositionMethodCustom(const v8::FunctionCallbackInfo<v8::Value> & info)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