Upstream version 11.40.271.0
[platform/framework/web/crosswalk.git] / src / components / devtools_bridge / test / android / javatests / src / org / chromium / components / devtools_bridge / ui / RemoteInstanceListFragment.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.ui;
6
7 import android.accounts.Account;
8 import android.accounts.AccountManager;
9 import android.accounts.AccountManagerCallback;
10 import android.accounts.AccountManagerFuture;
11 import android.app.Activity;
12 import android.app.ListFragment;
13 import android.content.Intent;
14 import android.os.AsyncTask;
15 import android.os.Bundle;
16 import android.util.Log;
17 import android.view.ContextMenu;
18 import android.view.LayoutInflater;
19 import android.view.MenuItem;
20 import android.view.View;
21 import android.view.ViewGroup;
22 import android.widget.ArrayAdapter;
23 import android.widget.ListView;
24 import android.widget.Toast;
25
26 import org.chromium.components.devtools_bridge.RTCConfiguration;
27 import org.chromium.components.devtools_bridge.SessionBase;
28 import org.chromium.components.devtools_bridge.apiary.ApiaryClientFactory;
29 import org.chromium.components.devtools_bridge.apiary.TestApiaryClientFactory;
30 import org.chromium.components.devtools_bridge.commands.Command;
31 import org.chromium.components.devtools_bridge.commands.CommandSender;
32 import org.chromium.components.devtools_bridge.gcd.RemoteInstance;
33
34 import java.io.IOException;
35 import java.util.List;
36
37 /**
38  * Fragment of application for manual testing the DevTools bridge. Shows instances
39  * registered in GCD and lets unregister them.
40  */
41 public abstract class RemoteInstanceListFragment extends ListFragment {
42     private static final String TAG = "RemoteInstanceListFragment";
43     private static final String NO_ID = "";
44     private static final int CODE_ACCOUNT_SELECTED = 1;
45
46     private final TestApiaryClientFactory mClientFactory = new TestApiaryClientFactory();
47     private ArrayAdapter<RemoteInstance> mListAdapter;
48     private String mOAuthToken;
49     private RemoteInstance mSelected;
50
51     @Override
52     public void onCreate(Bundle savedInstanceState) {
53         super.onCreate(savedInstanceState);
54         mListAdapter = new ArrayAdapter<RemoteInstance>(
55                 getActivity(), android.R.layout.simple_list_item_1);
56         new UpdateListAction().execute();
57         setListAdapter(mListAdapter);
58     }
59
60     @Override
61     public void onDestroy() {
62         new AsyncTask<Void, Void, Void>() {
63             @Override
64             protected final Void doInBackground(Void... args) {
65                 mClientFactory.close();
66                 return null;
67             }
68         }.execute();
69         super.onDestroy();
70     }
71
72     @Override
73     public View onCreateView(
74             LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
75         View root = super.onCreateView(inflater, container, savedInstanceState);
76         registerForContextMenu(root);
77         return root;
78     }
79
80     @Override
81     public void onListItemClick(ListView listView, View view, int position, long id) {
82         mSelected = mListAdapter.getItem(position);
83         if (mOAuthToken == null) {
84             signIn();
85         } else {
86             getActivity().openContextMenu(view);
87         }
88     }
89
90     @Override
91     public void onCreateContextMenu(
92             ContextMenu menu, View view, ContextMenu.ContextMenuInfo menuInfo) {
93         super.onCreateContextMenu(menu, view, menuInfo);
94
95         if (mOAuthToken == null) return;
96
97         menu.add("Connect")
98                 .setOnMenuItemClickListener(new ConnectAction())
99                 .setEnabled(mSelected != null);
100         menu.add("Send invalid offer")
101                 .setOnMenuItemClickListener(new SendInvalidOfferAction())
102                 .setEnabled(mSelected != null);
103         menu.add("Delete")
104                 .setOnMenuItemClickListener(new DeleteInstanceAction(mSelected))
105                 .setEnabled(mSelected != null);
106         menu.add("Update list")
107                 .setOnMenuItemClickListener(new UpdateListAction());
108         menu.add("Delete all")
109                 .setOnMenuItemClickListener(new DeleteAllAction());
110     }
111
112     public void signIn() {
113         AccountManager manager = AccountManager.get(getActivity());
114
115         Intent intent = manager.newChooseAccountIntent(
116                 null /* selectedAccount */,
117                 null /* allowableAccounts */,
118                 new String[] { "com.google" } /* allowableAccountTypes */,
119                 true /* alwaysPromptForAccount */,
120                 "Sign into GCD" /* descriptionOverrideText */,
121                 null /* addAccountAuthTokenType */,
122                 null /* addAccountRequiredFeatures */,
123                 null /* addAccountOptions */);
124         startActivityForResult(intent, CODE_ACCOUNT_SELECTED);
125     }
126
127     @Override
128     public void onActivityResult(final int requestCode, final int resultCode, final Intent data) {
129         if (requestCode == CODE_ACCOUNT_SELECTED && resultCode == Activity.RESULT_OK) {
130             queryOAuthToken(new Account(
131                     data.getStringExtra(AccountManager.KEY_ACCOUNT_NAME),
132                     data.getStringExtra(AccountManager.KEY_ACCOUNT_TYPE)));
133         }
134     }
135
136     protected abstract void connect(String oAuthToken, String remoteInstanceId);
137
138     public void queryOAuthToken(Account accout) {
139         AccountManager manager = AccountManager.get(getActivity());
140
141         manager.getAuthToken(
142                 accout,
143                 "oauth2:" + ApiaryClientFactory.OAUTH_SCOPE, null /* options */, getActivity(),
144                 new AccountManagerCallback<Bundle>() {
145                     @Override
146                     public void run(AccountManagerFuture<Bundle> future) {
147                         try {
148                             mOAuthToken = future.getResult().getString(
149                                     AccountManager.KEY_AUTHTOKEN);
150                             updateList();
151                         } catch (Exception e) {
152                             Log.d(TAG, "Failed to get token: ", e);
153                         }
154                     }
155                 }, null);
156     }
157
158     public void updateList() {
159         new UpdateListAction().execute();
160     }
161
162     private final class ConnectAction implements MenuItem.OnMenuItemClickListener {
163         @Override
164         public boolean onMenuItemClick(MenuItem item) {
165             if (mOAuthToken != null && mSelected != null) {
166                 connect(mOAuthToken, mSelected.id);
167                 return true;
168             }
169             return false;
170         }
171     }
172
173     private abstract class AsyncAction extends AsyncTask<Void, Void, Boolean>
174             implements MenuItem.OnMenuItemClickListener {
175         private final String mActionName;
176
177         protected AsyncAction(String actionName) {
178             mActionName = actionName;
179         }
180
181         @Override
182         public boolean onMenuItemClick(MenuItem item) {
183             execute();
184             return true;
185         }
186
187         @Override
188         protected final Boolean doInBackground(Void... args) {
189             try {
190                 doInBackgroundImpl();
191                 return Boolean.TRUE;
192             } catch (IOException e) {
193                 Log.e(TAG, mActionName + " failed", e);
194                 return Boolean.FALSE;
195             }
196         }
197
198         @Override
199         protected void onPostExecute(Boolean success) {
200             if (Boolean.TRUE.equals(success)) {
201                 onSuccess();
202                 showToast(mActionName + " completed");
203             } else {
204                 onFailure();
205                 showToast(mActionName + " failed");
206             }
207         }
208
209         protected void showToast(String message) {
210             Toast.makeText(getActivity(), message, Toast.LENGTH_SHORT).show();
211         }
212
213         protected abstract void doInBackgroundImpl() throws IOException;
214         protected abstract void onSuccess();
215         protected void onFailure() {}
216     }
217
218     private final class SendInvalidOfferAction extends AsyncAction {
219         private final String mOAuthTokenCopy = mOAuthToken;
220         private final RemoteInstance mSelectedCopy = mSelected;
221         private IOException mException;
222
223         public SendInvalidOfferAction() {
224             super("Sending invalid offer");
225         }
226
227         @Override
228         protected final void doInBackgroundImpl() throws IOException {
229             if (mOAuthTokenCopy == null || mSelected == null) {
230                 throw new IOException("Action cann't be applied.");
231             }
232
233             final String sessionId = "sessionId";
234             final String offer = "INVALID_OFFER";
235             final RTCConfiguration config = new RTCConfiguration();
236
237             CommandSender sender = new CommandSender() {
238                 @Override
239                 protected void send(Command command, Runnable completionCallback) {
240                     try {
241                         mClientFactory.newTestGCDClient(mOAuthTokenCopy)
242                                 .send(mSelectedCopy.id, command);
243                     } catch (IOException e) {
244                         mException = e;
245                         command.setFailure("IO exception");
246                     } finally {
247                         completionCallback.run();
248                     }
249                 }
250             };
251
252             sender.startSession(sessionId, config, offer, new SessionBase.NegotiationCallback() {
253                 @Override
254                 public void onSuccess(String answer) {
255                     mException = new IOException("Unexpected success");
256                 }
257
258                 @Override
259                 public void onFailure(String errorMessage) {
260                     Log.i(TAG, "Expected failure: " + errorMessage);
261                 }
262             });
263
264             if (mException != null)
265                 throw mException;
266         }
267
268         @Override
269         protected void onSuccess() {
270         }
271     }
272
273     private final class UpdateListAction extends AsyncAction {
274         private final String mOAuthTokenCopy = mOAuthToken;
275         private List<RemoteInstance> mResult;
276
277         public UpdateListAction() {
278             super("Updating instance list");
279         }
280
281         @Override
282         protected final void doInBackgroundImpl() throws IOException {
283             if (mOAuthTokenCopy == null) return;
284
285             mResult = mClientFactory.newTestGCDClient(mOAuthTokenCopy).fetchInstances();
286         }
287
288         @Override
289         protected void onSuccess() {
290             mListAdapter.clear();
291             if (mOAuthTokenCopy == null) {
292                 mListAdapter.add(new RemoteInstance(NO_ID, "Sign in"));
293             } else if (mResult.size() > 0) {
294                 mListAdapter.addAll(mResult);
295             } else {
296                 mListAdapter.add(new RemoteInstance(NO_ID, "Empty list"));
297             }
298         }
299
300         @Override
301         protected void onFailure() {
302             mListAdapter.clear();
303             mListAdapter.add(new RemoteInstance(NO_ID, "Update failed"));
304         }
305
306         @Override
307         protected void showToast(String message) {}
308     }
309
310     private final class DeleteInstanceAction extends AsyncAction {
311         private final String mOAuthTokenCopy = mOAuthToken;
312         private final RemoteInstance mInstance;
313
314         public DeleteInstanceAction(RemoteInstance instance) {
315             super("Deleting instance");
316             mInstance = instance;
317         }
318
319         @Override
320         protected final void doInBackgroundImpl() throws IOException {
321             mClientFactory.newTestGCDClient(mOAuthTokenCopy).deleteInstance(mInstance.id);
322         }
323
324         @Override
325         protected void onSuccess() {
326             updateList();
327         }
328     }
329
330     private final class DeleteAllAction extends AsyncAction {
331         private final String mOAuthTokenCopy = mOAuthToken;
332
333         public DeleteAllAction() {
334             super("Deleting all");
335         }
336
337         @Override
338         protected final void doInBackgroundImpl() throws IOException {
339             for (RemoteInstance instance :
340                         mClientFactory.newTestGCDClient(mOAuthTokenCopy).fetchInstances()) {
341                 mClientFactory.newTestGCDClient(mOAuthTokenCopy).deleteInstance(instance.id);
342             }
343         }
344
345         @Override
346         protected void onSuccess() {
347             updateList();
348         }
349     }
350 }