/* Copyright 2013 RobustNet Lab, University of Michigan. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.mobilyzer; import java.util.ArrayList; import java.util.HashMap; import java.util.concurrent.Callable; import android.content.Intent; import com.mobilyzer.MeasurementResult.TaskProgress; import com.mobilyzer.exceptions.MeasurementError; import com.mobilyzer.util.Logger; import com.mobilyzer.util.PhoneUtils; public class UserMeasurementTask implements Callable<MeasurementResult[]> { private MeasurementTask realTask; private MeasurementScheduler scheduler; private ContextCollector contextCollector; public UserMeasurementTask(MeasurementTask task, MeasurementScheduler scheduler) { realTask = task; this.scheduler = scheduler; this.contextCollector= new ContextCollector(); } /** * 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); } /** * 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); } } /** * 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; } }