diff --git a/Android.mk b/Android.mk index 357d17e35..f1e3f85d2 100644 --- a/Android.mk +++ b/Android.mk @@ -18,9 +18,11 @@ include $(CLEAR_VARS) LOCAL_MODULE_TAGS := optional LOCAL_SRC_FILES := $(call all-java-files-under, src) +# EXCHANGE-REMOVE-SECTION-START LOCAL_SRC_FILES += \ src/com/android/email/service/IEmailService.aidl \ src/com/android/email/service/IEmailServiceCallback.aidl +# EXCHANGE-REMOVE-SECTION-END LOCAL_PACKAGE_NAME := Email diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 13210efde..76ff91525 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -85,11 +85,13 @@ android:label="@string/account_setup_outgoing_title" > + + + @@ -180,6 +183,7 @@ + @@ -222,6 +226,7 @@ > + + &2 + exit 1 +fi + +echo "" +echo -n "Do you wish to remove exchange support from the email app? (y/N):" + +read answer +if [[ "$answer" != y ]] ; then + echo "Aborted." 1>&2 + exit 1 +fi + + +# Step 1. Remove all Exchange related packages. + +rm -fr src/com/android/exchange/ \ + tests/src/com/android/exchange/ + + +# Step 2. Remove lines surrounded by START-EXCHANGE and END-EXCHANGE + +find . \( -name '*.java' -o -name '*.xml' -o -name 'Android.mk' \) -print0 | + xargs -0 sed -i -e '/EXCHANGE-REMOVE-SECTION-START/,/EXCHANGE-REMOVE-SECTION-END/d' + + +# Step 3. Remove all imports from com.android.exchange (and its subpackages). + +find . -name '*.java' -print0 | + xargs -0 sed -i -e '/^import com\.android\.exchange/d' + + +echo "" +echo "Exchange support has been successfully removed." + +exit 0 diff --git a/res/layout/debug.xml b/res/layout/debug.xml index 7045289ee..41bf58c79 100644 --- a/res/layout/debug.xml +++ b/res/layout/debug.xml @@ -37,6 +37,7 @@ android:layout_height="wrap_content" android:text="@string/debug_enable_sensitive_logging_label" /> + + diff --git a/src/com/android/email/AccountBackupRestore.java b/src/com/android/email/AccountBackupRestore.java index 64324d72e..9191fd728 100644 --- a/src/com/android/email/AccountBackupRestore.java +++ b/src/com/android/email/AccountBackupRestore.java @@ -18,7 +18,6 @@ package com.android.email; import com.android.email.mail.store.ExchangeStore; import com.android.email.provider.EmailContent; -import com.android.exchange.Eas; import android.accounts.AccountManagerFuture; import android.content.ContentResolver; diff --git a/src/com/android/email/Email.java b/src/com/android/email/Email.java index 04c167d43..8abe59338 100644 --- a/src/com/android/email/Email.java +++ b/src/com/android/email/Email.java @@ -23,7 +23,6 @@ import com.android.email.mail.internet.BinaryTempFileBody; import com.android.email.provider.EmailContent; import com.android.email.service.BootReceiver; import com.android.email.service.MailService; -import com.android.exchange.Eas; import android.app.Application; import android.content.ComponentName; diff --git a/src/com/android/email/ExchangeUtils.java b/src/com/android/email/ExchangeUtils.java index 953c66fc4..701de7311 100644 --- a/src/com/android/email/ExchangeUtils.java +++ b/src/com/android/email/ExchangeUtils.java @@ -16,6 +16,7 @@ package com.android.email; +import com.android.email.mail.MessagingException; import com.android.email.service.EmailServiceProxy; import com.android.email.service.IEmailService; import com.android.email.service.IEmailServiceCallback; @@ -23,6 +24,9 @@ import com.android.exchange.SyncManager; import android.content.Context; import android.content.Intent; +import android.os.Bundle; +import android.os.IBinder; +import android.os.RemoteException; /** * Utility functions for Exchange support. @@ -32,7 +36,9 @@ public class ExchangeUtils { * Starts the service for Exchange, if supported. */ public static void startExchangeService(Context context) { + //EXCHANGE-REMOVE-SECTION-START context.startService(new Intent(context, SyncManager.class)); + //EXCHANGE-REMOVE-SECTION-END } /** @@ -44,7 +50,80 @@ public class ExchangeUtils { */ public static IEmailService getExchangeEmailService(Context context, IEmailServiceCallback callback) { - // TODO Return an empty IEmailService impl if exchange support is removed - return new EmailServiceProxy(context, SyncManager.class, callback); + IEmailService ret = null; + //EXCHANGE-REMOVE-SECTION-START + ret = new EmailServiceProxy(context, SyncManager.class, callback); + //EXCHANGE-REMOVE-SECTION-END + if (ret == null) { + ret = NullEmailService.INSTANCE; + } + return ret; + } + + /** + * An empty {@link IEmailService} implementation which is used instead of + * {@link com.android.exchange.SyncManager} on the build with no exchange support. + * + *

