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