/**
  * The call() method that broadcast intents before the measurement starts and after the
  * measurement finishes.
  */
 @Override
 public MeasurementResult[] call() throws MeasurementError {
   MeasurementResult[] results = null;
   PhoneUtils phoneUtils = PhoneUtils.getPhoneUtils();
   try {
     phoneUtils.acquireWakeLock();
     broadcastMeasurementStart();
     contextCollector.setInterval(realTask.getDescription().contextIntervalSec);
     contextCollector.startCollector();
     results = realTask.call();
     ArrayList<HashMap<String, String>> contextResults = contextCollector.stopCollector();
     for (MeasurementResult r : results) {
       r.addContextResults(contextResults);
       r.getDeviceProperty().dnResolvability = contextCollector.dnsConnectivity;
       r.getDeviceProperty().ipConnectivity = contextCollector.ipConnectivity;
     }
   } catch (MeasurementError e) {
     Logger.e("User measurement " + realTask.getDescriptor() + " has failed");
     Logger.e(e.getMessage());
     results = MeasurementResult.getFailureResult(realTask, e);
   } catch (Exception e) {
     Logger.e("User measurement " + realTask.getDescriptor() + " has failed");
     Logger.e("Unexpected Exception: " + e.getMessage());
     results = MeasurementResult.getFailureResult(realTask, e);
   } finally {
     broadcastMeasurementEnd(results);
     MeasurementTask currentTask = scheduler.getCurrentTask();
     if (currentTask != null && currentTask.equals(realTask)) {
       scheduler.setCurrentTask(null);
     }
     phoneUtils.releaseWakeLock();
   }
   return results;
 }
 private void doCheckin() {
   Logger.i("doCheckin() called");
   scheduler = parent.getScheduler();
   if (scheduler != null) {
     lastCheckinTimeText.setText("Checking in...");
     scheduler.handleCheckin(true);
   }
 }
 /** Notify the scheduler that this task is started */
 private void broadcastMeasurementStart() {
   Intent intent = new Intent();
   intent.setAction(UpdateIntent.MEASUREMENT_PROGRESS_UPDATE_ACTION);
   intent.putExtra(UpdateIntent.TASK_PRIORITY_PAYLOAD, MeasurementTask.USER_PRIORITY);
   intent.putExtra(UpdateIntent.TASK_STATUS_PAYLOAD, Config.TASK_STARTED);
   intent.putExtra(UpdateIntent.TASKID_PAYLOAD, realTask.getTaskId());
   intent.putExtra(UpdateIntent.CLIENTKEY_PAYLOAD, realTask.getKey());
   scheduler.sendBroadcast(intent);
 }
 private void updateLastCheckinTime() {
   Logger.i("updateLastCheckinTime() called");
   scheduler = parent.getScheduler();
   if (scheduler != null) {
     Date lastCheckin = scheduler.getLastCheckinTime();
     if (lastCheckin != null) {
       lastCheckinTimeText.setText("Last checkin " + lastCheckin);
     } else {
       lastCheckinTimeText.setText("No checkins yet");
     }
   }
 }
 private void updateConsole() {
   Logger.i("updateConsole() called");
   scheduler = parent.getScheduler();
   if (scheduler != null) {
     AbstractCollection<MeasurementTask> tasks = scheduler.getTaskQueue();
     consoleContent.clear();
     taskMap.clear();
     for (MeasurementTask task : tasks) {
       String taskStr = task.toString();
       consoleContent.add(taskStr);
       taskMap.put(taskStr, task.getDescription().key);
     }
   }
   updateLastCheckinTime();
 }
  /**
   * Notify the scheduler that this task is finished executing. The result can be completed, paused
   * or failed due to exception
   *
   * @param results Results of the task
   */
  private void broadcastMeasurementEnd(MeasurementResult[] results) {
    Intent intent = new Intent();
    intent.setAction(UpdateIntent.MEASUREMENT_PROGRESS_UPDATE_ACTION);
    // TODO fixed one value priority for all users task?
    intent.putExtra(UpdateIntent.TASK_PRIORITY_PAYLOAD, MeasurementTask.USER_PRIORITY);
    intent.putExtra(UpdateIntent.TASKID_PAYLOAD, realTask.getTaskId());
    intent.putExtra(UpdateIntent.CLIENTKEY_PAYLOAD, realTask.getKey());

    if (results != null) {
      // TODO only single task can be paused
      if (results[0].getTaskProgress() == TaskProgress.PAUSED) {
        intent.putExtra(UpdateIntent.TASK_STATUS_PAYLOAD, Config.TASK_PAUSED);
      } else {
        intent.putExtra(UpdateIntent.TASK_STATUS_PAYLOAD, Config.TASK_FINISHED);
        intent.putExtra(UpdateIntent.RESULT_PAYLOAD, results);
      }
      scheduler.sendBroadcast(intent);
    }
  }
 /** Handles the deletion of the measurement tasks when the user clicks the context menu */
 @Override
 public boolean onContextItemSelected(MenuItem item) {
   AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
   switch (item.getItemId()) {
     case R.id.ctxMenuDeleteTask:
       scheduler = parent.getScheduler();
       if (scheduler != null) {
         String selectedTaskString = consoleContent.getItem(longClickedItemPosition);
         String taskKey = taskMap.get(selectedTaskString);
         if (taskKey != null) {
           scheduler.removeTaskByKey(taskKey);
         }
       }
       updateConsole();
       return true;
     default:
   }
   return false;
 }