Hold a wake lock while events are pending for the deferred action thread.

Signed-off-by: Mike Lockwood <lockwood@android.com>
diff --git a/loc_api/libloc_api/loc_eng.cpp b/loc_api/libloc_api/loc_eng.cpp
index 514328c..46827ef 100755
--- a/loc_api/libloc_api/loc_eng.cpp
+++ b/loc_api/libloc_api/loc_eng.cpp
@@ -91,8 +91,7 @@
 static void loc_eng_process_conn_request (const rpc_loc_server_request_s_type *server_request_ptr);
 
 static void* loc_eng_process_deferred_action (void* arg);
-static void loc_eng_process_atl_deferred_action (boolean data_connection_succeeded,
-        boolean data_connection_closed);
+static void loc_eng_process_atl_deferred_action (int flags);
 static void loc_eng_delete_aiding_data_deferred_action (void);
 
 static int set_agps_server();
@@ -182,10 +181,12 @@
     memset (&loc_eng_data, 0, sizeof (loc_eng_data_s_type));
 
     // LOC ENG module data initialization
-    loc_eng_data.location_cb  = callbacks->location_cb;
-    loc_eng_data.sv_status_cb = callbacks->sv_status_cb;
-    loc_eng_data.status_cb    = callbacks->status_cb;
-    loc_eng_data.nmea_cb    = callbacks->nmea_cb;
+    loc_eng_data.location_cb    = callbacks->location_cb;
+    loc_eng_data.sv_status_cb   = callbacks->sv_status_cb;
+    loc_eng_data.status_cb      = callbacks->status_cb;
+    loc_eng_data.nmea_cb        = callbacks->nmea_cb;
+    loc_eng_data.acquire_wakelock_cb = callbacks->acquire_wakelock_cb;
+    loc_eng_data.release_wakelock_cb = callbacks->release_wakelock_cb;
 
     rpc_loc_event_mask_type event = RPC_LOC_EVENT_PARSED_POSITION_REPORT |
                                     RPC_LOC_EVENT_SATELLITE_REPORT |
@@ -200,12 +201,9 @@
 
     pthread_mutex_init (&(loc_eng_data.deferred_action_mutex), NULL);
     pthread_cond_init  (&(loc_eng_data.deferred_action_cond) , NULL);
-    loc_eng_data.deferred_action_thread_need_exit = FALSE;
  
     loc_eng_data.loc_event = 0;
-    loc_eng_data.data_connection_succeeded = FALSE;
-    loc_eng_data.data_connection_closed = FALSE;
-    loc_eng_data.data_connection_failed = FALSE;
+    loc_eng_data.deferred_action_flags = 0;
     memset (loc_eng_data.apn_name, 0, sizeof (loc_eng_data.apn_name));
 
     loc_eng_data.aiding_data_for_deletion = 0;
@@ -256,10 +254,12 @@
     if (loc_eng_data.deferred_action_thread)
     {
         /* Terminate deferred action working thread */
-        pthread_mutex_lock (&loc_eng_data.deferred_action_mutex);
-        loc_eng_data.deferred_action_thread_need_exit = TRUE;
-        pthread_cond_signal  (&loc_eng_data.deferred_action_cond);
-        pthread_mutex_unlock (&loc_eng_data.deferred_action_mutex);
+        pthread_mutex_lock(&loc_eng_data.deferred_action_mutex);
+        /* hold a wake lock while events are pending for deferred_action_thread */
+        loc_eng_data.acquire_wakelock_cb();
+        loc_eng_data.deferred_action_flags |= DEFERRED_ACTION_QUIT;
+        pthread_cond_signal(&loc_eng_data.deferred_action_cond);
+        pthread_mutex_unlock(&loc_eng_data.deferred_action_mutex);
 
         void* ignoredValue;
         pthread_join(loc_eng_data.deferred_action_thread, &ignoredValue);
@@ -520,6 +520,9 @@
     if ((loc_eng_data.engine_status != GPS_STATUS_SESSION_BEGIN) &&
         (loc_eng_data.aiding_data_for_deletion != 0))
     {
+        /* hold a wake lock while events are pending for deferred_action_thread */
+        loc_eng_data.acquire_wakelock_cb();
+        loc_eng_data.deferred_action_flags |= DEFERRED_ACTION_DELETE_AIDING;
         pthread_cond_signal(&(loc_eng_data.deferred_action_cond));
 
         // In case gps engine is ON, the assistance data will be deleted when the engine is OFF
@@ -666,8 +669,11 @@
         loc_eng_data.loc_event = loc_event;
         memcpy(&loc_eng_data.loc_event_payload, loc_event_payload, sizeof(*loc_event_payload));
 
-        pthread_cond_signal  (&loc_eng_data.deferred_action_cond);
-        pthread_mutex_unlock (&loc_eng_data.deferred_action_mutex);
+        /* hold a wake lock while events are pending for deferred_action_thread */
+        loc_eng_data.acquire_wakelock_cb();
+        loc_eng_data.deferred_action_flags |= DEFERRED_ACTION_EVENT;
+        pthread_cond_signal(&loc_eng_data.deferred_action_cond);
+        pthread_mutex_unlock(&loc_eng_data.deferred_action_mutex);
     }
     else
     {
@@ -919,18 +925,21 @@
         }
     }
 
