michael@0: /* -*- Mode: Java; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: nil; -*- michael@0: * This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: package org.mozilla.gecko.preferences; michael@0: michael@0: import org.mozilla.gecko.GeckoProfile; michael@0: import org.mozilla.gecko.db.BrowserContract; michael@0: import org.mozilla.gecko.db.BrowserContract.Bookmarks; michael@0: import org.mozilla.gecko.db.LocalBrowserDB; michael@0: michael@0: import android.content.ContentProviderOperation; michael@0: import android.content.ContentResolver; michael@0: import android.content.Context; michael@0: import android.content.OperationApplicationException; michael@0: import android.database.Cursor; michael@0: import android.os.RemoteException; michael@0: import android.provider.Browser; michael@0: import android.util.Log; michael@0: michael@0: import java.util.ArrayList; michael@0: michael@0: class AndroidImport implements Runnable { michael@0: static final private String LOGTAG = "AndroidImport"; michael@0: private Context mContext; michael@0: private Runnable mOnDoneRunnable; michael@0: private ArrayList mOperations; michael@0: private ContentResolver mCr; michael@0: private LocalBrowserDB mDB; michael@0: private boolean mImportBookmarks; michael@0: private boolean mImportHistory; michael@0: michael@0: public AndroidImport(Context context, Runnable onDoneRunnable, michael@0: boolean doBookmarks, boolean doHistory) { michael@0: mContext = context; michael@0: mOnDoneRunnable = onDoneRunnable; michael@0: mOperations = new ArrayList(); michael@0: mCr = mContext.getContentResolver(); michael@0: mDB = new LocalBrowserDB(GeckoProfile.get(context).getName()); michael@0: mImportBookmarks = doBookmarks; michael@0: mImportHistory = doHistory; michael@0: } michael@0: michael@0: public void mergeBookmarks() { michael@0: Cursor cursor = null; michael@0: try { michael@0: cursor = mCr.query(Browser.BOOKMARKS_URI, michael@0: null, michael@0: Browser.BookmarkColumns.BOOKMARK + " = 1", michael@0: null, michael@0: null); michael@0: michael@0: if (cursor != null) { michael@0: final int faviconCol = cursor.getColumnIndexOrThrow(Browser.BookmarkColumns.FAVICON); michael@0: final int titleCol = cursor.getColumnIndexOrThrow(Browser.BookmarkColumns.TITLE); michael@0: final int urlCol = cursor.getColumnIndexOrThrow(Browser.BookmarkColumns.URL); michael@0: // http://code.google.com/p/android/issues/detail?id=17969 michael@0: final int createCol = cursor.getColumnIndex(Browser.BookmarkColumns.CREATED); michael@0: michael@0: cursor.moveToFirst(); michael@0: while (!cursor.isAfterLast()) { michael@0: String url = cursor.getString(urlCol); michael@0: String title = cursor.getString(titleCol); michael@0: long created; michael@0: if (createCol >= 0) { michael@0: created = cursor.getLong(createCol); michael@0: } else { michael@0: created = System.currentTimeMillis(); michael@0: } michael@0: // Need to set it to the current time so Sync picks it up. michael@0: long modified = System.currentTimeMillis(); michael@0: byte[] data = cursor.getBlob(faviconCol); michael@0: mDB.updateBookmarkInBatch(mCr, mOperations, michael@0: url, title, null, -1, michael@0: created, modified, michael@0: BrowserContract.Bookmarks.DEFAULT_POSITION, michael@0: null, Bookmarks.TYPE_BOOKMARK); michael@0: if (data != null) { michael@0: mDB.updateFaviconInBatch(mCr, mOperations, url, null, null, data); michael@0: } michael@0: cursor.moveToNext(); michael@0: } michael@0: } michael@0: } finally { michael@0: if (cursor != null) michael@0: cursor.close(); michael@0: } michael@0: michael@0: flushBatchOperations(); michael@0: } michael@0: michael@0: public void mergeHistory() { michael@0: Cursor cursor = null; michael@0: try { michael@0: cursor = mCr.query(Browser.BOOKMARKS_URI, michael@0: null, michael@0: Browser.BookmarkColumns.BOOKMARK + " = 0 AND " + michael@0: Browser.BookmarkColumns.VISITS + " > 0", michael@0: null, michael@0: null); michael@0: michael@0: if (cursor != null) { michael@0: final int dateCol = cursor.getColumnIndexOrThrow(Browser.BookmarkColumns.DATE); michael@0: final int faviconCol = cursor.getColumnIndexOrThrow(Browser.BookmarkColumns.FAVICON); michael@0: final int titleCol = cursor.getColumnIndexOrThrow(Browser.BookmarkColumns.TITLE); michael@0: final int urlCol = cursor.getColumnIndexOrThrow(Browser.BookmarkColumns.URL); michael@0: final int visitsCol = cursor.getColumnIndexOrThrow(Browser.BookmarkColumns.VISITS); michael@0: michael@0: cursor.moveToFirst(); michael@0: while (!cursor.isAfterLast()) { michael@0: String url = cursor.getString(urlCol); michael@0: String title = cursor.getString(titleCol); michael@0: long date = cursor.getLong(dateCol); michael@0: int visits = cursor.getInt(visitsCol); michael@0: byte[] data = cursor.getBlob(faviconCol); michael@0: mDB.updateHistoryInBatch(mCr, mOperations, url, title, date, visits); michael@0: if (data != null) { michael@0: mDB.updateFaviconInBatch(mCr, mOperations, url, null, null, data); michael@0: } michael@0: cursor.moveToNext(); michael@0: } michael@0: } michael@0: } finally { michael@0: if (cursor != null) michael@0: cursor.close(); michael@0: } michael@0: michael@0: flushBatchOperations(); michael@0: } michael@0: michael@0: protected void flushBatchOperations() { michael@0: Log.d(LOGTAG, "Flushing " + mOperations.size() + " DB operations"); michael@0: try { michael@0: // We don't really care for the results, this is best-effort. michael@0: mCr.applyBatch(BrowserContract.AUTHORITY, mOperations); michael@0: } catch (RemoteException e) { michael@0: Log.e(LOGTAG, "Remote exception while updating db: ", e); michael@0: } catch (OperationApplicationException e) { michael@0: // Bug 716729 means this happens even in normal circumstances michael@0: Log.d(LOGTAG, "Error while applying database updates: ", e); michael@0: } michael@0: mOperations.clear(); michael@0: } michael@0: michael@0: @Override michael@0: public void run() { michael@0: if (mImportBookmarks) { michael@0: mergeBookmarks(); michael@0: } michael@0: if (mImportHistory) { michael@0: mergeHistory(); michael@0: } michael@0: michael@0: mOnDoneRunnable.run(); michael@0: } michael@0: }