10f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana/* 20f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana * Copyright (C) 2009 The Android Open Source Project 30f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana * 40f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana * Licensed under the Apache License, Version 2.0 (the "License"); 50f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana * you may not use this file except in compliance with the License. 60f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana * You may obtain a copy of the License at 70f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana * 80f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana * http://www.apache.org/licenses/LICENSE-2.0 90f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana * 100f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana * Unless required by applicable law or agreed to in writing, software 110f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana * distributed under the License is distributed on an "AS IS" BASIS, 120f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 130f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana * See the License for the specific language governing permissions and 140f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana * limitations under the License 150f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana */ 160f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana 170f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintanapackage android.provider; 180f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana 190f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintanaimport android.net.Uri; 200f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintanaimport android.content.ContentProviderClient; 210f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintanaimport android.content.ContentValues; 220f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintanaimport android.content.ContentProviderOperation; 23c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintanaimport android.content.ContentUris; 240f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintanaimport android.accounts.Account; 250f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintanaimport android.database.Cursor; 260f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintanaimport android.os.RemoteException; 27c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintanaimport android.util.Pair; 280f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana 290f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana/** 300f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana * The ContentProvider contract for associating data with ana data array account. 310f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana * This may be used by providers that want to store this data in a standard way. 320f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana */ 330f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintanapublic class SyncStateContract { 340f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana public interface Columns extends BaseColumns { 350f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana /** 360f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana * A reference to the name of the account to which this data belongs 370f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana * <P>Type: STRING</P> 380f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana */ 390f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana public static final String ACCOUNT_NAME = "account_name"; 400f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana 410f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana /** 420f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana * A reference to the type of the account to which this data belongs 430f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana * <P>Type: STRING</P> 440f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana */ 450f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana public static final String ACCOUNT_TYPE = "account_type"; 460f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana 470f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana /** 480f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana * The sync data associated with this account. 490f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana * <P>Type: NONE</P> 500f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana */ 510f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana public static final String DATA = "data"; 520f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana } 530f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana 540f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana public static class Constants implements Columns { 550f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana public static final String CONTENT_DIRECTORY = "syncstate"; 560f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana } 570f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana 580f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana public static final class Helpers { 59c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintana private static final String[] DATA_PROJECTION = new String[]{Columns.DATA, Columns._ID}; 600f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana private static final String SELECT_BY_ACCOUNT = 610f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana Columns.ACCOUNT_NAME + "=? AND " + Columns.ACCOUNT_TYPE + "=?"; 620f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana 630f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana /** 640f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana * Get the sync state that is associated with the account or null. 650f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana * @param provider the {@link ContentProviderClient} that is to be used to communicate 660f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana * with the {@link android.content.ContentProvider} that contains the sync state. 670f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana * @param uri the uri of the sync state 680f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana * @param account the {@link Account} whose sync state should be returned 690f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana * @return the sync state or null if there is no sync state associated with the account 700f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana * @throws RemoteException if there is a failure communicating with the remote 710f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana * {@link android.content.ContentProvider} 720f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana */ 730f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana public static byte[] get(ContentProviderClient provider, Uri uri, 740f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana Account account) throws RemoteException { 750f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana Cursor c = provider.query(uri, DATA_PROJECTION, SELECT_BY_ACCOUNT, 76ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana new String[]{account.name, account.type}, null); 770f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana try { 780f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana if (c.moveToNext()) { 790f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana return c.getBlob(c.getColumnIndexOrThrow(Columns.DATA)); 800f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana } 810f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana } finally { 820f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana c.close(); 830f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana } 840f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana return null; 850f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana } 860f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana 870f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana /** 880f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana * Assigns the data array as the sync state for the given account. 890f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana * @param provider the {@link ContentProviderClient} that is to be used to communicate 900f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana * with the {@link android.content.ContentProvider} that contains the sync state. 910f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana * @param uri the uri of the sync state 920f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana * @param account the {@link Account} whose sync state should be set 930f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana * @param data the byte[] that contains the sync state 940f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana * @throws RemoteException if there is a failure communicating with the remote 950f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana * {@link android.content.ContentProvider} 960f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana */ 970f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana public static void set(ContentProviderClient provider, Uri uri, 980f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana Account account, byte[] data) throws RemoteException { 990f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana ContentValues values = new ContentValues(); 1000f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana values.put(Columns.DATA, data); 101ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana values.put(Columns.ACCOUNT_NAME, account.name); 102ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana values.put(Columns.ACCOUNT_TYPE, account.type); 1030f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana provider.insert(uri, values); 1040f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana } 1050f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana 106c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintana public static Uri insert(ContentProviderClient provider, Uri uri, 107c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintana Account account, byte[] data) throws RemoteException { 108c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintana ContentValues values = new ContentValues(); 109c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintana values.put(Columns.DATA, data); 110c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintana values.put(Columns.ACCOUNT_NAME, account.name); 111c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintana values.put(Columns.ACCOUNT_TYPE, account.type); 112c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintana return provider.insert(uri, values); 113c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintana } 114c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintana 115c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintana public static void update(ContentProviderClient provider, Uri uri, byte[] data) 116c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintana throws RemoteException { 117c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintana ContentValues values = new ContentValues(); 118c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintana values.put(Columns.DATA, data); 119c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintana provider.update(uri, values, null, null); 120c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintana } 121c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintana 122c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintana public static Pair<Uri, byte[]> getWithUri(ContentProviderClient provider, Uri uri, 123c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintana Account account) throws RemoteException { 124c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintana Cursor c = provider.query(uri, DATA_PROJECTION, SELECT_BY_ACCOUNT, 125c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintana new String[]{account.name, account.type}, null); 126c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintana try { 127c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintana if (c.moveToNext()) { 128c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintana long rowId = c.getLong(1); 129c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintana byte[] blob = c.getBlob(c.getColumnIndexOrThrow(Columns.DATA)); 130c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintana return Pair.create(ContentUris.withAppendedId(uri, rowId), blob); 131c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintana } 132c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintana } finally { 133c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintana c.close(); 134c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintana } 135c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintana return null; 136c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintana } 137c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintana 1380f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana /** 1390f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana * Creates and returns a ContentProviderOperation that assigns the data array as the 1400f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana * sync state for the given account. 1410f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana * @param uri the uri of the sync state 1420f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana * @param account the {@link Account} whose sync state should be set 1430f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana * @param data the byte[] that contains the sync state 1440f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana * @return the new ContentProviderOperation that assigns the data array as the 1450f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana * account's sync state 1460f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana */ 1470f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana public static ContentProviderOperation newSetOperation(Uri uri, 1480f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana Account account, byte[] data) { 1490f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana ContentValues values = new ContentValues(); 1500f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana values.put(Columns.DATA, data); 1510f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana return ContentProviderOperation 1520f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana .newInsert(uri) 153ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana .withValue(Columns.ACCOUNT_NAME, account.name) 154ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana .withValue(Columns.ACCOUNT_TYPE, account.type) 1550f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana .withValues(values) 1560f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana .build(); 1570f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana } 158c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintana 159c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintana /** 160c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintana * Creates and returns a ContentProviderOperation that assigns the data array as the 161c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintana * sync state for the given account. 162c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintana * @param uri the uri of the specific sync state to set 163c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintana * @param data the byte[] that contains the sync state 164c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintana * @return the new ContentProviderOperation that assigns the data array as the 165c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintana * account's sync state 166c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintana */ 167c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintana public static ContentProviderOperation newUpdateOperation(Uri uri, byte[] data) { 168c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintana ContentValues values = new ContentValues(); 169c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintana values.put(Columns.DATA, data); 170c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintana return ContentProviderOperation 171c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintana .newUpdate(uri) 172c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintana .withValues(values) 173c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintana .build(); 174c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintana } 1750f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana } 1760f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana} 177