1c5afb16430a145f20d7c887e45f47b38687054daMarc Blank/* 2c5afb16430a145f20d7c887e45f47b38687054daMarc Blank * Copyright (C) 2009 The Android Open Source Project 3c5afb16430a145f20d7c887e45f47b38687054daMarc Blank * 4c5afb16430a145f20d7c887e45f47b38687054daMarc Blank * Licensed under the Apache License, Version 2.0 (the "License"); 5c5afb16430a145f20d7c887e45f47b38687054daMarc Blank * you may not use this file except in compliance with the License. 6c5afb16430a145f20d7c887e45f47b38687054daMarc Blank * You may obtain a copy of the License at 7c5afb16430a145f20d7c887e45f47b38687054daMarc Blank * 8c5afb16430a145f20d7c887e45f47b38687054daMarc Blank * http://www.apache.org/licenses/LICENSE-2.0 9c5afb16430a145f20d7c887e45f47b38687054daMarc Blank * 10c5afb16430a145f20d7c887e45f47b38687054daMarc Blank * Unless required by applicable law or agreed to in writing, software 11c5afb16430a145f20d7c887e45f47b38687054daMarc Blank * distributed under the License is distributed on an "AS IS" BASIS, 12c5afb16430a145f20d7c887e45f47b38687054daMarc Blank * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13c5afb16430a145f20d7c887e45f47b38687054daMarc Blank * See the License for the specific language governing permissions and 14c5afb16430a145f20d7c887e45f47b38687054daMarc Blank * limitations under the License. 15c5afb16430a145f20d7c887e45f47b38687054daMarc Blank */ 16c5afb16430a145f20d7c887e45f47b38687054daMarc Blank 17c5afb16430a145f20d7c887e45f47b38687054daMarc Blankpackage com.android.email.service; 18c5afb16430a145f20d7c887e45f47b38687054daMarc Blank 196a51abdf6e15e6cc28948ef163d3673adc6f6e7fMartin Hibdonimport com.android.email.service.EmailServiceUtils.EmailServiceInfo; 20bb68c13afa630cae058eb40d3ce68644f3f3c8b9Paul Westbrookimport com.android.email.setup.AuthenticatorSetupIntentHelper; 21c5afb16430a145f20d7c887e45f47b38687054daMarc Blankimport com.android.emailcommon.provider.EmailContent; 22c5afb16430a145f20d7c887e45f47b38687054daMarc Blank 23c5afb16430a145f20d7c887e45f47b38687054daMarc Blankimport android.accounts.AbstractAccountAuthenticator; 24c5afb16430a145f20d7c887e45f47b38687054daMarc Blankimport android.accounts.Account; 25c5afb16430a145f20d7c887e45f47b38687054daMarc Blankimport android.accounts.AccountAuthenticatorResponse; 26c5afb16430a145f20d7c887e45f47b38687054daMarc Blankimport android.accounts.AccountManager; 27c5afb16430a145f20d7c887e45f47b38687054daMarc Blankimport android.accounts.NetworkErrorException; 28c5afb16430a145f20d7c887e45f47b38687054daMarc Blankimport android.app.Service; 29c5afb16430a145f20d7c887e45f47b38687054daMarc Blankimport android.content.ContentResolver; 30c5afb16430a145f20d7c887e45f47b38687054daMarc Blankimport android.content.Context; 31c5afb16430a145f20d7c887e45f47b38687054daMarc Blankimport android.content.Intent; 32c5afb16430a145f20d7c887e45f47b38687054daMarc Blankimport android.os.Bundle; 33c5afb16430a145f20d7c887e45f47b38687054daMarc Blankimport android.os.IBinder; 34c5afb16430a145f20d7c887e45f47b38687054daMarc Blankimport android.provider.CalendarContract; 35c5afb16430a145f20d7c887e45f47b38687054daMarc Blankimport android.provider.ContactsContract; 36c5afb16430a145f20d7c887e45f47b38687054daMarc Blank 37c5afb16430a145f20d7c887e45f47b38687054daMarc Blank/** 38c5afb16430a145f20d7c887e45f47b38687054daMarc Blank * A very basic authenticator service for EAS. At the moment, it has no UI hooks. When called 39c5afb16430a145f20d7c887e45f47b38687054daMarc Blank * with addAccount, it simply adds the account to AccountManager directly with a username and 40c5afb16430a145f20d7c887e45f47b38687054daMarc Blank * password. 41c5afb16430a145f20d7c887e45f47b38687054daMarc Blank */ 42c5afb16430a145f20d7c887e45f47b38687054daMarc Blankpublic class AuthenticatorService extends Service { 43c5afb16430a145f20d7c887e45f47b38687054daMarc Blank public static final String OPTIONS_USERNAME = "username"; 44c5afb16430a145f20d7c887e45f47b38687054daMarc Blank public static final String OPTIONS_PASSWORD = "password"; 45c5afb16430a145f20d7c887e45f47b38687054daMarc Blank public static final String OPTIONS_CONTACTS_SYNC_ENABLED = "contacts"; 46c5afb16430a145f20d7c887e45f47b38687054daMarc Blank public static final String OPTIONS_CALENDAR_SYNC_ENABLED = "calendar"; 47c5afb16430a145f20d7c887e45f47b38687054daMarc Blank public static final String OPTIONS_EMAIL_SYNC_ENABLED = "email"; 48c5afb16430a145f20d7c887e45f47b38687054daMarc Blank 49c5afb16430a145f20d7c887e45f47b38687054daMarc Blank class Authenticator extends AbstractAccountAuthenticator { 50c5afb16430a145f20d7c887e45f47b38687054daMarc Blank 51c5afb16430a145f20d7c887e45f47b38687054daMarc Blank public Authenticator(Context context) { 52c5afb16430a145f20d7c887e45f47b38687054daMarc Blank super(context); 53c5afb16430a145f20d7c887e45f47b38687054daMarc Blank } 54c5afb16430a145f20d7c887e45f47b38687054daMarc Blank 55c5afb16430a145f20d7c887e45f47b38687054daMarc Blank @Override 56c5afb16430a145f20d7c887e45f47b38687054daMarc Blank public Bundle addAccount(AccountAuthenticatorResponse response, String accountType, 57c5afb16430a145f20d7c887e45f47b38687054daMarc Blank String authTokenType, String[] requiredFeatures, Bundle options) 58c5afb16430a145f20d7c887e45f47b38687054daMarc Blank throws NetworkErrorException { 59c5afb16430a145f20d7c887e45f47b38687054daMarc Blank 606a51abdf6e15e6cc28948ef163d3673adc6f6e7fMartin Hibdon final String protocol = EmailServiceUtils.getProtocolFromAccountType( 616a51abdf6e15e6cc28948ef163d3673adc6f6e7fMartin Hibdon AuthenticatorService.this, accountType); 626a51abdf6e15e6cc28948ef163d3673adc6f6e7fMartin Hibdon final EmailServiceInfo info = EmailServiceUtils.getServiceInfo( 636a51abdf6e15e6cc28948ef163d3673adc6f6e7fMartin Hibdon AuthenticatorService.this, protocol); 646a51abdf6e15e6cc28948ef163d3673adc6f6e7fMartin Hibdon 656a51abdf6e15e6cc28948ef163d3673adc6f6e7fMartin Hibdon // There are two cases here: 66c5afb16430a145f20d7c887e45f47b38687054daMarc Blank // 1) We are called with a username/password; this comes from the traditional email 67c5afb16430a145f20d7c887e45f47b38687054daMarc Blank // app UI; we simply create the account and return the proper bundle 68c5afb16430a145f20d7c887e45f47b38687054daMarc Blank if (options != null && options.containsKey(OPTIONS_PASSWORD) 69c5afb16430a145f20d7c887e45f47b38687054daMarc Blank && options.containsKey(OPTIONS_USERNAME)) { 70c5afb16430a145f20d7c887e45f47b38687054daMarc Blank final Account account = new Account(options.getString(OPTIONS_USERNAME), 71c5afb16430a145f20d7c887e45f47b38687054daMarc Blank accountType); 72c5afb16430a145f20d7c887e45f47b38687054daMarc Blank AccountManager.get(AuthenticatorService.this).addAccountExplicitly( 73c5afb16430a145f20d7c887e45f47b38687054daMarc Blank account, options.getString(OPTIONS_PASSWORD), null); 74c5afb16430a145f20d7c887e45f47b38687054daMarc Blank 75c5afb16430a145f20d7c887e45f47b38687054daMarc Blank // Set up contacts syncing, if appropriate 76473ce1fa354c81fd7d5bbd84b6a85d629a039e72Tony Mantler if (info != null && info.syncContacts) { 776a51abdf6e15e6cc28948ef163d3673adc6f6e7fMartin Hibdon boolean syncContacts = options.getBoolean(OPTIONS_CONTACTS_SYNC_ENABLED, false); 78c5afb16430a145f20d7c887e45f47b38687054daMarc Blank ContentResolver.setIsSyncable(account, ContactsContract.AUTHORITY, 1); 79c5afb16430a145f20d7c887e45f47b38687054daMarc Blank ContentResolver.setSyncAutomatically(account, ContactsContract.AUTHORITY, 80c5afb16430a145f20d7c887e45f47b38687054daMarc Blank syncContacts); 81c5afb16430a145f20d7c887e45f47b38687054daMarc Blank } 82c5afb16430a145f20d7c887e45f47b38687054daMarc Blank 83c5afb16430a145f20d7c887e45f47b38687054daMarc Blank // Set up calendar syncing, if appropriate 84473ce1fa354c81fd7d5bbd84b6a85d629a039e72Tony Mantler if (info != null && info.syncCalendar) { 856a51abdf6e15e6cc28948ef163d3673adc6f6e7fMartin Hibdon boolean syncCalendar = options.getBoolean(OPTIONS_CALENDAR_SYNC_ENABLED, false); 86c5afb16430a145f20d7c887e45f47b38687054daMarc Blank ContentResolver.setIsSyncable(account, CalendarContract.AUTHORITY, 1); 87c5afb16430a145f20d7c887e45f47b38687054daMarc Blank ContentResolver.setSyncAutomatically(account, CalendarContract.AUTHORITY, 88c5afb16430a145f20d7c887e45f47b38687054daMarc Blank syncCalendar); 89c5afb16430a145f20d7c887e45f47b38687054daMarc Blank } 90c5afb16430a145f20d7c887e45f47b38687054daMarc Blank 91c5afb16430a145f20d7c887e45f47b38687054daMarc Blank // Set up email syncing (it's always syncable, but we respect the user's choice 92c5afb16430a145f20d7c887e45f47b38687054daMarc Blank // for whether to enable it now) 93c5afb16430a145f20d7c887e45f47b38687054daMarc Blank boolean syncEmail = false; 94c5afb16430a145f20d7c887e45f47b38687054daMarc Blank if (options.containsKey(OPTIONS_EMAIL_SYNC_ENABLED) && 95c5afb16430a145f20d7c887e45f47b38687054daMarc Blank options.getBoolean(OPTIONS_EMAIL_SYNC_ENABLED)) { 96c5afb16430a145f20d7c887e45f47b38687054daMarc Blank syncEmail = true; 97c5afb16430a145f20d7c887e45f47b38687054daMarc Blank } 98c5afb16430a145f20d7c887e45f47b38687054daMarc Blank ContentResolver.setIsSyncable(account, EmailContent.AUTHORITY, 1); 99c5afb16430a145f20d7c887e45f47b38687054daMarc Blank ContentResolver.setSyncAutomatically(account, EmailContent.AUTHORITY, 100c5afb16430a145f20d7c887e45f47b38687054daMarc Blank syncEmail); 101c5afb16430a145f20d7c887e45f47b38687054daMarc Blank 102c5afb16430a145f20d7c887e45f47b38687054daMarc Blank Bundle b = new Bundle(); 103c5afb16430a145f20d7c887e45f47b38687054daMarc Blank b.putString(AccountManager.KEY_ACCOUNT_NAME, options.getString(OPTIONS_USERNAME)); 104c5afb16430a145f20d7c887e45f47b38687054daMarc Blank b.putString(AccountManager.KEY_ACCOUNT_TYPE, accountType); 105c5afb16430a145f20d7c887e45f47b38687054daMarc Blank return b; 106c5afb16430a145f20d7c887e45f47b38687054daMarc Blank // 2) The other case is that we're creating a new account from an Account manager 107c5afb16430a145f20d7c887e45f47b38687054daMarc Blank // activity. In this case, we add an intent that will be used to gather the 108c5afb16430a145f20d7c887e45f47b38687054daMarc Blank // account information... 109c5afb16430a145f20d7c887e45f47b38687054daMarc Blank } else { 110c5afb16430a145f20d7c887e45f47b38687054daMarc Blank Bundle b = new Bundle(); 111c5afb16430a145f20d7c887e45f47b38687054daMarc Blank Intent intent = 112bb68c13afa630cae058eb40d3ce68644f3f3c8b9Paul Westbrook AuthenticatorSetupIntentHelper.actionGetCreateAccountIntent( 113bb68c13afa630cae058eb40d3ce68644f3f3c8b9Paul Westbrook AuthenticatorService.this, accountType); 114c5afb16430a145f20d7c887e45f47b38687054daMarc Blank intent.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE, response); 115c5afb16430a145f20d7c887e45f47b38687054daMarc Blank b.putParcelable(AccountManager.KEY_INTENT, intent); 116c5afb16430a145f20d7c887e45f47b38687054daMarc Blank return b; 117c5afb16430a145f20d7c887e45f47b38687054daMarc Blank } 118c5afb16430a145f20d7c887e45f47b38687054daMarc Blank } 119c5afb16430a145f20d7c887e45f47b38687054daMarc Blank 120c5afb16430a145f20d7c887e45f47b38687054daMarc Blank @Override 121c5afb16430a145f20d7c887e45f47b38687054daMarc Blank public Bundle confirmCredentials(AccountAuthenticatorResponse response, Account account, 122c5afb16430a145f20d7c887e45f47b38687054daMarc Blank Bundle options) { 123c5afb16430a145f20d7c887e45f47b38687054daMarc Blank return null; 124c5afb16430a145f20d7c887e45f47b38687054daMarc Blank } 125c5afb16430a145f20d7c887e45f47b38687054daMarc Blank 126c5afb16430a145f20d7c887e45f47b38687054daMarc Blank @Override 127c5afb16430a145f20d7c887e45f47b38687054daMarc Blank public Bundle editProperties(AccountAuthenticatorResponse response, String accountType) { 128c5afb16430a145f20d7c887e45f47b38687054daMarc Blank return null; 129c5afb16430a145f20d7c887e45f47b38687054daMarc Blank } 130c5afb16430a145f20d7c887e45f47b38687054daMarc Blank 131c5afb16430a145f20d7c887e45f47b38687054daMarc Blank @Override 132c5afb16430a145f20d7c887e45f47b38687054daMarc Blank public Bundle getAuthToken(AccountAuthenticatorResponse response, Account account, 133c5afb16430a145f20d7c887e45f47b38687054daMarc Blank String authTokenType, Bundle loginOptions) throws NetworkErrorException { 134c5afb16430a145f20d7c887e45f47b38687054daMarc Blank return null; 135c5afb16430a145f20d7c887e45f47b38687054daMarc Blank } 136c5afb16430a145f20d7c887e45f47b38687054daMarc Blank 137c5afb16430a145f20d7c887e45f47b38687054daMarc Blank @Override 138c5afb16430a145f20d7c887e45f47b38687054daMarc Blank public String getAuthTokenLabel(String authTokenType) { 139c5afb16430a145f20d7c887e45f47b38687054daMarc Blank // null means we don't have compartmentalized authtoken types 140c5afb16430a145f20d7c887e45f47b38687054daMarc Blank return null; 141c5afb16430a145f20d7c887e45f47b38687054daMarc Blank } 142c5afb16430a145f20d7c887e45f47b38687054daMarc Blank 143c5afb16430a145f20d7c887e45f47b38687054daMarc Blank @Override 144c5afb16430a145f20d7c887e45f47b38687054daMarc Blank public Bundle hasFeatures(AccountAuthenticatorResponse response, Account account, 145c5afb16430a145f20d7c887e45f47b38687054daMarc Blank String[] features) throws NetworkErrorException { 146c5afb16430a145f20d7c887e45f47b38687054daMarc Blank return null; 147c5afb16430a145f20d7c887e45f47b38687054daMarc Blank } 148c5afb16430a145f20d7c887e45f47b38687054daMarc Blank 149c5afb16430a145f20d7c887e45f47b38687054daMarc Blank @Override 150c5afb16430a145f20d7c887e45f47b38687054daMarc Blank public Bundle updateCredentials(AccountAuthenticatorResponse response, Account account, 151c5afb16430a145f20d7c887e45f47b38687054daMarc Blank String authTokenType, Bundle loginOptions) { 152c5afb16430a145f20d7c887e45f47b38687054daMarc Blank return null; 153c5afb16430a145f20d7c887e45f47b38687054daMarc Blank } 154c5afb16430a145f20d7c887e45f47b38687054daMarc Blank 155c5afb16430a145f20d7c887e45f47b38687054daMarc Blank } 156c5afb16430a145f20d7c887e45f47b38687054daMarc Blank 157c5afb16430a145f20d7c887e45f47b38687054daMarc Blank @Override 158c5afb16430a145f20d7c887e45f47b38687054daMarc Blank public IBinder onBind(Intent intent) { 159c5afb16430a145f20d7c887e45f47b38687054daMarc Blank if (AccountManager.ACTION_AUTHENTICATOR_INTENT.equals(intent.getAction())) { 160c5afb16430a145f20d7c887e45f47b38687054daMarc Blank return new Authenticator(this).getIBinder(); 161c5afb16430a145f20d7c887e45f47b38687054daMarc Blank } else { 162c5afb16430a145f20d7c887e45f47b38687054daMarc Blank return null; 163c5afb16430a145f20d7c887e45f47b38687054daMarc Blank } 164c5afb16430a145f20d7c887e45f47b38687054daMarc Blank } 165c5afb16430a145f20d7c887e45f47b38687054daMarc Blank} 166