2 * Copyright (c) 2015 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 bool ctx::myplace_handle::start_monitor(int place_id)
37 _D("Starts to monitor Place-%d", place_id);
39 IF_FAIL_RETURN(place_id >= 0, false);
40 IF_FAIL_RETURN_TAG(geo_handle == NULL, false, _E, "Re-starting MyPlace monitor");
42 geofence_manager_create(&geo_handle);
43 IF_FAIL_RETURN_TAG(geo_handle, false, _E, "Geofence initialization failed");
47 ret = geofence_manager_set_geofence_state_changed_cb(geo_handle, fence_state_cb, this);
48 IF_FAIL_CATCH_TAG(ret == GEOFENCE_MANAGER_ERROR_NONE, _E, "Setting state callback failed");
50 ret = geofence_manager_set_geofence_event_cb(geo_handle, fence_event_cb, this);
51 IF_FAIL_CATCH_TAG(ret == GEOFENCE_MANAGER_ERROR_NONE, _E, "Setting event callback failed");
53 ret = geofence_manager_foreach_place_geofence_list(geo_handle, place_id, fence_list_cb, this);
54 IF_FAIL_CATCH_TAG(ret == GEOFENCE_MANAGER_ERROR_NONE, _E, "Getting fence list failed");
64 int ctx::myplace_handle::get_place_id()
69 void ctx::myplace_handle::stop_monitor()
71 _D("Stops monitoring Place-%d", _place_id);
73 //TODO: Do we need to stop all geofences explicitly?
75 geofence_manager_destroy(geo_handle);
79 geo_state_map.clear();
81 prev_state = GEOFENCE_STATE_UNCERTAIN;
84 bool ctx::myplace_handle::start_fence(int fence_id)
88 ret = geofence_manager_start(geo_handle, fence_id);
89 IF_FAIL_RETURN_TAG(ret == GEOFENCE_MANAGER_ERROR_NONE, true, _W, "Starting failed");
91 geofence_status_h status;
92 ret = geofence_status_create(fence_id, &status);
93 IF_FAIL_RETURN_TAG(ret == GEOFENCE_MANAGER_ERROR_NONE, true, _W, "Getting status failed");
95 geofence_state_e state = GEOFENCE_STATE_UNCERTAIN;
96 geofence_status_get_state(status, &state);
97 geofence_status_destroy(status);
99 geo_state_map[fence_id] = state;
104 void ctx::myplace_handle::remove_fence(int fence_id)
106 geofence_manager_stop(geo_handle, fence_id);
107 geo_state_map.erase(fence_id);
110 void ctx::myplace_handle::update_fence(int fence_id, geofence_manage_e manage)
113 case GEOFENCE_MANAGE_PLACE_REMOVED:
114 _W("[Place-%d] Removed", _place_id);
117 case GEOFENCE_MANAGE_FENCE_ADDED:
118 _I("[Place %d] Fence-%d added", _place_id, fence_id);
119 start_fence(fence_id);
122 case GEOFENCE_MANAGE_FENCE_REMOVED:
123 _I("[Place-%d] Fence-%d removed", _place_id, fence_id);
124 remove_fence(fence_id);
127 case GEOFENCE_MANAGE_FENCE_STARTED:
128 _D("[Place-%d] Fence-%d started", _place_id, fence_id);
130 case GEOFENCE_MANAGE_FENCE_STOPPED:
131 _D("[Place-%d] Fence-%d stopped", _place_id, fence_id);
132 //TODO: Do we need to restart this?
135 _D("[Place-%d] Ignoring the manage event %d", _place_id, manage);
140 void ctx::myplace_handle::update_state(int fence_id, geofence_state_e state)
142 geo_state_map[fence_id] = state;
145 static const char* get_state_string(geofence_state_e state)
148 case GEOFENCE_STATE_IN:
149 return MYPLACE_EVENT_IN;
150 case GEOFENCE_STATE_OUT:
151 return MYPLACE_EVENT_OUT;
152 case GEOFENCE_STATE_UNCERTAIN:
153 return MYPLACE_EVENT_UNCERTAIN;
155 return MYPLACE_EVENT_UNCERTAIN;
159 void ctx::myplace_handle::emit_state_change()
161 geofence_state_e current_state = GEOFENCE_STATE_UNCERTAIN;
164 for (geo_state_map_t::iterator it = geo_state_map.begin(); it != geo_state_map.end(); ++it) {
165 if (it->second == GEOFENCE_STATE_IN) {
166 current_state = GEOFENCE_STATE_IN;
168 } else if (it->second == GEOFENCE_STATE_OUT) {
173 if (current_state != GEOFENCE_STATE_IN && out_count > 0) {
174 current_state = GEOFENCE_STATE_OUT;
177 if (current_state == prev_state) {
181 prev_state = current_state;
184 option.set(NULL, PLACE_STATUS_DATA_MYPLACE_ID, _place_id);
187 data.set(NULL, PLACE_STATUS_DATA_MYPLACE_ID, _place_id);
188 data.set(NULL, PLACE_STATUS_DATA_MYPLACE_EVENT, get_state_string(current_state));
190 context_manager::publish(PLACE_SUBJ_GEOFENCE, option, ERR_NONE, data);
193 bool ctx::myplace_handle::fence_list_cb(int geofence_id, geofence_h fence, int fence_index, int fence_cnt, void* user_data)
195 _D("FenceID: %d, Index: %d, Count: %d", geofence_id, fence_index, fence_cnt);
196 IF_FAIL_RETURN(fence_cnt > 0, false);
198 myplace_handle *handle = reinterpret_cast<myplace_handle*>(user_data);
199 return handle->start_fence(geofence_id);
202 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)
204 IF_FAIL_VOID_TAG(error == GEOFENCE_MANAGER_ERROR_NONE, _W, "Geofence error: %d", error);
206 myplace_handle *handle = reinterpret_cast<myplace_handle*>(user_data);
208 IF_FAIL_VOID_TAG(place_id == handle->get_place_id(), _W, "Mismatched Place ID");
210 handle->update_fence(geofence_id, manage);
213 void ctx::myplace_handle::fence_state_cb(int geofence_id, geofence_state_e state, void* user_data)
215 myplace_handle *handle = reinterpret_cast<myplace_handle*>(user_data);
216 handle->update_state(geofence_id, state);
217 handle->emit_state_change();