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);
7732ef67bb88959e60d2c9c5540603d360852e80f5Subir Jhanb
7832ef67bb88959e60d2c9c5540603d360852e80f5Subir Jhanb            // Unable to query the provider
7932ef67bb88959e60d2c9c5540603d360852e80f5Subir Jhanb            if (c == null) {
8032ef67bb88959e60d2c9c5540603d360852e80f5Subir Jhanb                throw new RemoteException();
8132ef67bb88959e60d2c9c5540603d360852e80f5Subir Jhanb            }
8232ef67bb88959e60d2c9c5540603d360852e80f5Subir Jhanb
830f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana            try {
840f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana                if (c.moveToNext()) {
850f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana                    return c.getBlob(c.getColumnIndexOrThrow(Columns.DATA));
860f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana                }
870f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana            } finally {
880f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana                c.close();
890f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana            }
900f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana            return null;
910f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana        }
920f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana
930f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana        /**
940f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana         * Assigns the data array as the sync state for the given account.
950f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana         * @param provider the {@link ContentProviderClient} that is to be used to communicate
960f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana         * with the {@link android.content.ContentProvider} that contains the sync state.
970f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana         * @param uri the uri of the sync state
980f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana         * @param account the {@link Account} whose sync state should be set
990f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana         * @param data the byte[] that contains the sync state
1000f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana         * @throws RemoteException if there is a failure communicating with the remote
1010f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana         * {@link android.content.ContentProvider}
1020f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana         */
1030f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana        public static void set(ContentProviderClient provider, Uri uri,
1040f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana                Account account, byte[] data) throws RemoteException {
1050f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana            ContentValues values = new ContentValues();
1060f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana            values.put(Columns.DATA, data);
107ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana            values.put(Columns.ACCOUNT_NAME, account.name);
108ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana            values.put(Columns.ACCOUNT_TYPE, account.type);
1090f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana            provider.insert(uri, values);
1100f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana        }
1110f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana
112c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintana        public static Uri insert(ContentProviderClient provider, Uri uri,
113c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintana                Account account, byte[] data) throws RemoteException {
114c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintana            ContentValues values = new ContentValues();
115c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintana            values.put(Columns.DATA, data);
116c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintana            values.put(Columns.ACCOUNT_NAME, account.name);
117c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintana            values.put(Columns.ACCOUNT_TYPE, account.type);
118c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintana            return provider.insert(uri, values);
119c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintana        }
120c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintana
121c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintana        public static void update(ContentProviderClient provider, Uri uri, byte[] data)
122c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintana                throws RemoteException {
123c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintana            ContentValues values = new ContentValues();
124c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintana            values.put(Columns.DATA, data);
125c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintana            provider.update(uri, values, null, null);
126c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintana        }
127c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintana
128c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintana        public static Pair<Uri, byte[]> getWithUri(ContentProviderClient provider, Uri uri,
129c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintana                Account account) throws RemoteException {
130c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintana            Cursor c = provider.query(uri, DATA_PROJECTION, SELECT_BY_ACCOUNT,
131c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintana                    new String[]{account.name, account.type}, null);
13232ef67bb88959e60d2c9c5540603d360852e80f5Subir Jhanb
13332ef67bb88959e60d2c9c5540603d360852e80f5Subir Jhanb            if (c == null) {
13432ef67bb88959e60d2c9c5540603d360852e80f5Subir Jhanb                throw new RemoteException();
13532ef67bb88959e60d2c9c5540603d360852e80f5Subir Jhanb            }
13632ef67bb88959e60d2c9c5540603d360852e80f5Subir Jhanb
137c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintana            try {
138c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintana                if (c.moveToNext()) {
139c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintana                    long rowId = c.getLong(1);
140c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintana                    byte[] blob = c.getBlob(c.getColumnIndexOrThrow(Columns.DATA));
141c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintana                    return Pair.create(ContentUris.withAppendedId(uri, rowId), blob);
142c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintana                }
143c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintana            } finally {
144c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintana                c.close();
145c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintana            }
146c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintana            return null;
147c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintana        }
148c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintana
1490f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana        /**
1500f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana         * Creates and returns a ContentProviderOperation that assigns the data array as the
1510f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana         * sync state for the given account.
1520f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana         * @param uri the uri of the sync state
1530f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana         * @param account the {@link Account} whose sync state should be set
1540f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana         * @param data the byte[] that contains the sync state
1550f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana         * @return the new ContentProviderOperation that assigns the data array as the
1560f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana         * account's sync state
1570f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana         */
1580f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana        public static ContentProviderOperation newSetOperation(Uri uri,
1590f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana                Account account, byte[] data) {
1600f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana            ContentValues values = new ContentValues();
1610f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana            values.put(Columns.DATA, data);
1620f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana            return ContentProviderOperation
1630f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana                    .newInsert(uri)
164ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana                    .withValue(Columns.ACCOUNT_NAME, account.name)
165ffd0cb04f97e62d286d185c520580d81a9c328b1Fred Quintana                    .withValue(Columns.ACCOUNT_TYPE, account.type)
1660f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana                    .withValues(values)
1670f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana                    .build();
1680f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana        }
169c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintana
170c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintana        /**
171c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintana         * Creates and returns a ContentProviderOperation that assigns the data array as the
172c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintana         * sync state for the given account.
173c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintana         * @param uri the uri of the specific sync state to set
174c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintana         * @param data the byte[] that contains the sync state
175c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintana         * @return the new ContentProviderOperation that assigns the data array as the
176c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintana         * account's sync state
177c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintana         */
178c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintana        public static ContentProviderOperation newUpdateOperation(Uri uri, byte[] data) {
179c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintana            ContentValues values = new ContentValues();
180c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintana            values.put(Columns.DATA, data);
181c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintana            return ContentProviderOperation
182c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintana                    .newUpdate(uri)
183c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintana                    .withValues(values)
184c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintana                    .build();
185c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintana        }
1860f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana    }
1870f4e1ab773d4d52bfb85a9ad2f050ead3b8b4e49Fred Quintana}
188