1 /* 2 * Copyright (C) 2009 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License 15 */ 16 17 package android.provider; 18 19 import android.net.Uri; 20 import android.content.ContentProviderClient; 21 import android.content.ContentValues; 22 import android.content.ContentProviderOperation; 23 import android.content.ContentUris; 24 import android.accounts.Account; 25 import android.database.Cursor; 26 import android.os.RemoteException; 27 import android.util.Pair; 28 29 /** 30 * The ContentProvider contract for associating data with ana data array account. 31 * This may be used by providers that want to store this data in a standard way. 32 */ 33 public class SyncStateContract { 34 public interface Columns extends BaseColumns { 35 /** 36 * A reference to the name of the account to which this data belongs 37 * <P>Type: STRING</P> 38 */ 39 public static final String ACCOUNT_NAME = "account_name"; 40 41 /** 42 * A reference to the type of the account to which this data belongs 43 * <P>Type: STRING</P> 44 */ 45 public static final String ACCOUNT_TYPE = "account_type"; 46 47 /** 48 * The sync data associated with this account. 49 * <P>Type: NONE</P> 50 */ 51 public static final String DATA = "data"; 52 } 53 54 public static class Constants implements Columns { 55 public static final String CONTENT_DIRECTORY = "syncstate"; 56 } 57 58 public static final class Helpers { 59 private static final String[] DATA_PROJECTION = new String[]{Columns.DATA, Columns._ID}; 60 private static final String SELECT_BY_ACCOUNT = 61 Columns.ACCOUNT_NAME + "=? AND " + Columns.ACCOUNT_TYPE + "=?"; 62 63 /** 64 * Get the sync state that is associated with the account or null. 65 * @param provider the {@link ContentProviderClient} that is to be used to communicate 66 * with the {@link android.content.ContentProvider} that contains the sync state. 67 * @param uri the uri of the sync state 68 * @param account the {@link Account} whose sync state should be returned 69 * @return the sync state or null if there is no sync state associated with the account 70 * @throws RemoteException if there is a failure communicating with the remote 71 * {@link android.content.ContentProvider} 72 */ get(ContentProviderClient provider, Uri uri, Account account)73 public static byte[] get(ContentProviderClient provider, Uri uri, 74 Account account) throws RemoteException { 75 Cursor c = provider.query(uri, DATA_PROJECTION, SELECT_BY_ACCOUNT, 76 new String[]{account.name, account.type}, null); 77 78 // Unable to query the provider 79 if (c == null) { 80 throw new RemoteException(); 81 } 82 83 try { 84 if (c.moveToNext()) { 85 return c.getBlob(c.getColumnIndexOrThrow(Columns.DATA)); 86 } 87 } finally { 88 c.close(); 89 } 90 return null; 91 } 92 93 /** 94 * Assigns the data array as the sync state for the given account. 95 * @param provider the {@link ContentProviderClient} that is to be used to communicate 96 * with the {@link android.content.ContentProvider} that contains the sync state. 97 * @param uri the uri of the sync state 98 * @param account the {@link Account} whose sync state should be set 99 * @param data the byte[] that contains the sync state 100 * @throws RemoteException if there is a failure communicating with the remote 101 * {@link android.content.ContentProvider} 102 */ set(ContentProviderClient provider, Uri uri, Account account, byte[] data)103 public static void set(ContentProviderClient provider, Uri uri, 104 Account account, byte[] data) throws RemoteException { 105 ContentValues values = new ContentValues(); 106 values.put(Columns.DATA, data); 107 values.put(Columns.ACCOUNT_NAME, account.name); 108 values.put(Columns.ACCOUNT_TYPE, account.type); 109 provider.insert(uri, values); 110 } 111 insert(ContentProviderClient provider, Uri uri, Account account, byte[] data)112 public static Uri insert(ContentProviderClient provider, Uri uri, 113 Account account, byte[] data) throws RemoteException { 114 ContentValues values = new ContentValues(); 115 values.put(Columns.DATA, data); 116 values.put(Columns.ACCOUNT_NAME, account.name); 117 values.put(Columns.ACCOUNT_TYPE, account.type); 118 return provider.insert(uri, values); 119 } 120 update(ContentProviderClient provider, Uri uri, byte[] data)121 public static void update(ContentProviderClient provider, Uri uri, byte[] data) 122 throws RemoteException { 123 ContentValues values = new ContentValues(); 124 values.put(Columns.DATA, data); 125 provider.update(uri, values, null, null); 126 } 127 getWithUri(ContentProviderClient provider, Uri uri, Account account)128 public static Pair<Uri, byte[]> getWithUri(ContentProviderClient provider, Uri uri, 129 Account account) throws RemoteException { 130 Cursor c = provider.query(uri, DATA_PROJECTION, SELECT_BY_ACCOUNT, 131 new String[]{account.name, account.type}, null); 132 133 if (c == null) { 134 throw new RemoteException(); 135 } 136 137 try { 138 if (c.moveToNext()) { 139 long rowId = c.getLong(1); 140 byte[] blob = c.getBlob(c.getColumnIndexOrThrow(Columns.DATA)); 141 return Pair.create(ContentUris.withAppendedId(uri, rowId), blob); 142 } 143 } finally { 144 c.close(); 145 } 146 return null; 147 } 148 149 /** 150 * Creates and returns a ContentProviderOperation that assigns the data array as the 151 * sync state for the given account. 152 * @param uri the uri of the sync state 153 * @param account the {@link Account} whose sync state should be set 154 * @param data the byte[] that contains the sync state 155 * @return the new ContentProviderOperation that assigns the data array as the 156 * account's sync state 157 */ newSetOperation(Uri uri, Account account, byte[] data)158 public static ContentProviderOperation newSetOperation(Uri uri, 159 Account account, byte[] data) { 160 ContentValues values = new ContentValues(); 161 values.put(Columns.DATA, data); 162 return ContentProviderOperation 163 .newInsert(uri) 164 .withValue(Columns.ACCOUNT_NAME, account.name) 165 .withValue(Columns.ACCOUNT_TYPE, account.type) 166 .withValues(values) 167 .build(); 168 } 169 170 /** 171 * Creates and returns a ContentProviderOperation that assigns the data array as the 172 * sync state for the given account. 173 * @param uri the uri of the specific sync state to set 174 * @param data the byte[] that contains the sync state 175 * @return the new ContentProviderOperation that assigns the data array as the 176 * account's sync state 177 */ newUpdateOperation(Uri uri, byte[] data)178 public static ContentProviderOperation newUpdateOperation(Uri uri, byte[] data) { 179 ContentValues values = new ContentValues(); 180 values.put(Columns.DATA, data); 181 return ContentProviderOperation 182 .newUpdate(uri) 183 .withValues(values) 184 .build(); 185 } 186 } 187 } 188