package dk.silverbullet.telemed.video;
import android.util.Log;
import com.google.gson.annotations.Expose;
import dk.silverbullet.telemed.MainActivity;
import dk.silverbullet.telemed.questionnaire.Questionnaire;
import dk.silverbullet.telemed.rest.client.lowlevel.HttpHeaderBuilder;
import dk.silverbullet.telemed.rest.httpclient.HttpClientFactory;
import dk.silverbullet.telemed.utils.Json;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.BasicResponseHandler;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import java.io.IOException;
import java.net.URL;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import static java.util.concurrent.TimeUnit.SECONDS;
public class JoinConferencePoller {
private static final String TAG = "ConferenceHandler";
private static final int FIVE_SECONDS_IN_MILLIS = 5000;
private final MainActivity mainActivity;
private final Questionnaire mainQuestionnaire;
private volatile boolean stopped;
private volatile HttpGet httpGet;
private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
private Runnable checkForConferenceRunnable;
public JoinConferencePoller(final MainActivity mainActivity, Questionnaire mainQuestionnaire) {
this.mainActivity = mainActivity;
this.mainQuestionnaire = mainQuestionnaire;
checkForConferenceRunnable = new Runnable() {
@Override
public void run() {
PendingConferenceResponse checkForConferenceResponse = checkForConference();
if (!checkForConferenceResponse.roomKey.isEmpty()) {
Log.d(TAG, "Got roomkey" + checkForConferenceResponse.roomKey + "and service url:" + checkForConferenceResponse.serviceUrl);
mainActivity.startVideoConference(checkForConferenceResponse.roomKey, checkForConferenceResponse.serviceUrl);
scheduler.shutdown();
}
}
};
}
public void start() {
scheduler.scheduleWithFixedDelay(checkForConferenceRunnable, 0, 2, SECONDS);
}
public void stop() {
stopped = true;
final HttpGet pendingHttpGet = httpGet;
if (pendingHttpGet != null) {
new Thread(new Runnable() {
@Override
public void run() {
pendingHttpGet.abort();
}
}).start();
}
scheduler.shutdownNow();
}
private PendingConferenceResponse checkForConference() {
try {
// We don't use the otherwise nice and simple RestClient here, since we want to set an infinite timeout
// period AND hold on to our HttpGet object since we might like to abort it.
URL url = new URL(mainActivity.getServerURL());
httpGet = new HttpGet(new URL(url, "rest/conference/patientHasPendingConference").toExternalForm());
new HttpHeaderBuilder(httpGet, mainQuestionnaire)
.withAuthentication()
.withAcceptTypeJSON()
.withContentTypeJSON();
HttpClient httpClient = createHttpClientWithInfiniteTimeout();
String result = httpClient.execute(httpGet, new BasicResponseHandler());
if (!stopped && !result.isEmpty()) {
return Json.parse(result, PendingConferenceResponse.class);
}
} catch (IOException e) {
// If we're trying to stop this poller thread by aborting the GET request, we get an IOException. In
// that case, we don't log anything.
if (!stopped) {
Log.e(TAG, "Could not check for pending conference", e);
}
}
return new PendingConferenceResponse();
}
private HttpClient createHttpClientWithInfiniteTimeout() {
HttpClient httpClient = HttpClientFactory.createHttpClient(mainActivity);
HttpParams httpParameters = httpClient.getParams();
HttpConnectionParams.setConnectionTimeout(httpParameters, FIVE_SECONDS_IN_MILLIS);
HttpConnectionParams.setSoTimeout(httpParameters, 0);
return httpClient;
}
class PendingConferenceResponse {
@Expose String roomKey = "";
@Expose String serviceUrl = "";
}
}