Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(255)

Side by Side Diff: remoting/android/java/src/org/chromium/chromoting/HostListLoader.java

Issue 157013002: Pull HostListDirectoryGrabber out to a separate class. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix FindBugs warnings Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « remoting/android/java/src/org/chromium/chromoting/HostListAdapter.java ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 package org.chromium.chromoting;
6
7 import android.os.Handler;
8 import android.os.HandlerThread;
9 import android.os.Looper;
10 import android.util.Log;
11
12 import org.chromium.chromoting.jni.JniInterface;
13 import org.json.JSONArray;
14 import org.json.JSONException;
15 import org.json.JSONObject;
16
17 import java.io.IOException;
18 import java.net.HttpURLConnection;
19 import java.net.MalformedURLException;
20 import java.net.URL;
21 import java.util.ArrayList;
22 import java.util.Collections;
23 import java.util.Comparator;
24 import java.util.Scanner;
25
26 /** Helper for fetching the host list. */
27 public class HostListLoader {
28 public enum Error {
29 AUTH_FAILED,
30 NETWORK_ERROR,
31 SERVICE_UNAVAILABLE,
32 UNEXPECTED_RESPONSE,
33 UNKNOWN,
34 }
35
36 /** Callback for receiving the host list, or getting notified of an error. * /
37 public interface Callback {
38 void onHostListReceived(HostInfo[] hosts);
39 void onError(Error error);
40 }
41
42 /** Path from which to download a user's host list JSON object. */
43 private static final String HOST_LIST_PATH =
44 "https://www.googleapis.com/chromoting/v1/@me/hosts?key=";
45
46 /** Callback handler to be used for network operations. */
47 private Handler mNetworkThread;
48
49 /** Handler for main thread. */
50 private Handler mMainThread;
51
52 public HostListLoader() {
53 // Thread responsible for downloading the host list.
54
55 mMainThread = new Handler(Looper.getMainLooper());
56 }
57
58 private void initNetworkThread() {
59 if (mNetworkThread == null) {
60 HandlerThread thread = new HandlerThread("network");
61 thread.start();
62 mNetworkThread = new Handler(thread.getLooper());
63 }
64 }
65
66 /**
67 * Causes the host list to be fetched on a background thread. This should b e called on the
68 * main thread, and callbacks will also be invoked on the main thread. On s uccess,
69 * callback.onHostListReceived() will be called, otherwise callback.onError () will be called
70 * with an error-code describing the failure.
71 */
72 public void retrieveHostList(String authToken, Callback callback) {
73 initNetworkThread();
74 final String authTokenFinal = authToken;
75 final Callback callbackFinal = callback;
76 mNetworkThread.post(new Runnable() {
77 @Override
78 public void run() {
79 doRetrieveHostList(authTokenFinal, callbackFinal);
80 }
81 });
82 }
83
84 private void doRetrieveHostList(String authToken, Callback callback) {
85 HttpURLConnection link = null;
86 String response = null;
87 try {
88 link = (HttpURLConnection)
89 new URL(HOST_LIST_PATH + JniInterface.nativeGetApiKey()).ope nConnection();
90 link.addRequestProperty("client_id", JniInterface.nativeGetClientId( ));
91 link.addRequestProperty("client_secret", JniInterface.nativeGetClien tSecret());
92 link.setRequestProperty("Authorization", "OAuth " + authToken);
93
94 // Listen for the server to respond.
95 int status = link.getResponseCode();
96 switch (status) {
97 case HttpURLConnection.HTTP_OK: // 200
98 break;
99 case HttpURLConnection.HTTP_UNAUTHORIZED: // 401
100 postError(callback, Error.AUTH_FAILED);
101 return;
102 case HttpURLConnection.HTTP_BAD_GATEWAY: // 502
103 case HttpURLConnection.HTTP_UNAVAILABLE: // 503
104 postError(callback, Error.SERVICE_UNAVAILABLE);
105 return;
106 default:
107 postError(callback, Error.UNKNOWN);
108 return;
109 }
110
111 StringBuilder responseBuilder = new StringBuilder();
112 Scanner incoming = new Scanner(link.getInputStream());
113 Log.i("auth", "Successfully authenticated to directory server");
114 while (incoming.hasNext()) {
115 responseBuilder.append(incoming.nextLine());
116 }
117 response = String.valueOf(responseBuilder);
118 incoming.close();
119 } catch (MalformedURLException ex) {
120 // This should never happen.
121 throw new RuntimeException("Unexpected error while fetching host lis t: " + ex);
122 } catch (IOException ex) {
123 postError(callback, Error.NETWORK_ERROR);
124 return;
125 } finally {
126 if (link != null) {
127 link.disconnect();
128 }
129 }
130
131 // Parse directory response.
132 ArrayList<HostInfo> hostList = new ArrayList<HostInfo>();
133 try {
134 JSONObject data = new JSONObject(response).getJSONObject("data");
135 JSONArray hostsJson = data.getJSONArray("items");
136 Log.i("hostlist", "Received host listing from directory server");
137
138 int index = 0;
139 while (!hostsJson.isNull(index)) {
140 JSONObject hostJson = hostsJson.getJSONObject(index);
141 // If a host is only recently registered, it may be missing some of the keys below.
142 // It should still be visible in the list, even though a connect ion attempt will
143 // fail because of the missing keys. The failed attempt will tri gger reloading of
144 // the host-list (once crbug.com/304719 is fixed), by which time the keys will
145 // hopefully be present, and the retried connection can succeed.
146 HostInfo host = new HostInfo(
147 hostJson.getString("hostName"),
148 hostJson.getString("hostId"),
149 hostJson.optString("jabberId"),
150 hostJson.optString("publicKey"),
151 hostJson.optString("status").equals("ONLINE"));
152 hostList.add(host);
153 ++index;
154 }
155 } catch (JSONException ex) {
156 postError(callback, Error.UNEXPECTED_RESPONSE);
157 return;
158 }
159
160 sortHosts(hostList);
161
162 final Callback callbackFinal = callback;
163 final HostInfo[] hosts = hostList.toArray(new HostInfo[hostList.size()]) ;
164 mMainThread.post(new Runnable() {
165 @Override
166 public void run() {
167 callbackFinal.onHostListReceived(hosts);
168 }
169 });
170 }
171
172 /** Posts error to callback on main thread. */
173 private void postError(Callback callback, Error error) {
174 final Callback callbackFinal = callback;
175 final Error errorFinal = error;
176 mMainThread.post(new Runnable() {
177 @Override
178 public void run() {
179 callbackFinal.onError(errorFinal);
180 }
181 });
182 }
183
184 private static void sortHosts(ArrayList<HostInfo> hosts) {
185 Comparator<HostInfo> hostComparator = new Comparator<HostInfo>() {
186 public int compare(HostInfo a, HostInfo b) {
187 if (a.isOnline != b.isOnline) {
188 return a.isOnline ? -1 : 1;
189 }
190 String aName = a.name.toUpperCase();
191 String bName = b.name.toUpperCase();
192 return aName.compareTo(bName);
193 }
194 };
195 Collections.sort(hosts, hostComparator);
196 }
197 }
OLDNEW
« no previous file with comments | « remoting/android/java/src/org/chromium/chromoting/HostListAdapter.java ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698