Improve wakelock symantics in RIL.
am: 6ff9a87b25
* commit '6ff9a87b250598ea9e383f06a4257512bd0c8046':
Improve wakelock symantics in RIL.
diff --git a/include/telephony/ril.h b/include/telephony/ril.h
index f7141cc..cfa7138 100644
--- a/include/telephony/ril.h
+++ b/include/telephony/ril.h
@@ -60,11 +60,12 @@
* RIL_VERSION = 12 : This version corresponds to updated data structures namely
* RIL_Data_Call_Response_v11, RIL_SIM_IO_v6, RIL_CardStatus_v6,
* RIL_SimRefreshResponse_v7, RIL_CDMA_CallWaiting_v6,
- * RIL_LTE_SignalStrength_v8, RIL_SignalStrength_v10, RIL_SignalStrength_v10,
- * RIL_CellIdentityGsm_v12, RIL_CellIdentityWcdma_v12, RIL_CellIdentityLte_v12,
- * RIL_CellInfoGsm_v12, RIL_CellInfoWcdma_v12, RIL_CellInfoLte_v12, RIL_CellInfo_v12.
+ * RIL_LTE_SignalStrength_v8, RIL_SignalStrength_v10, RIL_CellIdentityGsm_v12
+ * RIL_CellIdentityWcdma_v12, RIL_CellIdentityLte_v12,RIL_CellInfoGsm_v12,
+ * RIL_CellInfoWcdma_v12, RIL_CellInfoLte_v12, RIL_CellInfo_v12.
*
- * RIL_VERSION = 13 : This version includes new wakelock semantics.
+ * RIL_VERSION = 13 : This version includes new wakelock semantics and as the first
+ * strongly versioned version it enforces structure use.
*/
#define RIL_VERSION 12
#define LAST_IMPRECISE_RIL_VERSION 12 // Better self-documented name
@@ -4618,6 +4619,22 @@
/***********************************************************************/
+/**
+ * RIL_RESPONSE_ACKNOWLEDGEMENT
+ *
+ * This is used by Asynchronous solicited messages and Unsolicited messages
+ * to acknowledge the receipt of those messages in RIL.java so that the ack
+ * can be used to let ril.cpp to release wakelock.
+ *
+ * Valid errors
+ * SUCCESS
+ * RADIO_NOT_AVAILABLE
+ */
+
+#define RIL_RESPONSE_ACKNOWLEDGEMENT 800
+
+/***********************************************************************/
+
#define RIL_UNSOL_RESPONSE_BASE 1000
@@ -5368,6 +5385,13 @@
void (*RequestTimedCallback) (RIL_TimedCallback callback,
void *param, const struct timeval *relativeTime);
+ /**
+ * "t" is parameter passed in on previous call RIL_Notification routine
+ *
+ * RIL_onRequestAck will be called by vendor when an Async RIL request was received
+ * by them and an ack needs to be sent back to java ril.
+ */
+ void (*OnRequestAck) (RIL_Token t);
};
@@ -5408,6 +5432,18 @@
void RIL_onRequestComplete(RIL_Token t, RIL_Errno e,
void *response, size_t responselen);
+/**
+ * RIL_onRequestAck will be called by vendor when an Async RIL request was received by them and
+ * an ack needs to be sent back to java ril. This doesn't mark the end of the command or it's
+ * results, just that the command was received and will take a while. After sending this Ack
+ * its vendor's responsibility to make sure that AP is up whenever needed while command is
+ * being processed.
+ *
+ * @param t is parameter passed in on previous call to RIL_Notification
+ * routine.
+ */
+void RIL_onRequestAck(RIL_Token t);
+
#if defined(ANDROID_MULTI_SIM)
/**
* @param unsolResponse is one of RIL_UNSOL_RESPONSE_*
diff --git a/libril/ril.cpp b/libril/ril.cpp
index 6fb7b8b..ff4ebc5 100755
--- a/libril/ril.cpp
+++ b/libril/ril.cpp
@@ -51,6 +51,9 @@
extern "C" void
RIL_onRequestComplete(RIL_Token t, RIL_Errno e, void *response, size_t responselen);
+
+extern "C" void
+RIL_onRequestAck(RIL_Token t);
namespace android {
#define PHONE_PROCESS "radio"
@@ -85,6 +88,8 @@
/* Constants for response types */
#define RESPONSE_SOLICITED 0
#define RESPONSE_UNSOLICITED 1
+#define RESPONSE_SOLICITED_ACK 2
+#define RESPONSE_SOLICITED_ACK_EXP 3
/* Negative values for private RIL errno's */
#define RIL_ERRNO_INVALID_RESPONSE -1
@@ -144,6 +149,7 @@
char cancelled;
char local; // responses to local commands do not go back to command process
RIL_SOCKET_ID socket_id;
+ int wasAckSent; // Indicates whether an ack was sent earlier
} RequestInfo;
typedef struct UserCallbackInfo {
@@ -176,6 +182,8 @@
static int s_fdWakeupRead;
static int s_fdWakeupWrite;
+int s_wakelock_count = 0;
+
static struct ril_event s_commands_event;
static struct ril_event s_wakeupfd_event;
static struct ril_event s_listen_event;
@@ -183,6 +191,7 @@
static pthread_mutex_t s_pendingRequestsMutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t s_writeMutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t s_wakeLockCountMutex = PTHREAD_MUTEX_INITIALIZER;
static RequestInfo *s_pendingRequests = NULL;
#if (SIM_COUNT >= 2)
@@ -308,6 +317,9 @@
static int decodeVoiceRadioTechnology (RIL_RadioState radioState);
static int decodeCdmaSubscriptionSource (RIL_RadioState radioState);
static RIL_RadioState processRadioState(RIL_RadioState newRadioState);
+static void grabPartialWakeLock();
+static void releaseWakeLock();
+static void wakeTimeoutCallback(void *);
static bool isServiceTypeCfQuery(RIL_SsServiceType serType, RIL_SsRequestType reqType);
@@ -528,6 +540,13 @@
return 0;
}
+ // Received an Ack for the previous result sent to RIL.java,
+ // so release wakelock and exit
+ if (request == RIL_RESPONSE_ACKNOWLEDGEMENT) {
+ releaseWakeLock();
+ return 0;
+ }
+
pRI = (RequestInfo *)calloc(1, sizeof(RequestInfo));
@@ -4796,8 +4815,9 @@
}
}
+// Check and remove RequestInfo if its a response and not just ack sent back
static int
-checkAndDequeueRequestInfo(struct RequestInfo *pRI) {
+checkAndDequeueRequestInfoIfAck(struct RequestInfo *pRI, bool isAck) {
int ret = 0;
/* Hook for current context
pendingRequestsMutextHook refer to &s_pendingRequestsMutex */
@@ -4835,8 +4855,15 @@
) {
if (pRI == *ppCur) {
ret = 1;
-
- *ppCur = (*ppCur)->p_next;
+ if (isAck) { // Async ack
+ if (pRI->wasAckSent == 1) {
+ RLOGD("Ack was already sent for %s", requestToString(pRI->pCI->requestNumber));
+ } else {
+ pRI->wasAckSent = 1;
+ }
+ } else {
+ *ppCur = (*ppCur)->p_next;
+ }
break;
}
}
@@ -4846,31 +4873,16 @@
return ret;
}
-
-extern "C" void
-RIL_onRequestComplete(RIL_Token t, RIL_Errno e, void *response, size_t responselen) {
- RequestInfo *pRI;
- int ret;
+static int findFd(int socket_id) {
int fd = s_ril_param_socket.fdCommand;
- size_t errorOffset;
- RIL_SOCKET_ID socket_id = RIL_SOCKET_1;
-
- pRI = (RequestInfo *)t;
-
- if (!checkAndDequeueRequestInfo(pRI)) {
- RLOGE ("RIL_onRequestComplete: invalid RIL_Token");
- return;
- }
-
- socket_id = pRI->socket_id;
#if (SIM_COUNT >= 2)
if (socket_id == RIL_SOCKET_2) {
fd = s_ril_param_socket2.fdCommand;
}
#if (SIM_COUNT >= 3)
- if (socket_id == RIL_SOCKET_3) {
- fd = s_ril_param_socket3.fdCommand;
- }
+ if (socket_id == RIL_SOCKET_3) {
+ fd = s_ril_param_socket3.fdCommand;
+ }
#endif
#if (SIM_COUNT >= 4)
if (socket_id == RIL_SOCKET_4) {
@@ -4878,6 +4890,65 @@
}
#endif
#endif
+ return fd;
+}
+
+extern "C" void
+RIL_onRequestAck(RIL_Token t) {
+ RequestInfo *pRI;
+ int ret, fd;
+
+ size_t errorOffset;
+ RIL_SOCKET_ID socket_id = RIL_SOCKET_1;
+
+ pRI = (RequestInfo *)t;
+
+ if (!checkAndDequeueRequestInfoIfAck(pRI, true)) {
+ RLOGE ("RIL_onRequestAck: invalid RIL_Token");
+ return;
+ }
+
+ socket_id = pRI->socket_id;
+ fd = findFd(socket_id);
+
+#if VDBG
+ RLOGD("Request Ack, %s", rilSocketIdToString(socket_id));
+#endif
+
+ appendPrintBuf("Ack [%04d]< %s", pRI->token, requestToString(pRI->pCI->requestNumber));
+
+ if (pRI->cancelled == 0) {
+ Parcel p;
+
+ p.writeInt32 (RESPONSE_SOLICITED_ACK);
+ p.writeInt32 (pRI->token);
+
+ if (fd < 0) {
+ RLOGD ("RIL onRequestComplete: Command channel closed");
+ }
+
+ sendResponse(p, socket_id);
+ }
+}
+
+extern "C" void
+RIL_onRequestComplete(RIL_Token t, RIL_Errno e, void *response, size_t responselen) {
+ RequestInfo *pRI;
+ int ret;
+ int fd;
+ size_t errorOffset;
+ RIL_SOCKET_ID socket_id = RIL_SOCKET_1;
+
+ pRI = (RequestInfo *)t;
+
+ if (!checkAndDequeueRequestInfoIfAck(pRI, false)) {
+ RLOGE ("RIL_onRequestComplete: invalid RIL_Token");
+ return;
+ }
+
+ socket_id = pRI->socket_id;
+ fd = findFd(socket_id);
+
#if VDBG
RLOGD("RequestComplete, %s", rilSocketIdToString(socket_id));
#endif
@@ -4896,7 +4967,14 @@
if (pRI->cancelled == 0) {
Parcel p;
- p.writeInt32 (RESPONSE_SOLICITED);
+ if (s_callbacks.version >= 13 && pRI->wasAckSent == 1) {
+ // If ack was already sent, then this call is an asynchronous response. So we need to
+ // send id indicating that we expect an ack from RIL.java as we acquire wakelock here.
+ p.writeInt32 (RESPONSE_SOLICITED_ACK_EXP);
+ grabPartialWakeLock();
+ } else {
+ p.writeInt32 (RESPONSE_SOLICITED);
+ }
p.writeInt32 (pRI->token);
errorOffset = p.dataPosition();
@@ -4928,15 +5006,50 @@
free(pRI);
}
-
static void
grabPartialWakeLock() {
- acquire_wake_lock(PARTIAL_WAKE_LOCK, ANDROID_WAKE_LOCK_NAME);
+ if (s_callbacks.version >= 13) {
+ int ret;
+ ret = pthread_mutex_lock(&s_wakeLockCountMutex);
+ assert(ret == 0);
+ acquire_wake_lock(PARTIAL_WAKE_LOCK, ANDROID_WAKE_LOCK_NAME);
+ s_wakelock_count++;
+ if (s_last_wake_timeout_info != NULL) {
+ s_last_wake_timeout_info->userParam = (void *)1;
+ }
+
+ s_last_wake_timeout_info
+ = internalRequestTimedCallback(wakeTimeoutCallback, NULL, &TIMEVAL_WAKE_TIMEOUT);
+
+ ret = pthread_mutex_unlock(&s_wakeLockCountMutex);
+ assert(ret == 0);
+ } else {
+ acquire_wake_lock(PARTIAL_WAKE_LOCK, ANDROID_WAKE_LOCK_NAME);
+ }
}
static void
releaseWakeLock() {
- release_wake_lock(ANDROID_WAKE_LOCK_NAME);
+ if (s_callbacks.version >= 13) {
+ int ret;
+ ret = pthread_mutex_lock(&s_wakeLockCountMutex);
+ assert(ret == 0);
+
+ if (s_wakelock_count > 1) {
+ s_wakelock_count--;
+ } else {
+ s_wakelock_count = 0;
+ release_wake_lock(ANDROID_WAKE_LOCK_NAME);
+ if (s_last_wake_timeout_info != NULL) {
+ s_last_wake_timeout_info->userParam = (void *)1;
+ }
+ }
+
+ ret = pthread_mutex_unlock(&s_wakeLockCountMutex);
+ assert(ret == 0);
+ } else {
+ release_wake_lock(ANDROID_WAKE_LOCK_NAME);
+ }
}
/**
@@ -4945,8 +5058,20 @@
static void
wakeTimeoutCallback (void *param) {
// We're using "param != NULL" as a cancellation mechanism
- if (param == NULL) {
- releaseWakeLock();
+ if (s_callbacks.version >= 13) {
+ if (param == NULL) {
+ int ret;
+ ret = pthread_mutex_lock(&s_wakeLockCountMutex);
+ assert(ret == 0);
+ s_wakelock_count = 0;
+ release_wake_lock(ANDROID_WAKE_LOCK_NAME);
+ ret = pthread_mutex_unlock(&s_wakeLockCountMutex);
+ assert(ret == 0);
+ }
+ } else {
+ if (param == NULL) {
+ releaseWakeLock();
+ }
}
}
@@ -5131,7 +5256,6 @@
appendPrintBuf("[UNSL]< %s", requestToString(unsolResponse));
Parcel p;
-
p.writeInt32 (RESPONSE_UNSOLICITED);
p.writeInt32 (unsolResponse);
@@ -5183,18 +5307,17 @@
memcpy(s_lastNITZTimeData, p.data(), p.dataSize());
}
- // For now, we automatically go back to sleep after TIMEVAL_WAKE_TIMEOUT
- // FIXME The java code should handshake here to release wake lock
+ if (s_callbacks.version < 13) {
+ if (shouldScheduleTimeout) {
+ // Cancel the previous request
+ if (s_last_wake_timeout_info != NULL) {
+ s_last_wake_timeout_info->userParam = (void *)1;
+ }
- if (shouldScheduleTimeout) {
- // Cancel the previous request
- if (s_last_wake_timeout_info != NULL) {
- s_last_wake_timeout_info->userParam = (void *)1;
+ s_last_wake_timeout_info
+ = internalRequestTimedCallback(wakeTimeoutCallback, NULL,
+ &TIMEVAL_WAKE_TIMEOUT);
}
-
- s_last_wake_timeout_info
- = internalRequestTimedCallback(wakeTimeoutCallback, NULL,
- &TIMEVAL_WAKE_TIMEOUT);
}
// Normal exit
@@ -5480,6 +5603,7 @@
case RIL_UNSOL_DC_RT_INFO_CHANGED: return "UNSOL_DC_RT_INFO_CHANGED";
case RIL_REQUEST_SHUTDOWN: return "SHUTDOWN";
case RIL_UNSOL_RADIO_CAPABILITY: return "RIL_UNSOL_RADIO_CAPABILITY";
+ case RIL_RESPONSE_ACKNOWLEDGEMENT: return "RIL_RESPONSE_ACKNOWLEDGEMENT";
default: return "<unknown request>";
}
}
diff --git a/rild/rild.c b/rild/rild.c
index bf9c421..b10329b 100644
--- a/rild/rild.c
+++ b/rild/rild.c
@@ -58,6 +58,8 @@
extern void RIL_onRequestComplete(RIL_Token t, RIL_Errno e,
void *response, size_t responselen);
+extern void RIL_onRequestAck(RIL_Token t);
+
extern void RIL_setRilSocketName(char *);
#if defined(ANDROID_MULTI_SIM)
@@ -75,7 +77,8 @@
static struct RIL_Env s_rilEnv = {
RIL_onRequestComplete,
RIL_onUnsolicitedResponse,
- RIL_requestTimedCallback
+ RIL_requestTimedCallback,
+ RIL_onRequestAck
};
extern void RIL_startEventLoop();