| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 package org.chromium.chromoting; | 5 package org.chromium.chromoting; |
| 6 | 6 |
| 7 import android.os.Handler; | 7 import android.os.Handler; |
| 8 import android.os.HandlerThread; | 8 import android.os.HandlerThread; |
| 9 import android.os.Looper; | 9 import android.os.Looper; |
| 10 | 10 |
| (...skipping 16 matching lines...) Expand all Loading... |
| 27 /** Helper for fetching and modifying the host list. */ | 27 /** Helper for fetching and modifying the host list. */ |
| 28 public class HostListManager { | 28 public class HostListManager { |
| 29 public enum Error { | 29 public enum Error { |
| 30 AUTH_FAILED, | 30 AUTH_FAILED, |
| 31 NETWORK_ERROR, | 31 NETWORK_ERROR, |
| 32 SERVICE_UNAVAILABLE, | 32 SERVICE_UNAVAILABLE, |
| 33 UNEXPECTED_RESPONSE, | 33 UNEXPECTED_RESPONSE, |
| 34 UNKNOWN, | 34 UNKNOWN, |
| 35 } | 35 } |
| 36 | 36 |
| 37 public enum RequestType { |
| 38 RETRIEVE_HOST_LIST, |
| 39 UPDATE_HOST, |
| 40 DELETE_HOST |
| 41 } |
| 42 |
| 37 /** Callback for receiving the host list, or getting notified of an error. *
/ | 43 /** Callback for receiving the host list, or getting notified of an error. *
/ |
| 38 public interface Callback { | 44 public interface Callback { |
| 39 void onHostListReceived(HostInfo[] response); | 45 void onHostListReceived(HostInfo[] response); |
| 40 void onHostUpdated(); | 46 void onHostUpdated(); |
| 41 void onHostDeleted(); | 47 void onHostDeleted(); |
| 42 void onError(Error error); | 48 void onError(RequestType type, Error error); |
| 43 } | 49 } |
| 44 | 50 |
| 45 /** | 51 /** |
| 46 * Represents a response from the directory server. | 52 * Represents a response from the directory server. |
| 47 * If the request failed, |error| will not be null and |body| will be null. | 53 * If the request failed, |error| will not be null and |body| will be null. |
| 48 * If the request succeeds, |error| will be null and |body| will not be null
. | 54 * If the request succeeds, |error| will be null and |body| will not be null
. |
| 49 **/ | 55 **/ |
| 50 private static class Response { | 56 private static class Response { |
| 51 public final Error error; | 57 public final Error error; |
| 52 public final String body; | 58 public final String body; |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 94 @Override | 100 @Override |
| 95 public void run() { | 101 public void run() { |
| 96 doRetrieveHostList(authToken, callback); | 102 doRetrieveHostList(authToken, callback); |
| 97 } | 103 } |
| 98 }); | 104 }); |
| 99 } | 105 } |
| 100 | 106 |
| 101 private void doRetrieveHostList(String authToken, Callback callback) { | 107 private void doRetrieveHostList(String authToken, Callback callback) { |
| 102 Response response = sendRequest(authToken, HOST_LIST_PATH, "GET", null,
null); | 108 Response response = sendRequest(authToken, HOST_LIST_PATH, "GET", null,
null); |
| 103 if (response.error != null) { | 109 if (response.error != null) { |
| 104 postError(callback, response.error); | 110 postError(callback, RequestType.RETRIEVE_HOST_LIST, response.error); |
| 105 return; | 111 return; |
| 106 } | 112 } |
| 107 | 113 |
| 108 // Parse directory response. | 114 // Parse directory response. |
| 109 ArrayList<HostInfo> hostList = new ArrayList<HostInfo>(); | 115 ArrayList<HostInfo> hostList = new ArrayList<HostInfo>(); |
| 110 try { | 116 try { |
| 111 JSONObject data = new JSONObject(response.body).getJSONObject("data"
); | 117 JSONObject data = new JSONObject(response.body).getJSONObject("data"
); |
| 112 if (data.has("items")) { | 118 if (data.has("items")) { |
| 113 JSONArray hostsJson = data.getJSONArray("items"); | 119 JSONArray hostsJson = data.getJSONArray("items"); |
| 114 | 120 |
| 115 int index = 0; | 121 int index = 0; |
| 116 while (!hostsJson.isNull(index)) { | 122 while (!hostsJson.isNull(index)) { |
| 117 JSONObject hostJson = hostsJson.getJSONObject(index); | 123 JSONObject hostJson = hostsJson.getJSONObject(index); |
| 118 // If a host is only recently registered, it may be missing
some of the keys | 124 // If a host is only recently registered, it may be missing
some of the keys |
| 119 // below. It should still be visible in the list, even thoug
h a connection | 125 // below. It should still be visible in the list, even thoug
h a connection |
| 120 // attempt will fail because of the missing keys. The failed
attempt will | 126 // attempt will fail because of the missing keys. The failed
attempt will |
| 121 // trigger reloading of the host-list, by which time the key
s will hopefully be | 127 // trigger reloading of the host-list, by which time the key
s will hopefully be |
| 122 // present, and the retried connection can succeed. | 128 // present, and the retried connection can succeed. |
| 123 HostInfo host = HostInfo.create(hostJson); | 129 HostInfo host = HostInfo.create(hostJson); |
| 124 hostList.add(host); | 130 hostList.add(host); |
| 125 ++index; | 131 ++index; |
| 126 } | 132 } |
| 127 } | 133 } |
| 128 } catch (JSONException ex) { | 134 } catch (JSONException ex) { |
| 129 // Logging the exception stack trace may be too spammy. | 135 // Logging the exception stack trace may be too spammy. |
| 130 Log.e(TAG, "Error parsing host list response: %s", ex.getMessage()); | 136 Log.e(TAG, "Error parsing host list response: %s", ex.getMessage()); |
| 131 postError(callback, Error.UNEXPECTED_RESPONSE); | 137 postError(callback, RequestType.RETRIEVE_HOST_LIST, Error.UNEXPECTED
_RESPONSE); |
| 132 return; | 138 return; |
| 133 } | 139 } |
| 134 | 140 |
| 135 sortHosts(hostList); | 141 sortHosts(hostList); |
| 136 | 142 |
| 137 final Callback callbackFinal = callback; | 143 final Callback callbackFinal = callback; |
| 138 final HostInfo[] hosts = hostList.toArray(new HostInfo[hostList.size()])
; | 144 final HostInfo[] hosts = hostList.toArray(new HostInfo[hostList.size()])
; |
| 139 mMainThread.post(new Runnable() { | 145 mMainThread.post(new Runnable() { |
| 140 @Override | 146 @Override |
| 141 public void run() { | 147 public void run() { |
| 142 callbackFinal.onHostListReceived(hosts); | 148 callbackFinal.onHostListReceived(hosts); |
| 143 } | 149 } |
| 144 }); | 150 }); |
| 145 } | 151 } |
| 146 | 152 |
| 147 /** | 153 /** |
| 148 * Updates a host on the background thread. On success, callback.onHostUpdat
ed() will be called, | 154 * Updates a host on the background thread. On success, callback.onHostUpdat
ed() will be called, |
| 149 * otherwise callback.onError() will be called with an error-code describing
the failure. | 155 * otherwise callback.onError() will be called with an error-code describing
the failure. |
| 150 */ | 156 */ |
| 151 public void putHost(final String authToken, final String hostId, final Strin
g hostName, | 157 public void updateHost(final String authToken, final String hostId, final St
ring hostName, |
| 152 final String publicKey, final Callback callback) { | 158 final String publicKey, final Callback callback) { |
| 153 runOnNetworkThread(new Runnable() { | 159 runOnNetworkThread(new Runnable() { |
| 154 @Override | 160 @Override |
| 155 public void run() { | 161 public void run() { |
| 156 doPutHost(authToken, hostId, hostName, publicKey, callback); | 162 doUpdateHost(authToken, hostId, hostName, publicKey, callback); |
| 157 } | 163 } |
| 158 }); | 164 }); |
| 159 } | 165 } |
| 160 | 166 |
| 161 private void doPutHost(String authToken, String hostId, String hostName, Str
ing publicKey, | 167 private void doUpdateHost(String authToken, String hostId, String hostName,
String publicKey, |
| 162 final Callback callback) { | 168 final Callback callback) { |
| 163 String requestJson; | 169 String requestJson; |
| 164 try { | 170 try { |
| 165 JSONObject data = new JSONObject(); | 171 JSONObject data = new JSONObject(); |
| 166 data.put("hostId", hostId); | 172 data.put("hostId", hostId); |
| 167 data.put("hostName", hostName); | 173 data.put("hostName", hostName); |
| 168 data.put("publicKey", publicKey); | 174 data.put("publicKey", publicKey); |
| 169 JSONObject request = new JSONObject(); | 175 JSONObject request = new JSONObject(); |
| 170 request.put("data", data); | 176 request.put("data", data); |
| 171 requestJson = request.toString(); | 177 requestJson = request.toString(); |
| 172 } catch (JSONException ex) { | 178 } catch (JSONException ex) { |
| 173 Log.e(TAG, "Error creating put host JSON string: %s", ex.getMessage(
)); | 179 Log.e(TAG, "Error creating put host JSON string: %s", ex.getMessage(
)); |
| 174 postError(callback, Error.UNKNOWN); | 180 postError(callback, RequestType.UPDATE_HOST, Error.UNKNOWN); |
| 175 return; | 181 return; |
| 176 } | 182 } |
| 177 Response response = sendRequest(authToken, HOST_LIST_PATH + '/' + hostId
, "PUT", | 183 Response response = sendRequest(authToken, HOST_LIST_PATH + '/' + hostId
, "PUT", |
| 178 "application/json", requestJson); | 184 "application/json", requestJson); |
| 179 if (response.error != null) { | 185 if (response.error != null) { |
| 180 postError(callback, response.error); | 186 postError(callback, RequestType.UPDATE_HOST, response.error); |
| 181 } else { | 187 } else { |
| 182 mMainThread.post(new Runnable() { | 188 mMainThread.post(new Runnable() { |
| 183 @Override | 189 @Override |
| 184 public void run() { | 190 public void run() { |
| 185 callback.onHostUpdated(); | 191 callback.onHostUpdated(); |
| 186 } | 192 } |
| 187 }); | 193 }); |
| 188 } | 194 } |
| 189 } | 195 } |
| 190 | 196 |
| 191 /** | 197 /** |
| 192 * Deletes a host on the background thread. On success, callback.onHostUpdat
ed() will be called, | 198 * Deletes a host on the background thread. On success, callback.onHostUpdat
ed() will be called, |
| 193 * otherwise callback.onError() will be called with an error-code describing
the failure. | 199 * otherwise callback.onError() will be called with an error-code describing
the failure. |
| 194 */ | 200 */ |
| 195 public void deleteHost(final String authToken, final String hostId, | 201 public void deleteHost(final String authToken, final String hostId, |
| 196 final Callback callback) { | 202 final Callback callback) { |
| 197 runOnNetworkThread(new Runnable() { | 203 runOnNetworkThread(new Runnable() { |
| 198 @Override | 204 @Override |
| 199 public void run() { | 205 public void run() { |
| 200 doDeleteHost(authToken, hostId, callback); | 206 doDeleteHost(authToken, hostId, callback); |
| 201 } | 207 } |
| 202 }); | 208 }); |
| 203 } | 209 } |
| 204 | 210 |
| 205 private void doDeleteHost(String authToken, String hostId, final Callback ca
llback) { | 211 private void doDeleteHost(String authToken, String hostId, final Callback ca
llback) { |
| 206 Response response = sendRequest(authToken, HOST_LIST_PATH + '/' + hostId
, "DELETE", | 212 Response response = sendRequest(authToken, HOST_LIST_PATH + '/' + hostId
, "DELETE", |
| 207 null, null); | 213 null, null); |
| 208 if (response.error != null) { | 214 if (response.error != null) { |
| 209 postError(callback, response.error); | 215 postError(callback, RequestType.DELETE_HOST, response.error); |
| 210 } else { | 216 } else { |
| 211 mMainThread.post(new Runnable() { | 217 mMainThread.post(new Runnable() { |
| 212 @Override | 218 @Override |
| 213 public void run() { | 219 public void run() { |
| 214 callback.onHostDeleted(); | 220 callback.onHostDeleted(); |
| 215 } | 221 } |
| 216 }); | 222 }); |
| 217 } | 223 } |
| 218 } | 224 } |
| 219 | 225 |
| 220 /** Posts error to callback on main thread. */ | 226 /** Posts error to callback on main thread. */ |
| 221 private void postError(Callback callback, Error error) { | 227 private void postError(final Callback callback, final RequestType type, fina
l Error error) { |
| 222 final Callback callbackFinal = callback; | |
| 223 final Error errorFinal = error; | |
| 224 mMainThread.post(new Runnable() { | 228 mMainThread.post(new Runnable() { |
| 225 @Override | 229 @Override |
| 226 public void run() { | 230 public void run() { |
| 227 callbackFinal.onError(errorFinal); | 231 callback.onError(type, error); |
| 228 } | 232 } |
| 229 }); | 233 }); |
| 230 } | 234 } |
| 231 | 235 |
| 232 private static void sortHosts(ArrayList<HostInfo> hosts) { | 236 private static void sortHosts(ArrayList<HostInfo> hosts) { |
| 233 Comparator<HostInfo> hostComparator = new Comparator<HostInfo>() { | 237 Comparator<HostInfo> hostComparator = new Comparator<HostInfo>() { |
| 234 @Override | 238 @Override |
| 235 public int compare(HostInfo a, HostInfo b) { | 239 public int compare(HostInfo a, HostInfo b) { |
| 236 if (a.isOnline != b.isOnline) { | 240 if (a.isOnline != b.isOnline) { |
| 237 return a.isOnline ? -1 : 1; | 241 return a.isOnline ? -1 : 1; |
| (...skipping 30 matching lines...) Expand all Loading... |
| 268 byte[] requestBytes = requestBody.getBytes("UTF-8"); | 272 byte[] requestBytes = requestBody.getBytes("UTF-8"); |
| 269 OutputStream outStream = link.getOutputStream(); | 273 OutputStream outStream = link.getOutputStream(); |
| 270 outStream.write(requestBytes); | 274 outStream.write(requestBytes); |
| 271 outStream.close(); | 275 outStream.close(); |
| 272 } | 276 } |
| 273 | 277 |
| 274 // Listen for the server to respond. | 278 // Listen for the server to respond. |
| 275 int status = link.getResponseCode(); | 279 int status = link.getResponseCode(); |
| 276 switch (status) { | 280 switch (status) { |
| 277 case HttpURLConnection.HTTP_OK: // 200 | 281 case HttpURLConnection.HTTP_OK: // 200 |
| 282 case HttpURLConnection.HTTP_NO_CONTENT: // 204 |
| 278 break; | 283 break; |
| 279 case HttpURLConnection.HTTP_UNAUTHORIZED: // 401 | 284 case HttpURLConnection.HTTP_UNAUTHORIZED: // 401 |
| 280 error = Error.AUTH_FAILED; | 285 error = Error.AUTH_FAILED; |
| 281 break; | 286 break; |
| 282 case HttpURLConnection.HTTP_BAD_GATEWAY: // 502 | 287 case HttpURLConnection.HTTP_BAD_GATEWAY: // 502 |
| 283 case HttpURLConnection.HTTP_UNAVAILABLE: // 503 | 288 case HttpURLConnection.HTTP_UNAVAILABLE: // 503 |
| 284 error = Error.SERVICE_UNAVAILABLE; | 289 error = Error.SERVICE_UNAVAILABLE; |
| 285 break; | 290 break; |
| 286 default: | 291 default: |
| 287 error = Error.UNKNOWN; | 292 error = Error.UNKNOWN; |
| (...skipping 15 matching lines...) Expand all Loading... |
| 303 throw new RuntimeException("Unexpected error while fetching host lis
t: ", ex); | 308 throw new RuntimeException("Unexpected error while fetching host lis
t: ", ex); |
| 304 } catch (IOException ex) { | 309 } catch (IOException ex) { |
| 305 return new Response(Error.NETWORK_ERROR, null); | 310 return new Response(Error.NETWORK_ERROR, null); |
| 306 } finally { | 311 } finally { |
| 307 if (link != null) { | 312 if (link != null) { |
| 308 link.disconnect(); | 313 link.disconnect(); |
| 309 } | 314 } |
| 310 } | 315 } |
| 311 } | 316 } |
| 312 } | 317 } |
| OLD | NEW |