From 44ca0515583bfca796df3c5d15fcb1c4436dd465 Mon Sep 17 00:00:00 2001 From: Luis Javier Rodriguez Restrepo Date: Tue, 9 Apr 2019 22:28:29 -0400 Subject: [PATCH] Android version --- src/android/MigrateStorage.java | 106 +++++++++++++++++--------------- 1 file changed, 56 insertions(+), 50 deletions(-) diff --git a/src/android/MigrateStorage.java b/src/android/MigrateStorage.java index 46d8ee9..ed32f68 100644 --- a/src/android/MigrateStorage.java +++ b/src/android/MigrateStorage.java @@ -1,5 +1,7 @@ package com.migrate.android; +import android.app.Activity; +import android.os.Build; import android.content.Context; import android.database.sqlite.SQLiteDatabase; import android.util.Log; @@ -18,9 +20,9 @@ /** * Main class that is instantiated by cordova * Acts as a "bridge" between the SDK and the cordova layer - * + * * This plugin migrates WebSQL and localStorage from the old webview to the new webview - * + * * TODO * - Test if we can we remove old file:// keys? * - Properly handle exceptions? We have a catch-all at the moment that is dealt with in the `initialize` function @@ -33,11 +35,40 @@ public class MigrateStorage extends CordovaPlugin { private static final String TAG = "com.migrate.android"; private static final String FILE_PROTOCOL = "file://"; private static final String WEBSQL_FILE_DIR_NAME = "file__0"; - private static final String DEFAULT_PORT_NUMBER = "8080"; + private static final String DEFAULT_PORT_NUMBER = "0"; private static final String CDV_SETTING_PORT_NUMBER = "WKPort"; + // Root dir for system webview data used by Android 4.4+ + private static String modernWebviewDir = "/app_webview"; + + // Root dir for system webview data used by Android 4.3 and below + private static String oldWebviewDir = "/app_database"; + + // Directory name for local storage files used by Android 4.4+ and XWalk + private static String modernLocalStorageDir = "/Local Storage"; + + // Directory name for local storage files used by Android 4.3 and below + private static String oldLocalStorageDir = "/localstorage"; + private String portNumber; + private boolean isModernAndroid; + private Activity activity; + + private String getWebviewPath(){ + if(isModernAndroid){ + return modernWebviewDir; + }else{ + return oldWebviewDir; + } + } + private String getWebviewLocalStoragePath(){ + if(isModernAndroid){ + return modernLocalStorageDir; + }else{ + return oldLocalStorageDir; + } + } private void logDebug(String message) { if(DEBUG_MODE) Log.d(TAG, message); @@ -57,11 +88,11 @@ private String getRootPath() { } private String getWebViewRootPath() { - return this.getRootPath() + "/app_webview"; + return this.getRootPath() + this.getWebviewPath(); } private String getLocalStorageRootPath() { - return this.getWebViewRootPath() + "/Local Storage"; + return this.getWebViewRootPath() + this.getWebviewLocalStoragePath(); } private String getWebSQLDatabasesPath() { @@ -82,55 +113,28 @@ private String getWebSQLReferenceDbPath() { private void migrateLocalStorage() throws Exception { this.logDebug("migrateLocalStorage: Migrating localStorage.."); - String levelDbPath = this.getLocalStorageRootPath() + "/leveldb"; - this.logDebug("migrateLocalStorage: levelDbPath: " + levelDbPath); - - File levelDbDir = new File(levelDbPath); - if(!levelDbDir.isDirectory() || !levelDbDir.exists()) { - this.logDebug("migrateLocalStorage: '" + levelDbPath + "' is not a directory or was not found; Exiting"); - return; - } + boolean hasMigratedData = false; - LevelDB db = new LevelDB(levelDbPath); + File fileLocalStorage = new File(this.getLocalStorageRootPath() + "/" + WEBSQL_FILE_DIR_NAME + ".localstorage"); + File fileLocalStorageJournal = new File(this.getLocalStorageRootPath() + "/" + WEBSQL_FILE_DIR_NAME + ".localstorage-journal"); - String localHostProtocol = this.getLocalHostProtocol(); + File ionicLocalStorage = new File(this.getLocalStorageRootPath() + "/" + this.getLocalHostProtocolDirName() + ".localstorage"); + File ionicLocalStorageJournal = new File(this.getLocalStorageRootPath() + "/" + this.getLocalHostProtocolDirName() + ".localstorage-journal"); - if(db.exists(Utils.stringToBytes("META:" + localHostProtocol))) { - this.logDebug("migrateLocalStorage: Found 'META:" + localHostProtocol + "' key; Skipping migration"); - db.close(); - return; + if (fileLocalStorage.exists()) { + fileLocalStorage.renameTo(ionicLocalStorage); + hasMigratedData = true; } - // Yes, there is a typo here; `newInterator` 😔 - LevelIterator iterator = db.newInterator(); - - // To update in bulk! - WriteBatch batch = new WriteBatch(); - - - // 🔃 Loop through the keys and replace `file://` with `http://localhost:{portNumber}` - logDebug("migrateLocalStorage: Starting replacements;"); - for(iterator.seekToFirst(); iterator.isValid(); iterator.next()) { - String key = Utils.bytesToString(iterator.key()); - byte[] value = iterator.value(); - - if (key.contains(FILE_PROTOCOL)) { - String newKey = key.replace(FILE_PROTOCOL, localHostProtocol); - - logDebug("migrateLocalStorage: Changing key:" + key + " to '" + newKey + "'"); - - // Add new key to db - batch.putBytes(Utils.stringToBytes(newKey), value); - } else { - logDebug("migrateLocalStorage: Skipping key:" + key); - } + if (fileLocalStorageJournal.exists()) { + fileLocalStorageJournal.renameTo(ionicLocalStorageJournal); + hasMigratedData = true; } - // Commit batch to DB - db.write(batch); - - iterator.close(); - db.close(); + if(hasMigratedData){ + Log.d(TAG, "restarting Cordova activity"); + activity.recreate(); + } this.logDebug("migrateLocalStorage: Successfully migrated localStorage.."); } @@ -171,7 +175,7 @@ private void migrateWebSQL() { // Update reference DB to point to `localhost:{portNumber}` db.execSQL("UPDATE Databases SET origin = ? WHERE origin = ?", new String[] { localHostDirName, WEBSQL_FILE_DIR_NAME }); - + // rename `databases/file__0` dir to `databases/localhost_http_{portNumber}` boolean renamed = originalWebSQLDir.renameTo(targetWebSQLDir); @@ -179,7 +183,7 @@ private void migrateWebSQL() { logDebug("migrateWebSQL: Tried renaming '" + originalWebSQLDir.getAbsolutePath() + "' to '" + targetWebSQLDir.getAbsolutePath() + "' but failed; Exiting..."); return; } - + db.close(); this.logDebug("migrateWebSQL: Successfully migrated WebSQL.."); @@ -196,13 +200,15 @@ public void initialize(CordovaInterface cordova, CordovaWebView webView) { try { super.initialize(cordova, webView); + activity = cordova.getActivity(); + this.isModernAndroid = Build.VERSION.SDK_INT >= 19; this.portNumber = this.preferences.getString(CDV_SETTING_PORT_NUMBER, ""); if(this.portNumber.isEmpty() || this.portNumber == null) this.portNumber = DEFAULT_PORT_NUMBER; logDebug("Starting migration;"); this.migrateLocalStorage(); - this.migrateWebSQL(); + // this.migrateWebSQL(); logDebug("Migration completed;"); } catch (Exception ex) {