In theory, the service in question isn't used on the no-exchange-support build, + * because we won't have any exchange accounts in that case, so we wouldn't have to have this + * class. However, there are a few places we do use the service even if there's no exchange + * accounts (e.g. setLogging), so this class is added for safety and simplicity. + */ + private static class NullEmailService implements IEmailService { + public static final NullEmailService INSTANCE = new NullEmailService(); + + public Bundle autoDiscover(String userName, String password) throws RemoteException { + return Bundle.EMPTY; + } + + public boolean createFolder(long accountId, String name) throws RemoteException { + return false; + } + + public boolean deleteFolder(long accountId, String name) throws RemoteException { + return false; + } + + public void hostChanged(long accountId) throws RemoteException { + } + + public void loadAttachment(long attachmentId, String destinationFile, + String contentUriString) throws RemoteException { + } + + public void loadMore(long messageId) throws RemoteException { + } + + public boolean renameFolder(long accountId, String oldName, String newName) + throws RemoteException { + return false; + } + + public void sendMeetingResponse(long messageId, int response) throws RemoteException { + } + + public void setCallback(IEmailServiceCallback cb) throws RemoteException { + } + + public void setLogging(int on) throws RemoteException { + } + + public void startSync(long mailboxId) throws RemoteException { + } + + public void stopSync(long mailboxId) throws RemoteException { + } + + public void updateFolderList(long accountId) throws RemoteException { + } + + public int validate(String protocol, String host, String userName, String password, + int port, boolean ssl, boolean trustCertificates) throws RemoteException { + return MessagingException.UNSPECIFIED_EXCEPTION; + } + + public IBinder asBinder() { + return null; + } } } diff --git a/src/com/android/email/activity/Debug.java b/src/com/android/email/activity/Debug.java index 4526f0d0a..eb42a95eb 100644 --- a/src/com/android/email/activity/Debug.java +++ b/src/com/android/email/activity/Debug.java @@ -53,21 +53,24 @@ public class Debug extends Activity implements OnCheckedChangeListener { mVersionView = (TextView)findViewById(R.id.version); mEnableDebugLoggingView = (CheckBox)findViewById(R.id.debug_logging); mEnableSensitiveLoggingView = (CheckBox)findViewById(R.id.sensitive_logging); - mEnableExchangeLoggingView = (CheckBox)findViewById(R.id.exchange_logging); - mEnableExchangeFileLoggingView = (CheckBox)findViewById(R.id.exchange_file_logging); mEnableDebugLoggingView.setOnCheckedChangeListener(this); mEnableSensitiveLoggingView.setOnCheckedChangeListener(this); - mEnableExchangeLoggingView.setOnCheckedChangeListener(this); - mEnableExchangeFileLoggingView.setOnCheckedChangeListener(this); mVersionView.setText(String.format(getString(R.string.debug_version_fmt).toString(), getString(R.string.build_number))); mEnableDebugLoggingView.setChecked(Email.DEBUG); mEnableSensitiveLoggingView.setChecked(Email.DEBUG_SENSITIVE); + + //EXCHANGE-REMOVE-SECTION-START + mEnableExchangeLoggingView = (CheckBox)findViewById(R.id.exchange_logging); + mEnableExchangeFileLoggingView = (CheckBox)findViewById(R.id.exchange_file_logging); + mEnableExchangeLoggingView.setOnCheckedChangeListener(this); + mEnableExchangeFileLoggingView.setOnCheckedChangeListener(this); mEnableExchangeLoggingView.setChecked(Eas.USER_LOG); mEnableExchangeFileLoggingView.setChecked(Eas.FILE_LOG); + //EXCHANGE-REMOVE-SECTION-END } public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { @@ -80,6 +83,7 @@ public class Debug extends Activity implements OnCheckedChangeListener { Email.DEBUG_SENSITIVE = isChecked; mPreferences.setEnableSensitiveLogging(Email.DEBUG_SENSITIVE); break; + //EXCHANGE-REMOVE-SECTION-START case R.id.exchange_logging: mPreferences.setEnableExchangeLogging(isChecked); break; @@ -89,6 +93,7 @@ public class Debug extends Activity implements OnCheckedChangeListener { FileLogger.close(); } break; + //EXCHANGE-REMOVE-SECTION-END } updateLoggingFlags(this); @@ -115,11 +120,13 @@ public class Debug extends Activity implements OnCheckedChangeListener { * Load enabled debug flags from the preferences and upadte the EAS debug flag. */ public static void updateLoggingFlags(Context context) { + //EXCHANGE-REMOVE-SECTION-START Preferences prefs = Preferences.getPreferences(context); int debugLogging = prefs.getEnableDebugLogging() ? Eas.DEBUG_BIT : 0; int exchangeLogging = prefs.getEnableExchangeLogging() ? Eas.DEBUG_EXCHANGE_BIT : 0; int fileLogging = prefs.getEnableExchangeFileLogging() ? Eas.DEBUG_FILE_BIT : 0; int debugBits = debugLogging | exchangeLogging | fileLogging; Controller.getInstance(context).serviceLogging(debugBits); + //EXCHANGE-REMOVE-SECTION-END } } diff --git a/src/com/android/email/activity/setup/AccountSettings.java b/src/com/android/email/activity/setup/AccountSettings.java index f44bba464..384586255 100644 --- a/src/com/android/email/activity/setup/AccountSettings.java +++ b/src/com/android/email/activity/setup/AccountSettings.java @@ -24,7 +24,6 @@ import com.android.email.mail.Store; import com.android.email.provider.EmailContent.Account; import com.android.email.provider.EmailContent.AccountColumns; import com.android.email.provider.EmailContent.HostAuth; -import com.android.exchange.Eas; import android.app.Activity; import android.content.ContentResolver; diff --git a/src/com/android/email/activity/setup/AccountSetupAccountType.java b/src/com/android/email/activity/setup/AccountSetupAccountType.java index 03b8ae947..a4f5075c8 100644 --- a/src/com/android/email/activity/setup/AccountSetupAccountType.java +++ b/src/com/android/email/activity/setup/AccountSetupAccountType.java @@ -157,14 +157,16 @@ public class AccountSetupAccountType extends Activity implements OnClickListener * like this. */ private boolean isExchangeAvailable() { + //EXCHANGE-REMOVE-SECTION-START try { URI uri = new URI(mAccount.getStoreUri(this)); uri = new URI("eas", uri.getUserInfo(), uri.getHost(), uri.getPort(), null, null, null); Store.StoreInfo storeInfo = Store.StoreInfo.getStoreInfo(uri.toString(), this); return (storeInfo != null && checkAccountInstanceLimit(storeInfo)); } catch (URISyntaxException e) { - return false; } + //EXCHANGE-REMOVE-SECTION-END + return false; } /** diff --git a/src/com/android/email/mail/store/ExchangeStore.java b/src/com/android/email/mail/store/ExchangeStore.java index 0f01e3192..9935d50ea 100644 --- a/src/com/android/email/mail/store/ExchangeStore.java +++ b/src/com/android/email/mail/store/ExchangeStore.java @@ -25,7 +25,6 @@ import com.android.email.mail.Store; import com.android.email.mail.StoreSynchronizer; import com.android.email.provider.EmailContent.Account; import com.android.email.service.EasAuthenticatorService; -import com.android.exchange.Eas; import android.accounts.AccountManager; import android.accounts.AccountManagerCallback; diff --git a/src/com/android/email/provider/EmailProvider.java b/src/com/android/email/provider/EmailProvider.java index e01b9487d..984d48149 100644 --- a/src/com/android/email/provider/EmailProvider.java +++ b/src/com/android/email/provider/EmailProvider.java @@ -30,7 +30,6 @@ import com.android.email.provider.EmailContent.MailboxColumns; import com.android.email.provider.EmailContent.Message; import com.android.email.provider.EmailContent.MessageColumns; import com.android.email.provider.EmailContent.SyncColumns; -import com.android.exchange.Eas; import android.accounts.AccountManager; import android.content.ContentProvider; diff --git a/src/com/android/email/service/EasAuthenticatorService.java b/src/com/android/email/service/EasAuthenticatorService.java index 3b47a8bfa..d8cf13caa 100644 --- a/src/com/android/email/service/EasAuthenticatorService.java +++ b/src/com/android/email/service/EasAuthenticatorService.java @@ -18,7 +18,6 @@ package com.android.email.service; import com.android.email.Email; import com.android.email.activity.setup.AccountSetupBasics; -import com.android.exchange.Eas; import android.accounts.AbstractAccountAuthenticator; import android.accounts.Account; diff --git a/tests/src/com/android/email/activity/setup/AccountSetupAccountTypeUnitTests.java b/tests/src/com/android/email/activity/setup/AccountSetupAccountTypeUnitTests.java index d5c5d6277..13ea7551a 100644 --- a/tests/src/com/android/email/activity/setup/AccountSetupAccountTypeUnitTests.java +++ b/tests/src/com/android/email/activity/setup/AccountSetupAccountTypeUnitTests.java @@ -35,16 +35,16 @@ import java.util.HashSet; * This is a series of unit tests for the AccountSetupAccountType class. */ @SmallTest -public class AccountSetupAccountTypeUnitTests +public class AccountSetupAccountTypeUnitTests extends ActivityUnitTestCase { // Borrowed from AccountSetupAccountType private static final String EXTRA_ACCOUNT = "account"; Context mContext; - + private HashSet mAccounts = new HashSet(); - + public AccountSetupAccountTypeUnitTests() { super(AccountSetupAccountType.class); } @@ -52,7 +52,7 @@ public class AccountSetupAccountTypeUnitTests @Override protected void setUp() throws Exception { super.setUp(); - + mContext = this.getInstrumentation().getTargetContext(); } @@ -65,11 +65,11 @@ public class AccountSetupAccountTypeUnitTests Uri uri = ContentUris.withAppendedId(Account.CONTENT_URI, account.mId); mContext.getContentResolver().delete(uri, null, null); } - + // must call last because it scrubs member variables super.tearDown(); } - + /** * Test store type limit enforcement */ @@ -77,7 +77,7 @@ public class AccountSetupAccountTypeUnitTests EmailContent.Account acct1 = createTestAccount("scheme1"); EmailContent.Account acct2 = createTestAccount("scheme1"); EmailContent.Account acct3 = createTestAccount("scheme2"); - + AccountSetupAccountType activity = startActivity(getTestIntent(acct1), null, null); // Test with no limit @@ -85,24 +85,30 @@ public class AccountSetupAccountTypeUnitTests info.mAccountInstanceLimit = -1; info.mScheme = "scheme1"; assertTrue("no limit", activity.checkAccountInstanceLimit(info)); - + // Test with limit, but not reached info.mAccountInstanceLimit = 3; assertTrue("limit, but not reached", activity.checkAccountInstanceLimit(info)); - + // Test with limit, reached info.mAccountInstanceLimit = 2; assertFalse("limit, reached", activity.checkAccountInstanceLimit(info)); } /** - * Confirm that EAS is presented (supported in this release) + * Confirm that EAS is presented, when supported. */ public void testEasOffered() { Account acct1 = createTestAccount("scheme1"); AccountSetupAccountType activity = startActivity(getTestIntent(acct1), null, null); View exchangeButton = activity.findViewById(R.id.exchange); - assertEquals(View.VISIBLE, exchangeButton.getVisibility()); + + int expected = View.GONE; // Default is hidden + //EXCHANGE-REMOVE-SECTION-START + expected = View.VISIBLE; // Will be visible if supported. + //EXCHANGE-REMOVE-SECTION-END + + assertEquals(expected, exchangeButton.getVisibility()); } /** @@ -115,7 +121,7 @@ public class AccountSetupAccountTypeUnitTests mAccounts.add(account); return account; } - + /** * Create an intent with the Account in it */ diff --git a/tests/src/com/android/email/activity/setup/AccountSetupExchangeTests.java b/tests/src/com/android/email/activity/setup/AccountSetupExchangeTests.java index 45413e380..d64ff10aa 100644 --- a/tests/src/com/android/email/activity/setup/AccountSetupExchangeTests.java +++ b/tests/src/com/android/email/activity/setup/AccountSetupExchangeTests.java @@ -37,17 +37,19 @@ import android.widget.EditText; @MediumTest public class AccountSetupExchangeTests extends ActivityInstrumentationTestCase2 { - + //EXCHANGE-REMOVE-SECTION-START private AccountSetupExchange mActivity; private EditText mServerView; private Button mNextButton; private CheckBox mSslRequiredCheckbox; private CheckBox mTrustAllCertificatesCheckbox; - + //EXCHANGE-REMOVE-SECTION-END + public AccountSetupExchangeTests() { super("com.android.email", AccountSetupExchange.class); } + //EXCHANGE-REMOVE-SECTION-START /** * Common setup code for all tests. Sets up a default launch intent, which some tests * will use (others will override). @@ -62,7 +64,7 @@ public class AccountSetupExchangeTests extends Intent i = getTestIntent("eas://user:password@server.com"); setActivityIntent(i); } - + /** * Test processing with a complete, good URI -> good fields */ @@ -72,7 +74,7 @@ public class AccountSetupExchangeTests extends getActivityAndFields(); assertTrue(mNextButton.isEnabled()); } - + // TODO Add tests for valid usernames in eas // They would be or \ or / or a valid email address @@ -85,7 +87,7 @@ public class AccountSetupExchangeTests extends getActivityAndFields(); assertFalse(mNextButton.isEnabled()); } - + /** * No password is not OK - not enabled */ @@ -95,7 +97,7 @@ public class AccountSetupExchangeTests extends getActivityAndFields(); assertFalse(mNextButton.isEnabled()); } - + /** * Test for non-standard but OK server names */ @@ -103,11 +105,11 @@ public class AccountSetupExchangeTests extends public void testGoodServerVariants() { getActivityAndFields(); assertTrue(mNextButton.isEnabled()); - + mServerView.setText(" server.com "); assertTrue(mNextButton.isEnabled()); } - + /** * Test for non-empty but non-OK server names */ @@ -115,10 +117,10 @@ public class AccountSetupExchangeTests extends public void testBadServerVariants() { getActivityAndFields(); assertTrue(mNextButton.isEnabled()); - + mServerView.setText(" "); assertFalse(mNextButton.isEnabled()); - + mServerView.setText("serv$er.com"); assertFalse(mNextButton.isEnabled()); } @@ -161,7 +163,7 @@ public class AccountSetupExchangeTests extends /** * TODO: Directly test validateFields() checking boolean result */ - + /** * Get the activity (which causes it to be started, using our intent) and get the UI fields */ @@ -173,7 +175,7 @@ public class AccountSetupExchangeTests extends mTrustAllCertificatesCheckbox = (CheckBox) mActivity.findViewById(R.id.account_trust_certificates); } - + /** * Create an intent with the Account in it */ @@ -185,5 +187,5 @@ public class AccountSetupExchangeTests extends i.putExtra(AccountSetupExchange.EXTRA_DISABLE_AUTO_DISCOVER, true); return i; } - + //EXCHANGE-REMOVE-SECTION-END }