-    pthread_mutex_lock (&loc_eng_data.deferred_action_mutex);
+    pthread_mutex_lock(&loc_eng_data.deferred_action_mutex);
     loc_eng_data.engine_status = status.status;
 
     // Wake up the thread for aiding data deletion.
     if ((loc_eng_data.engine_status != GPS_STATUS_SESSION_BEGIN) &&
         (loc_eng_data.aiding_data_for_deletion != 0))
     {
+        /* hold a wake lock while events are pending for deferred_action_thread */
+        loc_eng_data.acquire_wakelock_cb();
+        loc_eng_data.deferred_action_flags |= DEFERRED_ACTION_DELETE_AIDING;
         pthread_cond_signal(&(loc_eng_data.deferred_action_cond));
         // In case gps engine is ON, the assistance data will be deleted when the engine is OFF
     }
 
-    pthread_mutex_unlock (&loc_eng_data.deferred_action_mutex);
+    pthread_mutex_unlock(&loc_eng_data.deferred_action_mutex);
 }
 
 static void loc_eng_report_nmea (const rpc_loc_nmea_report_s_type *nmea_report_ptr)
@@ -982,8 +991,11 @@
         loc_eng_data.agps_status = GPS_RELEASE_AGPS_DATA_CONN;
     }
 
-    pthread_cond_signal  (&loc_eng_data.deferred_action_cond);
-    pthread_mutex_unlock (&loc_eng_data.deferred_action_mutex);
+    /* hold a wake lock while events are pending for deferred_action_thread */
+    loc_eng_data.acquire_wakelock_cb();
+    loc_eng_data.deferred_action_flags |= DEFERRED_ACTION_AGPS_STATUS;
+    pthread_cond_signal(&loc_eng_data.deferred_action_cond);
+    pthread_mutex_unlock(&loc_eng_data.deferred_action_mutex);
 }
 
 /*===========================================================================
@@ -1014,7 +1026,6 @@
     LOGD("loc_eng_agps_data_conn_open: %s\n", apn);
 
     pthread_mutex_lock(&(loc_eng_data.deferred_action_mutex));
-    loc_eng_data.data_connection_succeeded = TRUE;
 
     if (apn != NULL)
     {
@@ -1030,6 +1041,9 @@
         loc_eng_data.apn_name[apn_len] = '\0';
     }
 
+    /* hold a wake lock while events are pending for deferred_action_thread */
+    loc_eng_data.acquire_wakelock_cb();
+    loc_eng_data.deferred_action_flags |= DEFERRED_ACTION_AGPS_DATA_SUCCESS;
     pthread_cond_signal(&(loc_eng_data.deferred_action_cond));
     pthread_mutex_unlock(&(loc_eng_data.deferred_action_mutex));
     return 0;
