14035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin/* Copyright (c) 2011-2014, The Linux Foundation. All rights reserved.
24035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin *
34035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin * Redistribution and use in source and binary forms, with or without
44035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin * modification, are permitted provided that the following conditions are
54035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin * met:
64035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin *     * Redistributions of source code must retain the above copyright
74035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin *       notice, this list of conditions and the following disclaimer.
84035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin *     * Redistributions in binary form must reproduce the above
94035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin *       copyright notice, this list of conditions and the following
104035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin *       disclaimer in the documentation and/or other materials provided
114035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin *       with the distribution.
124035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin *     * Neither the name of The Linux Foundation, nor the names of its
134035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin *       contributors may be used to endorse or promote products derived
144035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin *       from this software without specific prior written permission.
154035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin *
164035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
174035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
184035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
194035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
204035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
214035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
224035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
234035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
244035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
254035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
264035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
274035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin *
284035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin */
294035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin#define LOG_NDDEBUG 0
304035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin#define LOG_TAG "LocSvc_DualCtx"
314035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
324035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin#include <cutils/sched_policy.h>
334035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin#include <unistd.h>
344035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin#include <LocDualContext.h>
354035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin#include <msg_q.h>
364035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin#include <log_util.h>
374035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin#include <loc_log.h>
384035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
394035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjinnamespace loc_core {
404035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
414035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin// nothing exclude for foreground
424035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjinconst LOC_API_ADAPTER_EVENT_MASK_T
434035be28a255eaa5605dbd9abeb2340db584249cPatrick TjinLocDualContext::mFgExclMask = 0;
444035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin// excluded events for background clients
454035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjinconst LOC_API_ADAPTER_EVENT_MASK_T
464035be28a255eaa5605dbd9abeb2340db584249cPatrick TjinLocDualContext::mBgExclMask =
474035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    (LOC_API_ADAPTER_BIT_PARSED_POSITION_REPORT |
484035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin     LOC_API_ADAPTER_BIT_SATELLITE_REPORT |
494035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin     LOC_API_ADAPTER_BIT_NMEA_1HZ_REPORT |
504035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin     LOC_API_ADAPTER_BIT_NMEA_POSITION_REPORT |
514035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin     LOC_API_ADAPTER_BIT_IOCTL_REPORT |
524035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin     LOC_API_ADAPTER_BIT_STATUS_REPORT |
534035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin     LOC_API_ADAPTER_BIT_GEOFENCE_GEN_ALERT |
544035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin     LOC_API_ADAPTER_BIT_GNSS_MEASUREMENT);
554035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
564035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjinconst MsgTask* LocDualContext::mMsgTask = NULL;
574035be28a255eaa5605dbd9abeb2340db584249cPatrick TjinContextBase* LocDualContext::mFgContext = NULL;
584035be28a255eaa5605dbd9abeb2340db584249cPatrick TjinContextBase* LocDualContext::mBgContext = NULL;
594035be28a255eaa5605dbd9abeb2340db584249cPatrick TjinContextBase* LocDualContext::mInjectContext = NULL;
604035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin// the name must be shorter than 15 chars
614035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjinconst char* LocDualContext::mLocationHalName = "Loc_hal_worker";
624035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjinconst char* LocDualContext::mLBSLibName = "liblbs_core.so";
634035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
644035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjinpthread_mutex_t LocDualContext::mGetLocContextMutex = PTHREAD_MUTEX_INITIALIZER;
654035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
664035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjinconst MsgTask* LocDualContext::getMsgTask(LocThread::tCreate tCreator,
674035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin                                          const char* name, bool joinable)
684035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin{
694035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    if (NULL == mMsgTask) {
704035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        mMsgTask = new MsgTask(tCreator, name, joinable);
714035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    }
724035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    return mMsgTask;
734035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin}
744035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
754035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjininline
764035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjinconst MsgTask* LocDualContext::getMsgTask(const char* name, bool joinable) {
774035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    return getMsgTask((LocThread::tCreate)NULL, name, joinable);
784035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin}
794035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
804035be28a255eaa5605dbd9abeb2340db584249cPatrick TjinContextBase* LocDualContext::getLocFgContext(LocThread::tCreate tCreator,
814035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin            LocMsg* firstMsg, const char* name, bool joinable)
824035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin{
834035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    pthread_mutex_lock(&LocDualContext::mGetLocContextMutex);
844035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    LOC_LOGD("%s:%d]: querying ContextBase with tCreator", __func__, __LINE__);
854035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    if (NULL == mFgContext) {
864035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        LOC_LOGD("%s:%d]: creating msgTask with tCreator", __func__, __LINE__);
874035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        const MsgTask* msgTask = getMsgTask(tCreator, name, joinable);
884035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        mFgContext = new LocDualContext(msgTask,
894035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin                                        mFgExclMask);
904035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    }
914035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    if(NULL == mInjectContext) {
924035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        LOC_LOGD("%s:%d]: mInjectContext is FgContext", __func__, __LINE__);
934035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        mInjectContext = mFgContext;
944035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        injectFeatureConfig(mInjectContext);
954035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    }
964035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    pthread_mutex_unlock(&LocDualContext::mGetLocContextMutex);
974035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
984035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    if (firstMsg) {
994035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        mFgContext->sendMsg(firstMsg);
1004035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    }
1014035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
1024035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    return mFgContext;
1034035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin}
1044035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
1054035be28a255eaa5605dbd9abeb2340db584249cPatrick TjinContextBase* LocDualContext::getLocBgContext(LocThread::tCreate tCreator,
1064035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin            LocMsg* firstMsg, const char* name, bool joinable)
1074035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin{
1084035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    pthread_mutex_lock(&LocDualContext::mGetLocContextMutex);
1094035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    LOC_LOGD("%s:%d]: querying ContextBase with tCreator", __func__, __LINE__);
1104035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    if (NULL == mBgContext) {
1114035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        LOC_LOGD("%s:%d]: creating msgTask with tCreator", __func__, __LINE__);
1124035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        const MsgTask* msgTask = getMsgTask(tCreator, name, joinable);
1134035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        mBgContext = new LocDualContext(msgTask,
1144035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin                                        mBgExclMask);
1154035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    }
1164035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    if(NULL == mInjectContext) {
1174035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        LOC_LOGD("%s:%d]: mInjectContext is BgContext", __func__, __LINE__);
1184035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        mInjectContext = mBgContext;
1194035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        injectFeatureConfig(mInjectContext);
1204035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    }
1214035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    pthread_mutex_unlock(&LocDualContext::mGetLocContextMutex);
1224035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
1234035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    if (firstMsg) {
1244035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        mBgContext->sendMsg(firstMsg);
1254035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    }
1264035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
1274035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    return mBgContext;
1284035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin}
1294035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
1304035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjinvoid LocDualContext :: injectFeatureConfig(ContextBase *curContext)
1314035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin{
1324035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    LOC_LOGD("%s:%d]: Enter", __func__, __LINE__);
1334035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    if(curContext == mInjectContext) {
1344035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        LOC_LOGD("%s:%d]: Calling LBSProxy (%p) to inject feature config",
1354035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin                 __func__, __LINE__, ((LocDualContext *)mInjectContext)->mLBSProxy);
1364035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        ((LocDualContext *)mInjectContext)->mLBSProxy->injectFeatureConfig(curContext);
1374035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    }
1384035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    LOC_LOGD("%s:%d]: Exit", __func__, __LINE__);
1394035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin}
1404035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
1414035be28a255eaa5605dbd9abeb2340db584249cPatrick TjinLocDualContext::LocDualContext(const MsgTask* msgTask,
1424035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin                               LOC_API_ADAPTER_EVENT_MASK_T exMask) :
1434035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    ContextBase(msgTask, exMask, mLBSLibName)
1444035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin{
1454035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin}
1464035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
1474035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin}
148