1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/mobile/android/base/preferences/AndroidImport.java Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,157 @@ 1.4 +/* -*- Mode: Java; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: nil; -*- 1.5 + * This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +package org.mozilla.gecko.preferences; 1.10 + 1.11 +import org.mozilla.gecko.GeckoProfile; 1.12 +import org.mozilla.gecko.db.BrowserContract; 1.13 +import org.mozilla.gecko.db.BrowserContract.Bookmarks; 1.14 +import org.mozilla.gecko.db.LocalBrowserDB; 1.15 + 1.16 +import android.content.ContentProviderOperation; 1.17 +import android.content.ContentResolver; 1.18 +import android.content.Context; 1.19 +import android.content.OperationApplicationException; 1.20 +import android.database.Cursor; 1.21 +import android.os.RemoteException; 1.22 +import android.provider.Browser; 1.23 +import android.util.Log; 1.24 + 1.25 +import java.util.ArrayList; 1.26 + 1.27 +class AndroidImport implements Runnable { 1.28 + static final private String LOGTAG = "AndroidImport"; 1.29 + private Context mContext; 1.30 + private Runnable mOnDoneRunnable; 1.31 + private ArrayList<ContentProviderOperation> mOperations; 1.32 + private ContentResolver mCr; 1.33 + private LocalBrowserDB mDB; 1.34 + private boolean mImportBookmarks; 1.35 + private boolean mImportHistory; 1.36 + 1.37 + public AndroidImport(Context context, Runnable onDoneRunnable, 1.38 + boolean doBookmarks, boolean doHistory) { 1.39 + mContext = context; 1.40 + mOnDoneRunnable = onDoneRunnable; 1.41 + mOperations = new ArrayList<ContentProviderOperation>(); 1.42 + mCr = mContext.getContentResolver(); 1.43 + mDB = new LocalBrowserDB(GeckoProfile.get(context).getName()); 1.44 + mImportBookmarks = doBookmarks; 1.45 + mImportHistory = doHistory; 1.46 + } 1.47 + 1.48 + public void mergeBookmarks() { 1.49 + Cursor cursor = null; 1.50 + try { 1.51 + cursor = mCr.query(Browser.BOOKMARKS_URI, 1.52 + null, 1.53 + Browser.BookmarkColumns.BOOKMARK + " = 1", 1.54 + null, 1.55 + null); 1.56 + 1.57 + if (cursor != null) { 1.58 + final int faviconCol = cursor.getColumnIndexOrThrow(Browser.BookmarkColumns.FAVICON); 1.59 + final int titleCol = cursor.getColumnIndexOrThrow(Browser.BookmarkColumns.TITLE); 1.60 + final int urlCol = cursor.getColumnIndexOrThrow(Browser.BookmarkColumns.URL); 1.61 + // http://code.google.com/p/android/issues/detail?id=17969 1.62 + final int createCol = cursor.getColumnIndex(Browser.BookmarkColumns.CREATED); 1.63 + 1.64 + cursor.moveToFirst(); 1.65 + while (!cursor.isAfterLast()) { 1.66 + String url = cursor.getString(urlCol); 1.67 + String title = cursor.getString(titleCol); 1.68 + long created; 1.69 + if (createCol >= 0) { 1.70 + created = cursor.getLong(createCol); 1.71 + } else { 1.72 + created = System.currentTimeMillis(); 1.73 + } 1.74 + // Need to set it to the current time so Sync picks it up. 1.75 + long modified = System.currentTimeMillis(); 1.76 + byte[] data = cursor.getBlob(faviconCol); 1.77 + mDB.updateBookmarkInBatch(mCr, mOperations, 1.78 + url, title, null, -1, 1.79 + created, modified, 1.80 + BrowserContract.Bookmarks.DEFAULT_POSITION, 1.81 + null, Bookmarks.TYPE_BOOKMARK); 1.82 + if (data != null) { 1.83 + mDB.updateFaviconInBatch(mCr, mOperations, url, null, null, data); 1.84 + } 1.85 + cursor.moveToNext(); 1.86 + } 1.87 + } 1.88 + } finally { 1.89 + if (cursor != null) 1.90 + cursor.close(); 1.91 + } 1.92 + 1.93 + flushBatchOperations(); 1.94 + } 1.95 + 1.96 + public void mergeHistory() { 1.97 + Cursor cursor = null; 1.98 + try { 1.99 + cursor = mCr.query(Browser.BOOKMARKS_URI, 1.100 + null, 1.101 + Browser.BookmarkColumns.BOOKMARK + " = 0 AND " + 1.102 + Browser.BookmarkColumns.VISITS + " > 0", 1.103 + null, 1.104 + null); 1.105 + 1.106 + if (cursor != null) { 1.107 + final int dateCol = cursor.getColumnIndexOrThrow(Browser.BookmarkColumns.DATE); 1.108 + final int faviconCol = cursor.getColumnIndexOrThrow(Browser.BookmarkColumns.FAVICON); 1.109 + final int titleCol = cursor.getColumnIndexOrThrow(Browser.BookmarkColumns.TITLE); 1.110 + final int urlCol = cursor.getColumnIndexOrThrow(Browser.BookmarkColumns.URL); 1.111 + final int visitsCol = cursor.getColumnIndexOrThrow(Browser.BookmarkColumns.VISITS); 1.112 + 1.113 + cursor.moveToFirst(); 1.114 + while (!cursor.isAfterLast()) { 1.115 + String url = cursor.getString(urlCol); 1.116 + String title = cursor.getString(titleCol); 1.117 + long date = cursor.getLong(dateCol); 1.118 + int visits = cursor.getInt(visitsCol); 1.119 + byte[] data = cursor.getBlob(faviconCol); 1.120 + mDB.updateHistoryInBatch(mCr, mOperations, url, title, date, visits); 1.121 + if (data != null) { 1.122 + mDB.updateFaviconInBatch(mCr, mOperations, url, null, null, data); 1.123 + } 1.124 + cursor.moveToNext(); 1.125 + } 1.126 + } 1.127 + } finally { 1.128 + if (cursor != null) 1.129 + cursor.close(); 1.130 + } 1.131 + 1.132 + flushBatchOperations(); 1.133 + } 1.134 + 1.135 + protected void flushBatchOperations() { 1.136 + Log.d(LOGTAG, "Flushing " + mOperations.size() + " DB operations"); 1.137 + try { 1.138 + // We don't really care for the results, this is best-effort. 1.139 + mCr.applyBatch(BrowserContract.AUTHORITY, mOperations); 1.140 + } catch (RemoteException e) { 1.141 + Log.e(LOGTAG, "Remote exception while updating db: ", e); 1.142 + } catch (OperationApplicationException e) { 1.143 + // Bug 716729 means this happens even in normal circumstances 1.144 + Log.d(LOGTAG, "Error while applying database updates: ", e); 1.145 + } 1.146 + mOperations.clear(); 1.147 + } 1.148 + 1.149 + @Override 1.150 + public void run() { 1.151 + if (mImportBookmarks) { 1.152 + mergeBookmarks(); 1.153 + } 1.154 + if (mImportHistory) { 1.155 + mergeHistory(); 1.156 + } 1.157 + 1.158 + mOnDoneRunnable.run(); 1.159 + } 1.160 +}