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