Generalize service discovery and calling
* On the road to removing direct references to Exchange (and potentially others) from Email.apk Change-Id: Id0fe59936067f9cacde66f2979b21de3f69526a1
This commit is contained in:
parent
8410a296c5
commit
19e006ede1
21
email2/res/xml/services.xml
Normal file
21
email2/res/xml/services.xml
Normal file
@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2012 The Android Open Source Project
|
||||
|
||||
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.
|
||||
-->
|
||||
|
||||
<services>
|
||||
<service protocol="pop3" name="POP3" class="com.android.email.service.ImapService" />
|
||||
<service protocol="imap" name="IMAP" class="com.android.email.service.Pop3Service" />
|
||||
<service protocol="eas" name="Exchange" intent="com.android.email.EXCHANGE_INTENT" />
|
||||
</services>
|
@ -67,7 +67,7 @@ public class AccountSetupAccountType extends AccountSetupActivity implements OnC
|
||||
// TODO If we decide to exclude the Exchange option in POP_IMAP mode, use the following line
|
||||
// instead of the line that follows it
|
||||
//if (ExchangeUtils.isExchangeAvailable(this) && flowMode != SetupData.FLOW_MODE_POP_IMAP) {
|
||||
if (EmailServiceUtils.isExchangeAvailable(this)) {
|
||||
if (EmailServiceUtils.isServiceAvailable(this, "eas")) {
|
||||
exchangeButton.setOnClickListener(this);
|
||||
exchangeButton.setVisibility(View.VISIBLE);
|
||||
if (VendorPolicyLoader.getInstance(this).useAlternateExchangeStrings()) {
|
||||
|
@ -117,11 +117,14 @@ public class AccountSetupExchangeFragment extends AccountServerBaseFragment
|
||||
// Calls validateFields() which enables or disables the Next button
|
||||
// based on the fields' validity.
|
||||
TextWatcher validationTextWatcher = new TextWatcher() {
|
||||
@Override
|
||||
public void afterTextChanged(Editable s) {
|
||||
validateFields();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeTextChanged(CharSequence s, int start, int count, int after) { }
|
||||
@Override
|
||||
public void onTextChanged(CharSequence s, int start, int before, int count) { }
|
||||
};
|
||||
// We're editing an existing account; don't allow modification of the user name
|
||||
@ -359,7 +362,7 @@ public class AccountSetupExchangeFragment extends AccountServerBaseFragment
|
||||
account.mHostAuthSend.update(mContext, account.mHostAuthSend.toContentValues());
|
||||
// For EAS, notify ExchangeService that the password has changed
|
||||
try {
|
||||
EmailServiceUtils.getExchangeService(mContext, null).hostChanged(account.mId);
|
||||
EmailServiceUtils.getService(mContext, null, "eas").hostChanged(account.mId);
|
||||
} catch (RemoteException e) {
|
||||
// Nothing to be done if this fails
|
||||
}
|
||||
|
@ -373,7 +373,7 @@ public class AccountSetupOptions extends AccountSetupActivity implements OnClick
|
||||
AccountSettingsUtils.commitSettings(context, account);
|
||||
// Start up services based on new account(s)
|
||||
MailActivityEmail.setServicesEnabledSync(context);
|
||||
EmailServiceUtils.startExchangeService(context);
|
||||
EmailServiceUtils.startService(context, "eas");
|
||||
// Move to final setup screen
|
||||
AccountSetupNames.actionSetNames(context);
|
||||
finish();
|
||||
|
@ -72,7 +72,7 @@ public class DebugFragment extends Fragment implements OnCheckedChangeListener,
|
||||
// Note: To prevent recursion while presetting checkboxes, assign all listeners last
|
||||
mEnableDebugLoggingView.setOnCheckedChangeListener(this);
|
||||
|
||||
boolean exchangeAvailable = EmailServiceUtils.isExchangeAvailable(context);
|
||||
boolean exchangeAvailable = EmailServiceUtils.isServiceAvailable(context, "eas");
|
||||
if (exchangeAvailable) {
|
||||
mEnableExchangeLoggingView.setChecked(MailActivityEmail.DEBUG_EXCHANGE_VERBOSE);
|
||||
mEnableExchangeFileLoggingView.setChecked(MailActivityEmail.DEBUG_EXCHANGE_FILE);
|
||||
|
@ -50,6 +50,6 @@ public class ExchangeStore extends ServiceStore {
|
||||
|
||||
@Override
|
||||
protected IEmailService getService() {
|
||||
return EmailServiceUtils.getExchangeService(mContext, null);
|
||||
return EmailServiceUtils.getService(mContext, null, "eas");
|
||||
}
|
||||
}
|
||||
|
@ -104,7 +104,7 @@ public class AccountService extends Service {
|
||||
@Override
|
||||
public void run() {
|
||||
// Make sure the service is properly running (re: lifecycle)
|
||||
EmailServiceUtils.startExchangeService(mContext);
|
||||
EmailServiceUtils.startService(mContext, "eas");
|
||||
// Send current logging flags
|
||||
MailActivityEmail.updateLoggingFlags(mContext);
|
||||
}});
|
||||
|
@ -131,7 +131,7 @@ public class EmailBroadcastProcessorService extends IntentService {
|
||||
performOneTimeInitialization();
|
||||
|
||||
// Starts the service for Exchange, if supported.
|
||||
EmailServiceUtils.startExchangeService(this);
|
||||
EmailServiceUtils.startService(this, "eas");
|
||||
}
|
||||
|
||||
private void performOneTimeInitialization() {
|
||||
@ -207,6 +207,6 @@ public class EmailBroadcastProcessorService extends IntentService {
|
||||
|
||||
// If the exchange service wasn't already running, starting it will cause exchange account
|
||||
// reconciliation to be performed. The service stops itself it there are no EAS accounts.
|
||||
EmailServiceUtils.startExchangeService(this);
|
||||
EmailServiceUtils.startService(this, "eas");
|
||||
}
|
||||
}
|
||||
|
@ -16,66 +16,46 @@
|
||||
|
||||
package com.android.email.service;
|
||||
|
||||
import android.app.Service;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.res.XmlResourceParser;
|
||||
|
||||
import com.android.email.R;
|
||||
import com.android.emailcommon.provider.Account;
|
||||
import com.android.emailcommon.provider.HostAuth;
|
||||
import com.android.emailcommon.service.EmailServiceProxy;
|
||||
import com.android.emailcommon.service.IEmailService;
|
||||
import com.android.emailcommon.service.IEmailServiceCallback;
|
||||
|
||||
import org.xmlpull.v1.XmlPullParserException;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
|
||||
/**
|
||||
* Utility functions for EmailService support.
|
||||
*/
|
||||
public class EmailServiceUtils {
|
||||
/**
|
||||
* Starts an EmailService by name
|
||||
*/
|
||||
public static void startService(Context context, String intentAction) {
|
||||
context.startService(new Intent(intentAction));
|
||||
}
|
||||
private static final HashMap<String, EmailServiceInfo> sServiceMap =
|
||||
new HashMap<String, EmailServiceInfo>();
|
||||
|
||||
/**
|
||||
* Returns an {@link IEmailService} for the service; otherwise returns an empty
|
||||
* {@link IEmailService} implementation.
|
||||
*
|
||||
* @param context
|
||||
* @param callback Object to get callback, or can be null
|
||||
* Starts an EmailService by protocol
|
||||
*/
|
||||
public static EmailServiceProxy getService(Context context, String intentAction,
|
||||
IEmailServiceCallback callback) {
|
||||
return new EmailServiceProxy(context, intentAction, callback);
|
||||
public static void startService(Context context, String protocol) {
|
||||
EmailServiceInfo info = getServiceInfo(context, protocol);
|
||||
if (info != null && info.intentAction != null) {
|
||||
context.startService(new Intent(info.intentAction));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the EmailService is available
|
||||
*/
|
||||
public static boolean isServiceAvailable(Context context, String intentAction) {
|
||||
return new EmailServiceProxy(context, intentAction, null).test();
|
||||
}
|
||||
|
||||
public static void startExchangeService(Context context) {
|
||||
startService(context, EmailServiceProxy.EXCHANGE_INTENT);
|
||||
}
|
||||
|
||||
public static EmailServiceProxy getExchangeService(Context context,
|
||||
IEmailServiceCallback callback) {
|
||||
return getService(context, EmailServiceProxy.EXCHANGE_INTENT, callback);
|
||||
}
|
||||
|
||||
public static EmailServiceProxy getImapService(Context context,
|
||||
IEmailServiceCallback callback) {
|
||||
return new EmailServiceProxy(context, ImapService.class, callback);
|
||||
}
|
||||
|
||||
public static EmailServiceProxy getPop3Service(Context context,
|
||||
IEmailServiceCallback callback) {
|
||||
return new EmailServiceProxy(context, Pop3Service.class, callback);
|
||||
}
|
||||
|
||||
public static boolean isExchangeAvailable(Context context) {
|
||||
return isServiceAvailable(context, EmailServiceProxy.EXCHANGE_INTENT);
|
||||
public static boolean isServiceAvailable(Context context, String protocol) {
|
||||
EmailServiceInfo info = getServiceInfo(context, protocol);
|
||||
if (info == null) return false;
|
||||
if (info.klass != null) return true;
|
||||
return new EmailServiceProxy(context, info.intentAction, null).test();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -86,15 +66,86 @@ public class EmailServiceUtils {
|
||||
*/
|
||||
public static EmailServiceProxy getServiceForAccount(Context context,
|
||||
IEmailServiceCallback callback, long accountId) {
|
||||
String protocol = Account.getProtocol(context, accountId);
|
||||
if (HostAuth.SCHEME_IMAP.equals(protocol)) {
|
||||
return getImapService(context, callback);
|
||||
} else if (HostAuth.SCHEME_POP3.equals(protocol)) {
|
||||
return getPop3Service(context, callback);
|
||||
} else if (HostAuth.SCHEME_EAS.equals(protocol)) {
|
||||
return getExchangeService(context, callback);
|
||||
return getService(context, callback, Account.getProtocol(context, accountId));
|
||||
}
|
||||
|
||||
/**
|
||||
* Holder of service information (currently just name and class/intent); if there is a class
|
||||
* member, this is a (local, i.e. same process) service; otherwise, this is a remote service
|
||||
*/
|
||||
static class EmailServiceInfo {
|
||||
String name;
|
||||
Class<? extends Service> klass;
|
||||
String intentAction;
|
||||
}
|
||||
|
||||
public static EmailServiceProxy getService(Context context, IEmailServiceCallback callback,
|
||||
String protocol) {
|
||||
EmailServiceInfo info = getServiceInfo(context, protocol);
|
||||
if (info.klass != null) {
|
||||
return new EmailServiceProxy(context, info.klass, callback);
|
||||
} else {
|
||||
return null;
|
||||
return new EmailServiceProxy(context, info.intentAction, callback);
|
||||
}
|
||||
}
|
||||
|
||||
private static EmailServiceInfo getServiceInfo(Context context, String protocol) {
|
||||
if (sServiceMap.isEmpty()) {
|
||||
findServices(context);
|
||||
}
|
||||
return sServiceMap.get(protocol);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse services.xml file to find our available email services
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
private static void findServices(Context context) {
|
||||
try {
|
||||
XmlResourceParser xml = context.getResources().getXml(R.xml.services);
|
||||
int xmlEventType;
|
||||
// walk through senders.xml file.
|
||||
while ((xmlEventType = xml.next()) != XmlResourceParser.END_DOCUMENT) {
|
||||
if (xmlEventType == XmlResourceParser.START_TAG &&
|
||||
"service".equals(xml.getName())) {
|
||||
EmailServiceInfo info = new EmailServiceInfo();
|
||||
String protocol = xml.getAttributeValue(null, "protocol");
|
||||
if (protocol == null) {
|
||||
throw new IllegalStateException(
|
||||
"No protocol specified in service descriptor");
|
||||
}
|
||||
info.name = xml.getAttributeValue(null, "name");
|
||||
if (info.name == null) {
|
||||
throw new IllegalStateException(
|
||||
"No name specified in service descriptor");
|
||||
}
|
||||
String klass = xml.getAttributeValue(null, "class");
|
||||
if (klass != null) {
|
||||
try {
|
||||
info.klass = (Class<? extends Service>) Class.forName(klass);
|
||||
} catch (ClassNotFoundException e) {
|
||||
throw new IllegalStateException(
|
||||
"Class not found in service descriptor: " + klass);
|
||||
}
|
||||
}
|
||||
info.intentAction = xml.getAttributeValue(null, "intent");
|
||||
|
||||
if (info.klass == null && info.intentAction == null) {
|
||||
throw new IllegalStateException(
|
||||
"No class or intent action specified in service descriptor");
|
||||
}
|
||||
if (info.klass != null && info.intentAction != null) {
|
||||
throw new IllegalStateException(
|
||||
"Both class and intent action specified in service descriptor");
|
||||
}
|
||||
sServiceMap.put(protocol, info);
|
||||
}
|
||||
}
|
||||
} catch (XmlPullParserException e) {
|
||||
// ignore
|
||||
} catch (IOException e) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -193,7 +193,7 @@ public class MailActivityEmail extends com.android.mail.ui.MailActivity {
|
||||
int enableStrictMode =
|
||||
prefs.getEnableStrictMode() ? EmailServiceProxy.DEBUG_ENABLE_STRICT_MODE : 0;
|
||||
int debugBits = debugLogging | verboseLogging | fileLogging | enableStrictMode;
|
||||
EmailServiceProxy service = EmailServiceUtils.getExchangeService(context, null);
|
||||
EmailServiceProxy service = EmailServiceUtils.getService(context, null, "eas");
|
||||
if (service != null) {
|
||||
try {
|
||||
service.setLogging(debugBits);
|
||||
|
Loading…
Reference in New Issue
Block a user