2 * Copyright (c) 2014 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 #include <types_internal.h>
19 #include <context_mgr.h>
20 #include "place_geofence_types.h"
21 #include "myplace_handle.h"
23 ctx::myplace_handle::myplace_handle()
25 , prev_state(GEOFENCE_STATE_UNCERTAIN)
30 ctx::myplace_handle::~myplace_handle()
35 void ctx::myplace_handle::add_zone(const char* zone)
37 _D("'%s' subscribes Place-%d", zone, _place_id);
41 void ctx::myplace_handle::remove_zone(const char* zone)
43 _D("'%s' unsubscribes Place-%d", zone, _place_id);
47 bool ctx::myplace_handle::zone_empty()
52 bool ctx::myplace_handle::start_monitor(int place_id)
54 _D("Starts to monitor Place-%d", place_id);
56 IF_FAIL_RETURN(place_id >= 0, false);
57 IF_FAIL_RETURN_TAG(geo_handle == NULL, false, _E, "Re-starting MyPlace monitor");
59 geofence_manager_create(&geo_handle);
60 IF_FAIL_RETURN_TAG(geo_handle, false, _E, "Geofence initialization failed");
64 ret = geofence_manager_set_geofence_state_changed_cb(geo_handle, fence_state_cb, this);
65 IF_FAIL_CATCH_TAG(ret == GEOFENCE_MANAGER_ERROR_NONE, _E, "Setting state callback failed");
67 ret = geofence_manager_set_geofence_event_cb(geo_handle, fence_event_cb, this);
68 IF_FAIL_CATCH_TAG(ret == GEOFENCE_MANAGER_ERROR_NONE, _E, "Setting event callback failed");
70 ret = geofence_manager_foreach_place_geofence_list(geo_handle, place_id, fence_list_cb, this);
71 IF_FAIL_CATCH_TAG(ret == GEOFENCE_MANAGER_ERROR_NONE, _E, "Getting fence list failed");
81 int ctx::myplace_handle::get_place_id()
86 void ctx::myplace_handle::stop_monitor()
88 _D("Stops monitoring Place-%d", _place_id);
90 //TODO: Do we need to stop all geofences explicitly?
92 geofence_manager_destroy(geo_handle);
96 geo_state_map.clear();
98 prev_state = GEOFENCE_STATE_UNCERTAIN;
101 bool ctx::myplace_handle::start_fence(int fence_id)
105 ret = geofence_manager_start(geo_handle, fence_id);
106 IF_FAIL_RETURN_TAG(ret == GEOFENCE_MANAGER_ERROR_NONE, true, _W, "Starting failed");
108 geofence_status_h status;
109 ret = geofence_status_create(fence_id, &status);
110 IF_FAIL_RETURN_TAG(ret == GEOFENCE_MANAGER_ERROR_NONE, true, _W, "Getting status failed");
112 geofence_state_e state = GEOFENCE_STATE_UNCERTAIN;
113 geofence_status_get_state(status, &state);
114 geofence_status_destroy(status);
116 geo_state_map[fence_id] = state;
121 void ctx::myplace_handle::remove_fence(int fence_id)
123 geofence_manager_stop(geo_handle, fence_id);
124 geo_state_map.erase(fence_id);
127 void ctx::myplace_handle::update_fence(int fence_id, geofence_manage_e manage)
130 case GEOFENCE_MANAGE_PLACE_REMOVED:
131 _W("[Place-%d] Removed", _place_id);
134 case GEOFENCE_MANAGE_FENCE_ADDED:
135 _I("[Place %d] Fence-%d added", _place_id, fence_id);
136 start_fence(fence_id);
139 case GEOFENCE_MANAGE_FENCE_REMOVED:
140 _I("[Place-%d] Fence-%d removed", _place_id, fence_id);
141 remove_fence(fence_id);
144 case GEOFENCE_MANAGE_FENCE_STARTED:
145 _D("[Place-%d] Fence-%d started", _place_id, fence_id);
147 case GEOFENCE_MANAGE_FENCE_STOPPED:
148 _D("[Place-%d] Fence-%d stopped", _place_id, fence_id);
149 //TODO: Do we need to restart this?
152 _D("[Place-%d] Ignoring the manage event %d", _place_id, manage);
157 void ctx::myplace_handle::update_state(int fence_id, geofence_state_e state)
159 geo_state_map[fence_id] = state;
162 static const char* get_state_string(geofence_state_e state)
165 case GEOFENCE_STATE_IN:
166 return MYPLACE_EVENT_IN;
167 case GEOFENCE_STATE_OUT:
168 return MYPLACE_EVENT_OUT;
169 case GEOFENCE_STATE_UNCERTAIN:
170 return MYPLACE_EVENT_UNCERTAIN;
172 return MYPLACE_EVENT_UNCERTAIN;
176 void ctx::myplace_handle::emit_state_change()
178 geofence_state_e current_state = GEOFENCE_STATE_UNCERTAIN;
181 for (geo_state_map_t::iterator it = geo_state_map.begin(); it != geo_state_map.end(); ++it) {
182 if (it->second == GEOFENCE_STATE_IN) {
183 current_state = GEOFENCE_STATE_IN;
185 } else if (it->second == GEOFENCE_STATE_OUT) {
190 if (current_state != GEOFENCE_STATE_IN && out_count > 0) {
191 current_state = GEOFENCE_STATE_OUT;
194 if (current_state == prev_state) {
198 prev_state = current_state;
201 option.set(NULL, PLACE_STATUS_DATA_MYPLACE_ID, _place_id);
204 data.set(NULL, PLACE_STATUS_DATA_MYPLACE_ID, _place_id);
205 data.set(NULL, PLACE_STATUS_DATA_MYPLACE_EVENT, get_state_string(current_state));
207 for (string_set_t::iterator it = _zone.begin(); it != _zone.end(); ++it) {
208 context_manager::publish(PLACE_SUBJ_GEOFENCE, option, ERR_NONE, data, it->c_str());
212 bool ctx::myplace_handle::fence_list_cb(int geofence_id, geofence_h fence, int fence_index, int fence_cnt, void* user_data)
214 myplace_handle *handle = reinterpret_cast<myplace_handle*>(user_data);
215 return handle->start_fence(geofence_id);
218 void ctx::myplace_handle::fence_event_cb(int place_id, int geofence_id, geofence_manager_error_e error, geofence_manage_e manage, void* user_data)
220 IF_FAIL_VOID_TAG(error == GEOFENCE_MANAGER_ERROR_NONE, _W, "Geofence error: %d", error);
222 myplace_handle *handle = reinterpret_cast<myplace_handle*>(user_data);
224 IF_FAIL_VOID_TAG(place_id == handle->get_place_id(), _W, "Mismatched Place ID");
226 handle->update_fence(geofence_id, manage);
229 void ctx::myplace_handle::fence_state_cb(int geofence_id, geofence_state_e state, void* user_data)
231 myplace_handle *handle = reinterpret_cast<myplace_handle*>(user_data);
232 handle->update_state(geofence_id, state);
233 handle->emit_state_change();