10ebd3ac69a76ec76d9caab65a1947f971242994eJohn Reck/* 20ebd3ac69a76ec76d9caab65a1947f971242994eJohn Reck * Copyright (C) 2010 The Android Open Source Project 30ebd3ac69a76ec76d9caab65a1947f971242994eJohn Reck * 40ebd3ac69a76ec76d9caab65a1947f971242994eJohn Reck * Licensed under the Apache License, Version 2.0 (the "License"); 50ebd3ac69a76ec76d9caab65a1947f971242994eJohn Reck * you may not use this file except in compliance with the License. 60ebd3ac69a76ec76d9caab65a1947f971242994eJohn Reck * You may obtain a copy of the License at 70ebd3ac69a76ec76d9caab65a1947f971242994eJohn Reck * 80ebd3ac69a76ec76d9caab65a1947f971242994eJohn Reck * http://www.apache.org/licenses/LICENSE-2.0 90ebd3ac69a76ec76d9caab65a1947f971242994eJohn Reck * 100ebd3ac69a76ec76d9caab65a1947f971242994eJohn Reck * Unless required by applicable law or agreed to in writing, software 110ebd3ac69a76ec76d9caab65a1947f971242994eJohn Reck * distributed under the License is distributed on an "AS IS" BASIS, 120ebd3ac69a76ec76d9caab65a1947f971242994eJohn Reck * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 130ebd3ac69a76ec76d9caab65a1947f971242994eJohn Reck * See the License for the specific language governing permissions and 140ebd3ac69a76ec76d9caab65a1947f971242994eJohn Reck * limitations under the License. 150ebd3ac69a76ec76d9caab65a1947f971242994eJohn Reck */ 160ebd3ac69a76ec76d9caab65a1947f971242994eJohn Reck 170ebd3ac69a76ec76d9caab65a1947f971242994eJohn Reck 180ebd3ac69a76ec76d9caab65a1947f971242994eJohn Reckpackage com.android.browser; 190ebd3ac69a76ec76d9caab65a1947f971242994eJohn Reck 200ebd3ac69a76ec76d9caab65a1947f971242994eJohn Reckimport android.content.ContentResolver; 210ebd3ac69a76ec76d9caab65a1947f971242994eJohn Reckimport android.content.ContentUris; 220ebd3ac69a76ec76d9caab65a1947f971242994eJohn Reckimport android.content.ContentValues; 230ebd3ac69a76ec76d9caab65a1947f971242994eJohn Reckimport android.content.Context; 240ebd3ac69a76ec76d9caab65a1947f971242994eJohn Reckimport android.database.Cursor; 25e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reckimport android.database.sqlite.SQLiteException; 264eadc34fc528b1b63ac8d87bfd7f06e50b738b6dJohn Reckimport android.graphics.Bitmap; 274eadc34fc528b1b63ac8d87bfd7f06e50b738b6dJohn Reckimport android.net.Uri; 280ebd3ac69a76ec76d9caab65a1947f971242994eJohn Reckimport android.os.Handler; 290ebd3ac69a76ec76d9caab65a1947f971242994eJohn Reckimport android.os.Message; 30e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reckimport android.provider.BrowserContract; 310ebd3ac69a76ec76d9caab65a1947f971242994eJohn Reckimport android.provider.BrowserContract.History; 32e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reckimport android.util.Log; 33e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck 344eadc34fc528b1b63ac8d87bfd7f06e50b738b6dJohn Reckimport com.android.browser.provider.BrowserProvider2.Thumbnails; 354eadc34fc528b1b63ac8d87bfd7f06e50b738b6dJohn Reck 364eadc34fc528b1b63ac8d87bfd7f06e50b738b6dJohn Reckimport java.nio.ByteBuffer; 37e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reckimport java.util.concurrent.BlockingQueue; 38e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reckimport java.util.concurrent.LinkedBlockingQueue; 390ebd3ac69a76ec76d9caab65a1947f971242994eJohn Reck 400ebd3ac69a76ec76d9caab65a1947f971242994eJohn Reckpublic class DataController { 41e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck private static final String LOGTAG = "DataController"; 420ebd3ac69a76ec76d9caab65a1947f971242994eJohn Reck // Message IDs 430ebd3ac69a76ec76d9caab65a1947f971242994eJohn Reck private static final int HISTORY_UPDATE_VISITED = 100; 440ebd3ac69a76ec76d9caab65a1947f971242994eJohn Reck private static final int HISTORY_UPDATE_TITLE = 101; 454eadc34fc528b1b63ac8d87bfd7f06e50b738b6dJohn Reck private static final int QUERY_URL_IS_BOOKMARK = 200; 464eadc34fc528b1b63ac8d87bfd7f06e50b738b6dJohn Reck private static final int TAB_LOAD_THUMBNAIL = 201; 474eadc34fc528b1b63ac8d87bfd7f06e50b738b6dJohn Reck private static final int TAB_SAVE_THUMBNAIL = 202; 484eadc34fc528b1b63ac8d87bfd7f06e50b738b6dJohn Reck private static final int TAB_DELETE_THUMBNAIL = 203; 490ebd3ac69a76ec76d9caab65a1947f971242994eJohn Reck private static DataController sInstance; 500ebd3ac69a76ec76d9caab65a1947f971242994eJohn Reck 510ebd3ac69a76ec76d9caab65a1947f971242994eJohn Reck private Context mContext; 52e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck private DataControllerHandler mDataHandler; 53e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck private Handler mCbHandler; // To respond on the UI thread 544eadc34fc528b1b63ac8d87bfd7f06e50b738b6dJohn Reck private ByteBuffer mBuffer; // to capture thumbnails 55e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck 56e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck /* package */ static interface OnQueryUrlIsBookmark { 57e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck void onQueryUrlIsBookmark(String url, boolean isBookmark); 58e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck } 59e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck private static class CallbackContainer { 60e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck Object replyTo; 61e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck Object[] args; 62e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck } 63e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck 64e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck private static class DCMessage { 65e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck int what; 66e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck Object obj; 67e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck Object replyTo; 68e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck DCMessage(int w, Object o) { 69e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck what = w; 70e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck obj = o; 71e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck } 72e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck } 730ebd3ac69a76ec76d9caab65a1947f971242994eJohn Reck 740ebd3ac69a76ec76d9caab65a1947f971242994eJohn Reck /* package */ static DataController getInstance(Context c) { 750ebd3ac69a76ec76d9caab65a1947f971242994eJohn Reck if (sInstance == null) { 760ebd3ac69a76ec76d9caab65a1947f971242994eJohn Reck sInstance = new DataController(c); 770ebd3ac69a76ec76d9caab65a1947f971242994eJohn Reck } 780ebd3ac69a76ec76d9caab65a1947f971242994eJohn Reck return sInstance; 790ebd3ac69a76ec76d9caab65a1947f971242994eJohn Reck } 800ebd3ac69a76ec76d9caab65a1947f971242994eJohn Reck 810ebd3ac69a76ec76d9caab65a1947f971242994eJohn Reck private DataController(Context c) { 820ebd3ac69a76ec76d9caab65a1947f971242994eJohn Reck mContext = c.getApplicationContext(); 83e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck mDataHandler = new DataControllerHandler(); 84e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck mDataHandler.start(); 85e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck mCbHandler = new Handler() { 86e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck @Override 87e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck public void handleMessage(Message msg) { 88e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck CallbackContainer cc = (CallbackContainer) msg.obj; 89e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck switch (msg.what) { 90e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck case QUERY_URL_IS_BOOKMARK: { 91e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck OnQueryUrlIsBookmark cb = (OnQueryUrlIsBookmark) cc.replyTo; 92e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck String url = (String) cc.args[0]; 93e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck boolean isBookmark = (Boolean) cc.args[1]; 94e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck cb.onQueryUrlIsBookmark(url, isBookmark); 95e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck break; 96e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck } 97e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck } 98e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck } 99e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck }; 1000ebd3ac69a76ec76d9caab65a1947f971242994eJohn Reck } 1010ebd3ac69a76ec76d9caab65a1947f971242994eJohn Reck 1020ebd3ac69a76ec76d9caab65a1947f971242994eJohn Reck public void updateVisitedHistory(String url) { 103e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck mDataHandler.sendMessage(HISTORY_UPDATE_VISITED, url); 1040ebd3ac69a76ec76d9caab65a1947f971242994eJohn Reck } 1050ebd3ac69a76ec76d9caab65a1947f971242994eJohn Reck 1060ebd3ac69a76ec76d9caab65a1947f971242994eJohn Reck public void updateHistoryTitle(String url, String title) { 107e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck mDataHandler.sendMessage(HISTORY_UPDATE_TITLE, new String[] { url, title }); 1080ebd3ac69a76ec76d9caab65a1947f971242994eJohn Reck } 1090ebd3ac69a76ec76d9caab65a1947f971242994eJohn Reck 110e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck public void queryBookmarkStatus(String url, OnQueryUrlIsBookmark replyTo) { 1116c702eed5791d0d46fbe3dfd3054549997f218dcJohn Reck if (url == null || url.trim().length() == 0) { 1126c702eed5791d0d46fbe3dfd3054549997f218dcJohn Reck // null or empty url is never a bookmark 1136c702eed5791d0d46fbe3dfd3054549997f218dcJohn Reck replyTo.onQueryUrlIsBookmark(url, false); 1146c702eed5791d0d46fbe3dfd3054549997f218dcJohn Reck return; 1156c702eed5791d0d46fbe3dfd3054549997f218dcJohn Reck } 1166c702eed5791d0d46fbe3dfd3054549997f218dcJohn Reck mDataHandler.sendMessage(QUERY_URL_IS_BOOKMARK, url.trim(), replyTo); 117e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck } 118e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck 1194eadc34fc528b1b63ac8d87bfd7f06e50b738b6dJohn Reck public void loadThumbnail(Tab tab) { 1204eadc34fc528b1b63ac8d87bfd7f06e50b738b6dJohn Reck mDataHandler.sendMessage(TAB_LOAD_THUMBNAIL, tab); 1214eadc34fc528b1b63ac8d87bfd7f06e50b738b6dJohn Reck } 1224eadc34fc528b1b63ac8d87bfd7f06e50b738b6dJohn Reck 1234eadc34fc528b1b63ac8d87bfd7f06e50b738b6dJohn Reck public void deleteThumbnail(Tab tab) { 1244eadc34fc528b1b63ac8d87bfd7f06e50b738b6dJohn Reck mDataHandler.sendMessage(TAB_DELETE_THUMBNAIL, tab.getId()); 1254eadc34fc528b1b63ac8d87bfd7f06e50b738b6dJohn Reck } 1264eadc34fc528b1b63ac8d87bfd7f06e50b738b6dJohn Reck 1274eadc34fc528b1b63ac8d87bfd7f06e50b738b6dJohn Reck public void saveThumbnail(Tab tab) { 1284eadc34fc528b1b63ac8d87bfd7f06e50b738b6dJohn Reck mDataHandler.sendMessage(TAB_SAVE_THUMBNAIL, tab); 1294eadc34fc528b1b63ac8d87bfd7f06e50b738b6dJohn Reck } 1304eadc34fc528b1b63ac8d87bfd7f06e50b738b6dJohn Reck 131e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck // The standard Handler and Message classes don't allow the queue manipulation 132e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck // we want (such as peeking). So we use our own queue. 133e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck class DataControllerHandler extends Thread { 134e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck private BlockingQueue<DCMessage> mMessageQueue 135e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck = new LinkedBlockingQueue<DCMessage>(); 1360ebd3ac69a76ec76d9caab65a1947f971242994eJohn Reck 1374eadc34fc528b1b63ac8d87bfd7f06e50b738b6dJohn Reck public DataControllerHandler() { 1384eadc34fc528b1b63ac8d87bfd7f06e50b738b6dJohn Reck super("DataControllerHandler"); 1394eadc34fc528b1b63ac8d87bfd7f06e50b738b6dJohn Reck } 1404eadc34fc528b1b63ac8d87bfd7f06e50b738b6dJohn Reck 1410ebd3ac69a76ec76d9caab65a1947f971242994eJohn Reck @Override 142e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck public void run() { 1434eadc34fc528b1b63ac8d87bfd7f06e50b738b6dJohn Reck setPriority(Thread.MIN_PRIORITY); 144e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck while (true) { 145e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck try { 146e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck handleMessage(mMessageQueue.take()); 147e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck } catch (InterruptedException ex) { 148e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck break; 149e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck } 150e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck } 151e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck } 152e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck 153e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck void sendMessage(int what, Object obj) { 154e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck DCMessage m = new DCMessage(what, obj); 155e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck mMessageQueue.add(m); 156e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck } 157e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck 158e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck void sendMessage(int what, Object obj, Object replyTo) { 159e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck DCMessage m = new DCMessage(what, obj); 160e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck m.replyTo = replyTo; 161e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck mMessageQueue.add(m); 162e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck } 163e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck 164e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck private void handleMessage(DCMessage msg) { 1650ebd3ac69a76ec76d9caab65a1947f971242994eJohn Reck switch (msg.what) { 1660ebd3ac69a76ec76d9caab65a1947f971242994eJohn Reck case HISTORY_UPDATE_VISITED: 1670ebd3ac69a76ec76d9caab65a1947f971242994eJohn Reck doUpdateVisitedHistory((String) msg.obj); 1680ebd3ac69a76ec76d9caab65a1947f971242994eJohn Reck break; 1690ebd3ac69a76ec76d9caab65a1947f971242994eJohn Reck case HISTORY_UPDATE_TITLE: 1700ebd3ac69a76ec76d9caab65a1947f971242994eJohn Reck String[] args = (String[]) msg.obj; 1710ebd3ac69a76ec76d9caab65a1947f971242994eJohn Reck doUpdateHistoryTitle(args[0], args[1]); 1720ebd3ac69a76ec76d9caab65a1947f971242994eJohn Reck break; 173e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck case QUERY_URL_IS_BOOKMARK: 174e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck // TODO: Look for identical messages in the queue and remove them 175e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck // TODO: Also, look for partial matches and merge them (such as 176e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck // multiple callbacks querying the same URL) 177e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck doQueryBookmarkStatus((String) msg.obj, msg.replyTo); 178e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck break; 1794eadc34fc528b1b63ac8d87bfd7f06e50b738b6dJohn Reck case TAB_LOAD_THUMBNAIL: 1804eadc34fc528b1b63ac8d87bfd7f06e50b738b6dJohn Reck doLoadThumbnail((Tab) msg.obj); 1814eadc34fc528b1b63ac8d87bfd7f06e50b738b6dJohn Reck break; 1824eadc34fc528b1b63ac8d87bfd7f06e50b738b6dJohn Reck case TAB_DELETE_THUMBNAIL: 1834eadc34fc528b1b63ac8d87bfd7f06e50b738b6dJohn Reck ContentResolver cr = mContext.getContentResolver(); 1844eadc34fc528b1b63ac8d87bfd7f06e50b738b6dJohn Reck try { 1854eadc34fc528b1b63ac8d87bfd7f06e50b738b6dJohn Reck cr.delete(ContentUris.withAppendedId( 1864eadc34fc528b1b63ac8d87bfd7f06e50b738b6dJohn Reck Thumbnails.CONTENT_URI, (Long)msg.obj), 1874eadc34fc528b1b63ac8d87bfd7f06e50b738b6dJohn Reck null, null); 1884eadc34fc528b1b63ac8d87bfd7f06e50b738b6dJohn Reck } catch (Throwable t) {} 1894eadc34fc528b1b63ac8d87bfd7f06e50b738b6dJohn Reck break; 1904eadc34fc528b1b63ac8d87bfd7f06e50b738b6dJohn Reck case TAB_SAVE_THUMBNAIL: 1914eadc34fc528b1b63ac8d87bfd7f06e50b738b6dJohn Reck doSaveThumbnail((Tab)msg.obj); 1924eadc34fc528b1b63ac8d87bfd7f06e50b738b6dJohn Reck break; 1934eadc34fc528b1b63ac8d87bfd7f06e50b738b6dJohn Reck } 1944eadc34fc528b1b63ac8d87bfd7f06e50b738b6dJohn Reck } 1954eadc34fc528b1b63ac8d87bfd7f06e50b738b6dJohn Reck 1964eadc34fc528b1b63ac8d87bfd7f06e50b738b6dJohn Reck private byte[] getCaptureBlob(Tab tab) { 1974eadc34fc528b1b63ac8d87bfd7f06e50b738b6dJohn Reck synchronized (tab) { 1984eadc34fc528b1b63ac8d87bfd7f06e50b738b6dJohn Reck Bitmap capture = tab.getScreenshot(); 1994eadc34fc528b1b63ac8d87bfd7f06e50b738b6dJohn Reck if (capture == null) { 2004eadc34fc528b1b63ac8d87bfd7f06e50b738b6dJohn Reck return null; 2014eadc34fc528b1b63ac8d87bfd7f06e50b738b6dJohn Reck } 2024eadc34fc528b1b63ac8d87bfd7f06e50b738b6dJohn Reck if (mBuffer == null || mBuffer.limit() < capture.getByteCount()) { 2034eadc34fc528b1b63ac8d87bfd7f06e50b738b6dJohn Reck mBuffer = ByteBuffer.allocate(capture.getByteCount()); 2044eadc34fc528b1b63ac8d87bfd7f06e50b738b6dJohn Reck } 2054eadc34fc528b1b63ac8d87bfd7f06e50b738b6dJohn Reck capture.copyPixelsToBuffer(mBuffer); 2064eadc34fc528b1b63ac8d87bfd7f06e50b738b6dJohn Reck mBuffer.rewind(); 2074eadc34fc528b1b63ac8d87bfd7f06e50b738b6dJohn Reck return mBuffer.array(); 2084eadc34fc528b1b63ac8d87bfd7f06e50b738b6dJohn Reck } 2094eadc34fc528b1b63ac8d87bfd7f06e50b738b6dJohn Reck } 2104eadc34fc528b1b63ac8d87bfd7f06e50b738b6dJohn Reck 2114eadc34fc528b1b63ac8d87bfd7f06e50b738b6dJohn Reck private void doSaveThumbnail(Tab tab) { 2124eadc34fc528b1b63ac8d87bfd7f06e50b738b6dJohn Reck byte[] blob = getCaptureBlob(tab); 2134eadc34fc528b1b63ac8d87bfd7f06e50b738b6dJohn Reck if (blob == null) { 2144eadc34fc528b1b63ac8d87bfd7f06e50b738b6dJohn Reck return; 2154eadc34fc528b1b63ac8d87bfd7f06e50b738b6dJohn Reck } 2164eadc34fc528b1b63ac8d87bfd7f06e50b738b6dJohn Reck ContentResolver cr = mContext.getContentResolver(); 2174eadc34fc528b1b63ac8d87bfd7f06e50b738b6dJohn Reck ContentValues values = new ContentValues(); 2184eadc34fc528b1b63ac8d87bfd7f06e50b738b6dJohn Reck values.put(Thumbnails._ID, tab.getId()); 2194eadc34fc528b1b63ac8d87bfd7f06e50b738b6dJohn Reck values.put(Thumbnails.THUMBNAIL, blob); 2204eadc34fc528b1b63ac8d87bfd7f06e50b738b6dJohn Reck cr.insert(Thumbnails.CONTENT_URI, values); 2214eadc34fc528b1b63ac8d87bfd7f06e50b738b6dJohn Reck } 2224eadc34fc528b1b63ac8d87bfd7f06e50b738b6dJohn Reck 2234eadc34fc528b1b63ac8d87bfd7f06e50b738b6dJohn Reck private void doLoadThumbnail(Tab tab) { 2244eadc34fc528b1b63ac8d87bfd7f06e50b738b6dJohn Reck ContentResolver cr = mContext.getContentResolver(); 2254eadc34fc528b1b63ac8d87bfd7f06e50b738b6dJohn Reck Cursor c = null; 2264eadc34fc528b1b63ac8d87bfd7f06e50b738b6dJohn Reck try { 2274eadc34fc528b1b63ac8d87bfd7f06e50b738b6dJohn Reck Uri uri = ContentUris.withAppendedId(Thumbnails.CONTENT_URI, tab.getId()); 2284eadc34fc528b1b63ac8d87bfd7f06e50b738b6dJohn Reck c = cr.query(uri, new String[] {Thumbnails._ID, 2294eadc34fc528b1b63ac8d87bfd7f06e50b738b6dJohn Reck Thumbnails.THUMBNAIL}, null, null, null); 2304eadc34fc528b1b63ac8d87bfd7f06e50b738b6dJohn Reck if (c.moveToFirst()) { 2314eadc34fc528b1b63ac8d87bfd7f06e50b738b6dJohn Reck byte[] data = c.getBlob(1); 2324eadc34fc528b1b63ac8d87bfd7f06e50b738b6dJohn Reck if (data != null && data.length > 0) { 2334eadc34fc528b1b63ac8d87bfd7f06e50b738b6dJohn Reck tab.updateCaptureFromBlob(data); 2344eadc34fc528b1b63ac8d87bfd7f06e50b738b6dJohn Reck } 2354eadc34fc528b1b63ac8d87bfd7f06e50b738b6dJohn Reck } 2364eadc34fc528b1b63ac8d87bfd7f06e50b738b6dJohn Reck } finally { 2374eadc34fc528b1b63ac8d87bfd7f06e50b738b6dJohn Reck if (c != null) { 2384eadc34fc528b1b63ac8d87bfd7f06e50b738b6dJohn Reck c.close(); 2394eadc34fc528b1b63ac8d87bfd7f06e50b738b6dJohn Reck } 2400ebd3ac69a76ec76d9caab65a1947f971242994eJohn Reck } 2410ebd3ac69a76ec76d9caab65a1947f971242994eJohn Reck } 2420ebd3ac69a76ec76d9caab65a1947f971242994eJohn Reck 243e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck private void doUpdateVisitedHistory(String url) { 244e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck ContentResolver cr = mContext.getContentResolver(); 245e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck Cursor c = null; 246e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck try { 247e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck c = cr.query(History.CONTENT_URI, new String[] { History._ID, History.VISITS }, 248e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck History.URL + "=?", new String[] { url }, null); 249e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck if (c.moveToFirst()) { 250e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck ContentValues values = new ContentValues(); 251e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck values.put(History.VISITS, c.getInt(1) + 1); 252e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck values.put(History.DATE_LAST_VISITED, System.currentTimeMillis()); 253e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck cr.update(ContentUris.withAppendedId(History.CONTENT_URI, c.getLong(0)), 254e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck values, null, null); 255e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck } else { 256e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck android.provider.Browser.truncateHistory(cr); 257e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck ContentValues values = new ContentValues(); 258e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck values.put(History.URL, url); 259e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck values.put(History.VISITS, 1); 260e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck values.put(History.DATE_LAST_VISITED, System.currentTimeMillis()); 261e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck values.put(History.TITLE, url); 262e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck values.put(History.DATE_CREATED, 0); 263e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck values.put(History.USER_ENTERED, 0); 264e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck cr.insert(History.CONTENT_URI, values); 265e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck } 266e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck } finally { 267e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck if (c != null) c.close(); 2680ebd3ac69a76ec76d9caab65a1947f971242994eJohn Reck } 2690ebd3ac69a76ec76d9caab65a1947f971242994eJohn Reck } 2700ebd3ac69a76ec76d9caab65a1947f971242994eJohn Reck 271e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck private void doQueryBookmarkStatus(String url, Object replyTo) { 272e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck // Check to see if the site is bookmarked 273e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck Cursor cursor = null; 274e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck boolean isBookmark = false; 275e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck try { 276e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck cursor = mContext.getContentResolver().query( 277e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck BookmarkUtils.getBookmarksUri(mContext), 278e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck new String[] { BrowserContract.Bookmarks.URL }, 279e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck BrowserContract.Bookmarks.URL + " == ?", 280e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck new String[] { url }, 281e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck null); 282e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck isBookmark = cursor.moveToFirst(); 283e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck } catch (SQLiteException e) { 284e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck Log.e(LOGTAG, "Error checking for bookmark: " + e); 285e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck } finally { 286e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck if (cursor != null) cursor.close(); 287e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck } 288e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck CallbackContainer cc = new CallbackContainer(); 289e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck cc.replyTo = replyTo; 290e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck cc.args = new Object[] { url, isBookmark }; 291e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck mCbHandler.obtainMessage(QUERY_URL_IS_BOOKMARK, cc).sendToTarget(); 292e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck } 293e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck 294e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck private void doUpdateHistoryTitle(String url, String title) { 295e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck ContentResolver cr = mContext.getContentResolver(); 296e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck ContentValues values = new ContentValues(); 297e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck values.put(History.TITLE, title); 298e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck cr.update(History.CONTENT_URI, values, History.URL + "=?", 299e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck new String[] { url }); 300e969cc59ddcc763ab9d6349a854dd17a6456d1a4John Reck } 3010ebd3ac69a76ec76d9caab65a1947f971242994eJohn Reck } 3020ebd3ac69a76ec76d9caab65a1947f971242994eJohn Reck} 303