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

Unified Diff: components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/ui/GCDRegistrationFragment.java

Issue 677843006: Registration of DevTools bridge in GCD. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@gcm-signaling
Patch Set: Created 6 years, 2 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 side-by-side diff with in-line comments
Download patch
Index: components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/ui/GCDRegistrationFragment.java
diff --git a/components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/ui/GCDRegistrationFragment.java b/components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/ui/GCDRegistrationFragment.java
new file mode 100644
index 0000000000000000000000000000000000000000..9e8dafa2357848670a2ed50a56f70db8f6fe1acc
--- /dev/null
+++ b/components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/ui/GCDRegistrationFragment.java
@@ -0,0 +1,283 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.components.devtools_bridge.ui;
+
+import android.accounts.Account;
+import android.accounts.AccountManager;
+import android.accounts.AccountManagerCallback;
+import android.accounts.AccountManagerFuture;
+import android.app.Activity;
+import android.app.Fragment;
+import android.app.ProgressDialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.util.Log;
+import android.widget.Toast;
+
+import org.chromium.components.devtools_bridge.apiary.ApiaryClientFactory;
+import org.chromium.components.devtools_bridge.apiary.OAuthResult;
+import org.chromium.components.devtools_bridge.gcd.InstanceCredential;
+import org.chromium.components.devtools_bridge.gcd.InstanceDescription;
+
+import java.io.IOException;
+
+/**
+ * Fragment that responsible for:
+ * 1. Displaying GCD registration status.
+ * 2. Instance registration.
+ * 3. Instance unregistration.
+ *
+ * Fragment is abstract and does not provide UI controls. Descendant is responsible for it.
+ * It also should have actionable item for registration/unregistration which invokes
+ * appropriate methods.
+ */
+public abstract class GCDRegistrationFragment extends Fragment {
+ private static final String TAG = "GCDRegistrationFragment";
+ private static final int CODE_ACCOUNT_SELECTED = 1;
+
+ private ApiaryClientFactory mClientFactory;
+ private Account mSelectedAccount = null;
+
+ private InstanceCredential mInstanceCredential;
+ private String mOwnerEmail;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ mClientFactory = newClientFactory();
+ super.onCreate(savedInstanceState);
+ }
+
+ @Override
+ public void onDestroy() {
+ super.onDestroy();
+ mClientFactory.close();
+ }
+
+ public void register() {
+ AccountManager manager = AccountManager.get(getActivity());
+
+ Intent intent = manager.newChooseAccountIntent(
+ mSelectedAccount,
+ null /* allowableAccounts */,
+ new String[] { "com.google" } /* allowableAccountTypes */,
+ true /* alwaysPromptForAccount */,
+ "Registration in GCD" /* descriptionOverrideText */,
+ null /* addAccountAuthTokenType */,
+ null /* addAccountRequiredFeatures */,
+ null /* addAccountOptions */);
+ startActivityForResult(intent, CODE_ACCOUNT_SELECTED);
+ }
+
+ public void unregister() {
+ if (mInstanceCredential == null) return;
+
+ new RegistrationTask("Unregistering instance") {
+ private InstanceCredential mInstranceCredentialCopy = mInstanceCredential;
+
+ @Override
+ protected void doInBackgroundImpl() throws IOException, InterruptedException {
+ OAuthResult result = mClientFactory.newOAuthClient()
+ .authenticate(mInstranceCredentialCopy.secret);
+
+ checkInterrupted();
+
+ Log.d(TAG, "Access token: " + result.accessToken);
+
+ mClientFactory.newGCDClient(result.accessToken)
+ .deleteInstance(mInstranceCredentialCopy.id);
+ }
+
+ @Override
+ protected void onSuccess() {
+ saveRegistration(null, null, null);
+ onRegistrationStatusChange();
+ showToast("Unregistered");
+ }
+
+ @Override
+ protected void onFailure(Exception e) {
+ Log.e(TAG, "Unregistration failed", e);
+ showToast("Unregistration failed. See log for details.");
+ }
+ }.execute();
+ }
+
+ public boolean isRegistered() {
+ return mInstanceCredential != null;
+ }
+
+ public String getOwner() {
+ return mOwnerEmail;
+ }
+
+ public void queryOAuthToken() {
+ if (mSelectedAccount == null) return;
+
+ AccountManager manager = AccountManager.get(getActivity());
+
+ final String ownerEmail = mSelectedAccount.name;
+
+ manager.getAuthToken(
+ mSelectedAccount,
+ "oauth2:" + ApiaryClientFactory.OAUTH_SCOPE, null /* options */, getActivity(),
+ new AccountManagerCallback<Bundle>() {
+ @Override
+ public void run(AccountManagerFuture<Bundle> future) {
+ try {
+ String token = future.getResult().getString(
+ AccountManager.KEY_AUTHTOKEN);
+ register(ownerEmail, token);
+ } catch (Exception e) {
+ Log.e(TAG, "Failed to get token: ", e);
+ }
+ }
+ }, null);
+ }
+
+ private void register(final String ownerEmail, final String oAuthToken) {
+ new RegistrationTask("Registering instance") {
+ private Context mContext;
+
+ private String mDisplayName;
+ private InstanceDescription mDescription;
+ private InstanceCredential mCredential;
+
+ @Override
+ protected void onPreExecute() {
+ mContext = getActivity();
+
+ mDisplayName = generateDisplayName();
+ super.onPreExecute();
+ }
+
+ @Override
+ protected void doInBackgroundImpl() throws IOException, InterruptedException {
+ String ticketId = mClientFactory.newGCDClient(oAuthToken)
+ .createRegistrationTicket();
+
+ checkInterrupted();
+
+ String gcmChannelId =
+ mClientFactory.newGCMRegistrar().blockingGetRegistrationId(mContext);
+
+ mDescription = new InstanceDescription.Builder()
+ .setOAuthClientId(mClientFactory.getOAuthClientId())
+ .setGCMChannelId(gcmChannelId)
+ .setDisplayName(mDisplayName)
+ .build();
+
+ mClientFactory.newAnonymousGCDClient().patchRegistrationTicket(
+ ticketId, mDescription);
+
+ checkInterrupted();
+
+ mCredential = mClientFactory.newAnonymousGCDClient().finalizeRegistration(ticketId);
+ }
+
+ @Override
+ protected void onSuccess() {
+ saveRegistration(mDescription, mCredential, ownerEmail);
+ onRegistrationStatusChange();
+ showToast("Registered");
+ }
+
+ @Override
+ protected void onFailure(Exception e) {
+ Log.e(TAG, "Registration failed", e);
+ showToast("Registration failed. See log for details.");
+ }
+ }.execute();
+ }
+
+ @Override
+ public void onActivityResult(final int requestCode, final int resultCode, final Intent data) {
+ if (requestCode == CODE_ACCOUNT_SELECTED && resultCode == Activity.RESULT_OK) {
+ mSelectedAccount = new Account(
+ data.getStringExtra(AccountManager.KEY_ACCOUNT_NAME),
+ data.getStringExtra(AccountManager.KEY_ACCOUNT_TYPE));
+ Log.d(TAG, "Selected account=" + mSelectedAccount);
+ queryOAuthToken();
+ }
+ }
+
+ private void saveRegistration(
+ InstanceDescription description, InstanceCredential credential, String ownerEmail) {
+ // TODO(serya): Make registration persistant.
+ mInstanceCredential = credential;
+ mOwnerEmail = ownerEmail;
+ onRegistrationStatusChange();
+ }
+
+ protected abstract void onRegistrationStatusChange();
+ protected abstract ApiaryClientFactory newClientFactory();
+ protected abstract String generateDisplayName();
+
+ private abstract class RegistrationTask extends AsyncTask<Void, Void, Boolean> {
+ private ProgressDialog mDialog;
+ private Exception mException;
+
+ private final String mProgressMessage;
+
+ protected RegistrationTask(String progressMessage) {
+ mProgressMessage = progressMessage;
+ }
+
+ @Override
+ protected void onPreExecute() {
+ mDialog = ProgressDialog.show(
+ getActivity(),
+ "GCD registration",
+ mProgressMessage,
+ true,
+ false,
+ new DialogInterface.OnCancelListener() {
+ @Override
+ public void onCancel(DialogInterface dialog) {
+ cancel(true);
+ }
+ });
+ }
+
+ @Override
+ protected final Boolean doInBackground(Void... args) {
+ try {
+ doInBackgroundImpl();
+ return Boolean.TRUE;
+ } catch (IOException e) {
+ mException = e;
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ }
+ return Boolean.FALSE;
+ }
+
+ protected final void checkInterrupted() throws InterruptedException {
+ if (Thread.currentThread().isInterrupted()) {
+ throw new InterruptedException();
+ }
+ }
+
+ @Override
+ protected void onPostExecute(Boolean success) {
+ mDialog.dismiss();
+ if (Boolean.TRUE.equals(success)) {
+ onSuccess();
+ } else if (mException != null) {
+ onFailure(mException);
+ }
+ }
+
+ protected void showToast(String message) {
+ Toast.makeText(getActivity(), message, Toast.LENGTH_SHORT).show();
+ }
+
+ protected abstract void doInBackgroundImpl() throws IOException, InterruptedException;
+ protected abstract void onSuccess();
+ protected abstract void onFailure(Exception e);
+ }
+}

Powered by Google App Engine
This is Rietveld 408576698