1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/mobile/android/base/db/HomeProvider.java Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,194 @@ 1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this file, 1.6 + * You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.7 + 1.8 +package org.mozilla.gecko.db; 1.9 + 1.10 +import java.io.IOException; 1.11 + 1.12 +import org.json.JSONArray; 1.13 +import org.json.JSONException; 1.14 +import org.json.JSONObject; 1.15 +import org.mozilla.gecko.R; 1.16 +import org.mozilla.gecko.db.BrowserContract.HomeItems; 1.17 +import org.mozilla.gecko.db.DBUtils; 1.18 +import org.mozilla.gecko.sqlite.SQLiteBridge; 1.19 +import org.mozilla.gecko.util.RawResource; 1.20 + 1.21 +import android.content.ContentResolver; 1.22 +import android.content.ContentValues; 1.23 +import android.content.UriMatcher; 1.24 +import android.database.Cursor; 1.25 +import android.database.MatrixCursor; 1.26 +import android.net.Uri; 1.27 +import android.util.Log; 1.28 + 1.29 +public class HomeProvider extends SQLiteBridgeContentProvider { 1.30 + private static final String LOGTAG = "GeckoHomeProvider"; 1.31 + 1.32 + // This should be kept in sync with the db version in mobile/android/modules/HomeProvider.jsm 1.33 + private static int DB_VERSION = 2; 1.34 + private static String DB_FILENAME = "home.sqlite"; 1.35 + private static final String TELEMETRY_TAG = "SQLITEBRIDGE_PROVIDER_HOME"; 1.36 + 1.37 + private static final String TABLE_ITEMS = "items"; 1.38 + 1.39 + // Endpoint to return static fake data. 1.40 + static final int ITEMS_FAKE = 100; 1.41 + static final int ITEMS = 101; 1.42 + static final int ITEMS_ID = 102; 1.43 + 1.44 + static final UriMatcher URI_MATCHER = new UriMatcher(UriMatcher.NO_MATCH); 1.45 + 1.46 + static { 1.47 + URI_MATCHER.addURI(BrowserContract.HOME_AUTHORITY, "items/fake", ITEMS_FAKE); 1.48 + URI_MATCHER.addURI(BrowserContract.HOME_AUTHORITY, "items", ITEMS); 1.49 + URI_MATCHER.addURI(BrowserContract.HOME_AUTHORITY, "items/#", ITEMS_ID); 1.50 + } 1.51 + 1.52 + public HomeProvider() { 1.53 + super(LOGTAG); 1.54 + } 1.55 + 1.56 + @Override 1.57 + public String getType(Uri uri) { 1.58 + final int match = URI_MATCHER.match(uri); 1.59 + 1.60 + switch (match) { 1.61 + case ITEMS_FAKE: { 1.62 + return HomeItems.CONTENT_TYPE; 1.63 + } 1.64 + case ITEMS: { 1.65 + return HomeItems.CONTENT_TYPE; 1.66 + } 1.67 + default: { 1.68 + throw new UnsupportedOperationException("Unknown type " + uri); 1.69 + } 1.70 + } 1.71 + } 1.72 + 1.73 + @Override 1.74 + public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { 1.75 + final int match = URI_MATCHER.match(uri); 1.76 + 1.77 + // If we're querying the fake items, don't try to get the database. 1.78 + if (match == ITEMS_FAKE) { 1.79 + return queryFakeItems(uri, projection, selection, selectionArgs, sortOrder); 1.80 + } 1.81 + 1.82 + final String datasetId = uri.getQueryParameter(BrowserContract.PARAM_DATASET_ID); 1.83 + if (datasetId == null) { 1.84 + throw new IllegalArgumentException("All queries should contain a dataset ID parameter"); 1.85 + } 1.86 + 1.87 + selection = DBUtils.concatenateWhere(selection, HomeItems.DATASET_ID + " = ?"); 1.88 + selectionArgs = DBUtils.appendSelectionArgs(selectionArgs, 1.89 + new String[] { datasetId }); 1.90 + 1.91 + // Otherwise, let the SQLiteContentProvider implementation take care of this query for us! 1.92 + Cursor c = super.query(uri, projection, selection, selectionArgs, sortOrder); 1.93 + 1.94 + // SQLiteBridgeContentProvider may return a null Cursor if the database hasn't been created yet. 1.95 + // However, we need a non-null cursor in order to listen for notifications. 1.96 + if (c == null) { 1.97 + c = new MatrixCursor(projection != null ? projection : HomeItems.DEFAULT_PROJECTION); 1.98 + } 1.99 + 1.100 + final ContentResolver cr = getContext().getContentResolver(); 1.101 + c.setNotificationUri(cr, getDatasetNotificationUri(datasetId)); 1.102 + 1.103 + return c; 1.104 + } 1.105 + 1.106 + /** 1.107 + * Returns a cursor populated with static fake data. 1.108 + */ 1.109 + private Cursor queryFakeItems(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { 1.110 + JSONArray items = null; 1.111 + try { 1.112 + final String jsonString = RawResource.getAsString(getContext(), R.raw.fake_home_items); 1.113 + items = new JSONArray(jsonString); 1.114 + } catch (IOException e) { 1.115 + Log.e(LOGTAG, "Error getting fake home items", e); 1.116 + return null; 1.117 + } catch (JSONException e) { 1.118 + Log.e(LOGTAG, "Error parsing fake_home_items.json", e); 1.119 + return null; 1.120 + } 1.121 + 1.122 + final MatrixCursor c = new MatrixCursor(HomeItems.DEFAULT_PROJECTION); 1.123 + for (int i = 0; i < items.length(); i++) { 1.124 + try { 1.125 + final JSONObject item = items.getJSONObject(i); 1.126 + c.addRow(new Object[] { 1.127 + item.getInt("id"), 1.128 + item.getString("dataset_id"), 1.129 + item.getString("url"), 1.130 + item.getString("title"), 1.131 + item.getString("description"), 1.132 + item.getString("image_url"), 1.133 + item.getString("filter") 1.134 + }); 1.135 + } catch (JSONException e) { 1.136 + Log.e(LOGTAG, "Error creating cursor row for fake home item", e); 1.137 + } 1.138 + } 1.139 + return c; 1.140 + } 1.141 + 1.142 + /** 1.143 + * SQLiteBridgeContentProvider implementation 1.144 + */ 1.145 + 1.146 + @Override 1.147 + protected String getDBName(){ 1.148 + return DB_FILENAME; 1.149 + } 1.150 + 1.151 + @Override 1.152 + protected String getTelemetryPrefix() { 1.153 + return TELEMETRY_TAG; 1.154 + } 1.155 + 1.156 + @Override 1.157 + protected int getDBVersion(){ 1.158 + return DB_VERSION; 1.159 + } 1.160 + 1.161 + @Override 1.162 + public String getTable(Uri uri) { 1.163 + final int match = URI_MATCHER.match(uri); 1.164 + switch (match) { 1.165 + case ITEMS: { 1.166 + return TABLE_ITEMS; 1.167 + } 1.168 + default: { 1.169 + throw new UnsupportedOperationException("Unknown table " + uri); 1.170 + } 1.171 + } 1.172 + } 1.173 + 1.174 + @Override 1.175 + public String getSortOrder(Uri uri, String aRequested) { 1.176 + return null; 1.177 + } 1.178 + 1.179 + @Override 1.180 + public void setupDefaults(Uri uri, ContentValues values) { } 1.181 + 1.182 + @Override 1.183 + public void initGecko() { } 1.184 + 1.185 + @Override 1.186 + public void onPreInsert(ContentValues values, Uri uri, SQLiteBridge db) { } 1.187 + 1.188 + @Override 1.189 + public void onPreUpdate(ContentValues values, Uri uri, SQLiteBridge db) { } 1.190 + 1.191 + @Override 1.192 + public void onPostQuery(Cursor cursor, Uri uri, SQLiteBridge db) { } 1.193 + 1.194 + public static Uri getDatasetNotificationUri(String datasetId) { 1.195 + return Uri.withAppendedPath(HomeItems.CONTENT_URI, datasetId); 1.196 + } 1.197 +}