|
1 /* -*- Mode: Java; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: nil; -*- |
|
2 * This Source Code Form is subject to the terms of the Mozilla Public |
|
3 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
5 |
|
6 package org.mozilla.gecko.preferences; |
|
7 |
|
8 import org.mozilla.gecko.GeckoProfile; |
|
9 import org.mozilla.gecko.db.BrowserContract; |
|
10 import org.mozilla.gecko.db.BrowserContract.Bookmarks; |
|
11 import org.mozilla.gecko.db.LocalBrowserDB; |
|
12 |
|
13 import android.content.ContentProviderOperation; |
|
14 import android.content.ContentResolver; |
|
15 import android.content.Context; |
|
16 import android.content.OperationApplicationException; |
|
17 import android.database.Cursor; |
|
18 import android.os.RemoteException; |
|
19 import android.provider.Browser; |
|
20 import android.util.Log; |
|
21 |
|
22 import java.util.ArrayList; |
|
23 |
|
24 class AndroidImport implements Runnable { |
|
25 static final private String LOGTAG = "AndroidImport"; |
|
26 private Context mContext; |
|
27 private Runnable mOnDoneRunnable; |
|
28 private ArrayList<ContentProviderOperation> mOperations; |
|
29 private ContentResolver mCr; |
|
30 private LocalBrowserDB mDB; |
|
31 private boolean mImportBookmarks; |
|
32 private boolean mImportHistory; |
|
33 |
|
34 public AndroidImport(Context context, Runnable onDoneRunnable, |
|
35 boolean doBookmarks, boolean doHistory) { |
|
36 mContext = context; |
|
37 mOnDoneRunnable = onDoneRunnable; |
|
38 mOperations = new ArrayList<ContentProviderOperation>(); |
|
39 mCr = mContext.getContentResolver(); |
|
40 mDB = new LocalBrowserDB(GeckoProfile.get(context).getName()); |
|
41 mImportBookmarks = doBookmarks; |
|
42 mImportHistory = doHistory; |
|
43 } |
|
44 |
|
45 public void mergeBookmarks() { |
|
46 Cursor cursor = null; |
|
47 try { |
|
48 cursor = mCr.query(Browser.BOOKMARKS_URI, |
|
49 null, |
|
50 Browser.BookmarkColumns.BOOKMARK + " = 1", |
|
51 null, |
|
52 null); |
|
53 |
|
54 if (cursor != null) { |
|
55 final int faviconCol = cursor.getColumnIndexOrThrow(Browser.BookmarkColumns.FAVICON); |
|
56 final int titleCol = cursor.getColumnIndexOrThrow(Browser.BookmarkColumns.TITLE); |
|
57 final int urlCol = cursor.getColumnIndexOrThrow(Browser.BookmarkColumns.URL); |
|
58 // http://code.google.com/p/android/issues/detail?id=17969 |
|
59 final int createCol = cursor.getColumnIndex(Browser.BookmarkColumns.CREATED); |
|
60 |
|
61 cursor.moveToFirst(); |
|
62 while (!cursor.isAfterLast()) { |
|
63 String url = cursor.getString(urlCol); |
|
64 String title = cursor.getString(titleCol); |
|
65 long created; |
|
66 if (createCol >= 0) { |
|
67 created = cursor.getLong(createCol); |
|
68 } else { |
|
69 created = System.currentTimeMillis(); |
|
70 } |
|
71 // Need to set it to the current time so Sync picks it up. |
|
72 long modified = System.currentTimeMillis(); |
|
73 byte[] data = cursor.getBlob(faviconCol); |
|
74 mDB.updateBookmarkInBatch(mCr, mOperations, |
|
75 url, title, null, -1, |
|
76 created, modified, |
|
77 BrowserContract.Bookmarks.DEFAULT_POSITION, |
|
78 null, Bookmarks.TYPE_BOOKMARK); |
|
79 if (data != null) { |
|
80 mDB.updateFaviconInBatch(mCr, mOperations, url, null, null, data); |
|
81 } |
|
82 cursor.moveToNext(); |
|
83 } |
|
84 } |
|
85 } finally { |
|
86 if (cursor != null) |
|
87 cursor.close(); |
|
88 } |
|
89 |
|
90 flushBatchOperations(); |
|
91 } |
|
92 |
|
93 public void mergeHistory() { |
|
94 Cursor cursor = null; |
|
95 try { |
|
96 cursor = mCr.query(Browser.BOOKMARKS_URI, |
|
97 null, |
|
98 Browser.BookmarkColumns.BOOKMARK + " = 0 AND " + |
|
99 Browser.BookmarkColumns.VISITS + " > 0", |
|
100 null, |
|
101 null); |
|
102 |
|
103 if (cursor != null) { |
|
104 final int dateCol = cursor.getColumnIndexOrThrow(Browser.BookmarkColumns.DATE); |
|
105 final int faviconCol = cursor.getColumnIndexOrThrow(Browser.BookmarkColumns.FAVICON); |
|
106 final int titleCol = cursor.getColumnIndexOrThrow(Browser.BookmarkColumns.TITLE); |
|
107 final int urlCol = cursor.getColumnIndexOrThrow(Browser.BookmarkColumns.URL); |
|
108 final int visitsCol = cursor.getColumnIndexOrThrow(Browser.BookmarkColumns.VISITS); |
|
109 |
|
110 cursor.moveToFirst(); |
|
111 while (!cursor.isAfterLast()) { |
|
112 String url = cursor.getString(urlCol); |
|
113 String title = cursor.getString(titleCol); |
|
114 long date = cursor.getLong(dateCol); |
|
115 int visits = cursor.getInt(visitsCol); |
|
116 byte[] data = cursor.getBlob(faviconCol); |
|
117 mDB.updateHistoryInBatch(mCr, mOperations, url, title, date, visits); |
|
118 if (data != null) { |
|
119 mDB.updateFaviconInBatch(mCr, mOperations, url, null, null, data); |
|
120 } |
|
121 cursor.moveToNext(); |
|
122 } |
|
123 } |
|
124 } finally { |
|
125 if (cursor != null) |
|
126 cursor.close(); |
|
127 } |
|
128 |
|
129 flushBatchOperations(); |
|
130 } |
|
131 |
|
132 protected void flushBatchOperations() { |
|
133 Log.d(LOGTAG, "Flushing " + mOperations.size() + " DB operations"); |
|
134 try { |
|
135 // We don't really care for the results, this is best-effort. |
|
136 mCr.applyBatch(BrowserContract.AUTHORITY, mOperations); |
|
137 } catch (RemoteException e) { |
|
138 Log.e(LOGTAG, "Remote exception while updating db: ", e); |
|
139 } catch (OperationApplicationException e) { |
|
140 // Bug 716729 means this happens even in normal circumstances |
|
141 Log.d(LOGTAG, "Error while applying database updates: ", e); |
|
142 } |
|
143 mOperations.clear(); |
|
144 } |
|
145 |
|
146 @Override |
|
147 public void run() { |
|
148 if (mImportBookmarks) { |
|
149 mergeBookmarks(); |
|
150 } |
|
151 if (mImportHistory) { |
|
152 mergeHistory(); |
|
153 } |
|
154 |
|
155 mOnDoneRunnable.run(); |
|
156 } |
|
157 } |