blob: c102dea062fac7f5605eb92428c0da1e4616ed6c [file] [log] [blame]
/**
* Copyright (c) 2012, Google Inc.
*
* 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.android.mail.providers;
import android.content.ContentValues;
import android.database.Cursor;
import android.database.MatrixCursor;
import android.net.Uri;
import android.os.Parcel;
import android.os.Parcelable;
import android.text.TextUtils;
import com.android.mail.content.CursorCreator;
import com.android.mail.content.ObjectCursor;
import com.android.mail.providers.UIProvider.AccountCapabilities;
import com.android.mail.providers.UIProvider.AccountColumns;
import com.android.mail.providers.UIProvider.AccountColumns.SettingsColumns;
import com.android.mail.providers.UIProvider.SyncStatus;
import com.android.mail.utils.LogTag;
import com.android.mail.utils.LogUtils;
import com.android.mail.utils.Utils;
import com.google.common.base.Objects;
import com.google.common.collect.Lists;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class Account extends android.accounts.Account implements Parcelable {
private static final String SETTINGS_KEY = "settings";
/**
* The version of the UI provider schema from which this account provider
* will return results.
*/
public final int providerVersion;
/**
* The uri to directly access the information for this account.
*/
public final Uri uri;
/**
* The possible capabilities that this account supports.
*/
public final int capabilities;
/**
* The content provider uri to return the list of top level folders for this
* account.
*/
public final Uri folderListUri;
/**
* The content provider uri to return the list of all folders for this
* account.
*/
public Uri fullFolderListUri;
/**
* The content provider uri that can be queried for search results.
*/
public final Uri searchUri;
/**
* The custom from addresses for this account or null if there are none.
*/
public String accountFromAddresses;
/**
* The content provider uri that can be used to expunge message from this
* account. NOTE: This might be better to be an update operation on the
* messageUri.
*/
public final Uri expungeMessageUri;
/**
* The content provider uri that can be used to undo the last operation
* performed.
*/
public final Uri undoUri;
/**
* Uri for EDIT intent that will cause the settings screens for this account type to be
* shown.
*/
public final Uri settingsIntentUri;
/**
* Uri for VIEW intent that will cause the help screens for this account type to be
* shown.
*/
public final Uri helpIntentUri;
/**
* Uri for VIEW intent that will cause the send feedback screens for this account type to be
* shown.
*/
public final Uri sendFeedbackIntentUri;
/**
* Uri for VIEW intent that will cause the reauthentication screen for this account to be
* shown.
*/
public final Uri reauthenticationIntentUri;
/**
* The sync status of the account
*/
public final int syncStatus;
/**
* Uri for VIEW intent that will cause the compose screen for this account type to be
* shown.
*/
public final Uri composeIntentUri;
public final String mimeType;
/**
* URI for recent folders for this account.
*/
public final Uri recentFolderListUri;
/**
* The color used for this account in combined view (Email)
*/
public final int color;
/**
* URI for default recent folders for this account, if any.
*/
public final Uri defaultRecentFolderListUri;
/**
* Settings object for this account.
*/
public final Settings settings;
/**
* URI for forcing a manual sync of this account.
*/
public final Uri manualSyncUri;
/**
* URI for account type specific supplementary account info on outgoing links, if any.
*/
public final Uri viewIntentProxyUri;
/**
* URI for querying for the account cookies to be used when displaying inline content in a
* conversation
*/
public final Uri accoutCookieQueryUri;
/**
* URI to be used with an update() ContentResolver call with a {@link ContentValues} object
* where the keys are from the {@link AccountColumns.SettingsColumns}, and the values are the
* new values.
*/
public final Uri updateSettingsUri;
/**
* Whether message transforms (HTML DOM manipulation) feature is enabled.
*/
public final int enableMessageTransforms;
/**
* Transient cache of parsed {@link #accountFromAddresses}, plus an entry for the main account
* address.
*/
private transient List<ReplyFromAccount> mReplyFroms;
private static final String LOG_TAG = LogTag.getLogTag();
/**
* Return a serialized String for this account.
*/
public synchronized String serialize() {
JSONObject json = new JSONObject();
try {
json.put(UIProvider.AccountColumns.NAME, name);
json.put(UIProvider.AccountColumns.TYPE, type);
json.put(UIProvider.AccountColumns.PROVIDER_VERSION, providerVersion);
json.put(UIProvider.AccountColumns.URI, uri);
json.put(UIProvider.AccountColumns.CAPABILITIES, capabilities);
json.put(UIProvider.AccountColumns.FOLDER_LIST_URI, folderListUri);
json.put(UIProvider.AccountColumns.FULL_FOLDER_LIST_URI, fullFolderListUri);
json.put(UIProvider.AccountColumns.SEARCH_URI, searchUri);
json.put(UIProvider.AccountColumns.ACCOUNT_FROM_ADDRESSES, accountFromAddresses);
json.put(UIProvider.AccountColumns.EXPUNGE_MESSAGE_URI, expungeMessageUri);
json.put(UIProvider.AccountColumns.UNDO_URI, undoUri);
json.put(UIProvider.AccountColumns.SETTINGS_INTENT_URI, settingsIntentUri);
json.put(UIProvider.AccountColumns.HELP_INTENT_URI, helpIntentUri);
json.put(UIProvider.AccountColumns.SEND_FEEDBACK_INTENT_URI, sendFeedbackIntentUri);
json.put(UIProvider.AccountColumns.REAUTHENTICATION_INTENT_URI,
reauthenticationIntentUri);
json.put(UIProvider.AccountColumns.SYNC_STATUS, syncStatus);
json.put(UIProvider.AccountColumns.COMPOSE_URI, composeIntentUri);
json.put(UIProvider.AccountColumns.MIME_TYPE, mimeType);
json.put(UIProvider.AccountColumns.RECENT_FOLDER_LIST_URI, recentFolderListUri);
json.put(UIProvider.AccountColumns.COLOR, color);
json.put(UIProvider.AccountColumns.DEFAULT_RECENT_FOLDER_LIST_URI,
defaultRecentFolderListUri);
json.put(UIProvider.AccountColumns.MANUAL_SYNC_URI,
manualSyncUri);
json.put(UIProvider.AccountColumns.VIEW_INTENT_PROXY_URI,
viewIntentProxyUri);
json.put(UIProvider.AccountColumns.ACCOUNT_COOKIE_QUERY_URI, accoutCookieQueryUri);
json.put(UIProvider.AccountColumns.UPDATE_SETTINGS_URI, updateSettingsUri);
json.put(UIProvider.AccountColumns.ENABLE_MESSAGE_TRANSFORMS, enableMessageTransforms);
if (settings != null) {
json.put(SETTINGS_KEY, settings.toJSON());
}
} catch (JSONException e) {
LogUtils.wtf(LOG_TAG, e, "Could not serialize account with name %s", name);
}
return json.toString();
}
/**
* Create a new instance of an Account object using a serialized instance created previously
* using {@link #serialize()}. This returns null if the serialized instance was invalid or does
* not represent a valid account object.
*
* @param serializedAccount
* @return
*/
public static Account newinstance(String serializedAccount) {
// The heavy lifting is done by Account(name, type, serializedAccount). This method
// is a wrapper to check for errors and exceptions and return back a null in cases
// something breaks.
JSONObject json = null;
try {
json = new JSONObject(serializedAccount);
final String name = (String) json.get(UIProvider.AccountColumns.NAME);
final String type = (String) json.get(UIProvider.AccountColumns.TYPE);
return new Account(name, type, serializedAccount);
} catch (JSONException e) {
LogUtils.w(LOG_TAG, e, "Could not create an account from this input: \"%s\"",
serializedAccount);
return null;
}
}
/**
* Construct a new Account instance from a previously serialized string. This calls
* {@link android.accounts.Account#Account(String, String)} with name and type given as the
* first two arguments.
*
* <p>
* This is private. Public uses should go through the safe {@link #newinstance(String)} method.
* </p>
* @param name name of account in {@link android.accounts.Account}
* @param type type of account in {@link android.accounts.Account}
* @param jsonAccount string obtained from {@link #serialize()} on a valid account.
* @throws JSONException
*/
private Account(String name, String type, String jsonAccount) throws JSONException {
super(name, type);
final JSONObject json = new JSONObject(jsonAccount);
providerVersion = json.getInt(UIProvider.AccountColumns.PROVIDER_VERSION);
uri = Uri.parse(json.optString(UIProvider.AccountColumns.URI));
capabilities = json.getInt(UIProvider.AccountColumns.CAPABILITIES);
folderListUri = Utils
.getValidUri(json.optString(UIProvider.AccountColumns.FOLDER_LIST_URI));
fullFolderListUri = Utils.getValidUri(json
.optString(UIProvider.AccountColumns.FULL_FOLDER_LIST_URI));
searchUri = Utils.getValidUri(json.optString(UIProvider.AccountColumns.SEARCH_URI));
accountFromAddresses = json.optString(UIProvider.AccountColumns.ACCOUNT_FROM_ADDRESSES,
"");
expungeMessageUri = Utils.getValidUri(json
.optString(UIProvider.AccountColumns.EXPUNGE_MESSAGE_URI));
undoUri = Utils.getValidUri(json.optString(UIProvider.AccountColumns.UNDO_URI));
settingsIntentUri = Utils.getValidUri(json
.optString(UIProvider.AccountColumns.SETTINGS_INTENT_URI));
helpIntentUri = Utils
.getValidUri(json.optString(UIProvider.AccountColumns.HELP_INTENT_URI));
sendFeedbackIntentUri = Utils.getValidUri(json
.optString(UIProvider.AccountColumns.SEND_FEEDBACK_INTENT_URI));
reauthenticationIntentUri = Utils.getValidUri(
json.optString(UIProvider.AccountColumns.REAUTHENTICATION_INTENT_URI));
syncStatus = json.optInt(UIProvider.AccountColumns.SYNC_STATUS);
composeIntentUri = Utils.getValidUri(json.optString(UIProvider.AccountColumns.COMPOSE_URI));
mimeType = json.optString(UIProvider.AccountColumns.MIME_TYPE);
recentFolderListUri = Utils.getValidUri(json
.optString(UIProvider.AccountColumns.RECENT_FOLDER_LIST_URI));
color = json.optInt(UIProvider.AccountColumns.COLOR, 0);
defaultRecentFolderListUri = Utils.getValidUri(json
.optString(UIProvider.AccountColumns.DEFAULT_RECENT_FOLDER_LIST_URI));
manualSyncUri = Utils
.getValidUri(json.optString(UIProvider.AccountColumns.MANUAL_SYNC_URI));
viewIntentProxyUri = Utils
.getValidUri(json.optString(UIProvider.AccountColumns.VIEW_INTENT_PROXY_URI));
accoutCookieQueryUri = Utils.getValidUri(
json.optString(UIProvider.AccountColumns.ACCOUNT_COOKIE_QUERY_URI));
updateSettingsUri = Utils.getValidUri(
json.optString(UIProvider.AccountColumns.UPDATE_SETTINGS_URI));
enableMessageTransforms = json.optInt(AccountColumns.ENABLE_MESSAGE_TRANSFORMS);
final Settings jsonSettings = Settings.newInstance(json.optJSONObject(SETTINGS_KEY));
if (jsonSettings != null) {
settings = jsonSettings;
} else {
LogUtils.e(LOG_TAG, new Throwable(),
"Unexpected null settings in Account(name, type, jsonAccount)");
settings = Settings.EMPTY_SETTINGS;
}
}
public Account(Parcel in) {
super(in);
providerVersion = in.readInt();
uri = in.readParcelable(null);
capabilities = in.readInt();
folderListUri = in.readParcelable(null);
fullFolderListUri = in.readParcelable(null);
searchUri = in.readParcelable(null);
accountFromAddresses = in.readString();
expungeMessageUri = in.readParcelable(null);
undoUri = in.readParcelable(null);
settingsIntentUri = in.readParcelable(null);
helpIntentUri = in.readParcelable(null);
sendFeedbackIntentUri = in.readParcelable(null);
reauthenticationIntentUri = in.readParcelable(null);
syncStatus = in.readInt();
composeIntentUri = in.readParcelable(null);
mimeType = in.readString();
recentFolderListUri = in.readParcelable(null);
color = in.readInt();
defaultRecentFolderListUri = in.readParcelable(null);
manualSyncUri = in.readParcelable(null);
viewIntentProxyUri = in.readParcelable(null);
accoutCookieQueryUri = in.readParcelable(null);
updateSettingsUri = in.readParcelable(null);
enableMessageTransforms = in.readInt();
final String serializedSettings = in.readString();
final Settings parcelSettings = Settings.newInstance(serializedSettings);
if (parcelSettings != null) {
settings = parcelSettings;
} else {
LogUtils.e(LOG_TAG, new Throwable(), "Unexpected null settings in Account(Parcel)");
settings = Settings.EMPTY_SETTINGS;
}
}
public Account(Cursor cursor) {
super(cursor.getString(cursor.getColumnIndex(UIProvider.AccountColumns.NAME)),
cursor.getString(cursor.getColumnIndex(UIProvider.AccountColumns.TYPE)));
accountFromAddresses = cursor.getString(
cursor.getColumnIndex(UIProvider.AccountColumns.ACCOUNT_FROM_ADDRESSES));
final int capabilitiesColumnIndex =
cursor.getColumnIndex(UIProvider.AccountColumns.CAPABILITIES);
if (capabilitiesColumnIndex != -1) {
capabilities = cursor.getInt(capabilitiesColumnIndex);
} else {
capabilities = 0;
}
providerVersion =
cursor.getInt(cursor.getColumnIndex(UIProvider.AccountColumns.PROVIDER_VERSION));
uri = Uri.parse(cursor.getString(cursor.getColumnIndex(UIProvider.AccountColumns.URI)));
folderListUri = Uri.parse(
cursor.getString(cursor.getColumnIndex(UIProvider.AccountColumns.FOLDER_LIST_URI)));
fullFolderListUri = Utils.getValidUri(cursor.getString(
cursor.getColumnIndex(UIProvider.AccountColumns.FULL_FOLDER_LIST_URI)));
searchUri = Utils.getValidUri(
cursor.getString(cursor.getColumnIndex(UIProvider.AccountColumns.SEARCH_URI)));
expungeMessageUri = Utils.getValidUri(cursor.getString(
cursor.getColumnIndex(UIProvider.AccountColumns.EXPUNGE_MESSAGE_URI)));
undoUri = Utils.getValidUri(
cursor.getString(cursor.getColumnIndex(UIProvider.AccountColumns.UNDO_URI)));
settingsIntentUri = Utils.getValidUri(cursor.getString(
cursor.getColumnIndex(UIProvider.AccountColumns.SETTINGS_INTENT_URI)));
helpIntentUri = Utils.getValidUri(
cursor.getString(cursor.getColumnIndex(UIProvider.AccountColumns.HELP_INTENT_URI)));
sendFeedbackIntentUri = Utils.getValidUri(cursor.getString(
cursor.getColumnIndex(UIProvider.AccountColumns.SEND_FEEDBACK_INTENT_URI)));
reauthenticationIntentUri = Utils.getValidUri(cursor.getString(
cursor.getColumnIndex(UIProvider.AccountColumns.REAUTHENTICATION_INTENT_URI)));
syncStatus = cursor.getInt(cursor.getColumnIndex(UIProvider.AccountColumns.SYNC_STATUS));
composeIntentUri = Utils.getValidUri(
cursor.getString(cursor.getColumnIndex(UIProvider.AccountColumns.COMPOSE_URI)));
mimeType = cursor.getString(cursor.getColumnIndex(UIProvider.AccountColumns.MIME_TYPE));
recentFolderListUri = Utils.getValidUri(cursor.getString(
cursor.getColumnIndex(UIProvider.AccountColumns.RECENT_FOLDER_LIST_URI)));
color = cursor.getInt(cursor.getColumnIndex(UIProvider.AccountColumns.COLOR));
defaultRecentFolderListUri = Utils.getValidUri(cursor.getString(
cursor.getColumnIndex(UIProvider.AccountColumns.DEFAULT_RECENT_FOLDER_LIST_URI)));
manualSyncUri = Utils.getValidUri(
cursor.getString(cursor.getColumnIndex(UIProvider.AccountColumns.MANUAL_SYNC_URI)));
viewIntentProxyUri = Utils.getValidUri(cursor.getString(
cursor.getColumnIndex(UIProvider.AccountColumns.VIEW_INTENT_PROXY_URI)));
accoutCookieQueryUri = Utils.getValidUri(cursor.getString(
cursor.getColumnIndex(UIProvider.AccountColumns.ACCOUNT_COOKIE_QUERY_URI)));
updateSettingsUri = Utils.getValidUri(cursor.getString(
cursor.getColumnIndex(UIProvider.AccountColumns.UPDATE_SETTINGS_URI)));
enableMessageTransforms = cursor.getInt(
cursor.getColumnIndex(AccountColumns.ENABLE_MESSAGE_TRANSFORMS));
settings = new Settings(cursor);
}
/**
* Returns an array of all Accounts located at this cursor. This method returns a zero length
* array if no account was found. This method does not close the cursor.
* @param cursor cursor pointing to the list of accounts
* @return the array of all accounts stored at this cursor.
*/
public static Account[] getAllAccounts(ObjectCursor<Account> cursor) {
final int initialLength = cursor.getCount();
if (initialLength <= 0 || !cursor.moveToFirst()) {
// Return zero length account array rather than null
return new Account[0];
}
final Account[] allAccounts = new Account[initialLength];
int i = 0;
do {
allAccounts[i++] = cursor.getModel();
} while (cursor.moveToNext());
// Ensure that the length of the array is accurate
assert (i == initialLength);
return allAccounts;
}
public boolean supportsCapability(int capability) {
return (capabilities & capability) != 0;
}
public boolean isAccountSyncRequired() {
return (syncStatus & SyncStatus.INITIAL_SYNC_NEEDED) == SyncStatus.INITIAL_SYNC_NEEDED;
}
public boolean isAccountInitializationRequired() {
return (syncStatus & SyncStatus.ACCOUNT_INITIALIZATION_REQUIRED) ==
SyncStatus.ACCOUNT_INITIALIZATION_REQUIRED;
}
/**
* Returns true when when the UI provider has indicated that the account has been initialized,
* and sync is not required.
*/
public boolean isAccountReady() {
return !isAccountInitializationRequired() && !isAccountSyncRequired();
}
@Override
public void writeToParcel(Parcel dest, int flags) {
super.writeToParcel(dest, flags);
dest.writeInt(providerVersion);
dest.writeParcelable(uri, 0);
dest.writeInt(capabilities);
dest.writeParcelable(folderListUri, 0);
dest.writeParcelable(fullFolderListUri, 0);
dest.writeParcelable(searchUri, 0);
dest.writeString(accountFromAddresses);
dest.writeParcelable(expungeMessageUri, 0);
dest.writeParcelable(undoUri, 0);
dest.writeParcelable(settingsIntentUri, 0);
dest.writeParcelable(helpIntentUri, 0);
dest.writeParcelable(sendFeedbackIntentUri, 0);
dest.writeParcelable(reauthenticationIntentUri, 0);
dest.writeInt(syncStatus);
dest.writeParcelable(composeIntentUri, 0);
dest.writeString(mimeType);
dest.writeParcelable(recentFolderListUri, 0);
dest.writeInt(color);
dest.writeParcelable(defaultRecentFolderListUri, 0);
dest.writeParcelable(manualSyncUri, 0);
dest.writeParcelable(viewIntentProxyUri, 0);
dest.writeParcelable(accoutCookieQueryUri, 0);
dest.writeParcelable(updateSettingsUri, 0);
dest.writeInt(enableMessageTransforms);
if (settings == null) {
LogUtils.e(LOG_TAG, "unexpected null settings object in writeToParcel");
}
dest.writeString(settings != null ? settings.serialize() : "");
}
@Override
public String toString() {
final StringBuilder sb = new StringBuilder();
sb.append("name=");
sb.append(name);
sb.append(",type=");
sb.append(type);
sb.append(",accountFromAddressUri=");
sb.append(accountFromAddresses);
sb.append(",capabilities=");
sb.append(capabilities);
sb.append(",providerVersion=");
sb.append(providerVersion);
sb.append(",folderListUri=");
sb.append(folderListUri);
sb.append(",fullFolderListUri=");
sb.append(fullFolderListUri);
sb.append(",searchUri=");
sb.append(searchUri);
sb.append(",saveDraftUri=");
sb.append(",expungeMessageUri=");
sb.append(expungeMessageUri);
sb.append(",undoUri=");
sb.append(undoUri);
sb.append(",settingsIntentUri=");
sb.append(settingsIntentUri);
sb.append(",helpIntentUri=");
sb.append(helpIntentUri);
sb.append(",sendFeedbackIntentUri=");
sb.append(sendFeedbackIntentUri);
sb.append(",reauthenticationIntentUri=");
sb.append(reauthenticationIntentUri);
sb.append(",syncStatus=");
sb.append(syncStatus);
sb.append(",composeIntentUri=");
sb.append(composeIntentUri);
sb.append(",mimeType=");
sb.append(mimeType);
sb.append(",recentFoldersUri=");
sb.append(recentFolderListUri);
sb.append(",color=");
sb.append(Integer.toHexString(color));
sb.append(",defaultRecentFoldersUri=");
sb.append(defaultRecentFolderListUri);
sb.append(",settings=");
sb.append(settings.serialize());
return sb.toString();
}
@Override
public boolean equals(Object o) {
if (o == this) {
return true;
}
if ((o == null) || (o.getClass() != this.getClass())) {
return false;
}
final Account other = (Account) o;
return TextUtils.equals(name, other.name) && TextUtils.equals(type, other.type) &&
capabilities == other.capabilities && providerVersion == other.providerVersion &&
Objects.equal(uri, other.uri) &&
Objects.equal(folderListUri, other.folderListUri) &&
Objects.equal(fullFolderListUri, other.fullFolderListUri) &&
Objects.equal(searchUri, other.searchUri) &&
Objects.equal(accountFromAddresses, other.accountFromAddresses) &&
Objects.equal(expungeMessageUri, other.expungeMessageUri) &&
Objects.equal(undoUri, other.undoUri) &&
Objects.equal(settingsIntentUri, other.settingsIntentUri) &&
Objects.equal(helpIntentUri, other.helpIntentUri) &&
Objects.equal(sendFeedbackIntentUri, other.sendFeedbackIntentUri) &&
Objects.equal(reauthenticationIntentUri, other.reauthenticationIntentUri) &&
(syncStatus == other.syncStatus) &&
Objects.equal(composeIntentUri, other.composeIntentUri) &&
TextUtils.equals(mimeType, other.mimeType) &&
Objects.equal(recentFolderListUri, other.recentFolderListUri) &&
color == other.color &&
Objects.equal(defaultRecentFolderListUri, other.defaultRecentFolderListUri) &&
Objects.equal(viewIntentProxyUri, other.viewIntentProxyUri) &&
Objects.equal(accoutCookieQueryUri, other.accoutCookieQueryUri) &&
Objects.equal(updateSettingsUri, other.updateSettingsUri) &&
Objects.equal(enableMessageTransforms, other.enableMessageTransforms) &&
Objects.equal(settings, other.settings);
}
/**
* Returns true if the two accounts differ in sync or server-side settings.
* This is <b>not</b> a replacement for {@link #equals(Object)}.
* @param other
* @return
*/
public final boolean settingsDiffer(Account other) {
// If the other object doesn't exist, they differ significantly.
if (other == null) {
return true;
}
// Check all the server-side settings, the user-side settings and the sync status.
return ((this.syncStatus != other.syncStatus)
|| !Objects.equal(accountFromAddresses, other.accountFromAddresses)
|| color != other.color
|| (this.settings.hashCode() != other.settings.hashCode()));
}
@Override
public int hashCode() {
return super.hashCode()
^ Objects.hashCode(name, type, capabilities, providerVersion, uri, folderListUri,
fullFolderListUri, searchUri, accountFromAddresses, expungeMessageUri,
undoUri, settingsIntentUri, helpIntentUri, sendFeedbackIntentUri,
reauthenticationIntentUri, syncStatus, composeIntentUri, mimeType,
recentFolderListUri, color, defaultRecentFolderListUri, viewIntentProxyUri,
accoutCookieQueryUri, updateSettingsUri, enableMessageTransforms);
}
/**
* Returns whether two Accounts match, as determined by their base URIs.
* <p>For a deep object comparison, use {@link #equals(Object)}.
*
*/
public boolean matches(Account other) {
return other != null && Objects.equal(uri, other.uri);
}
public List<ReplyFromAccount> getReplyFroms() {
if (mReplyFroms == null) {
mReplyFroms = Lists.newArrayList();
// skip if sending is unsupported
if (supportsCapability(AccountCapabilities.SENDING_UNAVAILABLE)) {
return mReplyFroms;
}
// add the main account address
mReplyFroms.add(new ReplyFromAccount(this, uri, name, name, name,
false /* isDefault */, false /* isCustom */));
if (!TextUtils.isEmpty(accountFromAddresses)) {
try {
JSONArray accounts = new JSONArray(accountFromAddresses);
for (int i = 0, len = accounts.length(); i < len; i++) {
final ReplyFromAccount a = ReplyFromAccount.deserialize(this,
accounts.getJSONObject(i));
if (a != null) {
mReplyFroms.add(a);
}
}
} catch (JSONException e) {
LogUtils.e(LOG_TAG, e, "Unable to parse accountFromAddresses. name=%s", name);
}
}
}
return mReplyFroms;
}
/**
* @param fromAddress a raw email address, e.g. "user@domain.com"
* @return if the address belongs to this Account (either as the main address or as a
* custom-from)
*/
public boolean ownsFromAddress(String fromAddress) {
for (ReplyFromAccount replyFrom : getReplyFroms()) {
if (TextUtils.equals(replyFrom.address, fromAddress)) {
return true;
}
}
return false;
}
@SuppressWarnings("hiding")
public static final Creator<Account> CREATOR = new Creator<Account>() {
@Override
public Account createFromParcel(Parcel source) {
return new Account(source);
}
@Override
public Account[] newArray(int size) {
return new Account[size];
}
};
/**
* Find the position of the given needle in the given array of accounts.
* @param haystack the array of accounts to search
* @param needle the URI of account to find
* @return a position between 0 and haystack.length-1 if an account is found, -1 if not found.
*/
public static int findPosition(Account[] haystack, Uri needle) {
if (haystack != null && haystack.length > 0 && needle != null) {
// Need to go through the list of current accounts, and fix the
// position.
for (int i = 0, size = haystack.length; i < size; ++i) {
if (haystack[i].uri.equals(needle)) {
LogUtils.d(LOG_TAG, "findPositionOfAccount: Found needle at position %d", i);
return i;
}
}
}
return -1;
}
/**
* Creates a {@link Map} where the column name is the key and the value is the value, which can
* be used for populating a {@link MatrixCursor}.
*/
public Map<String, Object> getMatrixCursorValueMap() {
// ImmutableMap.Builder does not allow null values
final Map<String, Object> map = new HashMap<String, Object>();
map.put(UIProvider.AccountColumns._ID, 0);
map.put(UIProvider.AccountColumns.NAME, name);
map.put(UIProvider.AccountColumns.TYPE, type);
map.put(UIProvider.AccountColumns.PROVIDER_VERSION, providerVersion);
map.put(UIProvider.AccountColumns.URI, uri);
map.put(UIProvider.AccountColumns.CAPABILITIES, capabilities);
map.put(UIProvider.AccountColumns.FOLDER_LIST_URI, folderListUri);
map.put(UIProvider.AccountColumns.FULL_FOLDER_LIST_URI, fullFolderListUri);
map.put(UIProvider.AccountColumns.SEARCH_URI, searchUri);
map.put(UIProvider.AccountColumns.ACCOUNT_FROM_ADDRESSES, accountFromAddresses);
map.put(UIProvider.AccountColumns.EXPUNGE_MESSAGE_URI, expungeMessageUri);
map.put(UIProvider.AccountColumns.UNDO_URI, undoUri);
map.put(UIProvider.AccountColumns.SETTINGS_INTENT_URI, settingsIntentUri);
map.put(UIProvider.AccountColumns.HELP_INTENT_URI, helpIntentUri);
map.put(UIProvider.AccountColumns.SEND_FEEDBACK_INTENT_URI, sendFeedbackIntentUri);
map.put(
UIProvider.AccountColumns.REAUTHENTICATION_INTENT_URI, reauthenticationIntentUri);
map.put(UIProvider.AccountColumns.SYNC_STATUS, syncStatus);
map.put(UIProvider.AccountColumns.COMPOSE_URI, composeIntentUri);
map.put(UIProvider.AccountColumns.MIME_TYPE, mimeType);
map.put(UIProvider.AccountColumns.RECENT_FOLDER_LIST_URI, recentFolderListUri);
map.put(UIProvider.AccountColumns.DEFAULT_RECENT_FOLDER_LIST_URI,
defaultRecentFolderListUri);
map.put(UIProvider.AccountColumns.MANUAL_SYNC_URI, manualSyncUri);
map.put(UIProvider.AccountColumns.VIEW_INTENT_PROXY_URI, viewIntentProxyUri);
map.put(UIProvider.AccountColumns.ACCOUNT_COOKIE_QUERY_URI, accoutCookieQueryUri);
map.put(UIProvider.AccountColumns.COLOR, color);
map.put(UIProvider.AccountColumns.UPDATE_SETTINGS_URI, updateSettingsUri);
map.put(UIProvider.AccountColumns.ENABLE_MESSAGE_TRANSFORMS, enableMessageTransforms);
map.put(AccountColumns.SettingsColumns.SIGNATURE, settings.signature);
map.put(AccountColumns.SettingsColumns.AUTO_ADVANCE, settings.getAutoAdvanceSetting());
map.put(AccountColumns.SettingsColumns.MESSAGE_TEXT_SIZE, settings.messageTextSize);
map.put(AccountColumns.SettingsColumns.SNAP_HEADERS, settings.snapHeaders);
map.put(AccountColumns.SettingsColumns.REPLY_BEHAVIOR, settings.replyBehavior);
map.put(AccountColumns.SettingsColumns.CONV_LIST_ICON, settings.convListIcon);
map.put(AccountColumns.SettingsColumns.CONV_LIST_ATTACHMENT_PREVIEWS,
settings.convListAttachmentPreviews ? 1 : 0);
map.put(AccountColumns.SettingsColumns.CONFIRM_DELETE, settings.confirmDelete ? 1 : 0);
map.put(
AccountColumns.SettingsColumns.CONFIRM_ARCHIVE, settings.confirmArchive ? 1 : 0);
map.put(AccountColumns.SettingsColumns.CONFIRM_SEND, settings.confirmSend ? 1 : 0);
map.put(AccountColumns.SettingsColumns.DEFAULT_INBOX, settings.defaultInbox);
map.put(AccountColumns.SettingsColumns.DEFAULT_INBOX_NAME, settings.defaultInboxName);
map.put(AccountColumns.SettingsColumns.FORCE_REPLY_FROM_DEFAULT,
settings.forceReplyFromDefault ? 1 : 0);
map.put(AccountColumns.SettingsColumns.MAX_ATTACHMENT_SIZE, settings.maxAttachmentSize);
map.put(AccountColumns.SettingsColumns.SWIPE, settings.swipe);
map.put(AccountColumns.SettingsColumns.PRIORITY_ARROWS_ENABLED,
settings.priorityArrowsEnabled ? 1 : 0);
map.put(AccountColumns.SettingsColumns.SETUP_INTENT_URI, settings.setupIntentUri);
map.put(AccountColumns.SettingsColumns.CONVERSATION_VIEW_MODE,
settings.conversationViewMode);
map.put(AccountColumns.SettingsColumns.VEILED_ADDRESS_PATTERN,
settings.veiledAddressPattern);
map.put(AccountColumns.SettingsColumns.MOVE_TO_INBOX, settings.moveToInbox);
return map;
}
/**
* Public object that knows how to construct Accounts given Cursors.
*/
public final static CursorCreator<Account> FACTORY = new CursorCreator<Account>() {
@Override
public Account createFromCursor(Cursor c) {
return new Account(c);
}
@Override
public String toString() {
return "Account CursorCreator";
}
};
}