blob: f327b106f31a7b58130df39442046ca499165b21 [file] [log] [blame]
// Copyright 2016 The Vanadium 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 io.v.syncbase.android;
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.FragmentTransaction;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
public class LoginFragment extends Fragment {
private static final String TAG = "LoginFragment";
private static final int REQUEST_CODE_PICK_ACCOUNT = 1000;
private static final int REQUEST_CODE_USER_APPROVAL = 1001;
private static final String OAUTH_SCOPE =
"oauth2:https://www.googleapis.com/auth/userinfo.email";
private static final String ACCOUNT_TYPE = "com.google";
private String mGoogleAccount = "";
private TokenReceiver tokenReceiver;
public LoginFragment() {}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Note: newChooseAccountIntent is deprecated, but the API level we're targeting is < 23,
// which is when the replacement is introduced. If we do upgrade to API v23, just remove the
// "false" parameter.
Intent accountIntent = AccountManager.newChooseAccountIntent(
null, null, new String[]{ACCOUNT_TYPE}, false, null, null, null, null);
startActivityForResult(accountIntent, REQUEST_CODE_PICK_ACCOUNT);
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case REQUEST_CODE_PICK_ACCOUNT:
if (resultCode != Activity.RESULT_OK) {
Log.e(TAG, "User didn't pick account: " + resultCode);
return;
}
mGoogleAccount = data.getStringExtra(AccountManager.KEY_ACCOUNT_NAME);
Log.i(TAG, "Account name: " + mGoogleAccount);
getAccessToken();
break;
case REQUEST_CODE_USER_APPROVAL:
if (resultCode != Activity.RESULT_OK) {
Log.e(TAG, "User didn't give proposed permissions: " + resultCode);
return;
}
getAccessToken();
break;
}
super.onActivityResult(requestCode, resultCode, data);
}
// Call this immediately after fragment creation.
public void setTokenReceiver(TokenReceiver receiver) {
tokenReceiver = receiver;
}
public interface TokenReceiver {
void receiveToken(String token);
}
private void getAccessToken() {
Account account = new Account(mGoogleAccount, ACCOUNT_TYPE);
AccountManager.get(this.getActivity()).getAuthToken(
account,
OAUTH_SCOPE,
new Bundle(),
false,
new OnTokenAcquired(this),
new Handler(new Handler.Callback() {
@Override
public boolean handleMessage(Message msg) {
Log.e(TAG, "Error getting auth token: " + msg.toString());
return true;
}
}));
}
private class OnTokenAcquired implements AccountManagerCallback<Bundle> {
private final Fragment fragment;
OnTokenAcquired(Fragment fragment) {
this.fragment = fragment;
}
@Override
public void run(AccountManagerFuture<Bundle> result) {
try {
Bundle bundle = result.getResult();
Intent launch = (Intent) bundle.get(AccountManager.KEY_INTENT);
if (launch != null) {
launch.setFlags(0);
startActivityForResult(launch, REQUEST_CODE_USER_APPROVAL);
return;
}
String token = bundle.getString(AccountManager.KEY_AUTHTOKEN);
Log.i(TAG, "token: " + token);
tokenReceiver.receiveToken(token);
} catch (Exception e) {
Log.e(TAG, "onTokenAcquired errored", e);
}
// The token has been acquired (or failed). Remove the fragment.
FragmentTransaction transaction = getActivity().getFragmentManager().beginTransaction();
transaction.remove(fragment);
transaction.commit();
}
}
}