• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2010 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.accounts.Account;
20 import android.compat.annotation.UnsupportedAppUsage;
21 import android.content.ContentProviderClient;
22 import android.content.ContentProviderOperation;
23 import android.content.ContentResolver;
24 import android.content.ContentUris;
25 import android.content.ContentValues;
26 import android.content.Context;
27 import android.database.Cursor;
28 import android.graphics.BitmapFactory;
29 import android.net.Uri;
30 import android.os.Build;
31 import android.os.RemoteException;
32 import android.util.Pair;
33 
34 /**
35  * <p>
36  * The contract between the browser provider and applications. Contains the definition
37  * for the supported URIS and columns.
38  * </p>
39  * <h3>Overview</h3>
40  * <p>
41  * BrowserContract defines an database of browser-related information which are bookmarks,
42  * history, images and the mapping between the image and URL.
43  * </p>
44  * @hide
45  */
46 public class BrowserContract {
47     /** The authority for the browser provider */
48     public static final String AUTHORITY = "com.android.browser";
49 
50     /** A content:// style uri to the authority for the browser provider */
51     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
52     public static final Uri AUTHORITY_URI = Uri.parse("content://" + AUTHORITY);
53 
54     /**
55      * An optional insert, update or delete URI parameter that allows the caller
56      * to specify that it is a sync adapter. The default value is false. If true
57      * the dirty flag is not automatically set and the "syncToNetwork" parameter
58      * is set to false when calling
59      * {@link ContentResolver#notifyChange(android.net.Uri, android.database.ContentObserver, boolean)}.
60      * @hide
61      */
62     public static final String CALLER_IS_SYNCADAPTER = "caller_is_syncadapter";
63 
64     /**
65      * A parameter for use when querying any table that allows specifying a limit on the number
66      * of rows returned.
67      * @hide
68      */
69     public static final String PARAM_LIMIT = "limit";
70 
71     /**
72      * Generic columns for use by sync adapters. The specific functions of
73      * these columns are private to the sync adapter. Other clients of the API
74      * should not attempt to either read or write these columns.
75      *
76      * @hide
77      */
78     interface BaseSyncColumns {
79         /** Generic column for use by sync adapters. */
80         public static final String SYNC1 = "sync1";
81         /** Generic column for use by sync adapters. */
82         public static final String SYNC2 = "sync2";
83         /** Generic column for use by sync adapters. */
84         public static final String SYNC3 = "sync3";
85         /** Generic column for use by sync adapters. */
86         public static final String SYNC4 = "sync4";
87         /** Generic column for use by sync adapters. */
88         public static final String SYNC5 = "sync5";
89     }
90 
91     /**
92      * Convenience definitions for use in implementing chrome bookmarks sync in the Bookmarks table.
93      * @hide
94      */
95     public static final class ChromeSyncColumns {
ChromeSyncColumns()96         private ChromeSyncColumns() {}
97 
98         /** The server unique ID for an item */
99         public static final String SERVER_UNIQUE = BaseSyncColumns.SYNC3;
100 
101         public static final String FOLDER_NAME_ROOT = "google_chrome";
102         public static final String FOLDER_NAME_BOOKMARKS = "google_chrome_bookmarks";
103         public static final String FOLDER_NAME_BOOKMARKS_BAR = "bookmark_bar";
104         public static final String FOLDER_NAME_OTHER_BOOKMARKS = "other_bookmarks";
105 
106         /** The client unique ID for an item */
107         public static final String CLIENT_UNIQUE = BaseSyncColumns.SYNC4;
108     }
109 
110     /**
111      * Columns that appear when each row of a table belongs to a specific
112      * account, including sync information that an account may need.
113      * @hide
114      */
115     interface SyncColumns extends BaseSyncColumns {
116         /**
117          * The name of the account instance to which this row belongs, which when paired with
118          * {@link #ACCOUNT_TYPE} identifies a specific account.
119          * <P>Type: TEXT</P>
120          */
121         public static final String ACCOUNT_NAME = "account_name";
122 
123         /**
124          * The type of account to which this row belongs, which when paired with
125          * {@link #ACCOUNT_NAME} identifies a specific account.
126          * <P>Type: TEXT</P>
127          */
128         public static final String ACCOUNT_TYPE = "account_type";
129 
130         /**
131          * String that uniquely identifies this row to its source account.
132          * <P>Type: TEXT</P>
133          */
134         public static final String SOURCE_ID = "sourceid";
135 
136         /**
137          * Version number that is updated whenever this row or its related data
138          * changes.
139          * <P>Type: INTEGER</P>
140          */
141         public static final String VERSION = "version";
142 
143         /**
144          * Flag indicating that {@link #VERSION} has changed, and this row needs
145          * to be synchronized by its owning account.
146          * <P>Type: INTEGER (boolean)</P>
147          */
148         public static final String DIRTY = "dirty";
149 
150         /**
151          * The time that this row was last modified by a client (msecs since the epoch).
152          * <P>Type: INTEGER</P>
153          */
154         public static final String DATE_MODIFIED = "modified";
155     }
156 
157     interface CommonColumns {
158         /**
159          * The unique ID for a row.
160          * <P>Type: INTEGER (long)</P>
161          */
162         public static final String _ID = "_id";
163 
164         /**
165          * This column is valid when the row is a URL. The history table's URL
166          * can not be updated.
167          * <P>Type: TEXT (URL)</P>
168          */
169         public static final String URL = "url";
170 
171         /**
172          * The user visible title.
173          * <P>Type: TEXT</P>
174          */
175         public static final String TITLE = "title";
176 
177         /**
178          * The time that this row was created on its originating client (msecs
179          * since the epoch).
180          * <P>Type: INTEGER</P>
181          * @hide
182          */
183         public static final String DATE_CREATED = "created";
184     }
185 
186     /**
187      * @hide
188      */
189     interface ImageColumns {
190         /**
191          * The favicon of the bookmark, may be NULL.
192          * Must decode via {@link BitmapFactory#decodeByteArray}.
193          * <p>Type: BLOB (image)</p>
194          */
195         public static final String FAVICON = "favicon";
196 
197         /**
198          * A thumbnail of the page,may be NULL.
199          * Must decode via {@link BitmapFactory#decodeByteArray}.
200          * <p>Type: BLOB (image)</p>
201          */
202         public static final String THUMBNAIL = "thumbnail";
203 
204         /**
205          * The touch icon for the web page, may be NULL.
206          * Must decode via {@link BitmapFactory#decodeByteArray}.
207          * <p>Type: BLOB (image)</p>
208          */
209         public static final String TOUCH_ICON = "touch_icon";
210     }
211 
212     interface HistoryColumns {
213         /**
214          * The date the item was last visited, in milliseconds since the epoch.
215          * <p>Type: INTEGER (date in milliseconds since January 1, 1970)</p>
216          */
217         public static final String DATE_LAST_VISITED = "date";
218 
219         /**
220          * The number of times the item has been visited.
221          * <p>Type: INTEGER</p>
222          */
223         public static final String VISITS = "visits";
224 
225         /**
226          * @hide
227          */
228         public static final String USER_ENTERED = "user_entered";
229     }
230 
231     interface ImageMappingColumns {
232         /**
233          * The ID of the image in Images. One image can map onto the multiple URLs.
234          * <P>Type: INTEGER (long)</P>
235          */
236         public static final String IMAGE_ID = "image_id";
237 
238         /**
239          * The URL. The URL can map onto the different type of images.
240          * <P>Type: TEXT (URL)</P>
241          */
242         public static final String URL = "url";
243     }
244 
245     /**
246      * The bookmarks table, which holds the user's browser bookmarks.
247      */
248     public static final class Bookmarks implements CommonColumns, ImageColumns, SyncColumns {
249         /**
250          * This utility class cannot be instantiated.
251          */
Bookmarks()252         private Bookmarks() {}
253 
254         /**
255          * The content:// style URI for this table
256          */
257         @UnsupportedAppUsage
258         public static final Uri CONTENT_URI = Uri.withAppendedPath(AUTHORITY_URI, "bookmarks");
259 
260         /**
261          * Used in {@link Bookmarks#TYPE} column and indicats the row is a bookmark.
262          */
263         public static final int BOOKMARK_TYPE_BOOKMARK = 1;
264 
265         /**
266          * Used in {@link Bookmarks#TYPE} column and indicats the row is a folder.
267          */
268         public static final int BOOKMARK_TYPE_FOLDER = 2;
269 
270         /**
271          * Used in {@link Bookmarks#TYPE} column and indicats the row is the bookmark bar folder.
272          */
273         public static final int BOOKMARK_TYPE_BOOKMARK_BAR_FOLDER = 3;
274 
275         /**
276          * Used in {@link Bookmarks#TYPE} column and indicats the row is other folder and
277          */
278         public static final int BOOKMARK_TYPE_OTHER_FOLDER = 4;
279 
280         /**
281          * Used in {@link Bookmarks#TYPE} column and indicats the row is other folder, .
282          */
283         public static final int BOOKMARK_TYPE_MOBILE_FOLDER = 5;
284 
285         /**
286          * The type of the item.
287          * <P>Type: INTEGER</P>
288          * <p>Allowed values are:</p>
289          * <p>
290          * <ul>
291          * <li>{@link #BOOKMARK_TYPE_BOOKMARK}</li>
292          * <li>{@link #BOOKMARK_TYPE_FOLDER}</li>
293          * <li>{@link #BOOKMARK_TYPE_BOOKMARK_BAR_FOLDER}</li>
294          * <li>{@link #BOOKMARK_TYPE_OTHER_FOLDER}</li>
295          * <li>{@link #BOOKMARK_TYPE_MOBILE_FOLDER}</li>
296          * </ul>
297          * </p>
298          * <p> The TYPE_BOOKMARK_BAR_FOLDER, TYPE_OTHER_FOLDER and TYPE_MOBILE_FOLDER
299          * can not be updated or deleted.</p>
300          */
301         public static final String TYPE = "type";
302 
303         /**
304          * The content:// style URI for the default folder
305          * @hide
306          */
307         @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
308         public static final Uri CONTENT_URI_DEFAULT_FOLDER =
309                 Uri.withAppendedPath(CONTENT_URI, "folder");
310 
311         /**
312          * Query parameter used to specify an account name
313          * @hide
314          */
315         public static final String PARAM_ACCOUNT_NAME = "acct_name";
316 
317         /**
318          * Query parameter used to specify an account type
319          * @hide
320          */
321         public static final String PARAM_ACCOUNT_TYPE = "acct_type";
322 
323         /**
324          * Builds a URI that points to a specific folder.
325          * @param folderId the ID of the folder to point to
326          * @hide
327          */
328         @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
buildFolderUri(long folderId)329         public static final Uri buildFolderUri(long folderId) {
330             return ContentUris.withAppendedId(CONTENT_URI_DEFAULT_FOLDER, folderId);
331         }
332 
333         /**
334          * The MIME type of {@link #CONTENT_URI} providing a directory of bookmarks.
335          */
336         public static final String CONTENT_TYPE = "vnd.android.cursor.dir/bookmark";
337 
338         /**
339          * The MIME type of a {@link #CONTENT_URI} of a single bookmark.
340          */
341         public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/bookmark";
342 
343         /**
344          * Query parameter to use if you want to see deleted bookmarks that are still
345          * around on the device and haven't been synced yet.
346          * @see #IS_DELETED
347          * @hide
348          */
349         public static final String QUERY_PARAMETER_SHOW_DELETED = "show_deleted";
350 
351         /**
352          * Flag indicating if an item is a folder or bookmark. Non-zero values indicate
353          * a folder and zero indicates a bookmark.
354          * <P>Type: INTEGER (boolean)</P>
355          * @hide
356          */
357         public static final String IS_FOLDER = "folder";
358 
359         /**
360          * The ID of the parent folder. ID 0 is the root folder.
361          * <P>Type: INTEGER (reference to item in the same table)</P>
362          */
363         public static final String PARENT = "parent";
364 
365         /**
366          * The source ID for an item's parent. Read-only.
367          * @see #PARENT
368          * @hide
369          */
370         public static final String PARENT_SOURCE_ID = "parent_source";
371 
372         /**
373          * The position of the bookmark in relation to it's siblings that share the same
374          * {@link #PARENT}. May be negative.
375          * <P>Type: INTEGER</P>
376          * @hide
377          */
378         public static final String POSITION = "position";
379 
380         /**
381          * The item that the bookmark should be inserted after.
382          * May be negative.
383          * <P>Type: INTEGER</P>
384          * @hide
385          */
386         public static final String INSERT_AFTER = "insert_after";
387 
388         /**
389          * The source ID for the item that the bookmark should be inserted after. Read-only.
390          * May be negative.
391          * <P>Type: INTEGER</P>
392          * @see #INSERT_AFTER
393          * @hide
394          */
395         public static final String INSERT_AFTER_SOURCE_ID = "insert_after_source";
396 
397         /**
398          * A flag to indicate if an item has been deleted. Queries will not return deleted
399          * entries unless you add the {@link #QUERY_PARAMETER_SHOW_DELETED} query paramter
400          * to the URI when performing your query.
401          * <p>Type: INTEGER (non-zero if the item has been deleted, zero if it hasn't)
402          * @see #QUERY_PARAMETER_SHOW_DELETED
403          * @hide
404          */
405         public static final String IS_DELETED = "deleted";
406     }
407 
408     /**
409      * Read-only table that lists all the accounts that are used to provide bookmarks.
410      * @hide
411      */
412     public static final class Accounts {
413         /**
414          * Directory under {@link Bookmarks#CONTENT_URI}
415          */
416         @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
417         public static final Uri CONTENT_URI =
418                 AUTHORITY_URI.buildUpon().appendPath("accounts").build();
419 
420         /**
421          * The name of the account instance to which this row belongs, which when paired with
422          * {@link #ACCOUNT_TYPE} identifies a specific account.
423          * <P>Type: TEXT</P>
424          */
425         public static final String ACCOUNT_NAME = "account_name";
426 
427         /**
428          * The type of account to which this row belongs, which when paired with
429          * {@link #ACCOUNT_NAME} identifies a specific account.
430          * <P>Type: TEXT</P>
431          */
432         public static final String ACCOUNT_TYPE = "account_type";
433 
434         /**
435          * The ID of the account's root folder. This will be the ID of the folder
436          * returned when querying {@link Bookmarks#CONTENT_URI_DEFAULT_FOLDER}.
437          * <P>Type: INTEGER</P>
438          */
439         public static final String ROOT_ID = "root_id";
440     }
441 
442     /**
443      * The history table, which holds the browsing history.
444      */
445     public static final class History implements CommonColumns, HistoryColumns, ImageColumns {
446         /**
447          * This utility class cannot be instantiated.
448          */
History()449         private History() {}
450 
451         /**
452          * The content:// style URI for this table
453          */
454         @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
455         public static final Uri CONTENT_URI = Uri.withAppendedPath(AUTHORITY_URI, "history");
456 
457         /**
458          * The MIME type of {@link #CONTENT_URI} providing a directory of browser history items.
459          */
460         public static final String CONTENT_TYPE = "vnd.android.cursor.dir/browser-history";
461 
462         /**
463          * The MIME type of a {@link #CONTENT_URI} of a single browser history item.
464          */
465         public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/browser-history";
466     }
467 
468     /**
469      * The search history table.
470      * @hide
471      */
472     public static final class Searches {
Searches()473         private Searches() {}
474 
475         /**
476          * The content:// style URI for this table
477          */
478         public static final Uri CONTENT_URI = Uri.withAppendedPath(AUTHORITY_URI, "searches");
479 
480         /**
481          * The MIME type of {@link #CONTENT_URI} providing a directory of browser search items.
482          */
483         public static final String CONTENT_TYPE = "vnd.android.cursor.dir/searches";
484 
485         /**
486          * The MIME type of a {@link #CONTENT_URI} of a single browser search item.
487          */
488         public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/searches";
489 
490         /**
491          * The unique ID for a row.
492          * <P>Type: INTEGER (long)</P>
493          */
494         public static final String _ID = "_id";
495 
496         /**
497          * The user entered search term.
498          */
499         public static final String SEARCH = "search";
500 
501         /**
502          * The date the search was performed, in milliseconds since the epoch.
503          * <p>Type: NUMBER (date in milliseconds since January 1, 1970)</p>
504          */
505         public static final String DATE = "date";
506     }
507 
508     /**
509      * A table provided for sync adapters to use for storing private sync state data.
510      *
511      * @see SyncStateContract
512      * @hide
513      */
514     public static final class SyncState implements SyncStateContract.Columns {
515         /**
516          * This utility class cannot be instantiated
517          */
SyncState()518         private SyncState() {}
519 
520         public static final String CONTENT_DIRECTORY =
521                 SyncStateContract.Constants.CONTENT_DIRECTORY;
522 
523         /**
524          * The content:// style URI for this table
525          */
526         public static final Uri CONTENT_URI =
527                 Uri.withAppendedPath(AUTHORITY_URI, CONTENT_DIRECTORY);
528 
529         /**
530          * @see android.provider.SyncStateContract.Helpers#get
531          */
get(ContentProviderClient provider, Account account)532         public static byte[] get(ContentProviderClient provider, Account account)
533                 throws RemoteException {
534             return SyncStateContract.Helpers.get(provider, CONTENT_URI, account);
535         }
536 
537         /**
538          * @see android.provider.SyncStateContract.Helpers#get
539          */
getWithUri(ContentProviderClient provider, Account account)540         public static Pair<Uri, byte[]> getWithUri(ContentProviderClient provider, Account account)
541                 throws RemoteException {
542             return SyncStateContract.Helpers.getWithUri(provider, CONTENT_URI, account);
543         }
544 
545         /**
546          * @see android.provider.SyncStateContract.Helpers#set
547          */
set(ContentProviderClient provider, Account account, byte[] data)548         public static void set(ContentProviderClient provider, Account account, byte[] data)
549                 throws RemoteException {
550             SyncStateContract.Helpers.set(provider, CONTENT_URI, account, data);
551         }
552 
553         /**
554          * @see android.provider.SyncStateContract.Helpers#newSetOperation
555          */
newSetOperation(Account account, byte[] data)556         public static ContentProviderOperation newSetOperation(Account account, byte[] data) {
557             return SyncStateContract.Helpers.newSetOperation(CONTENT_URI, account, data);
558         }
559     }
560 
561     /**
562      * <p>
563      * Stores images for URLs.
564      * </p>
565      * <p>
566      * The rows in this table can not be updated since there might have multiple URLs mapping onto
567      * the same image. If you want to update a URL's image, you need to add the new image in this
568      * table, then update the mapping onto the added image.
569      * </p>
570      * <p>
571      * Every image should be at least associated with one URL, otherwise it will be removed after a
572      * while.
573      * </p>
574      */
575     public static final class Images implements ImageColumns {
576         /**
577          * This utility class cannot be instantiated
578          */
Images()579         private Images() {}
580 
581         /**
582          * The content:// style URI for this table
583          */
584         @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
585         public static final Uri CONTENT_URI = Uri.withAppendedPath(AUTHORITY_URI, "images");
586 
587         /**
588          * The MIME type of {@link #CONTENT_URI} providing a directory of images.
589          */
590         public static final String CONTENT_TYPE = "vnd.android.cursor.dir/images";
591 
592         /**
593          * The MIME type of a {@link #CONTENT_URI} of a single image.
594          */
595         public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/images";
596 
597         /**
598          * Used in {@link Images#TYPE} column and indicats the row is a favicon.
599          */
600         public static final int IMAGE_TYPE_FAVICON = 1;
601 
602         /**
603          * Used in {@link Images#TYPE} column and indicats the row is a precomposed touch icon.
604          */
605         public static final int IMAGE_TYPE_PRECOMPOSED_TOUCH_ICON = 2;
606 
607         /**
608          * Used in {@link Images#TYPE} column and indicats the row is a touch icon.
609          */
610         public static final int IMAGE_TYPE_TOUCH_ICON = 4;
611 
612         /**
613          * The type of item in the table.
614          * <P>Type: INTEGER</P>
615          * <p>Allowed values are:</p>
616          * <p>
617          * <ul>
618          * <li>{@link #IMAGE_TYPE_FAVICON}</li>
619          * <li>{@link #IMAGE_TYPE_PRECOMPOSED_TOUCH_ICON}</li>
620          * <li>{@link #IMAGE_TYPE_TOUCH_ICON}</li>
621          * </ul>
622          * </p>
623          */
624         public static final String TYPE = "type";
625 
626         /**
627          * The image data.
628          * <p>Type: BLOB (image)</p>
629          */
630         public static final String DATA = "data";
631 
632         /**
633          * The URL the images came from.
634          * <P>Type: TEXT (URL)</P>
635          * @hide
636          */
637         public static final String URL = "url_key";
638     }
639 
640     /**
641      * <p>
642      * A table that stores the mappings between the image and the URL.
643      * </p>
644      * <p>
645      * Deleting or Updating a mapping might also deletes the mapped image if there is no other URL
646      * maps onto it.
647      * </p>
648      */
649     public static final class ImageMappings implements ImageMappingColumns {
650         /**
651          * This utility class cannot be instantiated
652          */
ImageMappings()653         private ImageMappings() {}
654 
655         /**
656          * The content:// style URI for this table
657          */
658         public static final Uri CONTENT_URI = Uri.withAppendedPath(AUTHORITY_URI, "image_mappings");
659 
660         /**
661          * The MIME type of {@link #CONTENT_URI} providing a directory of image mappings.
662          */
663         public static final String CONTENT_TYPE = "vnd.android.cursor.dir/image_mappings";
664 
665         /**
666          * The MIME type of a {@link #CONTENT_URI} of a single image mapping.
667          */
668         public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/image_mappings";
669     }
670 
671     /**
672      * A combined view of bookmarks and history. All bookmarks in all folders are included and
673      * no folders are included.
674      * @hide
675      */
676     public static final class Combined implements CommonColumns, HistoryColumns, ImageColumns {
677         /**
678          * This utility class cannot be instantiated
679          */
Combined()680         private Combined() {}
681 
682         /**
683          * The content:// style URI for this table
684          */
685         @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
686         public static final Uri CONTENT_URI = Uri.withAppendedPath(AUTHORITY_URI, "combined");
687 
688         /**
689          * Flag indicating that an item is a bookmark. A value of 1 indicates a bookmark, a value
690          * of 0 indicates a history item.
691          * <p>Type: INTEGER (boolean)</p>
692          */
693         public static final String IS_BOOKMARK = "bookmark";
694     }
695 
696     /**
697      * A table that stores settings specific to the browser. Only support query and insert.
698      * @hide
699      */
700     public static final class Settings {
701         /**
702          * This utility class cannot be instantiated
703          */
Settings()704         private Settings() {}
705 
706         /**
707          * The content:// style URI for this table
708          */
709         public static final Uri CONTENT_URI = Uri.withAppendedPath(AUTHORITY_URI, "settings");
710 
711         /**
712          * Key for a setting value.
713          */
714         public static final String KEY = "key";
715 
716         /**
717          * Value for a setting.
718          */
719         public static final String VALUE = "value";
720 
721         /**
722          * If set to non-0 the user has opted into bookmark sync.
723          */
724         public static final String KEY_SYNC_ENABLED = "sync_enabled";
725 
726         /**
727          * Returns true if bookmark sync is enabled
728          */
isSyncEnabled(Context context)729         static public boolean isSyncEnabled(Context context) {
730             Cursor cursor = null;
731             try {
732                 cursor = context.getContentResolver().query(CONTENT_URI, new String[] { VALUE },
733                         KEY + "=?", new String[] { KEY_SYNC_ENABLED }, null);
734                 if (cursor == null || !cursor.moveToFirst()) {
735                     return false;
736                 }
737                 return cursor.getInt(0) != 0;
738             } finally {
739                 if (cursor != null) cursor.close();
740             }
741         }
742 
743         /**
744          * Sets the bookmark sync enabled setting.
745          */
setSyncEnabled(Context context, boolean enabled)746         static public void setSyncEnabled(Context context, boolean enabled) {
747             ContentValues values = new ContentValues();
748             values.put(KEY, KEY_SYNC_ENABLED);
749             values.put(VALUE, enabled ? 1 : 0);
750             context.getContentResolver().insert(CONTENT_URI, values);
751         }
752     }
753 }
754