Merge "Allow database to hold oauth credentials" into ub-mail-master
This commit is contained in:
commit
44a6fc31a2
|
@ -31,11 +31,9 @@ import android.net.Uri;
|
|||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.os.RemoteException;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.android.emailcommon.provider.EmailContent.AccountColumns;
|
||||
import com.android.emailcommon.utility.Utility;
|
||||
import com.android.mail.utils.LogUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
@ -207,9 +205,6 @@ public final class Account extends EmailContent implements AccountColumns, Parce
|
|||
MailboxColumns.TYPE + " = " + Mailbox.TYPE_INBOX +
|
||||
" AND " + MailboxColumns.ACCOUNT_KEY + " =?";
|
||||
|
||||
/**
|
||||
* no public constructor since this is a utility class
|
||||
*/
|
||||
public Account() {
|
||||
mBaseUri = CONTENT_URI;
|
||||
|
||||
|
@ -739,23 +734,56 @@ public final class Account extends EmailContent implements AccountColumns, Parce
|
|||
|
||||
int index = 0;
|
||||
int recvIndex = -1;
|
||||
int recvCredentialsIndex = -1;
|
||||
int sendIndex = -1;
|
||||
int sendCredentialsIndex = -1;
|
||||
|
||||
// Create operations for saving the send and recv hostAuths
|
||||
// Create operations for saving the send and recv hostAuths, and their credentials.
|
||||
// Also, remember which operation in the array they represent
|
||||
ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
|
||||
if (mHostAuthRecv != null) {
|
||||
recvIndex = index++;
|
||||
ops.add(ContentProviderOperation.newInsert(mHostAuthRecv.mBaseUri)
|
||||
.withValues(mHostAuthRecv.toContentValues())
|
||||
if (mHostAuthRecv.mCredential != null) {
|
||||
recvCredentialsIndex = index++;
|
||||
ops.add(ContentProviderOperation.newInsert(mHostAuthRecv.mCredential.mBaseUri)
|
||||
.withValues(mHostAuthRecv.mCredential.toContentValues())
|
||||
.build());
|
||||
}
|
||||
|
||||
recvIndex = index++;
|
||||
final ContentProviderOperation.Builder b = ContentProviderOperation.newInsert(
|
||||
mHostAuthRecv.mBaseUri);
|
||||
b.withValues(mHostAuthRecv.toContentValues());
|
||||
if (recvCredentialsIndex >= 0) {
|
||||
final ContentValues cv = new ContentValues();
|
||||
cv.put(HostAuth.CREDENTIAL_KEY, recvCredentialsIndex);
|
||||
b.withValueBackReferences(cv);
|
||||
}
|
||||
ops.add(b.build());
|
||||
}
|
||||
if (mHostAuthSend != null) {
|
||||
sendIndex = index++;
|
||||
ops.add(ContentProviderOperation.newInsert(mHostAuthSend.mBaseUri)
|
||||
.withValues(mHostAuthSend.toContentValues())
|
||||
if (mHostAuthSend.mCredential != null) {
|
||||
if (mHostAuthRecv.mCredential != null &&
|
||||
mHostAuthRecv.mCredential.equals(mHostAuthSend.mCredential)) {
|
||||
// These two credentials are identical, use the same row.
|
||||
sendCredentialsIndex = recvCredentialsIndex;
|
||||
} else {
|
||||
sendCredentialsIndex = index++;
|
||||
ops.add(ContentProviderOperation.newInsert(mHostAuthRecv.mCredential.mBaseUri)
|
||||
.withValues(mHostAuthRecv.mCredential.toContentValues())
|
||||
.build());
|
||||
}
|
||||
}
|
||||
sendIndex = index++;
|
||||
final ContentProviderOperation.Builder b = ContentProviderOperation.newInsert(
|
||||
mHostAuthSend.mBaseUri);
|
||||
b.withValues(mHostAuthSend.toContentValues());
|
||||
if (sendCredentialsIndex >= 0) {
|
||||
final ContentValues cv = new ContentValues();
|
||||
cv.put(HostAuth.CREDENTIAL_KEY, sendCredentialsIndex);
|
||||
b.withValueBackReferences(cv);
|
||||
}
|
||||
ops.add(b.build());
|
||||
}
|
||||
|
||||
// Now do the Account
|
||||
ContentValues cv = null;
|
||||
|
|
|
@ -0,0 +1,158 @@
|
|||
package com.android.emailcommon.provider;
|
||||
|
||||
import android.content.ContentValues;
|
||||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.net.Uri;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import com.android.emailcommon.provider.EmailContent;
|
||||
import com.android.emailcommon.utility.Utility;
|
||||
import com.google.common.base.Objects;
|
||||
|
||||
public class Credential extends EmailContent implements Parcelable {
|
||||
|
||||
public static final String TABLE_NAME = "Credential";
|
||||
public static Uri CONTENT_URI;
|
||||
|
||||
public static final Credential EMPTY = new Credential(-1, "", "", 0);
|
||||
|
||||
public static void initCredential() {
|
||||
CONTENT_URI = Uri.parse(EmailContent.CONTENT_URI + "/credential");
|
||||
}
|
||||
|
||||
public static final String TYPE_OAUTH = "oauth";
|
||||
|
||||
public String mAccessToken;
|
||||
public String mRefreshToken;
|
||||
public long mExpiration;
|
||||
|
||||
// Name of the authentication provider.
|
||||
public static final String PROVIDER_COLUMN = "provider";
|
||||
// Access token.
|
||||
public static final String ACCESS_TOKEN_COLUMN = "accessToken";
|
||||
// Refresh token.
|
||||
public static final String REFRESH_TOKEN_COLUMN = "refreshToken";
|
||||
// Expiration date for these credentials.
|
||||
public static final String EXPIRATION_COLUMN = "expiration";
|
||||
|
||||
|
||||
public interface CredentialQuery {
|
||||
public static final int ID_COLUMN_INDEX = 0;
|
||||
public static final int PROVIDER_COLUMN_INDEX = 1;
|
||||
public static final int ACCESS_TOKEN_COLUMN_INDEX = 2;
|
||||
public static final int REFRESH_TOKEN_COLUMN_INDEX = 3;
|
||||
public static final int EXPIRATION_COLUMN_INDEX = 4;
|
||||
|
||||
public static final String[] PROJECTION = new String[] {
|
||||
RECORD_ID,
|
||||
PROVIDER_COLUMN,
|
||||
ACCESS_TOKEN_COLUMN,
|
||||
REFRESH_TOKEN_COLUMN,
|
||||
EXPIRATION_COLUMN
|
||||
};
|
||||
}
|
||||
|
||||
public Credential() {
|
||||
mBaseUri = CONTENT_URI;
|
||||
}
|
||||
|
||||
public Credential(long id, String accessToken, String refreshToken, long expiration) {
|
||||
mBaseUri = CONTENT_URI;
|
||||
mId = id;
|
||||
mAccessToken = accessToken;
|
||||
mRefreshToken = refreshToken;
|
||||
mExpiration = expiration;
|
||||
}
|
||||
|
||||
/**
|
||||
* Restore a Credential from the database, given its unique id
|
||||
* @param context
|
||||
* @param id
|
||||
* @return the instantiated Credential
|
||||
*/
|
||||
public static Credential restoreCredentialsWithId(Context context, long id) {
|
||||
return EmailContent.restoreContentWithId(context, Credential.class,
|
||||
Credential.CONTENT_URI, CredentialQuery.PROJECTION, id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void restore(Cursor cursor) {
|
||||
mBaseUri = CONTENT_URI;
|
||||
mId = cursor.getLong(CredentialQuery.ID_COLUMN_INDEX);
|
||||
mAccessToken = cursor.getString(CredentialQuery.ACCESS_TOKEN_COLUMN_INDEX);
|
||||
mRefreshToken = cursor.getString(CredentialQuery.REFRESH_TOKEN_COLUMN_INDEX);
|
||||
mExpiration = cursor.getInt(CredentialQuery.EXPIRATION_COLUMN_INDEX);
|
||||
}
|
||||
|
||||
/**
|
||||
* Supports Parcelable
|
||||
*/
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Supports Parcelable
|
||||
*/
|
||||
public static final Parcelable.Creator<Credential> CREATOR
|
||||
= new Parcelable.Creator<Credential>() {
|
||||
@Override
|
||||
public Credential createFromParcel(Parcel in) {
|
||||
return new Credential(in);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Credential[] newArray(int size) {
|
||||
return new Credential[size];
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
// mBaseUri is not parceled
|
||||
dest.writeLong(mId);
|
||||
dest.writeString(mAccessToken);
|
||||
dest.writeString(mRefreshToken);
|
||||
dest.writeLong(mExpiration);
|
||||
}
|
||||
|
||||
/**
|
||||
* Supports Parcelable
|
||||
*/
|
||||
public Credential(Parcel in) {
|
||||
mBaseUri = CONTENT_URI;
|
||||
mId = in.readLong();
|
||||
mAccessToken = in.readString();
|
||||
mRefreshToken = in.readString();
|
||||
mExpiration = in.readLong();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (!(o instanceof Credential)) {
|
||||
return false;
|
||||
}
|
||||
Credential that = (Credential)o;
|
||||
return Utility.areStringsEqual(mAccessToken, that.mAccessToken)
|
||||
&& Utility.areStringsEqual(mRefreshToken, that.mRefreshToken)
|
||||
&& mExpiration == that.mExpiration;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hashCode(mAccessToken, mRefreshToken, mExpiration);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ContentValues toContentValues() {
|
||||
ContentValues values = new ContentValues();
|
||||
values.put(ACCESS_TOKEN_COLUMN, mAccessToken);
|
||||
values.put(REFRESH_TOKEN_COLUMN, mRefreshToken);
|
||||
values.put(EXPIRATION_COLUMN, mExpiration);
|
||||
return values;
|
||||
}
|
||||
|
||||
}
|
|
@ -27,12 +27,14 @@ import android.content.res.Resources;
|
|||
import android.database.Cursor;
|
||||
import android.net.Uri;
|
||||
import android.os.Environment;
|
||||
import android.os.Looper;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.os.RemoteException;
|
||||
|
||||
import com.android.emailcommon.utility.TextUtilities;
|
||||
import com.android.emailcommon.utility.Utility;
|
||||
import com.android.emailcommon.Logging;
|
||||
import com.android.emailcommon.R;
|
||||
import com.android.mail.providers.UIProvider;
|
||||
import com.android.mail.utils.LogUtils;
|
||||
|
@ -160,6 +162,7 @@ public abstract class EmailContent {
|
|||
Mailbox.initMailbox();
|
||||
QuickResponse.initQuickResponse();
|
||||
HostAuth.initHostAuth();
|
||||
Credential.initCredential();
|
||||
Policy.initPolicy();
|
||||
Message.initMessage();
|
||||
MessageMove.init();
|
||||
|
@ -169,6 +172,14 @@ public abstract class EmailContent {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
private static void warnIfUiThread() {
|
||||
if (Looper.getMainLooper().getThread() == Thread.currentThread()) {
|
||||
LogUtils.w(Logging.LOG_TAG, "Method called on the UI thread",
|
||||
new Throwable());
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isInitialSyncKey(final String syncKey) {
|
||||
return syncKey == null || syncKey.isEmpty() || syncKey.equals("0");
|
||||
}
|
||||
|
@ -197,6 +208,7 @@ public abstract class EmailContent {
|
|||
*/
|
||||
public static <T extends EmailContent> T restoreContentWithId(Context context,
|
||||
Class<T> klass, Uri contentUri, String[] contentProjection, long id) {
|
||||
warnIfUiThread();
|
||||
Uri u = ContentUris.withAppendedId(contentUri, id);
|
||||
Cursor c = context.getContentResolver().query(u, contentProjection, null, null, null);
|
||||
if (c == null) throw new ProviderUnavailableException();
|
||||
|
@ -1718,6 +1730,8 @@ public abstract class EmailContent {
|
|||
static final String ACCOUNT_KEY = "accountKey";
|
||||
// A blob containing an X509 server certificate
|
||||
static final String SERVER_CERT = "serverCert";
|
||||
// The credentials row this hostAuth should use. Currently only set if using OAuth.
|
||||
static final String CREDENTIAL_KEY = "credentialKey";
|
||||
}
|
||||
|
||||
public interface PolicyColumns {
|
||||
|
|
|
@ -52,8 +52,9 @@ public final class HostAuth extends EmailContent implements HostAuthColumns, Par
|
|||
public static final int FLAG_TLS = 0x02; // Use TLS
|
||||
public static final int FLAG_AUTHENTICATE = 0x04; // Use name/password for authentication
|
||||
public static final int FLAG_TRUST_ALL = 0x08; // Trust all certificates
|
||||
public static final int FLAG_OAUTH = 0x10; // Use OAuth for authentication
|
||||
// Mask of settings directly configurable by the user
|
||||
public static final int USER_CONFIG_MASK = 0x0b;
|
||||
public static final int USER_CONFIG_MASK = 0x1b;
|
||||
|
||||
public String mProtocol;
|
||||
public String mAddress;
|
||||
|
@ -65,6 +66,9 @@ public final class HostAuth extends EmailContent implements HostAuthColumns, Par
|
|||
public String mClientCertAlias = null;
|
||||
// NOTE: The server certificate is NEVER automatically retrieved from EmailProvider
|
||||
public byte[] mServerCert = null;
|
||||
public long mCredentialKey;
|
||||
|
||||
public transient Credential mCredential;
|
||||
|
||||
public static final int CONTENT_ID_COLUMN = 0;
|
||||
public static final int CONTENT_PROTOCOL_COLUMN = 1;
|
||||
|
@ -75,16 +79,15 @@ public final class HostAuth extends EmailContent implements HostAuthColumns, Par
|
|||
public static final int CONTENT_PASSWORD_COLUMN = 6;
|
||||
public static final int CONTENT_DOMAIN_COLUMN = 7;
|
||||
public static final int CONTENT_CLIENT_CERT_ALIAS_COLUMN = 8;
|
||||
public static final int CONTENT_CREDENTIAL_KEY_COLUMN = 9;
|
||||
|
||||
public static final String[] CONTENT_PROJECTION = new String[] {
|
||||
RECORD_ID, HostAuthColumns.PROTOCOL, HostAuthColumns.ADDRESS, HostAuthColumns.PORT,
|
||||
HostAuthColumns.FLAGS, HostAuthColumns.LOGIN,
|
||||
HostAuthColumns.PASSWORD, HostAuthColumns.DOMAIN, HostAuthColumns.CLIENT_CERT_ALIAS
|
||||
HostAuthColumns.PASSWORD, HostAuthColumns.DOMAIN, HostAuthColumns.CLIENT_CERT_ALIAS,
|
||||
HostAuthColumns.CREDENTIAL_KEY
|
||||
};
|
||||
|
||||
/**
|
||||
* no public constructor since this is a utility class
|
||||
*/
|
||||
public HostAuth() {
|
||||
mBaseUri = CONTENT_URI;
|
||||
|
||||
|
@ -92,6 +95,41 @@ public final class HostAuth extends EmailContent implements HostAuthColumns, Par
|
|||
mPort = PORT_UNKNOWN;
|
||||
}
|
||||
|
||||
/**
|
||||
* getOrCreateCredentials
|
||||
* Return the credential object for this HostAuth, creating it if it does not yet exist.
|
||||
* This should not be called on the main thread.
|
||||
* @param context
|
||||
* @return the credential object for this HostAuth
|
||||
*/
|
||||
public Credential getOrCreateCredentials(Context context) {
|
||||
|
||||
if (mCredential == null) {
|
||||
if (mCredentialKey >= 0) {
|
||||
mCredential = Credential.restoreCredentialsWithId(context, mCredentialKey);
|
||||
} else {
|
||||
mCredential = new Credential();
|
||||
}
|
||||
}
|
||||
return mCredential;
|
||||
}
|
||||
|
||||
/**
|
||||
* getCredentials
|
||||
* Return the credential object for this HostAuth, or null if it does not exist.
|
||||
* This should not be called on the main thread.
|
||||
* @param context
|
||||
* @return
|
||||
*/
|
||||
public Credential getCredentials(Context context) {
|
||||
if (mCredential == null) {
|
||||
if (mCredentialKey >= 0) {
|
||||
mCredential = Credential.restoreCredentialsWithId(context, mCredentialKey);
|
||||
}
|
||||
}
|
||||
return mCredential;
|
||||
}
|
||||
|
||||
/**
|
||||
* Restore a HostAuth from the database, given its unique id
|
||||
* @param context
|
||||
|
@ -181,6 +219,7 @@ public final class HostAuth extends EmailContent implements HostAuthColumns, Par
|
|||
mPassword = cursor.getString(CONTENT_PASSWORD_COLUMN);
|
||||
mDomain = cursor.getString(CONTENT_DOMAIN_COLUMN);
|
||||
mClientCertAlias = cursor.getString(CONTENT_CLIENT_CERT_ALIAS_COLUMN);
|
||||
mCredentialKey = cursor.getLong(CONTENT_CREDENTIAL_KEY_COLUMN);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -194,6 +233,7 @@ public final class HostAuth extends EmailContent implements HostAuthColumns, Par
|
|||
values.put(HostAuthColumns.PASSWORD, mPassword);
|
||||
values.put(HostAuthColumns.DOMAIN, mDomain);
|
||||
values.put(HostAuthColumns.CLIENT_CERT_ALIAS, mClientCertAlias);
|
||||
values.put(HostAuthColumns.CREDENTIAL_KEY, mCredentialKey);
|
||||
values.put(HostAuthColumns.ACCOUNT_KEY, 0); // Need something to satisfy the DB
|
||||
return values;
|
||||
}
|
||||
|
@ -330,6 +370,12 @@ public final class HostAuth extends EmailContent implements HostAuthColumns, Par
|
|||
dest.writeString(mPassword);
|
||||
dest.writeString(mDomain);
|
||||
dest.writeString(mClientCertAlias);
|
||||
dest.writeLong(mCredentialKey);
|
||||
if (mCredential == null) {
|
||||
Credential.EMPTY.writeToParcel(dest, flags);
|
||||
} else {
|
||||
mCredential.writeToParcel(dest, flags);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -346,6 +392,11 @@ public final class HostAuth extends EmailContent implements HostAuthColumns, Par
|
|||
mPassword = in.readString();
|
||||
mDomain = in.readString();
|
||||
mClientCertAlias = in.readString();
|
||||
mCredentialKey = in.readLong();
|
||||
mCredential = new Credential(in);
|
||||
if (mCredential.equals(Credential.EMPTY)) {
|
||||
mCredential = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -362,7 +413,8 @@ public final class HostAuth extends EmailContent implements HostAuthColumns, Par
|
|||
&& Utility.areStringsEqual(mLogin, that.mLogin)
|
||||
&& Utility.areStringsEqual(mPassword, that.mPassword)
|
||||
&& Utility.areStringsEqual(mDomain, that.mDomain)
|
||||
&& Utility.areStringsEqual(mClientCertAlias, that.mClientCertAlias);
|
||||
&& Utility.areStringsEqual(mClientCertAlias, that.mClientCertAlias)
|
||||
&& mCredentialKey == that.mCredentialKey;
|
||||
// We don't care about the server certificate for equals
|
||||
}
|
||||
|
||||
|
|
|
@ -32,6 +32,7 @@ import com.android.email.R;
|
|||
import com.android.email2.ui.MailActivityEmail;
|
||||
import com.android.emailcommon.mail.Address;
|
||||
import com.android.emailcommon.provider.Account;
|
||||
import com.android.emailcommon.provider.Credential;
|
||||
import com.android.emailcommon.provider.EmailContent;
|
||||
import com.android.emailcommon.provider.EmailContent.AccountColumns;
|
||||
import com.android.emailcommon.provider.EmailContent.Attachment;
|
||||
|
@ -94,6 +95,15 @@ public final class DBHelper {
|
|||
" where " + EmailContent.RECORD_ID + "=old." + AccountColumns.POLICY_KEY +
|
||||
"; end";
|
||||
|
||||
private static final String TRIGGER_HOST_AUTH_DELETE =
|
||||
"create trigger host_auth_delete after delete on " + HostAuth.TABLE_NAME +
|
||||
" begin delete from " + Credential.TABLE_NAME +
|
||||
" where " + Credential.RECORD_ID + "=old." + HostAuth.CREDENTIAL_KEY +
|
||||
" and (select count(*) from " + HostAuth.TABLE_NAME + " where " +
|
||||
HostAuth.CREDENTIAL_KEY + "=old." + HostAuth.CREDENTIAL_KEY + ")=0" +
|
||||
"; end";
|
||||
|
||||
|
||||
// Any changes to the database format *must* include update-in-place code.
|
||||
// Original version: 3
|
||||
// Version 4: Database wipe required; changing AccountManager interface w/Exchange
|
||||
|
@ -163,7 +173,8 @@ public final class DBHelper {
|
|||
// Version 122: Need to update Message_Updates and Message_Deletes to match previous.
|
||||
// Version 123: Changed the duplicateMesage deletion trigger to ignore accounts that aren't
|
||||
// exchange accounts.
|
||||
public static final int DATABASE_VERSION = 123;
|
||||
// Version 124: Add credentials table for OAuth.
|
||||
public static final int DATABASE_VERSION = 124;
|
||||
|
||||
// Any changes to the database format *must* include update-in-place code.
|
||||
// Original version: 2
|
||||
|
@ -216,6 +227,17 @@ public final class DBHelper {
|
|||
"; end");
|
||||
}
|
||||
|
||||
static void createCredentialsTable(SQLiteDatabase db) {
|
||||
String s = " (" + Credential.RECORD_ID + " integer primary key autoincrement, "
|
||||
+ Credential.PROVIDER_COLUMN + " text,"
|
||||
+ Credential.ACCESS_TOKEN_COLUMN + " text,"
|
||||
+ Credential.REFRESH_TOKEN_COLUMN + " text,"
|
||||
+ Credential.EXPIRATION_COLUMN + " integer"
|
||||
+ ");";
|
||||
db.execSQL("create table " + Credential.TABLE_NAME + s);
|
||||
db.execSQL(TRIGGER_HOST_AUTH_DELETE);
|
||||
}
|
||||
|
||||
static void dropDeleteDuplicateMessagesTrigger(final SQLiteDatabase db) {
|
||||
db.execSQL("drop trigger message_delete_duplicates_on_insert");
|
||||
}
|
||||
|
@ -535,7 +557,8 @@ public final class DBHelper {
|
|||
+ HostAuthColumns.DOMAIN + " text, "
|
||||
+ HostAuthColumns.ACCOUNT_KEY + " integer,"
|
||||
+ HostAuthColumns.CLIENT_CERT_ALIAS + " text,"
|
||||
+ HostAuthColumns.SERVER_CERT + " blob"
|
||||
+ HostAuthColumns.SERVER_CERT + " blob,"
|
||||
+ HostAuthColumns.CREDENTIAL_KEY + " integer"
|
||||
+ ");";
|
||||
db.execSQL("create table " + HostAuth.TABLE_NAME + s);
|
||||
}
|
||||
|
@ -733,6 +756,7 @@ public final class DBHelper {
|
|||
createMessageStateChangeTable(db);
|
||||
createPolicyTable(db);
|
||||
createQuickResponseTable(db);
|
||||
createCredentialsTable(db);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1317,6 +1341,15 @@ public final class DBHelper {
|
|||
}
|
||||
createDeleteDuplicateMessagesTrigger(mContext, db);
|
||||
}
|
||||
|
||||
if (oldVersion <= 123) {
|
||||
createCredentialsTable(db);
|
||||
// Add the credentialKey column, and set it to -1 for all pre-existing hostAuths.
|
||||
db.execSQL("alter table " + HostAuth.TABLE_NAME
|
||||
+ " add " + HostAuthColumns.CREDENTIAL_KEY + " integer");
|
||||
db.execSQL("update table " + HostAuth.TABLE_NAME + " set "
|
||||
+ HostAuthColumns.CREDENTIAL_KEY + "=-1");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -72,6 +72,7 @@ import com.android.email2.ui.MailActivityEmail;
|
|||
import com.android.emailcommon.Logging;
|
||||
import com.android.emailcommon.mail.Address;
|
||||
import com.android.emailcommon.provider.Account;
|
||||
import com.android.emailcommon.provider.Credential;
|
||||
import com.android.emailcommon.provider.EmailContent;
|
||||
import com.android.emailcommon.provider.EmailContent.AccountColumns;
|
||||
import com.android.emailcommon.provider.EmailContent.Attachment;
|
||||
|
@ -264,6 +265,10 @@ public class EmailProvider extends ContentProvider {
|
|||
private static final int BODY = BODY_BASE;
|
||||
private static final int BODY_ID = BODY_BASE + 1;
|
||||
|
||||
private static final int CREDENTIAL_BASE = 0xB000;
|
||||
private static final int CREDENTIAL = CREDENTIAL_BASE;
|
||||
private static final int CREDENTIAL_ID = CREDENTIAL_BASE + 1;
|
||||
|
||||
private static final int BASE_SHIFT = 12; // 12 bits to the base type: 0, 0x1000, 0x2000, etc.
|
||||
|
||||
private static final SparseArray<String> TABLE_NAMES;
|
||||
|
@ -280,6 +285,7 @@ public class EmailProvider extends ContentProvider {
|
|||
array.put(QUICK_RESPONSE_BASE >> BASE_SHIFT, QuickResponse.TABLE_NAME);
|
||||
array.put(UI_BASE >> BASE_SHIFT, null);
|
||||
array.put(BODY_BASE >> BASE_SHIFT, Body.TABLE_NAME);
|
||||
array.put(CREDENTIAL_BASE >> BASE_SHIFT, Credential.TABLE_NAME);
|
||||
TABLE_NAMES = array;
|
||||
}
|
||||
|
||||
|
@ -652,6 +658,7 @@ public class EmailProvider extends ContentProvider {
|
|||
case HOSTAUTH_ID:
|
||||
case POLICY_ID:
|
||||
case QUICK_RESPONSE_ID:
|
||||
case CREDENTIAL_ID:
|
||||
id = uri.getPathSegments().get(1);
|
||||
if (match == SYNCED_MESSAGE_ID) {
|
||||
// For synced messages, first copy the old message to the deleted table and
|
||||
|
@ -829,6 +836,7 @@ public class EmailProvider extends ContentProvider {
|
|||
case MAILBOX:
|
||||
case ACCOUNT:
|
||||
case HOSTAUTH:
|
||||
case CREDENTIAL:
|
||||
case POLICY:
|
||||
case QUICK_RESPONSE:
|
||||
longId = db.insert(TABLE_NAMES.valueAt(table), "foo", values);
|
||||
|
@ -1048,6 +1056,11 @@ public class EmailProvider extends ContentProvider {
|
|||
// A specific hostauth
|
||||
sURIMatcher.addURI(EmailContent.AUTHORITY, "hostauth/*", HOSTAUTH_ID);
|
||||
|
||||
// All credential records
|
||||
sURIMatcher.addURI(EmailContent.AUTHORITY, "credential", CREDENTIAL);
|
||||
// A specific credential
|
||||
sURIMatcher.addURI(EmailContent.AUTHORITY, "credential/*", CREDENTIAL_ID);
|
||||
|
||||
/**
|
||||
* THIS URI HAS SPECIAL SEMANTICS
|
||||
* ITS USE IS INTENDED FOR THE UI TO MARK CHANGES THAT NEED TO BE SYNCED BACK
|
||||
|
@ -1885,6 +1898,7 @@ public class EmailProvider extends ContentProvider {
|
|||
case MAILBOX:
|
||||
case ACCOUNT:
|
||||
case HOSTAUTH:
|
||||
case CREDENTIAL:
|
||||
case POLICY:
|
||||
if (match == ATTACHMENT) {
|
||||
if (values.containsKey(AttachmentColumns.LOCATION) &&
|
||||
|
|
Loading…
Reference in New Issue