Upstream version 11.40.271.0
[platform/framework/web/crosswalk.git] / src / components / devtools_bridge / android / java / src / org / chromium / components / devtools_bridge / apiary / GCDClient.java
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.components.devtools_bridge.apiary;
6
7 import android.util.JsonReader;
8
9 import org.apache.http.HttpResponse;
10 import org.apache.http.client.HttpClient;
11 import org.apache.http.client.HttpResponseException;
12 import org.apache.http.client.ResponseHandler;
13 import org.apache.http.client.methods.HttpDelete;
14 import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
15 import org.apache.http.client.methods.HttpGet;
16 import org.apache.http.client.methods.HttpPost;
17 import org.apache.http.client.methods.HttpRequestBase;
18 import org.apache.http.entity.StringEntity;
19
20 import org.chromium.components.devtools_bridge.commands.Command;
21 import org.chromium.components.devtools_bridge.gcd.InstanceCredential;
22 import org.chromium.components.devtools_bridge.gcd.InstanceDescription;
23 import org.chromium.components.devtools_bridge.gcd.MessageReader;
24 import org.chromium.components.devtools_bridge.gcd.MessageWriter;
25
26 import java.io.IOException;
27 import java.io.UnsupportedEncodingException;
28 import java.net.URI;
29
30 /**
31  * Client for accessing GCD API.
32  */
33 public class GCDClient {
34     private static final String API_BASE = "https://www.googleapis.com/clouddevices/v1";
35     public static final String ENCODING = "UTF-8";
36     protected static final String CONTENT_TYPE = "application/json; charset=" + ENCODING;
37
38     protected final HttpClient mHttpClient;
39     private final String mAPIKey;
40     private final String mOAuthToken;
41
42     GCDClient(HttpClient httpClient, String apiKey, String oAuthToken) {
43         mHttpClient = httpClient;
44         mAPIKey = apiKey;
45         mOAuthToken = oAuthToken;
46     }
47
48     GCDClient(HttpClient httpClient, String apiKey) {
49         this(httpClient, apiKey, null);
50     }
51
52     /**
53      * Creation of a registration ticket is the first step in instance registration. Client must
54      * have user credentials. If the ticket has been registered it will be associated with the
55      * user. Next step is registration ticket patching.
56      */
57     public final String createRegistrationTicket() throws IOException {
58         assert mOAuthToken != null;
59
60         return mHttpClient.execute(
61                 newHttpPost("/registrationTickets", "{\"userEmail\":\"me\"}"),
62                 new JsonResponseHandler<String>() {
63                     @Override
64                     public String readResponse(JsonReader reader) throws IOException {
65                         return new MessageReader(reader).readTicketId();
66                     }
67                 });
68     }
69
70     /**
71      * Patching registration ticket. GCD gets device definition including commands metadata,
72      * GCM channel description and user-visible instance name.
73      */
74     public final void patchRegistrationTicket(String ticketId, InstanceDescription description)
75             throws IOException {
76         String content = new MessageWriter().writeTicketPatch(description).close().toString();
77
78         mHttpClient.execute(
79                 newHttpPatch("/registrationTickets/" + ticketId, content),
80                 new EmptyResponseHandler());
81     }
82
83     /**
84      * Finalizing registration. Client must be anonymous (GCD requirement). GCD provides
85      * instance credentials needed for handling commands.
86      */
87     public final InstanceCredential finalizeRegistration(String ticketId) throws IOException {
88         return mHttpClient.execute(
89                 newHttpPost("/registrationTickets/" + ticketId + "/finalize", ""),
90                 new JsonResponseHandler<InstanceCredential>() {
91                     @Override
92                     public InstanceCredential readResponse(JsonReader reader) throws IOException {
93                         return new MessageReader(reader).readInstanceCredential();
94                     }
95                 });
96     }
97
98     /**
99      * Deletes registered instance (unregisters). If client has instance credentials then
100      * instanceId must be it's own ID. If client has user credentials then instance must belong
101      * to the user.
102      */
103     public void deleteInstance(String instanceId) throws IOException {
104         mHttpClient.execute(
105                 newHttpDelete("/devices/" + instanceId),
106                 new EmptyResponseHandler());
107     }
108
109     /**
110      * Patches the command (previously received with Notification) with out-parameters or
111      * an error message.
112      */
113     public final void patchCommand(Command command) throws IOException {
114         String content = new MessageWriter().writeCommandPatch(command).close().toString();
115
116         mHttpClient.execute(
117                 newHttpPatch("/commands/" + command.id, content),
118                 new EmptyResponseHandler());
119     }
120
121     protected final HttpGet newHttpGet(String path) {
122         return prepare(new HttpGet(buildUrl(path)));
123     }
124
125     protected final HttpPost newHttpPost(String path, String content)
126             throws UnsupportedEncodingException {
127         return prepare(new HttpPost(buildUrl(path)), content);
128     }
129
130     protected final HttpPost newHttpPost(String path, String query, String content)
131             throws UnsupportedEncodingException {
132         return prepare(new HttpPost(buildUrl(path, query)), content);
133     }
134
135     protected final HttpPatch newHttpPatch(String path, String content)
136             throws UnsupportedEncodingException {
137         return prepare(new HttpPatch(buildUrl(path)), content);
138     }
139
140     protected final HttpDelete newHttpDelete(String path) {
141         return prepare(new HttpDelete(buildUrl(path)));
142     }
143
144     private String buildUrl(String path) {
145         return API_BASE + path + "?key=" + mAPIKey;
146     }
147
148     private String buildUrl(String path, String query) {
149         return API_BASE + path + "?" + query + "&key=" + mAPIKey;
150     }
151
152     private <T extends HttpEntityEnclosingRequestBase> T prepare(T request, String content)
153             throws UnsupportedEncodingException {
154         request.setEntity(new StringEntity(content, ENCODING));
155         request.addHeader("Content-Type", CONTENT_TYPE);
156         return prepare(request);
157     }
158
159     private <T extends HttpRequestBase> T prepare(T request) {
160         if (mOAuthToken != null) {
161             request.addHeader("Authorization", "Bearer " + mOAuthToken);
162         }
163         return request;
164     }
165
166     private static final class HttpPatch extends HttpEntityEnclosingRequestBase {
167         public HttpPatch(String uri) {
168             setURI(URI.create(uri));
169         }
170
171         public String getMethod() {
172             return "PATCH";
173         }
174     }
175
176     private static class EmptyResponseHandler implements ResponseHandler<Void> {
177         @Override
178         public Void handleResponse(HttpResponse response) throws HttpResponseException {
179             JsonResponseHandler.checkStatus(response);
180             return null;
181         }
182     }
183 }