- remove an un-needed constant

- add a content provider helper that manages a table for storing sync state by account
- add contact definitions to Contacts access the sync state
This commit is contained in:
Fred Quintana
2009-07-09 17:20:59 -07:00
parent 586d110ad4
commit 0f4e1ab773
5 changed files with 450 additions and 15 deletions

View File

@@ -17434,17 +17434,6 @@
visibility="public"
>
</field>
<field name="PASSWORD_KEY"
type="java.lang.String"
transient="false"
volatile="false"
value="&quot;password&quot;"
static="true"
final="true"
deprecated="not deprecated"
visibility="public"
>
</field>
<field name="USERDATA_KEY"
type="java.lang.String"
transient="false"
@@ -114140,6 +114129,170 @@
>
</field>
</class>
<class name="SyncStateContract"
extends="java.lang.Object"
abstract="false"
static="false"
final="false"
deprecated="not deprecated"
visibility="public"
>
<constructor name="SyncStateContract"
type="android.provider.SyncStateContract"
static="false"
final="false"
deprecated="not deprecated"
visibility="public"
>
</constructor>
</class>
<interface name="SyncStateContract.Columns"
abstract="true"
static="true"
final="false"
deprecated="not deprecated"
visibility="public"
>
<implements name="android.provider.BaseColumns">
</implements>
<field name="ACCOUNT_NAME"
type="java.lang.String"
transient="false"
volatile="false"
value="&quot;account_name&quot;"
static="true"
final="true"
deprecated="not deprecated"
visibility="public"
>
</field>
<field name="ACCOUNT_TYPE"
type="java.lang.String"
transient="false"
volatile="false"
value="&quot;account_type&quot;"
static="true"
final="true"
deprecated="not deprecated"
visibility="public"
>
</field>
<field name="DATA"
type="java.lang.String"
transient="false"
volatile="false"
value="&quot;data&quot;"
static="true"
final="true"
deprecated="not deprecated"
visibility="public"
>
</field>
</interface>
<class name="SyncStateContract.Constants"
extends="java.lang.Object"
abstract="false"
static="true"
final="false"
deprecated="not deprecated"
visibility="public"
>
<implements name="android.provider.SyncStateContract.Columns">
</implements>
<constructor name="SyncStateContract.Constants"
type="android.provider.SyncStateContract.Constants"
static="false"
final="false"
deprecated="not deprecated"
visibility="public"
>
</constructor>
<field name="CONTENT_DIRECTORY"
type="java.lang.String"
transient="false"
volatile="false"
value="&quot;syncstate&quot;"
static="true"
final="true"
deprecated="not deprecated"
visibility="public"
>
</field>
</class>
<class name="SyncStateContract.Helpers"
extends="java.lang.Object"
abstract="false"
static="true"
final="true"
deprecated="not deprecated"
visibility="public"
>
<constructor name="SyncStateContract.Helpers"
type="android.provider.SyncStateContract.Helpers"
static="false"
final="false"
deprecated="not deprecated"
visibility="public"
>
</constructor>
<method name="get"
return="byte[]"
abstract="false"
native="false"
synchronized="false"
static="true"
final="false"
deprecated="not deprecated"
visibility="public"
>
<parameter name="provider" type="android.content.ContentProviderClient">
</parameter>
<parameter name="uri" type="android.net.Uri">
</parameter>
<parameter name="account" type="android.accounts.Account">
</parameter>
<exception name="RemoteException" type="android.os.RemoteException">
</exception>
</method>
<method name="newSetOperation"
return="android.content.ContentProviderOperation"
abstract="false"
native="false"
synchronized="false"
static="true"
final="false"
deprecated="not deprecated"
visibility="public"
>
<parameter name="uri" type="android.net.Uri">
</parameter>
<parameter name="account" type="android.accounts.Account">
</parameter>
<parameter name="data" type="byte[]">
</parameter>
</method>
<method name="set"
return="void"
abstract="false"
native="false"
synchronized="false"
static="true"
final="false"
deprecated="not deprecated"
visibility="public"
>
<parameter name="provider" type="android.content.ContentProviderClient">
</parameter>
<parameter name="uri" type="android.net.Uri">
</parameter>
<parameter name="account" type="android.accounts.Account">
</parameter>
<parameter name="data" type="byte[]">
</parameter>
<exception name="RemoteException" type="android.os.RemoteException">
</exception>
</method>
</class>
<class name="UserDictionary"
extends="java.lang.Object"
abstract="false"

View File

