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

Unified Diff: services/authentication/src/org/chromium/mojo/authentication/AuthenticationServiceImpl.java

Issue 1116653002: Introduce authentication service. (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Created 5 years, 8 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: services/authentication/src/org/chromium/mojo/authentication/AuthenticationServiceImpl.java
diff --git a/services/authentication/src/org/chromium/mojo/authentication/AuthenticationServiceImpl.java b/services/authentication/src/org/chromium/mojo/authentication/AuthenticationServiceImpl.java
new file mode 100644
index 0000000000000000000000000000000000000000..1248d906ac149a8bee8272a6f3d52fc653f6e97c
--- /dev/null
+++ b/services/authentication/src/org/chromium/mojo/authentication/AuthenticationServiceImpl.java
@@ -0,0 +1,192 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
ppi 2015/04/29 13:32:23 2015
qsr 2015/04/29 14:22:20 Done.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.mojo.authentication;
+
+import android.accounts.AccountManager;
+import android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Parcel;
+
+import com.google.android.gms.auth.GoogleAuthException;
+import com.google.android.gms.auth.GoogleAuthUtil;
+import com.google.android.gms.auth.UserRecoverableAuthException;
+import com.google.android.gms.common.AccountPicker;
+
+import org.chromium.mojo.application.ShellHelper;
+import org.chromium.mojo.bindings.SideEffectFreeCloseable;
+import org.chromium.mojo.intent.IntentReceiver;
+import org.chromium.mojo.intent.IntentReceiverManager;
+import org.chromium.mojo.intent.IntentReceiverManager.RegisterActivityResultResponse;
+import org.chromium.mojo.system.Core;
+import org.chromium.mojo.system.MojoException;
+import org.chromium.mojom.mojo.Shell;
+
+import java.io.IOException;
+
+/**
+ * Implementation of AuthenticationService from services/authentication/authentication.mojom
+ */
+public class AuthenticationServiceImpl
+ extends SideEffectFreeCloseable implements AuthenticationService {
+ /**
+ * An callback that takes a serialized intent, add the intent the shell needs to send and start
+ * the container intent.
+ */
+ private final class TrampolineResponse implements RegisterActivityResultResponse {
ppi 2015/04/29 13:32:24 Should this be called RegisterStartActivityForResu
qsr 2015/04/29 14:22:20 Hum, I have no strong opinion, so done.
+ /**
+ * The intent the shell need to send.
ppi 2015/04/29 13:32:24 s/need/needs/
qsr 2015/04/29 14:22:20 Done.
+ */
+ private final Intent mIntent;
+
+ private TrampolineResponse(Intent intent) {
+ this.mIntent = intent;
ppi 2015/04/29 13:32:23 nit: "this." is probably not needed.
qsr 2015/04/29 14:22:20 Done.
+ }
+
+ /**
+ * @see RegisterActivityResultResponse#call(byte[])
+ */
+ @Override
+ public void call(byte[] serializedIntent) {
+ Intent trampolineIntent = bytesToIntent(serializedIntent);
+ trampolineIntent.putExtra("intent", mIntent);
+ mContext.startService(trampolineIntent);
+ }
+ }
+
+ private final Activity mContext;
+ private final String mConsumerURL;
+ private final IntentReceiverManager mIntentReceiverManager;
+
+ public AuthenticationServiceImpl(Context context, Core core, String consumerURL, Shell shell) {
+ mContext = (Activity) context;
+ mConsumerURL = consumerURL;
+ mIntentReceiverManager = ShellHelper.connectToService(
+ core, shell, "mojo:android_handler", IntentReceiverManager.MANAGER);
+ }
+
+ /**
+ * @see AuthenticationService#onConnectionError(MojoException)
+ */
+ @Override
+ public void onConnectionError(MojoException e) {}
+
+ /**
+ * @see AuthenticationService#getOAuth2Token(String, String[],
+ * AuthenticationService.GetOAuth2TokenResponse)
+ */
+ @Override
+ public void getOAuth2Token(
+ final String username, final String[] scopes, final GetOAuth2TokenResponse callback) {
+ if (scopes.length == 0) {
+ callback.call(null);
+ return;
+ }
+ StringBuilder scope = new StringBuilder("oauth2:");
+ for (int i = 0; i < scopes.length; ++i) {
ppi 2015/04/29 13:32:23 Can we use http://developer.android.com/reference/
qsr 2015/04/29 14:22:20 We could, and I will if you insist, but this is a
+ if (i > 0) {
+ scope.append(" ");
+ }
+ scope.append(scopes[i]);
+ }
+ String token = null;
+ try {
+ token = GoogleAuthUtil.getToken(mContext, username, scope.toString());
+ } catch (final UserRecoverableAuthException e) {
ppi 2015/04/29 13:32:23 Could you add a comment explaining when we would e
qsr 2015/04/29 14:22:20 Done.
+ mIntentReceiverManager.registerActivityResult(new IntentReceiver() {
+ GetOAuth2TokenResponse mCurrentCallback = callback;
+
+ @Override
+ public void close() {
+ call(null);
+ }
+
+ @Override
+ public void onConnectionError(MojoException e) {
+ call(null);
+ }
+
+ @Override
+ public void onIntent(byte[] bytes) {
+ if (mCurrentCallback == null) {
+ return;
+ }
+ getOAuth2Token(username, scopes, mCurrentCallback);
+ mCurrentCallback = null;
+ }
+
+ private void call(String token) {
+ if (mCurrentCallback == null) {
+ return;
+ }
+ mCurrentCallback.call(token);
+ mCurrentCallback = null;
+ }
+ }, new TrampolineResponse(e.getIntent()));
+ return;
+ } catch (IOException | GoogleAuthException e) {
+ // Unrecoverable error. A null token will be send to the client.
ppi 2015/04/29 13:32:24 Should we log something informative here?
qsr 2015/04/29 14:22:20 Added an error to the protocol -> we are sending t
+ }
+ callback.call(token);
+ }
+
+ /**
+ * @see AuthenticationService#selectAccount(AuthenticationService.SelectAccountResponse)
+ */
+ @Override
+ public void selectAccount(final SelectAccountResponse callback) {
+ String[] accountTypes = new String[] {"com.google"};
tonyg 2015/04/29 13:47:43 The mojom doesn't specify that this only produces
qsr 2015/04/29 14:22:20 This param is android specific, so passing it in s
+ String message = "Select an account to use with application: " + mConsumerURL;
tonyg 2015/04/29 13:47:43 I wonder whether we should make this message a lit
qsr 2015/04/29 14:22:20 This part is only sending the identity of an accou
+ Intent accountPickerIntent = AccountPicker.newChooseAccountIntent(
+ null, null, accountTypes, false, message, null, null, null);
+
+ mIntentReceiverManager.registerActivityResult(new IntentReceiver() {
+ SelectAccountResponse mCurrentCallback = callback;
+
+ @Override
+ public void close() {
+ call(null);
+ }
+
+ @Override
+ public void onConnectionError(MojoException e) {
+ call(null);
+ }
+
+ @Override
+ public void onIntent(byte[] bytes) {
+ Intent intent = bytesToIntent(bytes);
+ call(intent.getStringExtra(AccountManager.KEY_ACCOUNT_NAME));
+ }
+
+ private void call(String username) {
+ if (mCurrentCallback == null) {
+ return;
+ }
+ mCurrentCallback.call(username);
+ mCurrentCallback = null;
+ }
+ }, new TrampolineResponse(accountPickerIntent));
+ }
+
+ /**
+ * @see AuthenticationService#clearOAuth2Token(String)
+ */
+ @Override
+ public void clearOAuth2Token(String token) {
+ try {
+ GoogleAuthUtil.clearToken(mContext, token);
+ } catch (GoogleAuthException | IOException e) {
+ // Nothing to do.
ppi 2015/04/29 13:32:24 Should we log something informative here?
qsr 2015/04/29 14:22:20 Not really. On a failure here, there is absolutely
+ }
+ }
+
+ private static Intent bytesToIntent(byte[] bytes) {
+ Parcel p = Parcel.obtain();
+ p.unmarshall(bytes, 0, bytes.length);
+ p.setDataPosition(0);
+ return Intent.CREATOR.createFromParcel(p);
+ }
+}

Powered by Google App Engine
This is Rietveld 408576698