AgpsState* AgpsReleasedState::onRsrcEvent(AgpsRsrcStatus event, void* data) { LOC_LOGD("AgpsReleasedState::onRsrcEvent; event:%d\n", (int)event); if (mStateMachine->hasSubscribers()) { LOC_LOGE("Error: %s subscriber list not empty!!!", whoami()); // I don't know how to recover from it. I am adding this rather // for debugging purpose. } AgpsState* nextState = this; switch (event) { case RSRC_SUBSCRIBE: { // no notification until we get RSRC_GRANTED // but we need to add subscriber to the list mStateMachine->addSubscriber((Subscriber*)data); // request from connecivity service for NIF //The if condition is added so that if the data call setup fails //for DS State Machine, we want to retry in released state. //for AGps State Machine, sendRsrcRequest() will always return success if(!mStateMachine->sendRsrcRequest(GPS_REQUEST_AGPS_DATA_CONN)) { // move the state to PENDING nextState = mPendingState; } } break; case RSRC_UNSUBSCRIBE: { // the list should really be empty, nothing to remove. // but we might as well just tell the client it is // unsubscribed. False tolerance, right? Subscriber* subscriber = (Subscriber*) data; Notification notification(subscriber, event, false); subscriber->notifyRsrcStatus(notification); } // break; case RSRC_GRANTED: case RSRC_RELEASED: case RSRC_DENIED: default: LOC_LOGW("%s: unrecognized event %d", whoami(), event); // no state change. break; } LOC_LOGD("onRsrcEvent, old state %s, new state %s, event %d", whoami(), nextState->whoami(), event); return nextState; }
AgpsState* AgpsReleasingState::onRsrcEvent(AgpsRsrcStatus event, void* data) { AgpsState* nextState = this;; switch (event) { case RSRC_SUBSCRIBE: { // already requested for NIF resource, // do nothing until we get RSRC_GRANTED indication // but we need to add subscriber to the list mStateMachine->addSubscriber((Subscriber*)data); // no state change. } break; case RSRC_UNSUBSCRIBE: { Subscriber* subscriber = (Subscriber*) data; if (subscriber->waitForCloseComplete()) { subscriber->setInactive(); } else { // auto notify this subscriber of the unsubscribe Notification notification(subscriber, event, true); mStateMachine->notifySubscribers(notification); } // now check if there is any subscribers left if (!mStateMachine->hasSubscribers()) { // no more subscribers, move to RELEASED state nextState = mReleasedState; } } break; case RSRC_DENIED: // A race condition subscriber unsubscribes before AFW denies resource. case RSRC_RELEASED: { nextState = mAcquiredState; Notification notification(Notification::BROADCAST_INACTIVE, event, true); // notify all subscribers that are active NIF resource RELEASE // by setting false, we keep subscribers on the linked list mStateMachine->notifySubscribers(notification); if (mStateMachine->hasSubscribers()) { nextState = mPendingState; // request from connecivity service for NIF mStateMachine->sendRsrcRequest(GPS_REQUEST_AGPS_DATA_CONN); } else { nextState = mReleasedState; } } break; case RSRC_GRANTED: default: LOC_LOGE("%s: unrecognized event %d", whoami(), event); // no state change. } LOC_LOGD("onRsrcEvent, old state %s, new state %s, event %d", whoami(), nextState->whoami(), event); return nextState; }
AgpsState* AgpsAcquiredState::onRsrcEvent(AgpsRsrcStatus event, void* data) { AgpsState* nextState = this; switch (event) { case RSRC_SUBSCRIBE: { // we already have the NIF resource, simply notify subscriber Subscriber* subscriber = (Subscriber*) data; // we have rsrc in hand, so grant it right away Notification notification(subscriber, RSRC_GRANTED, false); subscriber->notifyRsrcStatus(notification); // add subscriber to the list mStateMachine->addSubscriber(subscriber); // no state change. } break; case RSRC_UNSUBSCRIBE: { Subscriber* subscriber = (Subscriber*) data; if (subscriber->waitForCloseComplete()) { subscriber->setInactive(); } else { // auto notify this subscriber of the unsubscribe Notification notification(subscriber, event, true); mStateMachine->notifySubscribers(notification); } // now check if there is any subscribers left if (!mStateMachine->hasSubscribers()) { // no more subscribers, move to RELEASED state nextState = mReleasedState; // tell connecivity service we can release NIF mStateMachine->sendRsrcRequest(GPS_RELEASE_AGPS_DATA_CONN); } else if (!mStateMachine->hasActiveSubscribers()) { // only inactive subscribers, move to RELEASING state nextState = mReleasingState; // tell connecivity service we can release NIF mStateMachine->sendRsrcRequest(GPS_RELEASE_AGPS_DATA_CONN); } } break; case RSRC_GRANTED: LOC_LOGW("%s: %d, RSRC_GRANTED already received", whoami(), event); // no state change. break; case RSRC_RELEASED: { LOC_LOGW("%s: %d, a force rsrc release", whoami(), event); nextState = mReleasedState; Notification notification(Notification::BROADCAST_ALL, event, true); // by setting true, we remove subscribers from the linked list mStateMachine->notifySubscribers(notification); } break; case RSRC_DENIED: // no state change. // we are expecting RELEASED. Handling DENIED // may like break our state machine in race conditions. break; default: LOC_LOGE("%s: unrecognized event %d", whoami(), event); // no state change. } LOC_LOGD("onRsrcEvent, old state %s, new state %s, event %d", whoami(), nextState->whoami(), event); return nextState; }
AgpsState* AgpsPendingState::onRsrcEvent(AgpsRsrcStatus event, void* data) { AgpsState* nextState = this;; switch (event) { case RSRC_SUBSCRIBE: { // already requested for NIF resource, // do nothing until we get RSRC_GRANTED indication // but we need to add subscriber to the list mStateMachine->addSubscriber((Subscriber*)data); // no state change. } break; case RSRC_UNSUBSCRIBE: { Subscriber* subscriber = (Subscriber*) data; if (subscriber->waitForCloseComplete()) { subscriber->setInactive(); } else { // auto notify this subscriber of the unsubscribe Notification notification(subscriber, event, true); mStateMachine->notifySubscribers(notification); } // now check if there is any subscribers left if (!mStateMachine->hasSubscribers()) { // no more subscribers, move to RELEASED state nextState = mReleasedState; // tell connecivity service we can release NIF mStateMachine->sendRsrcRequest(GPS_RELEASE_AGPS_DATA_CONN); } else if (!mStateMachine->hasActiveSubscribers()) { // only inactive subscribers, move to RELEASING state nextState = mReleasingState; // tell connecivity service we can release NIF mStateMachine->sendRsrcRequest(GPS_RELEASE_AGPS_DATA_CONN); } } break; case RSRC_GRANTED: { nextState = mAcquiredState; Notification notification(Notification::BROADCAST_ACTIVE, event, false); // notify all subscribers NIF resource GRANTED // by setting false, we keep subscribers on the linked list mStateMachine->notifySubscribers(notification); } break; case RSRC_RELEASED: // no state change. // we are expecting either GRANTED or DENIED. Handling RELEASED // may like break our state machine in race conditions. break; case RSRC_DENIED: { nextState = mReleasedState; Notification notification(Notification::BROADCAST_ALL, event, true); // notify all subscribers NIF resource RELEASED or DENIED // by setting true, we remove subscribers from the linked list mStateMachine->notifySubscribers(notification); } break; default: LOC_LOGE("%s: unrecognized event %d", whoami(), event); // no state change. } LOC_LOGD("onRsrcEvent, old state %s, new state %s, event %d", whoami(), nextState->whoami(), event); return nextState; }