| Index: remoting/android/java/src/org/chromium/chromoting/HostListManager.java
|
| diff --git a/remoting/android/java/src/org/chromium/chromoting/HostListLoader.java b/remoting/android/java/src/org/chromium/chromoting/HostListManager.java
|
| similarity index 52%
|
| rename from remoting/android/java/src/org/chromium/chromoting/HostListLoader.java
|
| rename to remoting/android/java/src/org/chromium/chromoting/HostListManager.java
|
| index a7e35905d51ffa80bd2a45383564ff409bbb4704..64fb6658cbc830d48a6b8fa1e18725b7b9721eed 100644
|
| --- a/remoting/android/java/src/org/chromium/chromoting/HostListLoader.java
|
| +++ b/remoting/android/java/src/org/chromium/chromoting/HostListManager.java
|
| @@ -14,6 +14,7 @@ import org.json.JSONException;
|
| import org.json.JSONObject;
|
|
|
| import java.io.IOException;
|
| +import java.io.OutputStream;
|
| import java.net.HttpURLConnection;
|
| import java.net.MalformedURLException;
|
| import java.net.URL;
|
| @@ -23,8 +24,8 @@ import java.util.Comparator;
|
| import java.util.Locale;
|
| import java.util.Scanner;
|
|
|
| -/** Helper for fetching the host list. */
|
| -public class HostListLoader {
|
| +/** Helper for fetching and modifying the host list. */
|
| +public class HostListManager {
|
| public enum Error {
|
| AUTH_FAILED,
|
| NETWORK_ERROR,
|
| @@ -35,10 +36,26 @@ public class HostListLoader {
|
|
|
| /** Callback for receiving the host list, or getting notified of an error. */
|
| public interface Callback {
|
| - void onHostListReceived(HostInfo[] hosts);
|
| + void onHostListReceived(HostInfo[] response);
|
| + void onHostUpdated();
|
| + void onHostDeleted();
|
| void onError(Error error);
|
| }
|
|
|
| + /**
|
| + * Represents a response from the directory server.
|
| + * If the request failed, |error| will not be null and |body| will be null.
|
| + * If the request succeeds, |error| will be null and |body| will not be null.
|
| + **/
|
| + private static class Response {
|
| + public final Error error;
|
| + public final String body;
|
| + public Response(Error error, String body) {
|
| + this.error = error;
|
| + this.body = body;
|
| + }
|
| + }
|
| +
|
| private static final String TAG = "Chromoting";
|
|
|
| /** Path from which to download a user's host list JSON object. */
|
| @@ -51,18 +68,19 @@ public class HostListLoader {
|
| /** Handler for main thread. */
|
| private Handler mMainThread;
|
|
|
| - public HostListLoader() {
|
| + public HostListManager() {
|
| // Thread responsible for downloading the host list.
|
|
|
| mMainThread = new Handler(Looper.getMainLooper());
|
| }
|
|
|
| - private void initNetworkThread() {
|
| + private void runOnNetworkThread(Runnable runnable) {
|
| if (mNetworkThread == null) {
|
| HandlerThread thread = new HandlerThread("network");
|
| thread.start();
|
| mNetworkThread = new Handler(thread.getLooper());
|
| }
|
| + mNetworkThread.post(runnable);
|
| }
|
|
|
| /**
|
| @@ -71,65 +89,26 @@ public class HostListLoader {
|
| * callback.onHostListReceived() will be called, otherwise callback.onError() will be called
|
| * with an error-code describing the failure.
|
| */
|
| - public void retrieveHostList(String authToken, Callback callback) {
|
| - initNetworkThread();
|
| - final String authTokenFinal = authToken;
|
| - final Callback callbackFinal = callback;
|
| - mNetworkThread.post(new Runnable() {
|
| + public void retrieveHostList(final String authToken, final Callback callback) {
|
| + runOnNetworkThread(new Runnable() {
|
| @Override
|
| public void run() {
|
| - doRetrieveHostList(authTokenFinal, callbackFinal);
|
| + doRetrieveHostList(authToken, callback);
|
| }
|
| });
|
| }
|
|
|
| private void doRetrieveHostList(String authToken, Callback callback) {
|
| - HttpURLConnection link = null;
|
| - String response = null;
|
| - try {
|
| - link = (HttpURLConnection) new URL(HOST_LIST_PATH).openConnection();
|
| - link.setRequestProperty("Authorization", "OAuth " + authToken);
|
| -
|
| - // Listen for the server to respond.
|
| - int status = link.getResponseCode();
|
| - switch (status) {
|
| - case HttpURLConnection.HTTP_OK: // 200
|
| - break;
|
| - case HttpURLConnection.HTTP_UNAUTHORIZED: // 401
|
| - postError(callback, Error.AUTH_FAILED);
|
| - return;
|
| - case HttpURLConnection.HTTP_BAD_GATEWAY: // 502
|
| - case HttpURLConnection.HTTP_UNAVAILABLE: // 503
|
| - postError(callback, Error.SERVICE_UNAVAILABLE);
|
| - return;
|
| - default:
|
| - postError(callback, Error.UNKNOWN);
|
| - return;
|
| - }
|
| -
|
| - StringBuilder responseBuilder = new StringBuilder();
|
| - Scanner incoming = new Scanner(link.getInputStream());
|
| - while (incoming.hasNext()) {
|
| - responseBuilder.append(incoming.nextLine());
|
| - }
|
| - response = String.valueOf(responseBuilder);
|
| - incoming.close();
|
| - } catch (MalformedURLException ex) {
|
| - // This should never happen.
|
| - throw new RuntimeException("Unexpected error while fetching host list: ", ex);
|
| - } catch (IOException ex) {
|
| - postError(callback, Error.NETWORK_ERROR);
|
| + Response response = sendRequest(authToken, HOST_LIST_PATH, "GET", null, null);
|
| + if (response.error != null) {
|
| + postError(callback, response.error);
|
| return;
|
| - } finally {
|
| - if (link != null) {
|
| - link.disconnect();
|
| - }
|
| }
|
|
|
| // Parse directory response.
|
| ArrayList<HostInfo> hostList = new ArrayList<HostInfo>();
|
| try {
|
| - JSONObject data = new JSONObject(response).getJSONObject("data");
|
| + JSONObject data = new JSONObject(response.body).getJSONObject("data");
|
| if (data.has("items")) {
|
| JSONArray hostsJson = data.getJSONArray("items");
|
|
|
| @@ -165,6 +144,79 @@ public class HostListLoader {
|
| });
|
| }
|
|
|
| + /**
|
| + * Updates a host on the background thread. On success, callback.onHostUpdated() will be called,
|
| + * otherwise callback.onError() will be called with an error-code describing the failure.
|
| + */
|
| + public void putHost(final String authToken, final String hostId, final String hostName,
|
| + final String publicKey, final Callback callback) {
|
| + runOnNetworkThread(new Runnable() {
|
| + @Override
|
| + public void run() {
|
| + doPutHost(authToken, hostId, hostName, publicKey, callback);
|
| + }
|
| + });
|
| + }
|
| +
|
| + private void doPutHost(String authToken, String hostId, String hostName, String publicKey,
|
| + final Callback callback) {
|
| + String requestJson;
|
| + try {
|
| + JSONObject data = new JSONObject();
|
| + data.put("hostId", hostId);
|
| + data.put("hostName", hostName);
|
| + data.put("publicKey", publicKey);
|
| + JSONObject request = new JSONObject();
|
| + request.put("data", data);
|
| + requestJson = request.toString();
|
| + } catch (JSONException ex) {
|
| + Log.e(TAG, "Error creating put host JSON string: %s", ex.getMessage());
|
| + postError(callback, Error.UNKNOWN);
|
| + return;
|
| + }
|
| + Response response = sendRequest(authToken, HOST_LIST_PATH + '/' + hostId, "PUT",
|
| + "application/json", requestJson);
|
| + if (response.error != null) {
|
| + postError(callback, response.error);
|
| + } else {
|
| + mMainThread.post(new Runnable() {
|
| + @Override
|
| + public void run() {
|
| + callback.onHostUpdated();
|
| + }
|
| + });
|
| + }
|
| + }
|
| +
|
| + /**
|
| + * Deletes a host on the background thread. On success, callback.onHostUpdated() will be called,
|
| + * otherwise callback.onError() will be called with an error-code describing the failure.
|
| + */
|
| + public void deleteHost(final String authToken, final String hostId,
|
| + final Callback callback) {
|
| + runOnNetworkThread(new Runnable() {
|
| + @Override
|
| + public void run() {
|
| + doDeleteHost(authToken, hostId, callback);
|
| + }
|
| + });
|
| + }
|
| +
|
| + private void doDeleteHost(String authToken, String hostId, final Callback callback) {
|
| + Response response = sendRequest(authToken, HOST_LIST_PATH + '/' + hostId, "DELETE",
|
| + null, null);
|
| + if (response.error != null) {
|
| + postError(callback, response.error);
|
| + } else {
|
| + mMainThread.post(new Runnable() {
|
| + @Override
|
| + public void run() {
|
| + callback.onHostDeleted();
|
| + }
|
| + });
|
| + }
|
| + }
|
| +
|
| /** Posts error to callback on main thread. */
|
| private void postError(Callback callback, Error error) {
|
| final Callback callbackFinal = callback;
|
| @@ -191,4 +243,70 @@ public class HostListLoader {
|
| };
|
| Collections.sort(hosts, hostComparator);
|
| }
|
| +
|
| + /**
|
| + * Sends request to the url and returns the response.
|
| + * @param authToken auth token
|
| + * @param url the URL to send the request
|
| + * @param method /GET/POST/PUT/DELETE/etc.
|
| + * @param requestContentType The content type of the request body. This can be null.
|
| + * @param requestBody This can be null.
|
| + * @return The response.
|
| + */
|
| + private static Response sendRequest(String authToken, String url, String method,
|
| + String requestContentType, String requestBody) {
|
| + HttpURLConnection link = null;
|
| + Error error = null;
|
| + try {
|
| + link = (HttpURLConnection) new URL(url).openConnection();
|
| + link.setRequestMethod(method);
|
| + link.setRequestProperty("Authorization", "OAuth " + authToken);
|
| + if (requestContentType != null) {
|
| + link.setRequestProperty("Content-Type", requestContentType);
|
| + }
|
| + if (requestBody != null) {
|
| + byte[] requestBytes = requestBody.getBytes("UTF-8");
|
| + OutputStream outStream = link.getOutputStream();
|
| + outStream.write(requestBytes);
|
| + outStream.close();
|
| + }
|
| +
|
| + // Listen for the server to respond.
|
| + int status = link.getResponseCode();
|
| + switch (status) {
|
| + case HttpURLConnection.HTTP_OK: // 200
|
| + break;
|
| + case HttpURLConnection.HTTP_UNAUTHORIZED: // 401
|
| + error = Error.AUTH_FAILED;
|
| + break;
|
| + case HttpURLConnection.HTTP_BAD_GATEWAY: // 502
|
| + case HttpURLConnection.HTTP_UNAVAILABLE: // 503
|
| + error = Error.SERVICE_UNAVAILABLE;
|
| + break;
|
| + default:
|
| + error = Error.UNKNOWN;
|
| + }
|
| +
|
| + if (error != null) {
|
| + return new Response(error, null);
|
| + }
|
| +
|
| + StringBuilder responseBuilder = new StringBuilder();
|
| + Scanner incoming = new Scanner(link.getInputStream());
|
| + while (incoming.hasNext()) {
|
| + responseBuilder.append(incoming.nextLine());
|
| + }
|
| + incoming.close();
|
| + return new Response(null, responseBuilder.toString());
|
| + } catch (MalformedURLException ex) {
|
| + // This should never happen.
|
| + throw new RuntimeException("Unexpected error while fetching host list: ", ex);
|
| + } catch (IOException ex) {
|
| + return new Response(Error.NETWORK_ERROR, null);
|
| + } finally {
|
| + if (link != null) {
|
| + link.disconnect();
|
| + }
|
| + }
|
| + }
|
| }
|
|
|