@@ -1039,8 +1053,9 @@
 {
     LOGD("loc_eng_agps_data_conn_closed\n");
     pthread_mutex_lock(&(loc_eng_data.deferred_action_mutex));
-    loc_eng_data.data_connection_closed = TRUE;
-// DO WE NEED TO SIGNAL HERE?
+    /* hold a wake lock while events are pending for deferred_action_thread */
+    loc_eng_data.acquire_wakelock_cb();
+    loc_eng_data.deferred_action_flags |= DEFERRED_ACTION_AGPS_DATA_CLOSED;
     pthread_cond_signal(&(loc_eng_data.deferred_action_cond));
     pthread_mutex_unlock(&(loc_eng_data.deferred_action_mutex));
     return 0;
@@ -1051,7 +1066,9 @@
     LOGD("loc_eng_agps_data_conn_failed\n");
 
     pthread_mutex_lock(&(loc_eng_data.deferred_action_mutex));
-    loc_eng_data.data_connection_failed = TRUE;
+    /* hold a wake lock while events are pending for deferred_action_thread */
+    loc_eng_data.acquire_wakelock_cb();
+    loc_eng_data.deferred_action_flags |= DEFERRED_ACTION_AGPS_DATA_FAILED;
     pthread_cond_signal(&(loc_eng_data.deferred_action_cond));
     pthread_mutex_unlock(&(loc_eng_data.deferred_action_mutex));
     return 0;
@@ -1185,8 +1202,7 @@
    N/A
 
 ===========================================================================*/
-static void loc_eng_process_atl_deferred_action (boolean data_connection_succeeded,
-        boolean data_connection_closed)
+static void loc_eng_process_atl_deferred_action (int flags)
 {
     rpc_loc_server_open_status_s_type  *conn_open_status_ptr;
     rpc_loc_server_close_status_s_type *conn_close_status_ptr;
@@ -1198,7 +1214,7 @@
 
     memset (&ioctl_data, 0, sizeof (rpc_loc_ioctl_data_u_type));
  
-    if (data_connection_closed)
+    if (flags & DEFERRED_ACTION_AGPS_DATA_CLOSED)
     {
         ioctl_data.disc = RPC_LOC_IOCTL_INFORM_SERVER_CLOSE_STATUS;
         conn_close_status_ptr = &(ioctl_data.rpc_loc_ioctl_data_u_type_u.conn_close_status);
@@ -1210,7 +1226,7 @@
         ioctl_data.disc = RPC_LOC_IOCTL_INFORM_SERVER_OPEN_STATUS;
         conn_open_status_ptr = &ioctl_data.rpc_loc_ioctl_data_u_type_u.conn_open_status;
         conn_open_status_ptr->conn_handle = loc_eng_data.conn_handle;
-        if (data_connection_succeeded)
+        if (flags & DEFERRED_ACTION_AGPS_DATA_SUCCESS)
         {
             conn_open_status_ptr->open_status = RPC_LOC_SERVER_OPEN_SUCCESS;
             // Both buffer are of the same maximum size, and the source is null terminated
@@ -1352,23 +1368,24 @@
     LOGD("Setting GPS privacy lock to RPC_LOC_LOCK_NONE\n");
     loc_eng_set_gps_lock(RPC_LOC_LOCK_NONE);
 
-    while (loc_eng_data.deferred_action_thread_need_exit == FALSE)
+    while (1)
     {
         GpsAidingData   aiding_data_for_deletion;
         GpsStatusValue  engine_status;
-        boolean         data_connection_succeeded;
-        boolean         data_connection_closed;
-        boolean         data_connection_failed;
 
         rpc_loc_event_mask_type         loc_event;
         rpc_loc_event_payload_u_type    loc_event_payload;
 
         // Wait until we are signalled to do a deferred action, or exit
         pthread_mutex_lock(&loc_eng_data.deferred_action_mutex);
+
+        if (loc_eng_data.deferred_action_flags == 0)
+            loc_eng_data.release_wakelock_cb();
+
         pthread_cond_wait(&loc_eng_data.deferred_action_cond,
                             &loc_eng_data.deferred_action_mutex);
 
-        if (loc_eng_data.deferred_action_thread_need_exit == TRUE)
+        if (loc_eng_data.deferred_action_flags & DEFERRED_ACTION_QUIT)
         {
             pthread_mutex_unlock(&loc_eng_data.deferred_action_mutex);
             break;
@@ -1381,16 +1398,12 @@
             loc_eng_data.loc_event = 0;
         }
 
+        int flags = loc_eng_data.deferred_action_flags;
+        loc_eng_data.deferred_action_flags = 0;
         engine_status = loc_eng_data.agps_status;
         aiding_data_for_deletion = loc_eng_data.aiding_data_for_deletion;
         status.status = loc_eng_data.agps_status;
         loc_eng_data.agps_status = 0;
-        data_connection_succeeded = loc_eng_data.data_connection_succeeded;
-        data_connection_closed = loc_eng_data.data_connection_closed;
-        data_connection_failed = loc_eng_data.data_connection_failed;
-        loc_eng_data.data_connection_closed = FALSE;
-        loc_eng_data.data_connection_succeeded = FALSE;
-        loc_eng_data.data_connection_failed = FALSE;
 
         // perform all actions after releasing the mutex to avoid blocking RPCs from the ARM9
         pthread_mutex_unlock(&(loc_eng_data.deferred_action_mutex));
@@ -1405,15 +1418,16 @@
             loc_eng_delete_aiding_data_deferred_action ();
         }
 
-        if (data_connection_succeeded || data_connection_closed || data_connection_failed)
+        if (flags & (DEFERRED_ACTION_AGPS_DATA_SUCCESS |
+                     DEFERRED_ACTION_AGPS_DATA_CLOSED |
+                     DEFERRED_ACTION_AGPS_DATA_FAILED))
         {
-            loc_eng_process_atl_deferred_action(data_connection_succeeded, data_connection_closed);
+            loc_eng_process_atl_deferred_action(flags);
         }
 
         if (status.status != 0 && loc_eng_data.agps_status_cb) {
             loc_eng_data.agps_status_cb(&status);
         }
-
     }
 
     // reenable the GPS lock
@@ -1421,6 +1435,7 @@
     loc_eng_set_gps_lock(RPC_LOC_LOCK_ALL);
 
     LOGD("loc_eng_process_deferred_action thread exiting\n");
+    loc_eng_data.release_wakelock_cb();
     return NULL;
 }
 
diff --git a/loc_api/libloc_api/loc_eng.h b/loc_api/libloc_api/loc_eng.h
index f13df31..6a09a37 100755
--- a/loc_api/libloc_api/loc_eng.h
+++ b/loc_api/libloc_api/loc_eng.h
@@ -51,52 +51,62 @@
 
 #define LOC_IOCTL_DEFAULT_TIMEOUT 1000 // 1000 milli-seconds
 
+enum {
+    DEFERRED_ACTION_EVENT               = 0x01,
+    DEFERRED_ACTION_DELETE_AIDING       = 0x02,
+    DEFERRED_ACTION_AGPS_STATUS         = 0x04,
+    DEFERRED_ACTION_AGPS_DATA_SUCCESS   = 0x08,
+    DEFERRED_ACTION_AGPS_DATA_CLOSED    = 0x10,
+    DEFERRED_ACTION_AGPS_DATA_FAILED    = 0x20,
+    DEFERRED_ACTION_QUIT                = 0x40,
+};
+
 // Module data
 typedef struct
 {
-    rpc_loc_client_handle_type     client_handle;
+    rpc_loc_client_handle_type  client_handle;
 
-    gps_location_callback          location_cb;
-    gps_status_callback            status_cb;
-    gps_sv_status_callback         sv_status_cb;
-    agps_status_callback           agps_status_cb;
-    gps_nmea_callback              nmea_cb;
-    gps_ni_notify_callback         ni_notify_cb;
-    int                            agps_status;
+    gps_location_callback           location_cb;
+    gps_status_callback             status_cb;
+    gps_sv_status_callback          sv_status_cb;
+    agps_status_callback            agps_status_cb;
+    gps_nmea_callback               nmea_cb;
+    gps_ni_notify_callback          ni_notify_cb;
+    gps_acquire_wakelock            acquire_wakelock_cb;
+    gps_release_wakelock            release_wakelock_cb;
+    int                             agps_status;
 
-    loc_eng_xtra_data_s_type       xtra_module_data;
+    loc_eng_xtra_data_s_type        xtra_module_data;
 
-    loc_eng_ioctl_data_s_type      ioctl_data;
+    loc_eng_ioctl_data_s_type       ioctl_data;
 
     // data from loc_event_cb
     rpc_loc_event_mask_type         loc_event;
     rpc_loc_event_payload_u_type    loc_event_payload;
 
-    boolean                        data_connection_succeeded;
-    boolean                        data_connection_closed;
-    boolean                        data_connection_failed;
     // TBD:
-    char                           agps_server_host[256];
-    int                            agps_server_port;
-    uint32                         agps_server_address;
-    char                           apn_name[100];
-    int                            position_mode;
+    char                            agps_server_host[256];
+    int                             agps_server_port;
+    uint32                          agps_server_address;
+    char                            apn_name[100];
+    int                             position_mode;
     rpc_loc_server_connection_handle  conn_handle;
 
     // GPS engine status
-    GpsStatusValue                 engine_status;
+    GpsStatusValue                  engine_status;
 
     // Aiding data information to be deleted, aiding data can only be deleted when GPS engine is off
-    GpsAidingData                  aiding_data_for_deletion;
+    GpsAidingData                   aiding_data_for_deletion;
 
     // Data variables used by deferred action thread
-    pthread_t                      deferred_action_thread;
-    // Signal deferred action thread to exit
-    boolean                        deferred_action_thread_need_exit;
+    pthread_t                       deferred_action_thread;
     // Mutex used by deferred action thread
-    pthread_mutex_t                deferred_action_mutex;
+    pthread_mutex_t                 deferred_action_mutex;
     // Condition variable used by deferred action thread
-    pthread_cond_t                 deferred_action_cond;
+    pthread_cond_t                  deferred_action_cond;
+
+    // flags for pending events for deferred action thread
+    int                             deferred_action_flags;
 } loc_eng_data_s_type;
    
 extern loc_eng_data_s_type loc_eng_data;