зеркало из https://github.com/mozilla/pjs.git
Bug 709402 preparation. r=rnewman
This commit is contained in:
Родитель
afff5474f8
Коммит
8119425bc1
|
@ -1,54 +1,22 @@
|
|||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Android Sync Client.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* the Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2011
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Jason Voll <jvoll@mozilla.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
package org.mozilla.gecko.sync.repositories.android;
|
||||
|
||||
import org.json.simple.JSONArray;
|
||||
import org.json.simple.JSONObject;
|
||||
import org.mozilla.gecko.db.BrowserContract;
|
||||
import org.mozilla.gecko.sync.Logger;
|
||||
import org.mozilla.gecko.sync.repositories.domain.HistoryRecord;
|
||||
import org.mozilla.gecko.sync.repositories.domain.Record;
|
||||
|
||||
import android.content.ContentValues;
|
||||
import android.content.Context;
|
||||
import android.net.Uri;
|
||||
import android.util.Log;
|
||||
|
||||
public class AndroidBrowserHistoryDataAccessor extends AndroidBrowserRepositoryDataAccessor {
|
||||
public class AndroidBrowserHistoryDataAccessor extends
|
||||
AndroidBrowserRepositoryDataAccessor {
|
||||
|
||||
private AndroidBrowserHistoryDataExtender dataExtender;
|
||||
|
||||
|
@ -78,7 +46,8 @@ public class AndroidBrowserHistoryDataAccessor extends AndroidBrowserRepositoryD
|
|||
long mostRecent = 0;
|
||||
for (int i = 0; i < visits.size(); i++) {
|
||||
JSONObject visit = (JSONObject) visits.get(i);
|
||||
long visitDate = (Long) visit.get(AndroidBrowserHistoryRepositorySession.KEY_DATE);
|
||||
long visitDate = (Long) visit
|
||||
.get(AndroidBrowserHistoryRepositorySession.KEY_DATE);
|
||||
if (visitDate > mostRecent) {
|
||||
mostRecent = visitDate;
|
||||
}
|
||||
|
@ -98,9 +67,9 @@ public class AndroidBrowserHistoryDataAccessor extends AndroidBrowserRepositoryD
|
|||
@Override
|
||||
public Uri insert(Record record) {
|
||||
HistoryRecord rec = (HistoryRecord) record;
|
||||
Log.d(LOG_TAG, "Storing visits for " + record.guid);
|
||||
Logger.debug(LOG_TAG, "Storing visits for " + record.guid);
|
||||
dataExtender.store(record.guid, rec.visits);
|
||||
Log.d(LOG_TAG, "Storing record " + record.guid);
|
||||
Logger.debug(LOG_TAG, "Storing record " + record.guid);
|
||||
return super.insert(record);
|
||||
}
|
||||
|
||||
|
@ -108,17 +77,17 @@ public class AndroidBrowserHistoryDataAccessor extends AndroidBrowserRepositoryD
|
|||
public void update(String oldGUID, Record newRecord) {
|
||||
HistoryRecord rec = (HistoryRecord) newRecord;
|
||||
String newGUID = newRecord.guid;
|
||||
Log.d(LOG_TAG, "Storing visits for " + newGUID + ", replacing " + oldGUID);
|
||||
Logger.debug(LOG_TAG, "Storing visits for " + newGUID + ", replacing " + oldGUID);
|
||||
dataExtender.delete(oldGUID);
|
||||
dataExtender.store(newGUID, rec.visits);
|
||||
super.update(oldGUID, newRecord);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void delete(String guid) {
|
||||
Log.d(LOG_TAG, "Deleting record " + guid);
|
||||
super.delete(guid);
|
||||
public int purgeGuid(String guid) {
|
||||
Logger.debug(LOG_TAG, "Purging record with " + guid);
|
||||
dataExtender.delete(guid);
|
||||
return super.purgeGuid(guid);
|
||||
}
|
||||
|
||||
public void closeExtender() {
|
||||
|
|
|
@ -1,42 +1,10 @@
|
|||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Android Sync Client.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* the Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2011
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Jason Voll <jvoll@mozilla.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
package org.mozilla.gecko.sync.repositories.android;
|
||||
|
||||
import org.mozilla.gecko.db.BrowserContract;
|
||||
import org.mozilla.gecko.sync.repositories.domain.PasswordRecord;
|
||||
import org.mozilla.gecko.sync.repositories.domain.Record;
|
||||
|
||||
|
@ -55,20 +23,20 @@ public class AndroidBrowserPasswordsDataAccessor extends AndroidBrowserRepositor
|
|||
PasswordRecord rec = (PasswordRecord) record;
|
||||
|
||||
ContentValues cv = new ContentValues();
|
||||
cv.put(PasswordColumns.GUID, rec.guid);
|
||||
cv.put(PasswordColumns.HOSTNAME, rec.hostname);
|
||||
cv.put(PasswordColumns.HTTP_REALM, rec.httpRealm);
|
||||
cv.put(PasswordColumns.FORM_SUBMIT_URL, rec.formSubmitURL);
|
||||
cv.put(PasswordColumns.USERNAME_FIELD, rec.usernameField);
|
||||
cv.put(PasswordColumns.PASSWORD_FIELD, rec.passwordField);
|
||||
cv.put(BrowserContract.Passwords.GUID, rec.guid);
|
||||
cv.put(BrowserContract.Passwords.HOSTNAME, rec.hostname);
|
||||
cv.put(BrowserContract.Passwords.HTTP_REALM, rec.httpRealm);
|
||||
cv.put(BrowserContract.Passwords.FORM_SUBMIT_URL, rec.formSubmitURL);
|
||||
cv.put(BrowserContract.Passwords.USERNAME_FIELD, rec.usernameField);
|
||||
cv.put(BrowserContract.Passwords.PASSWORD_FIELD, rec.passwordField);
|
||||
|
||||
// TODO Do encryption of username/password here. Bug 711636
|
||||
cv.put(PasswordColumns.ENC_TYPE, rec.encType);
|
||||
cv.put(PasswordColumns.ENCRYPTED_USERNAME, rec.username);
|
||||
cv.put(PasswordColumns.ENCRYPTED_PASSWORD, rec.password);
|
||||
cv.put(BrowserContract.Passwords.ENC_TYPE, rec.encType);
|
||||
cv.put(BrowserContract.Passwords.ENCRYPTED_USERNAME, rec.username);
|
||||
cv.put(BrowserContract.Passwords.ENCRYPTED_PASSWORD, rec.password);
|
||||
|
||||
cv.put(PasswordColumns.TIMES_USED, rec.timesUsed);
|
||||
cv.put(PasswordColumns.TIME_LAST_USED, rec.timeLastUsed);
|
||||
cv.put(BrowserContract.Passwords.TIMES_USED, rec.timesUsed);
|
||||
cv.put(BrowserContract.Passwords.TIME_LAST_USED, rec.timeLastUsed);
|
||||
return cv;
|
||||
}
|
||||
|
||||
|
|
|
@ -61,9 +61,20 @@ public abstract class AndroidBrowserRepositoryDataAccessor {
|
|||
}
|
||||
|
||||
protected abstract String[] getAllColumns();
|
||||
|
||||
/**
|
||||
* Produce a <code>ContentValues</code> instance that represents the provided <code>Record</code>.
|
||||
*
|
||||
* @param record The <code>Record</code> to be converted.
|
||||
* @return The <code>ContentValues</code> corresponding to <code>record</code>.
|
||||
*/
|
||||
protected abstract ContentValues getContentValues(Record record);
|
||||
|
||||
protected abstract Uri getUri();
|
||||
|
||||
/**
|
||||
* Dump all the records in raw format.
|
||||
*/
|
||||
public void dumpDB() {
|
||||
Cursor cur = null;
|
||||
try {
|
||||
|
@ -83,36 +94,34 @@ public abstract class AndroidBrowserRepositoryDataAccessor {
|
|||
|
||||
public void wipe() {
|
||||
Uri uri = getUri();
|
||||
Logger.info(LOG_TAG, "wiping: " + uri);
|
||||
Logger.debug(LOG_TAG, "Wiping: " + uri);
|
||||
context.getContentResolver().delete(uri, null, null);
|
||||
}
|
||||
|
||||
public void purgeDeleted() throws NullCursorException {
|
||||
String where = BrowserContract.SyncColumns.IS_DELETED + "= 1";
|
||||
Cursor cur = queryHelper.safeQuery(".purgeDeleted", GUID_COLUMNS, where, null, null);
|
||||
|
||||
try {
|
||||
if (!cur.moveToFirst()) {
|
||||
return;
|
||||
}
|
||||
while (!cur.isAfterLast()) {
|
||||
delete(RepoUtils.getStringFromCursor(cur, BrowserContract.SyncColumns.GUID));
|
||||
cur.moveToNext();
|
||||
}
|
||||
} finally {
|
||||
cur.close();
|
||||
}
|
||||
Uri uri = getUri();
|
||||
Logger.info(LOG_TAG, "Purging deleted from: " + uri);
|
||||
context.getContentResolver().delete(uri, where, null);
|
||||
}
|
||||
|
||||
protected void delete(String guid) {
|
||||
/**
|
||||
* Remove matching records from the database entirely, i.e., do not set a
|
||||
* deleted flag, delete entirely.
|
||||
*
|
||||
* @param guid
|
||||
* The GUID of the record to be deleted.
|
||||
* @return The number of records deleted.
|
||||
*/
|
||||
public int purgeGuid(String guid) {
|
||||
String where = BrowserContract.SyncColumns.GUID + " = ?";
|
||||
String[] args = new String[] { guid };
|
||||
|
||||
int deleted = context.getContentResolver().delete(getUri(), where, args);
|
||||
if (deleted == 1) {
|
||||
return;
|
||||
if (deleted != 1) {
|
||||
Logger.warn(LOG_TAG, "Unexpectedly deleted " + deleted + " records for guid " + guid);
|
||||
}
|
||||
Logger.warn(LOG_TAG, "Unexpectedly deleted " + deleted + " rows for guid " + guid);
|
||||
return deleted;
|
||||
}
|
||||
|
||||
public void update(String guid, Record newRecord) {
|
||||
|
@ -132,9 +141,10 @@ public abstract class AndroidBrowserRepositoryDataAccessor {
|
|||
|
||||
/**
|
||||
* Fetch all records.
|
||||
* <p>
|
||||
* The caller is responsible for closing the cursor.
|
||||
*
|
||||
* @return A cursor. You *must* close this when you're done with it.
|
||||
* @return A cursor. You </b>must</b> close this when you're done with it.
|
||||
* @throws NullCursorException
|
||||
*/
|
||||
public Cursor fetchAll() throws NullCursorException {
|
||||
|
@ -143,10 +153,11 @@ public abstract class AndroidBrowserRepositoryDataAccessor {
|
|||
|
||||
/**
|
||||
* Fetch GUIDs for records modified since the provided timestamp.
|
||||
* <p>
|
||||
* The caller is responsible for closing the cursor.
|
||||
*
|
||||
* @param timestamp
|
||||
* @return A cursor. You *must* close this when you're done with it.
|
||||
* @param timestamp A timestamp in milliseconds.
|
||||
* @return A cursor. You <b>must</b> close this when you're done with it.
|
||||
* @throws NullCursorException
|
||||
*/
|
||||
public Cursor getGUIDsSince(long timestamp) throws NullCursorException {
|
||||
|
@ -158,10 +169,11 @@ public abstract class AndroidBrowserRepositoryDataAccessor {
|
|||
|
||||
/**
|
||||
* Fetch records modified since the provided timestamp.
|
||||
* <p>
|
||||
* The caller is responsible for closing the cursor.
|
||||
*
|
||||
* @param timestamp
|
||||
* @return A cursor. You *must* close this when you're done with it.
|
||||
* @param timestamp A timestamp in milliseconds.
|
||||
* @return A cursor. You <b>must</b> close this when you're done with it.
|
||||
* @throws NullCursorException
|
||||
*/
|
||||
public Cursor fetchSince(long timestamp) throws NullCursorException {
|
||||
|
@ -173,10 +185,11 @@ public abstract class AndroidBrowserRepositoryDataAccessor {
|
|||
|
||||
/**
|
||||
* Fetch records for the provided GUIDs.
|
||||
* <p>
|
||||
* The caller is responsible for closing the cursor.
|
||||
*
|
||||
* @param guids
|
||||
* @return A cursor. You *must* close this when you're done with it.
|
||||
* @param guids The GUIDs of the records to fetch.
|
||||
* @return A cursor. You <b>must</b> close this when you're done with it.
|
||||
* @throws NullCursorException
|
||||
*/
|
||||
public Cursor fetch(String guids[]) throws NullCursorException {
|
||||
|
@ -198,17 +211,6 @@ public abstract class AndroidBrowserRepositoryDataAccessor {
|
|||
return builder.toString();
|
||||
}
|
||||
|
||||
public void delete(Record record) {
|
||||
String where = BrowserContract.SyncColumns.GUID + " = ?";
|
||||
String[] args = new String[] { record.guid };
|
||||
|
||||
int deleted = context.getContentResolver().delete(getUri(), where, args);
|
||||
if (deleted == 1) {
|
||||
return;
|
||||
}
|
||||
Logger.warn(LOG_TAG, "Unexpectedly deleted " + deleted + " rows for guid " + record.guid);
|
||||
}
|
||||
|
||||
public void updateByGuid(String guid, ContentValues cv) {
|
||||
String where = BrowserContract.SyncColumns.GUID + " = ?";
|
||||
String[] args = new String[] { guid };
|
||||
|
|
|
@ -489,9 +489,9 @@ public abstract class AndroidBrowserRepositorySession extends StoreTrackingRepos
|
|||
}
|
||||
|
||||
protected void storeRecordDeletion(final Record record) {
|
||||
// TODO: we ought to mark the record as deleted rather than deleting it,
|
||||
// TODO: we ought to mark the record as deleted rather than purging it,
|
||||
// in order to support syncing to multiple destinations. Bug 722607.
|
||||
dbHelper.delete(record); // TODO: mm?
|
||||
dbHelper.purgeGuid(record.guid);
|
||||
delegate.onRecordStoreSucceeded(record);
|
||||
}
|
||||
|
||||
|
|
|
@ -13,6 +13,12 @@ import org.mozilla.gecko.db.BrowserContract;
|
|||
import android.net.Uri;
|
||||
|
||||
public class BrowserContractHelpers extends BrowserContract {
|
||||
protected static Uri withSync(Uri u) {
|
||||
return u.buildUpon()
|
||||
.appendQueryParameter(PARAM_IS_SYNC, "true")
|
||||
.build();
|
||||
}
|
||||
|
||||
protected static Uri withSyncAndDeleted(Uri u) {
|
||||
return u.buildUpon()
|
||||
.appendQueryParameter(PARAM_IS_SYNC, "true")
|
||||
|
@ -30,9 +36,9 @@ public class BrowserContractHelpers extends BrowserContract {
|
|||
public static final Uri PASSWORDS_CONTENT_URI = null;
|
||||
/*
|
||||
public static final Uri PASSWORDS_CONTENT_URI = withSyncAndDeleted(Passwords.CONTENT_URI);
|
||||
public static final Uri FORM_HISTORY_CONTENT_URI = withSyncAndDeleted(FormHistory.CONTENT_URI);
|
||||
public static final Uri DELETED_FORM_HISTORY_CONTENT_URI = withSyncAndDeleted(DeletedFormHistory.CONTENT_URI);
|
||||
*/
|
||||
public static final Uri FORM_HISTORY_CONTENT_URI = withSync(FormHistory.CONTENT_URI);
|
||||
public static final Uri DELETED_FORM_HISTORY_CONTENT_URI = withSync(DeletedFormHistory.CONTENT_URI);
|
||||
|
||||
public static final String[] PasswordColumns = new String[] {
|
||||
CommonColumns._ID,
|
||||
|
@ -80,6 +86,23 @@ public class BrowserContractHelpers extends BrowserContract {
|
|||
Bookmarks.KEYWORD
|
||||
};
|
||||
|
||||
|
||||
public static final String[] FormHistoryColumns = new String[] {
|
||||
FormHistory.ID,
|
||||
FormHistory.GUID,
|
||||
FormHistory.FIELD_NAME,
|
||||
FormHistory.VALUE,
|
||||
FormHistory.TIMES_USED,
|
||||
FormHistory.FIRST_USED,
|
||||
FormHistory.LAST_USED
|
||||
};
|
||||
|
||||
public static final String[] DeletedColumns = new String[] {
|
||||
DeletedFormHistory.ID,
|
||||
DeletedFormHistory.GUID,
|
||||
DeletedFormHistory.TIME_DELETED
|
||||
};
|
||||
|
||||
// Mapping from Sync types to Fennec types.
|
||||
public static final String[] BOOKMARK_TYPE_CODE_TO_STRING = {
|
||||
// Observe omissions: "microsummary", "item".
|
||||
|
|
|
@ -146,7 +146,7 @@ public class RepoUtils {
|
|||
Logger.pii(LOG_TAG, "> URI: " + rec.histURI);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Logger.debug(LOG_TAG, "Exception logging bookmark record " + rec, e);
|
||||
Logger.debug(LOG_TAG, "Exception logging history record " + rec, e);
|
||||
}
|
||||
return rec;
|
||||
}
|
||||
|
@ -217,19 +217,26 @@ public class RepoUtils {
|
|||
return " ".substring(0, i);
|
||||
}
|
||||
|
||||
private static String dashes(int i) {
|
||||
return "-------------------------------------".substring(0, i);
|
||||
}
|
||||
|
||||
public static void dumpCursor(Cursor cur) {
|
||||
dumpCursor(cur, 18, "records");
|
||||
}
|
||||
|
||||
public static void dumpCursor(Cursor cur, int columnWidth, String tag) {
|
||||
int originalPosition = cur.getPosition();
|
||||
try {
|
||||
String[] columnNames = cur.getColumnNames();
|
||||
int columnCount = cur.getColumnCount();
|
||||
|
||||
// 12 chars each column.
|
||||
for (int i = 0; i < columnCount; ++i) {
|
||||
System.out.print(fixedWidth(12, columnNames[i]) + " | ");
|
||||
System.out.print(fixedWidth(columnWidth, columnNames[i]) + " | ");
|
||||
}
|
||||
System.out.println("");
|
||||
System.out.println("(" + cur.getCount() + " " + tag + ")");
|
||||
for (int i = 0; i < columnCount; ++i) {
|
||||
System.out.print("------------" + " | ");
|
||||
System.out.print(dashes(columnWidth) + " | ");
|
||||
}
|
||||
System.out.println("");
|
||||
if (!cur.moveToFirst()) {
|
||||
|
@ -238,15 +245,17 @@ public class RepoUtils {
|
|||
}
|
||||
|
||||
cur.moveToFirst();
|
||||
while (cur.moveToNext()) {
|
||||
while (!cur.isAfterLast()) {
|
||||
for (int i = 0; i < columnCount; ++i) {
|
||||
System.out.print(fixedWidth(12, cur.getString(i)) + " | ");
|
||||
System.out.print(fixedWidth(columnWidth, cur.getString(i)) + " | ");
|
||||
}
|
||||
System.out.println("");
|
||||
cur.moveToNext();
|
||||
}
|
||||
for (int i = 0; i < columnCount; ++i) {
|
||||
System.out.print("---------------");
|
||||
for (int i = 0; i < columnCount-1; ++i) {
|
||||
System.out.print(dashes(columnWidth + 3));
|
||||
}
|
||||
System.out.print(dashes(columnWidth + 3 - 1));
|
||||
System.out.println("");
|
||||
} finally {
|
||||
cur.moveToPosition(originalPosition);
|
||||
|
|
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
Загрузка…
Ссылка в новой задаче