@@ -29,7 +29,6 @@ public class Constants {
public static final String ACCOUNTS_KEY = "accounts";
public static final String AUTHENTICATOR_TYPES_KEY = "authenticator_types";
public static final String PASSWORD_KEY = "password";
public static final String USERDATA_KEY = "userdata";
public static final String AUTHTOKEN_KEY = "authtoken";
public static final String ACCOUNT_NAME_KEY = "authAccount";

View File

@@ -16,13 +16,14 @@
package android.provider;
import java.util.Arrays;
import java.util.List;
import android.content.Intent;
import android.content.ContentProviderClient;
import android.content.ContentProviderOperation;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.provider.ContactsContract.CommonDataKinds.GroupMembership;
import android.accounts.Account;
import android.os.RemoteException;
/**
* The contract between the contacts provider and applications. Contains definitions
@@ -36,6 +37,48 @@ public final class ContactsContract {
/** A content:// style uri to the authority for the contacts provider */
public static final Uri AUTHORITY_URI = Uri.parse("content://" + AUTHORITY);
public interface SyncStateColumns extends SyncStateContract.Columns {
}
public static final class SyncState {
/**
* This utility class cannot be instantiated
*/
private SyncState() {}
public static final String CONTENT_DIRECTORY =
SyncStateContract.Constants.CONTENT_DIRECTORY;
/**
* The content:// style URI for this table
*/
public static final Uri CONTENT_URI =
Uri.withAppendedPath(AUTHORITY_URI, CONTENT_DIRECTORY);
/**
* @see android.provider.SyncStateContract.Helpers#get
*/
public static byte[] get(ContentProviderClient provider, Account account)
throws RemoteException {
return SyncStateContract.Helpers.get(provider, CONTENT_URI, account);
}
/**
* @see android.provider.SyncStateContract.Helpers#set
*/
public static void set(ContentProviderClient provider, Account account, byte[] data)
throws RemoteException {
SyncStateContract.Helpers.set(provider, CONTENT_URI, account, data);
}
/**
* @see android.provider.SyncStateContract.Helpers#newSetOperation
*/
public static ContentProviderOperation newSetOperation(Account account, byte[] data) {
return SyncStateContract.Helpers.newSetOperation(CONTENT_URI, account, data);
}
}
public interface AggregatesColumns {
/**
* The display name for the contact.

View File

@@ -0,0 +1,125 @@
/*
* Copyright (C) 2009 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
*/
package android.provider;
import android.net.Uri;
import android.content.ContentProviderClient;
import android.content.ContentValues;
import android.content.ContentProviderOperation;
import android.accounts.Account;
import android.database.Cursor;
import android.os.RemoteException;
/**
* The ContentProvider contract for associating data with ana data array account.
* This may be used by providers that want to store this data in a standard way.
*/
public class SyncStateContract {
public interface Columns extends BaseColumns {
/**
* A reference to the name of the account to which this data belongs
* <P>Type: STRING</P>
*/
public static final String ACCOUNT_NAME = "account_name";
/**
* A reference to the type of the account to which this data belongs
* <P>Type: STRING</P>
*/
public static final String ACCOUNT_TYPE = "account_type";
/**
* The sync data associated with this account.
* <P>Type: NONE</P>
*/
public static final String DATA = "data";
}
public static class Constants implements Columns {
public static final String CONTENT_DIRECTORY = "syncstate";
}
public static final class Helpers {
private static final String[] DATA_PROJECTION = new String[]{Columns.DATA};
private static final String SELECT_BY_ACCOUNT =
Columns.ACCOUNT_NAME + "=? AND " + Columns.ACCOUNT_TYPE + "=?";
/**
* Get the sync state that is associated with the account or null.
* @param provider the {@link ContentProviderClient} that is to be used to communicate
* with the {@link android.content.ContentProvider} that contains the sync state.
* @param uri the uri of the sync state
* @param account the {@link Account} whose sync state should be returned
* @return the sync state or null if there is no sync state associated with the account
* @throws RemoteException if there is a failure communicating with the remote
* {@link android.content.ContentProvider}
*/
public static byte[] get(ContentProviderClient provider, Uri uri,
Account account) throws RemoteException {
Cursor c = provider.query(uri, DATA_PROJECTION, SELECT_BY_ACCOUNT,
new String[]{account.mName, account.mType}, null);
try {
if (c.moveToNext()) {
return c.getBlob(c.getColumnIndexOrThrow(Columns.DATA));
}
} finally {
c.close();
}
return null;
}
/**
* Assigns the data array as the sync state for the given account.
* @param provider the {@link ContentProviderClient} that is to be used to communicate
* with the {@link android.content.ContentProvider} that contains the sync state.
* @param uri the uri of the sync state
* @param account the {@link Account} whose sync state should be set
* @param data the byte[] that contains the sync state
* @throws RemoteException if there is a failure communicating with the remote
* {@link android.content.ContentProvider}
*/
public static void set(ContentProviderClient provider, Uri uri,
Account account, byte[] data) throws RemoteException {
ContentValues values = new ContentValues();
values.put(Columns.DATA, data);
values.put(Columns.ACCOUNT_NAME, account.mName);
values.put(Columns.ACCOUNT_TYPE, account.mType);
provider.insert(uri, values);
}
/**
* Creates and returns a ContentProviderOperation that assigns the data array as the
* sync state for the given account.
* @param uri the uri of the sync state
* @param account the {@link Account} whose sync state should be set
* @param data the byte[] that contains the sync state
* @return the new ContentProviderOperation that assigns the data array as the
* account's sync state
*/
public static ContentProviderOperation newSetOperation(Uri uri,
Account account, byte[] data) {
ContentValues values = new ContentValues();
values.put(Columns.DATA, data);
return ContentProviderOperation
.newInsert(uri)
.withValue(Columns.ACCOUNT_NAME, account.mName)
.withValue(Columns.ACCOUNT_TYPE, account.mType)
.withValues(values)
.build();
}
}
}

View File

@@ -0,0 +1,115 @@
/*
* Copyright (C) 2007 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.
*/
package com.android.internal.content;
import com.android.internal.util.ArrayUtils;
import android.database.Cursor;
import android.database.DatabaseUtils;
import android.database.sqlite.SQLiteDatabase;
import android.accounts.Account;
import android.content.ContentValues;
import android.provider.SyncStateContract;
/**
* Extends the schema of a ContentProvider to include the _sync_state table
* and implements query/insert/update/delete to access that table using the
* authority "syncstate". This can be used to store the sync state for a
* set of accounts.
*
* @hide
*/
public class SyncStateContentProviderHelper {
private static final String SELECT_BY_ACCOUNT =
SyncStateContract.Columns.ACCOUNT_NAME + "=? AND "
+ SyncStateContract.Columns.ACCOUNT_TYPE + "=?";
private static final String SYNC_STATE_TABLE = "_sync_state";
private static final String SYNC_STATE_META_TABLE = "_sync_state_metadata";
private static final String SYNC_STATE_META_VERSION_COLUMN = "version";
private static long DB_VERSION = 1;
private static final String[] ACCOUNT_PROJECTION =
new String[]{SyncStateContract.Columns.ACCOUNT_NAME,
SyncStateContract.Columns.ACCOUNT_TYPE};
public static final String PATH = "syncstate";
public void createDatabase(SQLiteDatabase db) {
db.execSQL("DROP TABLE IF EXISTS " + SYNC_STATE_TABLE);
db.execSQL("CREATE TABLE " + SYNC_STATE_TABLE + " ("
+ SyncStateContract.Columns._ID + " INTEGER PRIMARY KEY,"
+ SyncStateContract.Columns.ACCOUNT_NAME + " TEXT NOT NULL,"
+ SyncStateContract.Columns.ACCOUNT_TYPE + " TEXT NOT NULL,"
+ SyncStateContract.Columns.DATA + " TEXT,"
+ "UNIQUE(" + SyncStateContract.Columns.ACCOUNT_NAME + ", "
+ SyncStateContract.Columns.ACCOUNT_TYPE + "));");
db.execSQL("DROP TABLE IF EXISTS " + SYNC_STATE_META_TABLE);
db.execSQL("CREATE TABLE " + SYNC_STATE_META_TABLE + " ("
+ SYNC_STATE_META_VERSION_COLUMN + " INTEGER);");
ContentValues values = new ContentValues();
values.put(SYNC_STATE_META_VERSION_COLUMN, DB_VERSION);
db.insert(SYNC_STATE_META_TABLE, SYNC_STATE_META_VERSION_COLUMN, values);
}
public void onDatabaseOpened(SQLiteDatabase db) {
long version = DatabaseUtils.longForQuery(db,
"SELECT " + SYNC_STATE_META_VERSION_COLUMN + " FROM " + SYNC_STATE_META_TABLE,
null);
if (version != DB_VERSION) {
createDatabase(db);
}
}
public Cursor query(SQLiteDatabase db, String[] projection,
String selection, String[] selectionArgs, String sortOrder) {
return db.query(SYNC_STATE_TABLE, projection, selection, selectionArgs,
null, null, sortOrder);
}
public long insert(SQLiteDatabase db, ContentValues values) {
return db.replace(SYNC_STATE_TABLE, SyncStateContract.Columns.ACCOUNT_NAME, values);
}
public int delete(SQLiteDatabase db, String userWhere, String[] whereArgs) {
return db.delete(SYNC_STATE_TABLE, userWhere, whereArgs);
}
public int update(SQLiteDatabase db, ContentValues values,
String selection, String[] selectionArgs) {
return db.update(SYNC_STATE_TABLE, values, selection, selectionArgs);
}
public void onAccountsChanged(SQLiteDatabase db, Account[] accounts) {
Cursor c = db.query(SYNC_STATE_TABLE, ACCOUNT_PROJECTION, null, null, null, null, null);
try {
while (c.moveToNext()) {
final String accountName = c.getString(0);
final String accountType = c.getString(1);
Account account = new Account(accountName, accountType);
if (!ArrayUtils.contains(accounts, account)) {
db.delete(SYNC_STATE_TABLE, SELECT_BY_ACCOUNT,
new String[]{accountName, accountType});
}
}
} finally {
c.close();
}
}
}