mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 886587 - Remove profile migrator, r=gcp, f=rnewman
This commit is contained in:
parent
4b376ff6ea
commit
bcae12953a
@ -744,14 +744,6 @@ abstract public class BrowserApp extends GeckoApp
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void finishProfileMigration() {
|
||||
// Update about:home with the new information.
|
||||
updateAboutHomeTopSites();
|
||||
|
||||
super.finishProfileMigration();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initializeChrome() {
|
||||
super.initializeChrome();
|
||||
|
@ -167,6 +167,10 @@ abstract public class GeckoApp
|
||||
|
||||
static private final String LOCATION_URL = "https://location.services.mozilla.com/v1/submit";
|
||||
|
||||
// Delay before running one-time "cleanup" tasks that may be needed
|
||||
// after a version upgrade.
|
||||
private static final int CLEANUP_DEFERRAL_SECONDS = 15;
|
||||
|
||||
protected RelativeLayout mMainLayout;
|
||||
protected RelativeLayout mGeckoLayout;
|
||||
public View getView() { return mGeckoLayout; }
|
||||
@ -2245,23 +2249,54 @@ abstract public class GeckoApp
|
||||
ThreadUtils.postToBackgroundThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
ProfileMigrator profileMigrator = new ProfileMigrator(app);
|
||||
|
||||
profileMigrator.launchDeferredCleanup();
|
||||
|
||||
// Do a migration run on the first start after an upgrade.
|
||||
if (!GeckoApp.sIsUsingCustomProfile &&
|
||||
!profileMigrator.hasMigrationRun()) {
|
||||
|
||||
profileMigrator.launchPlaces(profileDir);
|
||||
finishProfileMigration();
|
||||
Handler handler = new Handler();
|
||||
handler.postDelayed(new DeferredCleanupTask(), CLEANUP_DEFERRAL_SECONDS * 1000);
|
||||
}
|
||||
}}
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
protected void finishProfileMigration() {
|
||||
private class DeferredCleanupTask implements Runnable {
|
||||
// The cleanup-version setting is recorded to avoid repeating the same
|
||||
// tasks on subsequent startups; CURRENT_CLEANUP_VERSION may be updated
|
||||
// if we need to do additional cleanup for future Gecko versions.
|
||||
|
||||
private static final String CLEANUP_VERSION = "cleanup-version";
|
||||
private static final int CURRENT_CLEANUP_VERSION = 1;
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
long cleanupVersion = getAppSharedPreferences().getInt(CLEANUP_VERSION, 0);
|
||||
|
||||
if (cleanupVersion < 1) {
|
||||
// Reduce device storage footprint by removing .ttf files from
|
||||
// the res/fonts directory: we no longer need to copy our
|
||||
// bundled fonts out of the APK in order to use them.
|
||||
// See https://bugzilla.mozilla.org/show_bug.cgi?id=878674.
|
||||
File dir = new File("res/fonts");
|
||||
if (dir.exists() && dir.isDirectory()) {
|
||||
for (File file : dir.listFiles()) {
|
||||
if (file.isFile() && file.getName().endsWith(".ttf")) {
|
||||
Log.i(LOGTAG, "deleting " + file.toString());
|
||||
file.delete();
|
||||
}
|
||||
}
|
||||
if (!dir.delete()) {
|
||||
Log.w(LOGTAG, "unable to delete res/fonts directory (not empty?)");
|
||||
} else {
|
||||
Log.i(LOGTAG, "res/fonts directory deleted");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Additional cleanup needed for future versions would go here
|
||||
|
||||
if (cleanupVersion != CURRENT_CLEANUP_VERSION) {
|
||||
SharedPreferences.Editor editor = getAppSharedPreferences().edit();
|
||||
editor.putInt(CLEANUP_VERSION, CURRENT_CLEANUP_VERSION);
|
||||
editor.commit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public PromptService getPromptService() {
|
||||
|
@ -162,15 +162,7 @@ public final class GeckoProfile {
|
||||
}
|
||||
|
||||
try {
|
||||
// Check for old profiles that may need migration.
|
||||
ProfileMigrator profileMigrator = new ProfileMigrator(mContext);
|
||||
if (!GeckoApp.sIsUsingCustomProfile &&
|
||||
!profileMigrator.isProfileMoved()) {
|
||||
Log.i(LOGTAG, "New installation or update, checking for old profiles.");
|
||||
profileMigrator.launchMoveProfile();
|
||||
}
|
||||
|
||||
// now check if a profile with this name that already exists
|
||||
// Check if a profile with this name already exists.
|
||||
File mozillaDir = ensureMozillaDirectory(mContext);
|
||||
mDir = findProfileDir(mozillaDir);
|
||||
if (mDir == null) {
|
||||
|
@ -134,7 +134,6 @@ FENNEC_JAVA_FILES = \
|
||||
PrefsHelper.java \
|
||||
PrivateDataPreference.java \
|
||||
PrivateTab.java \
|
||||
ProfileMigrator.java \
|
||||
Prompt.java \
|
||||
PromptInput.java \
|
||||
PromptService.java \
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -173,18 +173,6 @@ public class BrowserContract {
|
||||
public static final String VERSION = "version";
|
||||
}
|
||||
|
||||
public static final class Control {
|
||||
private Control() {}
|
||||
|
||||
public static final Uri CONTENT_URI = Uri.withAppendedPath(AUTHORITY_URI, "control");
|
||||
|
||||
// These return 1 if done/finished, 0 if not.
|
||||
// Check if history was completely migrated, do a bunch if it wasn't.
|
||||
public static final String ENSURE_HISTORY_MIGRATED = "ensure_history_migrated";
|
||||
// Check if bookmarks were completely migrated, migrate them if not.
|
||||
public static final String ENSURE_BOOKMARKS_MIGRATED = "ensure_bookmarks_migrated";
|
||||
}
|
||||
|
||||
public static final class Passwords {
|
||||
private Passwords() {}
|
||||
public static final Uri CONTENT_URI = Uri.withAppendedPath(PASSWORDS_AUTHORITY_URI, "passwords");
|
||||
|
@ -8,12 +8,10 @@ package org.mozilla.gecko.db;
|
||||
import org.mozilla.gecko.AppConstants;
|
||||
import org.mozilla.gecko.Distribution;
|
||||
import org.mozilla.gecko.GeckoProfile;
|
||||
import org.mozilla.gecko.ProfileMigrator;
|
||||
import org.mozilla.gecko.R;
|
||||
import org.mozilla.gecko.db.BrowserContract.Bookmarks;
|
||||
import org.mozilla.gecko.db.BrowserContract.Combined;
|
||||
import org.mozilla.gecko.db.BrowserContract.CommonColumns;
|
||||
import org.mozilla.gecko.db.BrowserContract.Control;
|
||||
import org.mozilla.gecko.db.BrowserContract.FaviconColumns;
|
||||
import org.mozilla.gecko.db.BrowserContract.Favicons;
|
||||
import org.mozilla.gecko.db.BrowserContract.History;
|
||||
@ -2511,80 +2509,6 @@ public class BrowserProvider extends ContentProvider {
|
||||
return updated;
|
||||
}
|
||||
|
||||
private Cursor controlQuery(Uri uri,
|
||||
String[] projection, String selection,
|
||||
String[] selectionArgs, String sortOrder) {
|
||||
|
||||
trace("controlQuery projection = " + projection);
|
||||
|
||||
final String[] allFields = {
|
||||
Control.ENSURE_BOOKMARKS_MIGRATED,
|
||||
Control.ENSURE_HISTORY_MIGRATED
|
||||
};
|
||||
|
||||
// null projection must return all fields.
|
||||
if (projection == null) {
|
||||
projection = allFields;
|
||||
}
|
||||
|
||||
if (selection != null) {
|
||||
throw new UnsupportedOperationException("No selection in virtual CONTROL queries");
|
||||
}
|
||||
|
||||
File profileDir = GeckoProfile.get(mContext).getDir();
|
||||
|
||||
if (uri != null) {
|
||||
String profile = uri.getQueryParameter(BrowserContract.PARAM_PROFILE);
|
||||
if (!TextUtils.isEmpty(profile)) {
|
||||
profileDir = GeckoProfile.get(mContext, profile).getDir();
|
||||
}
|
||||
}
|
||||
|
||||
MatrixCursor cursor = new MatrixCursor(projection);
|
||||
MatrixCursor.RowBuilder row = cursor.newRow();
|
||||
synchronized (this) {
|
||||
boolean wantBookmarks = false;
|
||||
boolean wantHistory = false;
|
||||
|
||||
for (String key : projection) {
|
||||
if (key.equals(Control.ENSURE_BOOKMARKS_MIGRATED)) {
|
||||
wantBookmarks = true;
|
||||
} else if (key.equals(Control.ENSURE_HISTORY_MIGRATED)) {
|
||||
wantHistory = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (wantHistory || wantBookmarks) {
|
||||
ProfileMigrator migrator = new ProfileMigrator(mContext);
|
||||
|
||||
boolean needBookmarks = wantBookmarks && !migrator.areBookmarksMigrated();
|
||||
boolean needHistory = wantHistory && !migrator.isHistoryMigrated();
|
||||
|
||||
if (needBookmarks || needHistory) {
|
||||
migrator.launchPlaces(profileDir);
|
||||
|
||||
needBookmarks = wantBookmarks && !migrator.areBookmarksMigrated();
|
||||
needHistory = wantHistory && !migrator.isHistoryMigrated();
|
||||
// Bookmarks are expected to finish at the first run.
|
||||
if (needBookmarks) {
|
||||
Log.w(LOGTAG, "Bookmarks migration did not finish.");
|
||||
}
|
||||
}
|
||||
|
||||
// Now set the results.
|
||||
for (String key: projection) {
|
||||
if (key.equals(Control.ENSURE_BOOKMARKS_MIGRATED)) {
|
||||
row.add(needBookmarks ? 0 : 1);
|
||||
} else if (key.equals(Control.ENSURE_HISTORY_MIGRATED)) {
|
||||
row.add(needHistory ? 0 : 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return cursor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Cursor query(Uri uri, String[] projection, String selection,
|
||||
String[] selectionArgs, String sortOrder) {
|
||||
@ -2710,15 +2634,6 @@ public class BrowserProvider extends ContentProvider {
|
||||
break;
|
||||
}
|
||||
|
||||
case CONTROL: {
|
||||
debug("Query is on control: " + uri);
|
||||
|
||||
Cursor controlCursor =
|
||||
controlQuery(uri, projection, selection, selectionArgs, sortOrder);
|
||||
|
||||
return controlCursor;
|
||||
}
|
||||
|
||||
case SEARCH_SUGGEST: {
|
||||
debug("Query is on search suggest: " + uri);
|
||||
selection = DBUtils.concatenateWhere(selection, "(" + Combined.URL + " LIKE ? OR " +
|
||||
|
@ -1,131 +0,0 @@
|
||||
/* 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.background.common.log.Logger;
|
||||
import org.mozilla.gecko.db.BrowserContract.Control;
|
||||
import org.mozilla.gecko.sync.repositories.NoContentProviderException;
|
||||
|
||||
import android.content.ContentProviderClient;
|
||||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.net.Uri;
|
||||
|
||||
/**
|
||||
* This class provides an interface to Fenec's control content provider, which
|
||||
* exposes some of Fennec's internal state, particularly around migrations.
|
||||
*/
|
||||
public class FennecControlHelper {
|
||||
private static final String LOG_TAG = "FennecControlHelper";
|
||||
|
||||
protected ContentProviderClient providerClient;
|
||||
protected final RepoUtils.QueryHelper queryHelper;
|
||||
|
||||
public FennecControlHelper(Context context) throws NoContentProviderException {
|
||||
providerClient = acquireContentProvider(context);
|
||||
queryHelper = new RepoUtils.QueryHelper(context, Control.CONTENT_URI, LOG_TAG);
|
||||
}
|
||||
|
||||
/**
|
||||
* Acquire the content provider client.
|
||||
* <p>
|
||||
* The caller is responsible for releasing the client.
|
||||
*
|
||||
* @param context The application context.
|
||||
* @return The <code>ContentProviderClient</code>. Never null.
|
||||
* @throws NoContentProviderException
|
||||
*/
|
||||
public static ContentProviderClient acquireContentProvider(final Context context)
|
||||
throws NoContentProviderException {
|
||||
final Uri uri = Control.CONTENT_URI;
|
||||
final ContentProviderClient client = context.getContentResolver().acquireContentProviderClient(uri);
|
||||
if (client == null) {
|
||||
throw new NoContentProviderException(uri);
|
||||
}
|
||||
return client;
|
||||
}
|
||||
|
||||
/**
|
||||
* After invoking this method, this instance should be discarded.
|
||||
*/
|
||||
public void releaseProviders() {
|
||||
try {
|
||||
if (providerClient != null) {
|
||||
providerClient.release();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
}
|
||||
providerClient = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void finalize() throws Throwable {
|
||||
this.releaseProviders();
|
||||
super.finalize();
|
||||
}
|
||||
|
||||
private static String[] HISTORY_MIGRATION_COLUMNS = new String[] { Control.ENSURE_HISTORY_MIGRATED };
|
||||
private static String[] BOOKMARKS_MIGRATION_COLUMNS = new String[] { Control.ENSURE_BOOKMARKS_MIGRATED };
|
||||
|
||||
/**
|
||||
* Pass in a unit array. Returns true if the named column is
|
||||
* finished migrating; false otherwise.
|
||||
*
|
||||
* @param columns an array of a single string, which should be one of the
|
||||
* permitted control values.
|
||||
* @return true if the named column is finished migrating; false otherwise.
|
||||
*/
|
||||
protected boolean isColumnMigrated(final String[] columns) {
|
||||
try {
|
||||
final Cursor cursor = queryHelper.safeQuery(providerClient, ".isColumnMigrated(" + columns[0] + ")",
|
||||
columns, null, null, null);
|
||||
try {
|
||||
if (!cursor.moveToFirst()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// This is why we require a unit array.
|
||||
return cursor.getInt(0) > 0;
|
||||
} finally {
|
||||
cursor.close();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Logger.warn(LOG_TAG, "Caught exception checking if Fennec has migrated column " + columns[0] + ".", e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param context the context to use when querying.
|
||||
* @param columns an array of a single string, which should be one of the
|
||||
* permitted control values.
|
||||
* @return true if the named column is finished migrating; false otherwise.
|
||||
*/
|
||||
protected static boolean isColumnMigrated(Context context, String[] columns) {
|
||||
if (context == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
final FennecControlHelper control = new FennecControlHelper(context);
|
||||
try {
|
||||
return control.isColumnMigrated(columns);
|
||||
} finally {
|
||||
control.releaseProviders();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Logger.warn(LOG_TAG, "Caught exception checking if Fennec has migrated column " + columns[0] + ".", e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isHistoryMigrated(Context context) {
|
||||
return isColumnMigrated(context, HISTORY_MIGRATION_COLUMNS);
|
||||
}
|
||||
|
||||
public static boolean areBookmarksMigrated(Context context) {
|
||||
return isColumnMigrated(context, BOOKMARKS_MIGRATION_COLUMNS);
|
||||
}
|
||||
}
|
Binary file not shown.
@ -6,7 +6,6 @@
|
||||
[testBookmark]
|
||||
[testBookmarklets]
|
||||
[testJNI]
|
||||
[testMigration]
|
||||
[testLoad]
|
||||
[testNewTab]
|
||||
[testOrderedBroadcast]
|
||||
|
@ -47,9 +47,6 @@
|
||||
#[testLoad]
|
||||
# fails on gs2, nexus one, lg revolution, droid pro, nexus s
|
||||
|
||||
[testMigration]
|
||||
# fails on lg-revolution random android.database.sqlite.SQLiteDiskIOException
|
||||
|
||||
[testNewTab]
|
||||
# fails on nexus s random crash [@ libpvrANDROID_WSEGL.so + 0x73c]
|
||||
|
||||
|
@ -1,350 +0,0 @@
|
||||
#filter substitution
|
||||
package @ANDROID_PACKAGE_NAME@.tests;
|
||||
|
||||
import android.content.ContentResolver;
|
||||
import android.content.res.AssetManager;
|
||||
import android.database.Cursor;
|
||||
import android.content.Context;
|
||||
import android.net.Uri;
|
||||
import android.util.Log;
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipInputStream;
|
||||
|
||||
/**
|
||||
* Tests the profile migration. Unpacks an old database, moves
|
||||
* it to the profile, then call the BrowserProvider Control URI
|
||||
* to launch a migration and check the results.
|
||||
*/
|
||||
public class testMigration extends ContentProviderTest {
|
||||
// Big files are zipped to allow us to manually extract them,
|
||||
// the APK extractor will fail >1Mb.
|
||||
private static final String ASSET_SUFFIX = ".zip";
|
||||
private static final String DB_NAME = "places.sqlite";
|
||||
|
||||
@Override
|
||||
protected int getTestType() {
|
||||
return TEST_MOCHITEST;
|
||||
}
|
||||
|
||||
private File extractAsset(String dbName) {
|
||||
File oldDbLocation = null;
|
||||
boolean foundFile = false;
|
||||
String fullAssetName = dbName + ASSET_SUFFIX;
|
||||
|
||||
AssetManager assets = getAssetManager();
|
||||
try {
|
||||
String[] assetList = assets.list("");
|
||||
String assetString = "";
|
||||
for (String file: assetList) {
|
||||
assetString = assetString.concat(file);
|
||||
assetString = assetString.concat(" ");
|
||||
if (file.equals(fullAssetName)) {
|
||||
foundFile = true;
|
||||
}
|
||||
}
|
||||
mAsserter.is(foundFile, true, fullAssetName + " found in assets: " + assetString);
|
||||
} catch (IOException e) {
|
||||
String stackTrace = Log.getStackTraceString(e);
|
||||
mAsserter.is(false, true, "Error getting asset dir: " + stackTrace);
|
||||
}
|
||||
|
||||
// Extract the old places database from assets
|
||||
// and write it out in the profile directory
|
||||
try {
|
||||
InputStream profData = assets.open(fullAssetName);
|
||||
File profile = new File(mProfile);
|
||||
oldDbLocation = new File(profile, dbName);
|
||||
OutputStream out = new FileOutputStream(oldDbLocation);
|
||||
|
||||
ZipInputStream zis = new ZipInputStream(new BufferedInputStream(profData));
|
||||
try {
|
||||
ZipEntry ze;
|
||||
while ((ze = zis.getNextEntry()) != null) {
|
||||
byte[] buffer = new byte[1024];
|
||||
int count;
|
||||
while ((count = zis.read(buffer)) != -1) {
|
||||
out.write(buffer, 0, count);
|
||||
}
|
||||
String fileName = ze.getName();
|
||||
mAsserter.is(fileName, DB_NAME, "Filename match: " + fileName);
|
||||
}
|
||||
} finally {
|
||||
zis.close();
|
||||
}
|
||||
|
||||
profData.close();
|
||||
out.flush();
|
||||
out.close();
|
||||
} catch (IOException e) {
|
||||
String stackTrace = Log.getStackTraceString(e);
|
||||
mAsserter.is(false, true, "Error getting profile data: " + stackTrace);
|
||||
}
|
||||
|
||||
return oldDbLocation;
|
||||
}
|
||||
|
||||
public void testMigration() {
|
||||
Context context = (Context)getActivity();
|
||||
|
||||
File oldDbLocation = extractAsset(DB_NAME);
|
||||
mAsserter.is(oldDbLocation.exists(), true, "OK old file exists: "
|
||||
+ oldDbLocation.toString());
|
||||
|
||||
// Set up BrowserDB
|
||||
try {
|
||||
Class browserDBClass =
|
||||
mClassLoader.loadClass("org.mozilla.gecko.db.BrowserDB");
|
||||
Method initializeMethod =
|
||||
browserDBClass.getDeclaredMethod("initialize", String.class);
|
||||
initializeMethod.invoke(null, "default");
|
||||
} catch (Exception ex) {
|
||||
mAsserter.is(true, false, "Error setting up BrowserDB: "
|
||||
+ ex.getMessage());
|
||||
return;
|
||||
}
|
||||
|
||||
// Use reflection to look up the ProfileMigrator things we need
|
||||
// access to (constructor, launch), as well as BrowserContract.Control.
|
||||
Method launchPlacesTest;
|
||||
Constructor constructor;
|
||||
Class pmClass;
|
||||
|
||||
try {
|
||||
pmClass = mClassLoader.loadClass("org.mozilla.gecko.ProfileMigrator");
|
||||
launchPlacesTest = pmClass.getMethod("launchPlacesTest", File.class);
|
||||
constructor = pmClass.getConstructor(Context.class, ContentResolver.class);
|
||||
} catch(ClassNotFoundException ex) {
|
||||
mAsserter.is(false, true, "Error getting class: " + ex.getMessage());
|
||||
return;
|
||||
} catch (java.lang.NoSuchMethodException ex) {
|
||||
mAsserter.is(true, false, "Unable to find method: " + ex.getMessage());
|
||||
return;
|
||||
}
|
||||
|
||||
Object pm = null;
|
||||
try {
|
||||
// Construct ProfileMigrator object
|
||||
pm = constructor.newInstance(context, mResolver);
|
||||
} catch (Exception ex) {
|
||||
mAsserter.is(true, false, "Error instantiating ProfileMigrator instance: "
|
||||
+ ex.getMessage());
|
||||
return;
|
||||
}
|
||||
|
||||
// Reset history entries from previous tests
|
||||
clearHistory();
|
||||
|
||||
// Launch the Profile Migration
|
||||
try {
|
||||
launchPlacesTest.invoke(pm, new File(mProfile));
|
||||
} catch (Exception ex) {
|
||||
String stackTrace = Log.getStackTraceString(ex);
|
||||
mAsserter.is(true, false, "Unable to invoke launchPlacesTest:" + stackTrace);
|
||||
return;
|
||||
}
|
||||
|
||||
// Run the tests to see if that worked
|
||||
runTestViaContentProvider();
|
||||
runTestViaBrowserDB();
|
||||
|
||||
mAsserter.is(oldDbLocation.exists(), false, "OK old file gone now");
|
||||
}
|
||||
|
||||
private void clearHistory() {
|
||||
Method clearHistory = null;
|
||||
|
||||
try {
|
||||
Class browserDB =
|
||||
mClassLoader.loadClass("org.mozilla.gecko.db.BrowserDB");
|
||||
clearHistory =
|
||||
browserDB.getMethod("clearHistory", ContentResolver.class);
|
||||
} catch (java.lang.ClassNotFoundException ex) {
|
||||
mAsserter.is(true, false, "Unable to find class");
|
||||
return;
|
||||
} catch (java.lang.NoSuchMethodException ex) {
|
||||
mAsserter.is(true, false, "Unable to find method");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
clearHistory.invoke(null, mResolver);
|
||||
} catch (Exception ex) {
|
||||
String stackTrace = Log.getStackTraceString(ex);
|
||||
mAsserter.is(true, false, "Exception clearing history:" + stackTrace);
|
||||
}
|
||||
}
|
||||
|
||||
// stolen from testBookmarks
|
||||
private void runTestViaBrowserDB() {
|
||||
Method isBookmarked = null;
|
||||
Method getAllVisitedHistory = null;
|
||||
Constructor constructor = null;
|
||||
|
||||
try {
|
||||
Class localBrowserDB =
|
||||
mClassLoader.loadClass("org.mozilla.gecko.db.LocalBrowserDB");
|
||||
isBookmarked =
|
||||
localBrowserDB.getMethod("isBookmark", ContentResolver.class, String.class);
|
||||
getAllVisitedHistory =
|
||||
localBrowserDB.getMethod("getAllVisitedHistory", ContentResolver.class);
|
||||
constructor = localBrowserDB.getConstructor(String.class);
|
||||
} catch (java.lang.ClassNotFoundException ex) {
|
||||
mAsserter.is(true, false, "Unable to find class");
|
||||
return;
|
||||
} catch (java.lang.NoSuchMethodException ex) {
|
||||
mAsserter.is(true, false, "Unable to find method:" + ex.getMessage());
|
||||
return;
|
||||
}
|
||||
|
||||
Object db = null;
|
||||
try {
|
||||
String defaultProfile = "default";
|
||||
db = constructor.newInstance(defaultProfile);
|
||||
} catch (Exception ex) {
|
||||
mAsserter.is(true, false, "Error instantiating LocalBrowserDB instance: "
|
||||
+ ex.getMessage());
|
||||
return;
|
||||
}
|
||||
|
||||
final String[] knownBookmarks = new String[] {
|
||||
"http://www.androidpolice.com/",
|
||||
"https://developer.mozilla.org/En/Mozilla_Coding_Style_Guide",
|
||||
"http://planet.mozilla.org/",
|
||||
"http://www.crockford.com/",
|
||||
"https://wiki.mozilla.org/Mobile/Fennec/Android"
|
||||
};
|
||||
|
||||
for (String url: knownBookmarks) {
|
||||
try {
|
||||
// Check for some bookmarks we know must exist
|
||||
boolean isbookmark =
|
||||
(Boolean)isBookmarked.invoke(db,
|
||||
mResolver,
|
||||
url);
|
||||
mAsserter.is(isbookmark, true, "Expected page is bookmarked: " + url);
|
||||
} catch (Exception ex) {
|
||||
mAsserter.is(true, false, "Exception checking bookmark existence");
|
||||
ex.printStackTrace();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Check the amount of history, this should match the following on the
|
||||
// database in assets:
|
||||
// SELECT COUNT(DISTINCT(url)) FROM moz_historyvisits
|
||||
// JOIN moz_places ON moz_historyvisits.place_id = moz_places.id
|
||||
final int PLACES_KNOWN_HISTORY_URLS = 184;
|
||||
try {
|
||||
Cursor cursor =
|
||||
(Cursor)getAllVisitedHistory.invoke(db,
|
||||
mResolver);
|
||||
int historyCount = cursor.getCount();
|
||||
cursor.close();
|
||||
mAsserter.is(historyCount, PLACES_KNOWN_HISTORY_URLS,
|
||||
"History count " + historyCount +
|
||||
", expected was " + PLACES_KNOWN_HISTORY_URLS);
|
||||
} catch (Exception ex) {
|
||||
mAsserter.is(true, false, "Exception checking history count");
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private void runTestViaContentProvider() {
|
||||
String ensureHistory;
|
||||
String ensureBookmarks;
|
||||
String urlField;
|
||||
String visitsField;
|
||||
|
||||
Uri controlUri;
|
||||
Uri historyUri;
|
||||
|
||||
try {
|
||||
Class browserContract =
|
||||
mClassLoader.loadClass("org.mozilla.gecko.db.BrowserContract");
|
||||
Class browserContractControl =
|
||||
mClassLoader.loadClass("org.mozilla.gecko.db.BrowserContract$Control");
|
||||
Class browserContractHistory =
|
||||
mClassLoader.loadClass("org.mozilla.gecko.db.BrowserContract$History");
|
||||
Class browserContractUrl =
|
||||
mClassLoader.loadClass("org.mozilla.gecko.db.BrowserContract$URLColumns");
|
||||
Class browserContractHistoryColumns =
|
||||
mClassLoader.loadClass("org.mozilla.gecko.db.BrowserContract$HistoryColumns");
|
||||
|
||||
controlUri = (Uri)browserContractControl.getField("CONTENT_URI").get(null);
|
||||
historyUri = (Uri)browserContractHistory.getField("CONTENT_URI").get(null);
|
||||
urlField = (String)browserContractUrl.getField("URL").get(null);
|
||||
visitsField = (String)browserContractHistoryColumns.getField("VISITS").get(null);
|
||||
String profilePath = (String)browserContract.getField("PARAM_PROFILE_PATH").get(null);
|
||||
Uri.Builder builder = controlUri.buildUpon();
|
||||
controlUri = builder.build();
|
||||
ensureHistory =
|
||||
(String)browserContractControl.getField("ENSURE_HISTORY_MIGRATED").get(null);
|
||||
ensureBookmarks =
|
||||
(String)browserContractControl.getField("ENSURE_BOOKMARKS_MIGRATED").get(null);
|
||||
} catch (Exception ex) {
|
||||
mAsserter.is(true, false, "Reflection error getting BrowserContract classes and Uri's");
|
||||
ex.printStackTrace();
|
||||
return;
|
||||
}
|
||||
|
||||
Cursor c = mResolver.query(controlUri,
|
||||
new String[] { ensureHistory,
|
||||
ensureBookmarks },
|
||||
null,
|
||||
null,
|
||||
null);
|
||||
|
||||
int historyMigrated = 0;
|
||||
int bookmarksMigrated = 0;
|
||||
|
||||
if (c.moveToFirst()) {
|
||||
historyMigrated = c.getInt(0);
|
||||
bookmarksMigrated = c.getInt(1);
|
||||
}
|
||||
c.close();
|
||||
|
||||
mAsserter.is(historyMigrated, 1, "History migrated");
|
||||
mAsserter.is(bookmarksMigrated, 1, "Bookmarks migrated");
|
||||
|
||||
// Check whether visit counts are as expected. The test profile
|
||||
// has visited reddit 4 times so we expect to find that in our
|
||||
// own database too now.
|
||||
c = mResolver.query(historyUri,
|
||||
new String[] { visitsField },
|
||||
urlField + " = ?",
|
||||
new String[] { "http://www.reddit.com/" },
|
||||
null);
|
||||
mAsserter.is(c.moveToFirst(), true, "Expected URL found");
|
||||
int visits = c.getInt(0);
|
||||
c.close();
|
||||
|
||||
mAsserter.is(visits, 4, "Visit count of " + visits + " equals expected 4");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setUp() throws Exception {
|
||||
super.setUp("org.mozilla.gecko.db.BrowserProvider", "AUTHORITY");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tearDown() throws Exception {
|
||||
// remove the database file
|
||||
File profile = new File(mProfile);
|
||||
File db = new File(profile, DB_NAME);
|
||||
if (db.delete()) {
|
||||
mAsserter.dumpLog("tearDown deleted "+db.toString());
|
||||
} else {
|
||||
mAsserter.dumpLog("tearDown did not delete "+db.toString());
|
||||
}
|
||||
|
||||
super.tearDown();
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user