1 //******************************************************************
3 // Copyright 2014 Intel Mobile Communications GmbH All Rights Reserved.
5 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
7 // Licensed under the Apache License, Version 2.0 (the "License");
8 // you may not use this file except in compliance with the License.
9 // You may obtain a copy of the License at
11 // http://www.apache.org/licenses/LICENSE-2.0
13 // Unless required by applicable law or agreed to in writing, software
14 // distributed under the License is distributed on an "AS IS" BASIS,
15 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 // See the License for the specific language governing permissions and
17 // limitations under the License.
19 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
21 // ============================================================================
23 // ============================================================================
24 #include "LiteRemoting.h"
26 #include <boost/make_shared.hpp>
27 #include <boost/bind.hpp>
32 #include <android/log.h>
35 // ============================================================================
37 // ============================================================================
40 // ============================================================================
42 // ============================================================================
43 // TODO: Need application ID for Remoting
44 const std::string LiteRemoting::APPLICATION_UUID_STRING = "7A1B397B-B576-44C4-943F-000000000001";
46 // ============================================================================
48 // ============================================================================
50 #define LOG_PRINT(X) __android_log_print(ANDROID_LOG_VERBOSE, "LiteRemoting", (X));
55 // ============================================================================
56 // Constructor/Destructor/getInstance
57 // ============================================================================
58 //---------------------------------------------------------------------------
60 // Called by getInstance method (Singleton patter)
61 //---------------------------------------------------------------------------
62 LiteRemoting::LiteRemoting(PrivateConstructKey key) {
64 apiResultReady_ = false;
66 // public static final String applicationId = "7A1B397B-B576-44C4-943F-000000000001";
67 // public static final UUID applicationUUID = UUID.fromString(applicationId);
69 // Begin CCF API interaction
70 pCCFService_ = API::Service::createService();
73 pCCFService_->registerApplication();
76 StringToUuid(APPLICATION_UUID_STRING.c_str(), &applicationId);
78 pCCFContext_ = pCCFService_->createContext(applicationId);
87 //---------------------------------------------------------------------------
89 //---------------------------------------------------------------------------
90 LiteRemoting::~LiteRemoting() {
93 targetDeviceProxyMap_.clear();
95 // Turn off observer callbacks
96 pCCFContext_->setSessionObserver();
97 pCCFContext_->setUserObserver();
99 // CCF APP interaction
102 pCCFService_->deregisterApplication();
106 //---------------------------------------------------------------------------
107 // getInstance (Singleton pattern
108 //---------------------------------------------------------------------------
109 // Get singleton instance of LiteRemoting
110 boost::shared_ptr<LiteRemoting> LiteRemoting::getInstance() {
111 LOG_PRINT("LiteRemoting::getInstance()");
113 static boost::shared_ptr<LiteRemoting> instance = boost::make_shared<LiteRemoting>(PrivateConstructKey());
118 // ============================================================================
120 // ============================================================================
121 void LiteRemoting::doStartup() {
123 // Get the local session id
124 boost::unique_lock<boost::mutex> lock(mutex_);
126 while (!apiResultReady_)
128 // TODO: maybe do cond_.timed_wait() ???
132 // Get local session info
134 queryMySessionInfo();
135 while (!apiResultReady_)
137 // TODO: maybe do cond_.timed_wait() ???
141 // Now that we have local session info, set the session observer
142 pCCFContext_->setSessionObserver(boost::bind(&LiteRemoting::sessionObserver, this, _1));
144 // TODO: set up connection observer
146 // TODO: set up device observer
150 void LiteRemoting::addSessionToMap(UUID_t sessionId) {
151 // Add session to the sessionMap
152 auto iter = sessionMap_.find(sessionId);
153 if (iter == sessionMap_.end() )
155 // sessionUUID not found, so add session
156 sessionMap_[sessionId] = boost::make_shared<LiteSessionImpl>(pCCFContext_, sessionId);
160 boost::shared_ptr<LiteSessionImpl> LiteRemoting::getSessionFromMap(UUID_t sessionId) {
161 boost::shared_ptr<LiteSessionImpl> pSession;
163 pSession = sessionMap_.at(sessionId);
165 catch (const std::out_of_range& oor) {
166 // sessionId not found, so add session
167 sessionMap_[sessionId] = boost::make_shared<LiteSessionImpl>(pCCFContext_, sessionId);
170 return sessionMap_[sessionId];
173 void LiteRemoting::addTargetDeviceToMap(UUID_t targetDeviceId) {
174 // A LiteTargetDeviceProxy with this targetDeviceId was not found, so add
175 // Add target device to the targetDeviceProxyMap_
176 auto iter = targetDeviceProxyMap_.find(targetDeviceId);
177 if (iter == targetDeviceProxyMap_.end() )
179 // targetDeviceId not found, so add session
180 targetDeviceProxyMap_[targetDeviceId] = boost::make_shared<LiteTargetDeviceProxy>(targetDeviceId);
185 boost::shared_ptr<LiteTargetDeviceProxy> LiteRemoting::getTargetDeviceFromMap(UUID_t targetDeviceId) {
186 boost::shared_ptr<LiteTargetDeviceProxy> pTargetDevice;
188 pTargetDevice = targetDeviceProxyMap_.at(targetDeviceId);
190 catch (const std::out_of_range& oor) {
191 // sessionId not found, so add session
192 targetDeviceProxyMap_[targetDeviceId] = boost::make_shared<LiteTargetDeviceProxy>(targetDeviceId);
195 return targetDeviceProxyMap_[targetDeviceId];
199 void LiteRemoting::handleNewTargetDevice(UUID_t targetDeviceId) {
200 addTargetDeviceToMap(targetDeviceId);
201 //session.sendDeviceArrival(device);
204 // TODO: socket parameter is faked with an int for now until I know how the connection info will be conveyed
205 void LiteRemoting::handleNewConnection(UUID_t sessionId, int socket) {
211 // Get the specified session and a new connection
212 boost::shared_ptr<LiteSessionImpl> pSession = getSessionFromMap(sessionId);
213 boost::shared_ptr<LiteConnection> pConnection = boost::make_shared<LiteConnection>(socket);
214 // TODO: add device info to connection
216 // List<LiteDeviceProxy> deviceProxyList = new ArrayList<LiteDeviceProxy>();
217 // synchronized (deviceProxySet) {
218 // for(LiteDeviceProxy device : deviceProxySet) {
219 // if (device.isLocal()) {
220 // deviceProxyList.add(device);
224 // for(LiteDeviceProxy device : deviceProxyList) {
226 // connection.sendDeviceArrival(device);
227 // } catch (IOException e) {
228 // e.printStackTrace();
232 // Add the new connection to the session
233 pSession->addConnection(pConnection);
236 void LiteRemoting::queryMySessionId() {
237 apiResultReady_ = false;
239 pCCFContext_->querySessionId([this](const API::SessionIdResult& sessionIdResult) -> void {
241 API::SessionIdResult::ResultType queryResult = sessionIdResult.getResult();
242 boost::lock_guard<boost::mutex> lock(mutex_);
243 switch (queryResult) {
244 case API::SessionIdResult::ResultType::Success:
245 LOG_PRINT("LiteRemoting::queryMySessionId() - queryResult == Success");
246 mySessionId_ = sessionIdResult.getSessionId();
247 apiResultReady_ = true;
249 case API::SessionIdResult::ResultType::InternalError:
250 LOG_PRINT("LiteRemoting::queryMySessionId() - queryResult == InternalError");
252 case API::SessionIdResult::ResultType::InvalidLocalSession:
253 LOG_PRINT("LiteRemoting::queryMySessionId() - queryResult == InvalidLocalSession");
256 LOG_PRINT("LiteRemoting::queryMySessionId() - queryResult == unknown");
263 void LiteRemoting::queryMySessionInfo()
265 apiResultReady_ = false;
267 // pCCFContext_->querySession(sessionUUID, std::bind(&LiteRemoting::querySessionObserver, this, _1));
268 pCCFContext_->querySession(mySessionId_, [this](const API::SessionQueryResult& sessionQueryResult) -> void {
270 API::QueryResultType queryResult = sessionQueryResult.getResult();
271 boost::lock_guard<boost::mutex> lock(mutex_);
272 switch (queryResult) {
273 case API::QueryResultType::Success:
274 LOG_PRINT("LiteRemoting::queryMySessionInfo() - queryResult == Success");
275 // TODO: verify that CCF application is in the session application set?
277 // Add my local session to the sessionMap
278 addSessionToMap(mySessionId_);
279 sessionMap_[mySessionId_]->setPublicAvatarId(sessionQueryResult.getPublicAvatarId());
280 sessionMap_[mySessionId_]->setPrivateAvatarId(sessionQueryResult.getPrivateAvatarId());
281 sessionMap_[mySessionId_]->setPublicAvatarId(sessionQueryResult.getPublicAvatarId());
282 sessionMap_[mySessionId_]->setUserId(sessionQueryResult.getUserId());
283 sessionMap_[mySessionId_]->setIssuer(sessionQueryResult.getIssuer());
284 sessionMap_[mySessionId_]->setName(sessionQueryResult.getName());
285 sessionMap_[mySessionId_]->setStatusText(sessionQueryResult.getStatusText());
286 sessionMap_[mySessionId_]->setSecurityCode(sessionQueryResult.getSecurityCode());
287 sessionMap_[mySessionId_]->setApplicationSet(sessionQueryResult.getApplicationSet());
289 // TODO: add more conditions before inviting to join session?
290 if (!sessionMap_[mySessionId_]->isConnected() && !sessionMap_[mySessionId_]->isInvited()) {
291 sessionMap_[mySessionId_]->invite();
294 apiResultReady_ = true;
296 case API::QueryResultType::NotFound:
297 LOG_PRINT("LiteRemoting::queryMySessionInfo() - queryResult == NotFound");
300 LOG_PRINT("LiteRemoting::queryMySessionInfo() - queryResult == unknown");
307 // ============================================================================
309 // ============================================================================
310 void LiteRemoting::sessionObserver(const API::SessionEvent& sessionEvent)
313 UUID_t sessionId = sessionEvent.getSessionId();
315 // TODO: Need to put in logic for seeing what's changed. Added, dropped, paused?
316 // int changeMask = sessionEvent.getWhatChanged();
318 // See if we already have the session in the map. If not, create and add
319 addSessionToMap(sessionId);