// Copyright (C) 2016 DigiGene, (www.DigiGene.com)(alinhayati[at]gmail[dot]com) // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package com.digigene.accountauthenticator; import android.accounts.AbstractAccountAuthenticator; import android.accounts.Account; import android.accounts.AccountAuthenticatorResponse; import android.accounts.AccountManager; import android.accounts.NetworkErrorException; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.os.Bundle; import android.preference.PreferenceManager; import android.support.annotation.NonNull; import android.util.Log; import com.digigene.accountauthenticator.activity.RegistrationActivity; public class AppAccountAuthenticator extends AbstractAccountAuthenticator { private Context context; private Class<? extends RegistrationActivity> registrationActivityClass; public AppAccountAuthenticator(Context context) { super(context); this.context = context; loadRegistrationClassFromSharedPref(); } @Override public Bundle addAccount(AccountAuthenticatorResponse response, String accountType, String authTokenType, String[] requiredFeatures, Bundle options) throws NetworkErrorException { Intent intent = makeIntent(response, accountType, authTokenType, requiredFeatures, options); Bundle bundle = makeBundle(intent); return bundle; } @Override public Bundle getAuthToken(AccountAuthenticatorResponse response, Account account, String authTokenType, Bundle options) throws NetworkErrorException { AuthenticatorManager authenticatorManager = AuthenticatorManager.authenticatorManager; Bundle result; AccountManager accountManager = AccountManager.get(context); // case 1: access token is available result = authenticatorManager.getAccessTokenFromCache(account, authTokenType, accountManager); if (result != null) { return result; } final String refreshToken = accountManager.getPassword(account); // case 2: access token is not available but refresh token is if (refreshToken != null) { result = authenticatorManager.makeResultBundle(account, refreshToken, null); return result; } // case 3: neither tokens is available but the account exists if (isAccountAvailable(account, accountManager)) { result = authenticatorManager.makeResultBundle(account, null, null); return result; } // case 4: account does not exist return new Bundle(); } @Override public String getAuthTokenLabel(String authTokenType) { return null; } @Override public Bundle confirmCredentials(AccountAuthenticatorResponse response, Account account, Bundle options) throws NetworkErrorException { return null; } @Override public Bundle editProperties(AccountAuthenticatorResponse response, String accountType) { return null; } @Override public Bundle updateCredentials(AccountAuthenticatorResponse response, Account account, String authTokenType, Bundle options) throws NetworkErrorException { return null; } @Override public Bundle hasFeatures(AccountAuthenticatorResponse response, Account account, String[] features) throws NetworkErrorException { return null; } private boolean isAccountAvailable(Account account, AccountManager accountManager) { Account[] availableAccounts = accountManager.getAccountsByType(account.type); for (Account availableAccount : availableAccounts) { if (account.name.equals(availableAccount.name) && account.type.equals(availableAccount.type)) { return true; } } return false; } private void loadRegistrationClassFromSharedPref() { SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context); String registrationActivityClassName = sharedPreferences.getString(AuthenticatorManager.KEY_REGISTRATION_ACTIVITY_CLASS_NAME, RegistrationActivity.class.getName()); try { registrationActivityClass = (Class<? extends RegistrationActivity>) Class.forName(registrationActivityClassName); } catch (ClassNotFoundException e) { e.printStackTrace(); Log.d("AppAccountAuthenticator", "The class name for RegistrationActivity is not correct or it does not extend " + RegistrationActivity.class.getName()); } } @NonNull private Bundle makeBundle(Intent intent) { Bundle bundle = new Bundle(); bundle.putParcelable(AccountManager.KEY_INTENT, intent); return bundle; } @NonNull private Intent makeIntent(AccountAuthenticatorResponse response, String accountType, String authTokenType, String[] requiredFeatures, Bundle options) { Intent intent = new Intent(context, registrationActivityClass); intent.putExtra(AccountManager.KEY_ACCOUNT_TYPE, accountType); intent.putExtra(AuthenticatorManager.KEY_AUTH_TOKEN_TYPE, authTokenType); intent.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE, response); intent.putExtra(AuthenticatorManager.KEY_REQUIRED_FEATURES, requiredFeatures); intent.putExtra(AuthenticatorManager.KEY_AUTH_ACCOUNT_OPTIONS, options); return intent; } }