From b17a40c215ecd5571205d55b57f1987a8878dcd2 Mon Sep 17 00:00:00 2001 From: Dimitri Rusin Date: Thu, 5 Jul 2018 00:14:40 +0200 Subject: [PATCH 01/28] now default repos from /oem are loaded every time ./databases cannot be found --- .../java/org/fdroid/fdroid/data/DBHelper.java | 72 +++++++++++++++++++ 1 file changed, 72 insertions(+) diff --git a/app/src/main/java/org/fdroid/fdroid/data/DBHelper.java b/app/src/main/java/org/fdroid/fdroid/data/DBHelper.java index 7d7f74158..5a3f2573f 100644 --- a/app/src/main/java/org/fdroid/fdroid/data/DBHelper.java +++ b/app/src/main/java/org/fdroid/fdroid/data/DBHelper.java @@ -46,6 +46,12 @@ import org.fdroid.fdroid.data.Schema.RepoTable; import java.util.ArrayList; import java.util.List; +import java.io.IOException; +import java.io.BufferedReader; +import java.io.FileReader; +import org.json.*; + + /** * This is basically a singleton used to represent the database at the core * of all of the {@link android.content.ContentProvider}s used at the core @@ -56,6 +62,7 @@ import java.util.List; public class DBHelper extends SQLiteOpenHelper { private static final String TAG = "DBHelper"; + private static final String EXTERNAL_REPO_PATH = "/oem/fdroid/default_repos.json"; public static final int REPO_XML_ARG_COUNT = 8; @@ -276,8 +283,73 @@ public class DBHelper extends SQLiteOpenHelper { defaultRepos[offset + 7] // pubkey ); } + + // Load a couple default repos from /oem in json format + loadExternalRepos(db); } + + private String readFile(String file) throws IOException { + BufferedReader reader = new BufferedReader(new FileReader (file)); + String line = null; + StringBuilder stringBuilder = new StringBuilder(); + String ls = System.getProperty("line.separator"); + + try { + while((line = reader.readLine()) != null) { + stringBuilder.append(line); + stringBuilder.append(ls); + } + return stringBuilder.toString(); + } finally { + reader.close(); + } + } + + private void loadExternalRepos(SQLiteDatabase db) { + Utils.debugLog(TAG, "Loading external repos: Opening " + EXTERNAL_REPO_PATH); + + JSONObject repos_json; + try { + String json_contents = readFile(EXTERNAL_REPO_PATH); + repos_json = new JSONObject(json_contents); + } catch (Exception e) { + Utils.debugLog(TAG, "Error loading " + EXTERNAL_REPO_PATH); + return; + } + Utils.debugLog(TAG, EXTERNAL_REPO_PATH + " successfully opened."); + + JSONArray repos; + try { + repos = repos_json.getJSONArray("default_repos"); + } catch (JSONException e) { + Utils.debugLog(TAG, "Default repos json file has wrong root, should be 'default_repos'"); + return; + } + Utils.debugLog(TAG, "Root 'default_repos' found."); + + try { + for (int i = 0; i < repos.length(); i++) { + insertRepo( + db, + repos.getJSONObject(i).getString("name"), + repos.getJSONObject(i).getString("address"), + repos.getJSONObject(i).getString("description"), + repos.getJSONObject(i).getString("version"), + repos.getJSONObject(i).getString("enabled"), + repos.getJSONObject(i).getString("priority"), + repos.getJSONObject(i).getString("pushRequests"), + repos.getJSONObject(i).getString("pubkey") + ); + } + } catch (JSONException e) { + Utils.debugLog(TAG, "Error loading at least one external json repository from " + EXTERNAL_REPO_PATH); + return; + } + Utils.debugLog(TAG, "All external repositories successfully added!"); + } + + @Override public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) { resetTransient(context); From b150a01706788031735ebd9e08df1bf5d3ebd92c Mon Sep 17 00:00:00 2001 From: Dimitri Rusin Date: Thu, 5 Jul 2018 15:48:47 +0000 Subject: [PATCH 02/28] improved syntax --- .../java/org/fdroid/fdroid/data/DBHelper.java | 64 ++++++++----------- 1 file changed, 28 insertions(+), 36 deletions(-) diff --git a/app/src/main/java/org/fdroid/fdroid/data/DBHelper.java b/app/src/main/java/org/fdroid/fdroid/data/DBHelper.java index 5a3f2573f..c51da328e 100644 --- a/app/src/main/java/org/fdroid/fdroid/data/DBHelper.java +++ b/app/src/main/java/org/fdroid/fdroid/data/DBHelper.java @@ -62,7 +62,7 @@ import org.json.*; public class DBHelper extends SQLiteOpenHelper { private static final String TAG = "DBHelper"; - private static final String EXTERNAL_REPO_PATH = "/oem/fdroid/default_repos.json"; + private static final String OEM_DEFAULT_REPOS_PATH = "/oem/fdroid/default_repos.json"; public static final int REPO_XML_ARG_COUNT = 8; @@ -285,71 +285,63 @@ public class DBHelper extends SQLiteOpenHelper { } // Load a couple default repos from /oem in json format - loadExternalRepos(db); + loadOemDefaultRepos(db); } - private String readFile(String file) throws IOException { - BufferedReader reader = new BufferedReader(new FileReader (file)); - String line = null; - StringBuilder stringBuilder = new StringBuilder(); - String ls = System.getProperty("line.separator"); + BufferedReader reader = new BufferedReader(new FileReader(file)); + StringBuilder stringBuilder = new StringBuilder(); try { + String ls = System.getProperty("line.separator"); + String line = null; while((line = reader.readLine()) != null) { stringBuilder.append(line); stringBuilder.append(ls); } - return stringBuilder.toString(); } finally { reader.close(); } + + return stringBuilder.toString(); } - private void loadExternalRepos(SQLiteDatabase db) { - Utils.debugLog(TAG, "Loading external repos: Opening " + EXTERNAL_REPO_PATH); + private void loadOemDefaultRepos(SQLiteDatabase db) { + Utils.debugLog(TAG, "Loading external repos: Opening " + OEM_DEFAULT_REPOS_PATH); - JSONObject repos_json; + JSONArray reposArray; try { - String json_contents = readFile(EXTERNAL_REPO_PATH); - repos_json = new JSONObject(json_contents); + String jsonContents = readFile(OEM_DEFAULT_REPOS_PATH); + reposArray = new JSONArray(jsonContents); } catch (Exception e) { - Utils.debugLog(TAG, "Error loading " + EXTERNAL_REPO_PATH); + Utils.debugLog(TAG, "Error loading " + OEM_DEFAULT_REPOS_PATH); + Utils.debugLog(TAG, "Exception: " + e.getMessage()); return; } - Utils.debugLog(TAG, EXTERNAL_REPO_PATH + " successfully opened."); - - JSONArray repos; - try { - repos = repos_json.getJSONArray("default_repos"); - } catch (JSONException e) { - Utils.debugLog(TAG, "Default repos json file has wrong root, should be 'default_repos'"); - return; - } - Utils.debugLog(TAG, "Root 'default_repos' found."); + Utils.debugLog(TAG, OEM_DEFAULT_REPOS_PATH + " successfully opened."); try { - for (int i = 0; i < repos.length(); i++) { + for (int i = 0; i < reposArray.length(); i++) { insertRepo( db, - repos.getJSONObject(i).getString("name"), - repos.getJSONObject(i).getString("address"), - repos.getJSONObject(i).getString("description"), - repos.getJSONObject(i).getString("version"), - repos.getJSONObject(i).getString("enabled"), - repos.getJSONObject(i).getString("priority"), - repos.getJSONObject(i).getString("pushRequests"), - repos.getJSONObject(i).getString("pubkey") + reposArray.getJSONObject(i).getString("name"), + reposArray.getJSONObject(i).getString("address"), + reposArray.getJSONObject(i).getString("description"), + reposArray.getJSONObject(i).getString("version"), + reposArray.getJSONObject(i).getString("enabled"), + reposArray.getJSONObject(i).getString("priority"), + reposArray.getJSONObject(i).getString("pushRequests"), + reposArray.getJSONObject(i).getString("pubkey") ); } - } catch (JSONException e) { - Utils.debugLog(TAG, "Error loading at least one external json repository from " + EXTERNAL_REPO_PATH); + } catch (Exception e) { + Utils.debugLog(TAG, "Error loading at least one external json repository from " + OEM_DEFAULT_REPOS_PATH); + Utils.debugLog(TAG, "Exception: " + e.getMessage()); return; } Utils.debugLog(TAG, "All external repositories successfully added!"); } - @Override public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) { resetTransient(context); From adc1c80b7768e27bfca9562239faf90c023b16e8 Mon Sep 17 00:00:00 2001 From: Dimitri Rusin Date: Thu, 5 Jul 2018 16:39:18 +0000 Subject: [PATCH 03/28] more syntax improvements --- .../java/org/fdroid/fdroid/data/DBHelper.java | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/app/src/main/java/org/fdroid/fdroid/data/DBHelper.java b/app/src/main/java/org/fdroid/fdroid/data/DBHelper.java index c51da328e..69ab41840 100644 --- a/app/src/main/java/org/fdroid/fdroid/data/DBHelper.java +++ b/app/src/main/java/org/fdroid/fdroid/data/DBHelper.java @@ -51,7 +51,6 @@ import java.io.BufferedReader; import java.io.FileReader; import org.json.*; - /** * This is basically a singleton used to represent the database at the core * of all of the {@link android.content.ContentProvider}s used at the core @@ -322,16 +321,17 @@ public class DBHelper extends SQLiteOpenHelper { try { for (int i = 0; i < reposArray.length(); i++) { + JSONObject repo = reposArray.getJSONObject(i); insertRepo( db, - reposArray.getJSONObject(i).getString("name"), - reposArray.getJSONObject(i).getString("address"), - reposArray.getJSONObject(i).getString("description"), - reposArray.getJSONObject(i).getString("version"), - reposArray.getJSONObject(i).getString("enabled"), - reposArray.getJSONObject(i).getString("priority"), - reposArray.getJSONObject(i).getString("pushRequests"), - reposArray.getJSONObject(i).getString("pubkey") + repo.getString("name"), + repo.getString("address"), + repo.getString("description"), + repo.getString("version"), + repo.getString("enabled"), + repo.getString("priority"), + repo.getString("pushRequests"), + repo.getString("pubkey") ); } } catch (Exception e) { From 03507804b65bc6265a7467e5716e432836a40258 Mon Sep 17 00:00:00 2001 From: Dimitri Rusin Date: Wed, 11 Jul 2018 20:55:44 +0000 Subject: [PATCH 04/28] started implementing xml approach with priority checking --- .../java/org/fdroid/fdroid/data/DBHelper.java | 131 +++++++++++++++--- 1 file changed, 113 insertions(+), 18 deletions(-) diff --git a/app/src/main/java/org/fdroid/fdroid/data/DBHelper.java b/app/src/main/java/org/fdroid/fdroid/data/DBHelper.java index 69ab41840..6828ab957 100644 --- a/app/src/main/java/org/fdroid/fdroid/data/DBHelper.java +++ b/app/src/main/java/org/fdroid/fdroid/data/DBHelper.java @@ -61,8 +61,7 @@ import org.json.*; public class DBHelper extends SQLiteOpenHelper { private static final String TAG = "DBHelper"; - private static final String OEM_DEFAULT_REPOS_PATH = "/oem/fdroid/default_repos.json"; - + public static final int REPO_XML_ARG_COUNT = 8; private static DBHelper instance; @@ -250,7 +249,6 @@ public class DBHelper extends SQLiteOpenHelper { @Override public void onCreate(SQLiteDatabase db) { - db.execSQL(CREATE_TABLE_PACKAGE); db.execSQL(CREATE_TABLE_APP_METADATA); db.execSQL(CREATE_TABLE_APK); @@ -263,30 +261,126 @@ public class DBHelper extends SQLiteOpenHelper { db.execSQL(CREATE_TABLE_APK_ANTI_FEATURE_JOIN); ensureIndexes(db); - String[] defaultRepos = context.getResources().getStringArray(R.array.default_repos); - if (defaultRepos.length % REPO_XML_ARG_COUNT != 0) { + Log.debugLog(TAG, "TEST PACKAGE NAME: " + context.getPackage()); + + // Always, load the internal defaults afterwards. This way, F-Droid native repos can never be deleted + List default_repos = loadDefaultReposInternal(); + + // Insert all the repos into the database + if (defaultRepos.size() % REPO_XML_ARG_COUNT != 0) { throw new IllegalArgumentException( "default_repo.xml array does not have the right number of elements"); } - for (int i = 0; i < defaultRepos.length / REPO_XML_ARG_COUNT; i++) { - int offset = i * REPO_XML_ARG_COUNT; + + // Load a couple external default repos from one of { "/oem", "/odm", "/vendor", "/system" } + int minPriority = (default_repos.size() / REPO_XML_ARG_COUNT) + 1; + default_repos.addAll(loadDefaultReposExternal(minPriority)); + + for (int i = 0; i < defaultRepos.size; i += REPO_XML_ARG_COUNT) { insertRepo( db, - defaultRepos[offset], // name - defaultRepos[offset + 1], // address - defaultRepos[offset + 2], // description - defaultRepos[offset + 3], // version - defaultRepos[offset + 4], // enabled - defaultRepos[offset + 5], // priority - defaultRepos[offset + 6], // pushRequests - defaultRepos[offset + 7] // pubkey + defaultRepos[i], // name + defaultRepos[i + 1], // address + defaultRepos[i + 2], // description + defaultRepos[i + 3], // version + defaultRepos[i + 4], // enabled + defaultRepos[i + 5], // priority + defaultRepos[i + 6], // pushRequests + defaultRepos[i + 7] // pubkey ); } - - // Load a couple default repos from /oem in json format - loadOemDefaultRepos(db); } + private void loadDefaultReposInternal() { + return new LinkedList(context.getResources().getStringArray(R.array.default_repos)); + } + + /* + * Look for external repositories under { "/oem", "/odm", "/vendor", "/system" } in this order and only load the first one. + * If ROOT is one of those paths and 'packageName' is the name of the package + * that contains this class, then we look under ROOT/etc/'packageName'/default_repos.xml + */ + private loadDefaultReposExternal(int minPriority) { + final String packageName = context.getPackage(); + for (String root : { "/oem", "/odm", "/vendor", "/system" }) { + String defaultReposPath = root + "/etc/" + packageName + "/default_repos.xml"; + try { + File defaultReposFile = new File(defaultReposPath); + // Only try loading external repos once. Even if this one fails, we will not try the other roots + if (defaultReposFile.exists() && defaultReposFile.isFile()) { + return parseXmlRepos(defaultReposFile, minPriority); + } + } catch (Exception e) { + Utils.debugLog(TAG, "Error loading " + defaultReposPath); + Utils.debugLog(TAG, "Exception: " + e.getMessage()); + return; + } + } + } + + private List parseXmlRepos(File defaultReposFile, int minPriority) { + List default_repos = LinkedList<>(); + try { + InputStream xmlInputStream = new FileInputStream(defaultReposFile); + XmlPullParserFactoryfactory = XmlPullParserFactory.newInstance(); + factory.setNamespaceAware(true); + XmlPullParser parser = factory.newPullParser(); + parser.setInput(is, "UTF-8"); + + // Type of piece of xml file, can be END_DOCUMENT, TEXT, END_TAG, START_TAG, ... We only care about TEXT. + int eventType = parser.getEventType(); + + static final int PRIORITY_INDEX = 5; + int indexItem = 0; + /* Walk through all TEXT pieces of the xml file and put them into our list of default repos. + * This could be improved by structuring the content for example into a list of lists where each contained list represents a repository, but + * we do it the traditional way. + */ + while (eventType != XmlPullParser.END_DOCUMENT) { + String tagname = parser.getName(); + switch (eventType) { + /* + * This checks whether the current repository does not violate the priority constraint: Its priority is higher or equal to minPrioriry. + * minPriority is at least the number of internal repos plus one. This way, the external repos can never be shown before the internal ones in the UI. + * + * Very ugly though. We count the number of items read in the xml file, because the items are not named but just rowed one after another. + * We also skip one event here, namely the text event after the START_TAG event. + */ + case XmlPullParser.START_TAG: + if (indexItem == PRIORITY_INDEX) { + parser.next(); + int priority = Integer.parseInt(parser.getText()); + // If some repository violates the priority constraint, immediately dismiss this whole external set of repos + if (priority > minPriority) { + return new LinkedList<>(); + } + } + indexItem++; + if (indexItem > 7) { indexItem -= 7; } + break; + case XmlPullParser.TEXT: + default_repos.add(parser.getText()); // This is a piece of real information in the xml file + break; + } + eventType = parser.next(); + } + + } catch (XmlPullParserException e) { + Utils.debugLog(TAG, "Error loading " + defaultReposFile.getAbsolutePath()); + Utils.debugLog(TAG, "Exception: " + e.getMessage()); + return; + } catch (IOException e) { + Utils.debugLog(TAG, "Error loading " + defaultReposFile.getAbsolutePath()); + Utils.debugLog(TAG, "Exception: " + e.getMessage()); + return; + } + return default_repos; + } + + /* + * The following two functions might be useful in the future to add repositories in json format as proposed in + * https://gitlab.com/fdroid/fdroidclient/merge_requests/705 + * private String readFile(String file) throws IOException { BufferedReader reader = new BufferedReader(new FileReader(file)); StringBuilder stringBuilder = new StringBuilder(); @@ -341,6 +435,7 @@ public class DBHelper extends SQLiteOpenHelper { } Utils.debugLog(TAG, "All external repositories successfully added!"); } + */ @Override public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) { From 51135e568436de80c4b2aaeeceafc3de3b367ae9 Mon Sep 17 00:00:00 2001 From: Dimitri Rusin Date: Thu, 12 Jul 2018 20:03:31 +0000 Subject: [PATCH 05/28] replaced json with xml --- .../java/org/fdroid/fdroid/data/DBHelper.java | 204 ++++++------------ 1 file changed, 61 insertions(+), 143 deletions(-) diff --git a/app/src/main/java/org/fdroid/fdroid/data/DBHelper.java b/app/src/main/java/org/fdroid/fdroid/data/DBHelper.java index 6828ab957..405efedec 100644 --- a/app/src/main/java/org/fdroid/fdroid/data/DBHelper.java +++ b/app/src/main/java/org/fdroid/fdroid/data/DBHelper.java @@ -43,13 +43,9 @@ import org.fdroid.fdroid.data.Schema.InstalledAppTable; import org.fdroid.fdroid.data.Schema.PackageTable; import org.fdroid.fdroid.data.Schema.RepoTable; -import java.util.ArrayList; -import java.util.List; - -import java.io.IOException; -import java.io.BufferedReader; -import java.io.FileReader; -import org.json.*; +import java.util.*; +import java.io.*; +import org.xmlpull.v1.*; /** * This is basically a singleton used to represent the database at the core @@ -261,10 +257,8 @@ public class DBHelper extends SQLiteOpenHelper { db.execSQL(CREATE_TABLE_APK_ANTI_FEATURE_JOIN); ensureIndexes(db); - Log.debugLog(TAG, "TEST PACKAGE NAME: " + context.getPackage()); - // Always, load the internal defaults afterwards. This way, F-Droid native repos can never be deleted - List default_repos = loadDefaultReposInternal(); + List defaultRepos = loadDefaultReposInternal(); // Insert all the repos into the database if (defaultRepos.size() % REPO_XML_ARG_COUNT != 0) { @@ -273,170 +267,94 @@ public class DBHelper extends SQLiteOpenHelper { } // Load a couple external default repos from one of { "/oem", "/odm", "/vendor", "/system" } - int minPriority = (default_repos.size() / REPO_XML_ARG_COUNT) + 1; - default_repos.addAll(loadDefaultReposExternal(minPriority)); + defaultRepos.addAll(loadDefaultReposExternal()); - for (int i = 0; i < defaultRepos.size; i += REPO_XML_ARG_COUNT) { + Utils.debugLog(TAG, "defaultRepos.size(): " + defaultRepos.size()); + for (int i = 0; i < defaultRepos.size(); i += REPO_XML_ARG_COUNT) { insertRepo( db, - defaultRepos[i], // name - defaultRepos[i + 1], // address - defaultRepos[i + 2], // description - defaultRepos[i + 3], // version - defaultRepos[i + 4], // enabled - defaultRepos[i + 5], // priority - defaultRepos[i + 6], // pushRequests - defaultRepos[i + 7] // pubkey + defaultRepos.get(i), // name + defaultRepos.get(i + 1), // address + defaultRepos.get(i + 2), // description + defaultRepos.get(i + 3), // version + defaultRepos.get(i + 4), // enabled + defaultRepos.get(i + 5), // priority + defaultRepos.get(i + 6), // pushRequests + defaultRepos.get(i + 7) // pubkey ); } } - private void loadDefaultReposInternal() { - return new LinkedList(context.getResources().getStringArray(R.array.default_repos)); + private List loadDefaultReposInternal() { + return new LinkedList<>(Arrays.asList(context.getResources().getStringArray(R.array.default_repos))); } /* * Look for external repositories under { "/oem", "/odm", "/vendor", "/system" } in this order and only load the first one. * If ROOT is one of those paths and 'packageName' is the name of the package - * that contains this class, then we look under ROOT/etc/'packageName'/default_repos.xml + * that contains this class, then we look under 'root'/etc/'packageName'/default_repos.xml */ - private loadDefaultReposExternal(int minPriority) { - final String packageName = context.getPackage(); - for (String root : { "/oem", "/odm", "/vendor", "/system" }) { + private List loadDefaultReposExternal() { + final String packageName = context.getPackageName(); + for (String root : Arrays.asList("/oem", "/odm", "/vendor", "/system")) { String defaultReposPath = root + "/etc/" + packageName + "/default_repos.xml"; try { File defaultReposFile = new File(defaultReposPath); + // Only try loading external repos once. Even if this one fails, we will not try the other roots if (defaultReposFile.exists() && defaultReposFile.isFile()) { - return parseXmlRepos(defaultReposFile, minPriority); + return parseXmlRepos(defaultReposFile); } } catch (Exception e) { Utils.debugLog(TAG, "Error loading " + defaultReposPath); Utils.debugLog(TAG, "Exception: " + e.getMessage()); - return; + break; } } + return new LinkedList<>(); } - private List parseXmlRepos(File defaultReposFile, int minPriority) { - List default_repos = LinkedList<>(); - try { - InputStream xmlInputStream = new FileInputStream(defaultReposFile); - XmlPullParserFactoryfactory = XmlPullParserFactory.newInstance(); - factory.setNamespaceAware(true); - XmlPullParser parser = factory.newPullParser(); - parser.setInput(is, "UTF-8"); - - // Type of piece of xml file, can be END_DOCUMENT, TEXT, END_TAG, START_TAG, ... We only care about TEXT. - int eventType = parser.getEventType(); + private List parseXmlRepos(File defaultReposFile) throws IOException, XmlPullParserException { + List defaultRepos = new LinkedList<>(); + InputStream xmlInputStream = null; + xmlInputStream = new FileInputStream(defaultReposFile); + XmlPullParserFactory factory = XmlPullParserFactory.newInstance(); + factory.setNamespaceAware(true); + XmlPullParser parser = factory.newPullParser(); + parser.setInput(xmlInputStream, "UTF-8"); - static final int PRIORITY_INDEX = 5; - int indexItem = 0; - /* Walk through all TEXT pieces of the xml file and put them into our list of default repos. - * This could be improved by structuring the content for example into a list of lists where each contained list represents a repository, but - * we do it the traditional way. - */ - while (eventType != XmlPullParser.END_DOCUMENT) { - String tagname = parser.getName(); - switch (eventType) { - /* - * This checks whether the current repository does not violate the priority constraint: Its priority is higher or equal to minPrioriry. - * minPriority is at least the number of internal repos plus one. This way, the external repos can never be shown before the internal ones in the UI. - * - * Very ugly though. We count the number of items read in the xml file, because the items are not named but just rowed one after another. - * We also skip one event here, namely the text event after the START_TAG event. - */ - case XmlPullParser.START_TAG: - if (indexItem == PRIORITY_INDEX) { - parser.next(); - int priority = Integer.parseInt(parser.getText()); - // If some repository violates the priority constraint, immediately dismiss this whole external set of repos - if (priority > minPriority) { - return new LinkedList<>(); - } - } - indexItem++; - if (indexItem > 7) { indexItem -= 7; } - break; - case XmlPullParser.TEXT: - default_repos.add(parser.getText()); // This is a piece of real information in the xml file - break; - } - eventType = parser.next(); + // Type of piece of xml file, can be END_DOCUMENT, TEXT, END_TAG, START_TAG, ... + int eventType = parser.getEventType(); + + boolean isItem = false; + /* Walk through all TEXT pieces of the xml file and put them into our list of default repos. + * This could be improved by structuring the content for example into a list of lists where each contained list represents a repository, but + * we do it the traditional way. + */ + while (eventType != XmlPullParser.END_DOCUMENT) { + String tagname = parser.getName(); + switch (eventType) { + case XmlPullParser.START_TAG: + if (tagname.equals("item")) { + isItem = true; + } + break; + case XmlPullParser.END_TAG: + isItem = false; + break; + case XmlPullParser.TEXT: + if (isItem) { + defaultRepos.add(new String(parser.getText())); // This is a piece of real information in the xml file + } + break; } - - } catch (XmlPullParserException e) { - Utils.debugLog(TAG, "Error loading " + defaultReposFile.getAbsolutePath()); - Utils.debugLog(TAG, "Exception: " + e.getMessage()); - return; - } catch (IOException e) { - Utils.debugLog(TAG, "Error loading " + defaultReposFile.getAbsolutePath()); - Utils.debugLog(TAG, "Exception: " + e.getMessage()); - return; + + eventType = parser.next(); } - return default_repos; + xmlInputStream.close(); + return defaultRepos; } - /* - * The following two functions might be useful in the future to add repositories in json format as proposed in - * https://gitlab.com/fdroid/fdroidclient/merge_requests/705 - * - private String readFile(String file) throws IOException { - BufferedReader reader = new BufferedReader(new FileReader(file)); - StringBuilder stringBuilder = new StringBuilder(); - - try { - String ls = System.getProperty("line.separator"); - String line = null; - while((line = reader.readLine()) != null) { - stringBuilder.append(line); - stringBuilder.append(ls); - } - } finally { - reader.close(); - } - - return stringBuilder.toString(); - } - - private void loadOemDefaultRepos(SQLiteDatabase db) { - Utils.debugLog(TAG, "Loading external repos: Opening " + OEM_DEFAULT_REPOS_PATH); - - JSONArray reposArray; - try { - String jsonContents = readFile(OEM_DEFAULT_REPOS_PATH); - reposArray = new JSONArray(jsonContents); - } catch (Exception e) { - Utils.debugLog(TAG, "Error loading " + OEM_DEFAULT_REPOS_PATH); - Utils.debugLog(TAG, "Exception: " + e.getMessage()); - return; - } - Utils.debugLog(TAG, OEM_DEFAULT_REPOS_PATH + " successfully opened."); - - try { - for (int i = 0; i < reposArray.length(); i++) { - JSONObject repo = reposArray.getJSONObject(i); - insertRepo( - db, - repo.getString("name"), - repo.getString("address"), - repo.getString("description"), - repo.getString("version"), - repo.getString("enabled"), - repo.getString("priority"), - repo.getString("pushRequests"), - repo.getString("pubkey") - ); - } - } catch (Exception e) { - Utils.debugLog(TAG, "Error loading at least one external json repository from " + OEM_DEFAULT_REPOS_PATH); - Utils.debugLog(TAG, "Exception: " + e.getMessage()); - return; - } - Utils.debugLog(TAG, "All external repositories successfully added!"); - } - */ - @Override public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) { resetTransient(context); From a96621c6ecde24be740e7237507c48f72236cd65 Mon Sep 17 00:00:00 2001 From: Dimitri Rusin Date: Thu, 12 Jul 2018 20:34:55 +0000 Subject: [PATCH 06/28] renamed to additional_repos.xml, now collects them on all custom partitions --- .../java/org/fdroid/fdroid/data/DBHelper.java | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/app/src/main/java/org/fdroid/fdroid/data/DBHelper.java b/app/src/main/java/org/fdroid/fdroid/data/DBHelper.java index 405efedec..564ed0186 100644 --- a/app/src/main/java/org/fdroid/fdroid/data/DBHelper.java +++ b/app/src/main/java/org/fdroid/fdroid/data/DBHelper.java @@ -57,7 +57,6 @@ import org.xmlpull.v1.*; public class DBHelper extends SQLiteOpenHelper { private static final String TAG = "DBHelper"; - public static final int REPO_XML_ARG_COUNT = 8; private static DBHelper instance; @@ -245,6 +244,7 @@ public class DBHelper extends SQLiteOpenHelper { @Override public void onCreate(SQLiteDatabase db) { + db.execSQL(CREATE_TABLE_PACKAGE); db.execSQL(CREATE_TABLE_APP_METADATA); db.execSQL(CREATE_TABLE_APK); @@ -290,20 +290,19 @@ public class DBHelper extends SQLiteOpenHelper { } /* - * Look for external repositories under { "/oem", "/odm", "/vendor", "/system" } in this order and only load the first one. + * Look for external repositories under { "/oem", "/odm", "/vendor", "/system" } * If ROOT is one of those paths and 'packageName' is the name of the package - * that contains this class, then we look under 'root'/etc/'packageName'/default_repos.xml + * that contains this class, then we look under 'root'/etc/'packageName'/additional_repos.xml */ private List loadDefaultReposExternal() { + List externalRepos = new LinkedList<>(); final String packageName = context.getPackageName(); for (String root : Arrays.asList("/oem", "/odm", "/vendor", "/system")) { - String defaultReposPath = root + "/etc/" + packageName + "/default_repos.xml"; + String defaultReposPath = root + "/etc/" + packageName + "/additional_repos.xml"; try { File defaultReposFile = new File(defaultReposPath); - - // Only try loading external repos once. Even if this one fails, we will not try the other roots if (defaultReposFile.exists() && defaultReposFile.isFile()) { - return parseXmlRepos(defaultReposFile); + externalRepos.addAll(parseXmlRepos(defaultReposFile)); } } catch (Exception e) { Utils.debugLog(TAG, "Error loading " + defaultReposPath); @@ -311,7 +310,7 @@ public class DBHelper extends SQLiteOpenHelper { break; } } - return new LinkedList<>(); + return externalRepos; } private List parseXmlRepos(File defaultReposFile) throws IOException, XmlPullParserException { From 3193b7f93ad89f10f674c2f15048808437e3b632 Mon Sep 17 00:00:00 2001 From: Dimitri Rusin Date: Fri, 13 Jul 2018 16:34:32 +0000 Subject: [PATCH 07/28] syntactic improvements, plus now prioritizes correctly --- .../java/org/fdroid/fdroid/data/DBHelper.java | 42 +++++++++---------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/app/src/main/java/org/fdroid/fdroid/data/DBHelper.java b/app/src/main/java/org/fdroid/fdroid/data/DBHelper.java index 564ed0186..9dda7a7a7 100644 --- a/app/src/main/java/org/fdroid/fdroid/data/DBHelper.java +++ b/app/src/main/java/org/fdroid/fdroid/data/DBHelper.java @@ -258,18 +258,13 @@ public class DBHelper extends SQLiteOpenHelper { ensureIndexes(db); // Always, load the internal defaults afterwards. This way, F-Droid native repos can never be deleted - List defaultRepos = loadDefaultReposInternal(); + List defaultRepos = loadDefaultRepos(); // Insert all the repos into the database if (defaultRepos.size() % REPO_XML_ARG_COUNT != 0) { throw new IllegalArgumentException( - "default_repo.xml array does not have the right number of elements"); + "At least one of the internally or externally loaded default repos does not have " + REPO_XML_ARG_COUNT + " entries."); } - - // Load a couple external default repos from one of { "/oem", "/odm", "/vendor", "/system" } - defaultRepos.addAll(loadDefaultReposExternal()); - - Utils.debugLog(TAG, "defaultRepos.size(): " + defaultRepos.size()); for (int i = 0; i < defaultRepos.size(); i += REPO_XML_ARG_COUNT) { insertRepo( db, @@ -278,41 +273,43 @@ public class DBHelper extends SQLiteOpenHelper { defaultRepos.get(i + 2), // description defaultRepos.get(i + 3), // version defaultRepos.get(i + 4), // enabled - defaultRepos.get(i + 5), // priority + Integer.toString(i), // priority; currently ignored defaultRepos.get(i + 6), // pushRequests defaultRepos.get(i + 7) // pubkey ); } } - private List loadDefaultReposInternal() { - return new LinkedList<>(Arrays.asList(context.getResources().getStringArray(R.array.default_repos))); - } - /* * Look for external repositories under { "/oem", "/odm", "/vendor", "/system" } * If ROOT is one of those paths and 'packageName' is the name of the package * that contains this class, then we look under 'root'/etc/'packageName'/additional_repos.xml */ - private List loadDefaultReposExternal() { - List externalRepos = new LinkedList<>(); + private List loadDefaultRepos() { + // First, take the built-in repos. + List externalRepos = new LinkedList<>(Arrays.asList(context.getResources().getStringArray(R.array.default_repos))); + + // Second, take the external repos. We will later prioritize the repos according their order in the list externalRepos. final String packageName = context.getPackageName(); - for (String root : Arrays.asList("/oem", "/odm", "/vendor", "/system")) { - String defaultReposPath = root + "/etc/" + packageName + "/additional_repos.xml"; + for (String root : Arrays.asList("/system", "/vendor", "/odm", "/oem")) { + String additionalReposPath = root + "/etc/" + packageName + "/additional_repos.xml"; try { - File defaultReposFile = new File(defaultReposPath); + File defaultReposFile = new File(additionalReposPath); if (defaultReposFile.exists() && defaultReposFile.isFile()) { externalRepos.addAll(parseXmlRepos(defaultReposFile)); } } catch (Exception e) { - Utils.debugLog(TAG, "Error loading " + defaultReposPath); + Utils.debugLog(TAG, "Error loading " + additionalReposPath); Utils.debugLog(TAG, "Exception: " + e.getMessage()); - break; + continue; } } return externalRepos; } + /* + * Take an xml file in the same format as the internal default_repos.xml and parse it into a list of items. + */ private List parseXmlRepos(File defaultReposFile) throws IOException, XmlPullParserException { List defaultRepos = new LinkedList<>(); InputStream xmlInputStream = null; @@ -325,31 +322,34 @@ public class DBHelper extends SQLiteOpenHelper { // Type of piece of xml file, can be END_DOCUMENT, TEXT, END_TAG, START_TAG, ... int eventType = parser.getEventType(); - boolean isItem = false; /* Walk through all TEXT pieces of the xml file and put them into our list of default repos. * This could be improved by structuring the content for example into a list of lists where each contained list represents a repository, but * we do it the traditional way. */ + boolean isItem = false; while (eventType != XmlPullParser.END_DOCUMENT) { String tagname = parser.getName(); switch (eventType) { + // If an item starts, remember that in isItem case XmlPullParser.START_TAG: if (tagname.equals("item")) { isItem = true; } break; + // If an item ends, also remember that in isItem case XmlPullParser.END_TAG: isItem = false; break; + // If this is a textblock of an item tag, extract that into defaultRepos case XmlPullParser.TEXT: if (isItem) { defaultRepos.add(new String(parser.getText())); // This is a piece of real information in the xml file } break; } - eventType = parser.next(); } + xmlInputStream.close(); return defaultRepos; } From 9e2882451f91c0380d3c98c3eaa415c29a658941 Mon Sep 17 00:00:00 2001 From: Dimitri Rusin Date: Mon, 16 Jul 2018 16:07:40 +0000 Subject: [PATCH 08/28] add internal repos after additional ones --- .../main/java/org/fdroid/fdroid/data/DBHelper.java | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/org/fdroid/fdroid/data/DBHelper.java b/app/src/main/java/org/fdroid/fdroid/data/DBHelper.java index 9dda7a7a7..219bd38a9 100644 --- a/app/src/main/java/org/fdroid/fdroid/data/DBHelper.java +++ b/app/src/main/java/org/fdroid/fdroid/data/DBHelper.java @@ -257,8 +257,10 @@ public class DBHelper extends SQLiteOpenHelper { db.execSQL(CREATE_TABLE_APK_ANTI_FEATURE_JOIN); ensureIndexes(db); - // Always, load the internal defaults afterwards. This way, F-Droid native repos can never be deleted - List defaultRepos = loadDefaultRepos(); + // Load additional repos first, then internal repos. This way, internal repos will be shown after the OEM-added ones on the Manage Repos screen. + List defaultRepos = loadAdditionalRepos(); + List internalRepos = Arrays.asList(context.getResources().getStringArray(R.array.default_repos)); + defaultRepos.addAll(internalRepos); // Insert all the repos into the database if (defaultRepos.size() % REPO_XML_ARG_COUNT != 0) { @@ -281,13 +283,13 @@ public class DBHelper extends SQLiteOpenHelper { } /* - * Look for external repositories under { "/oem", "/odm", "/vendor", "/system" } + * Look for external repositories under { "/system", "/vendor", "/odm", "/oem" } * If ROOT is one of those paths and 'packageName' is the name of the package * that contains this class, then we look under 'root'/etc/'packageName'/additional_repos.xml */ - private List loadDefaultRepos() { + private List loadAdditionalRepos() { // First, take the built-in repos. - List externalRepos = new LinkedList<>(Arrays.asList(context.getResources().getStringArray(R.array.default_repos))); + List externalRepos = new LinkedList<>(); // Second, take the external repos. We will later prioritize the repos according their order in the list externalRepos. final String packageName = context.getPackageName(); From f5a5260e3e8c7446bf565f4a120447c166cb854e Mon Sep 17 00:00:00 2001 From: Dimitri Rusin Date: Thu, 26 Jul 2018 15:56:53 +0000 Subject: [PATCH 09/28] removed priority from additional_repos.xml --- app/src/main/java/org/fdroid/fdroid/data/DBHelper.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/app/src/main/java/org/fdroid/fdroid/data/DBHelper.java b/app/src/main/java/org/fdroid/fdroid/data/DBHelper.java index 219bd38a9..b77d9b4e2 100644 --- a/app/src/main/java/org/fdroid/fdroid/data/DBHelper.java +++ b/app/src/main/java/org/fdroid/fdroid/data/DBHelper.java @@ -306,6 +306,12 @@ public class DBHelper extends SQLiteOpenHelper { continue; } } + + final int PRIORITY_INDEX = 5; + for (int i = PRIORITY_INDEX; i < externalRepos.size(); i += REPO_XML_ARG_COUNT) { + externalRepos.add(i, "0"); + } + return externalRepos; } From 895166e9dbcd1d5842aa4734b35d9acbb4be4f03 Mon Sep 17 00:00:00 2001 From: Dimitri Rusin Date: Mon, 6 Aug 2018 21:23:46 +0200 Subject: [PATCH 10/28] started implementing test --- .../java/org/fdroid/fdroid/data/DBHelper.java | 33 +++++++------ .../fdroid/fdroid/data/RepoProviderTest.java | 46 +++++++++++++++++++ 2 files changed, 66 insertions(+), 13 deletions(-) diff --git a/app/src/main/java/org/fdroid/fdroid/data/DBHelper.java b/app/src/main/java/org/fdroid/fdroid/data/DBHelper.java index b77d9b4e2..661d77b4c 100644 --- a/app/src/main/java/org/fdroid/fdroid/data/DBHelper.java +++ b/app/src/main/java/org/fdroid/fdroid/data/DBHelper.java @@ -257,16 +257,8 @@ public class DBHelper extends SQLiteOpenHelper { db.execSQL(CREATE_TABLE_APK_ANTI_FEATURE_JOIN); ensureIndexes(db); - // Load additional repos first, then internal repos. This way, internal repos will be shown after the OEM-added ones on the Manage Repos screen. - List defaultRepos = loadAdditionalRepos(); - List internalRepos = Arrays.asList(context.getResources().getStringArray(R.array.default_repos)); - defaultRepos.addAll(internalRepos); + List defaultRepos = DBHelper.loadDefaultRepos(context); - // Insert all the repos into the database - if (defaultRepos.size() % REPO_XML_ARG_COUNT != 0) { - throw new IllegalArgumentException( - "At least one of the internally or externally loaded default repos does not have " + REPO_XML_ARG_COUNT + " entries."); - } for (int i = 0; i < defaultRepos.size(); i += REPO_XML_ARG_COUNT) { insertRepo( db, @@ -282,23 +274,38 @@ public class DBHelper extends SQLiteOpenHelper { } } + private static List loadDefaultRepos(Context context) throws IllegalArgumentException { + // Load additional repos first, then internal repos. This way, internal repos will be shown after the OEM-added ones on the Manage Repos screen. + String packageName = context.getPackageName(); + List defaultRepos = DBHelper.loadAdditionalRepos(packageName); + List internalRepos = Arrays.asList(context.getResources().getStringArray(R.array.default_repos)); + defaultRepos.addAll(internalRepos); + + // Insert all the repos into the database + if (defaultRepos.size() % REPO_XML_ARG_COUNT != 0) { + throw new IllegalArgumentException( + "At least one of the internally or externally loaded default repos does not have " + REPO_XML_ARG_COUNT + " entries."); + } + + return defaultRepos; + } + /* * Look for external repositories under { "/system", "/vendor", "/odm", "/oem" } * If ROOT is one of those paths and 'packageName' is the name of the package * that contains this class, then we look under 'root'/etc/'packageName'/additional_repos.xml */ - private List loadAdditionalRepos() { + private static List loadAdditionalRepos(String packageName) { // First, take the built-in repos. List externalRepos = new LinkedList<>(); // Second, take the external repos. We will later prioritize the repos according their order in the list externalRepos. - final String packageName = context.getPackageName(); for (String root : Arrays.asList("/system", "/vendor", "/odm", "/oem")) { String additionalReposPath = root + "/etc/" + packageName + "/additional_repos.xml"; try { File defaultReposFile = new File(additionalReposPath); if (defaultReposFile.exists() && defaultReposFile.isFile()) { - externalRepos.addAll(parseXmlRepos(defaultReposFile)); + externalRepos.addAll(DBHelper.parseXmlRepos(defaultReposFile)); } } catch (Exception e) { Utils.debugLog(TAG, "Error loading " + additionalReposPath); @@ -318,7 +325,7 @@ public class DBHelper extends SQLiteOpenHelper { /* * Take an xml file in the same format as the internal default_repos.xml and parse it into a list of items. */ - private List parseXmlRepos(File defaultReposFile) throws IOException, XmlPullParserException { + private static List parseXmlRepos(File defaultReposFile) throws IOException, XmlPullParserException { List defaultRepos = new LinkedList<>(); InputStream xmlInputStream = null; xmlInputStream = new FileInputStream(defaultReposFile); diff --git a/app/src/test/java/org/fdroid/fdroid/data/RepoProviderTest.java b/app/src/test/java/org/fdroid/fdroid/data/RepoProviderTest.java index 378ef8cfa..ffea1e2b8 100644 --- a/app/src/test/java/org/fdroid/fdroid/data/RepoProviderTest.java +++ b/app/src/test/java/org/fdroid/fdroid/data/RepoProviderTest.java @@ -156,6 +156,7 @@ public class RepoProviderTest extends FDroidProviderTest { List defaultRepos = RepoProvider.Helper.all(context); assertEquals(defaultRepos.size(), 4); // based on app/src/main/res/default_repo.xml + String[] reposFromXml = context.getResources().getStringArray(R.array.default_repos); if (reposFromXml.length % DBHelper.REPO_XML_ARG_COUNT != 0) { throw new IllegalArgumentException( @@ -173,6 +174,51 @@ public class RepoProviderTest extends FDroidProviderTest { } } + @Test + public void canAddAdditionalRepos() { + // TODO write to oem partition + + String packageName = context.getPackageName(); + Utils.debugLog(TAG, "canAddAdditionalRepos; packageName: " + packageName); + List defaultRepos = DBHelper.loadDefaultRepos(context); + /* + Repo is structured as follows: + 0) name + 1) address + 2) description + 3) version + 4) enabled + 5) priority (actually ignored in this use case) + 6) pushRequests + 7) pubkey + */ + List oem0 = Arrays.asList("oem0Name", "https://www.oem0.com/yeah/repo", "I'm the first oem repo.", + "22", "1", "123", "ignore", "fffff2313aaaaabcccc111"); + List oem1 = Arrays.asList("oem1MyNameIs", "https://www.mynameis.com/rapper/repo", "Who is the first repo?", + "22", "0", "123", "ignore", "ddddddd2313aaaaabcccc111"); + List fdroid0 = Arrays.asList("F-Droid", "https://f-droid.org/repo", "The official F-Droid repository. Applications in this repository are mostly built directory from the source code. Some are official binaries built by the original application developers - these will be replaced by source-built versions over time.", + "13", "1", "1", "ignore", "3082035e30820246a00302010202044c49cd00300d06092a864886f70d01010505003071310b300906035504061302554b3110300e06035504081307556e6b6e6f776e3111300f0603550407130857657468657262793110300e060355040a1307556e6b6e6f776e3110300e060355040b1307556e6b6e6f776e311930170603550403131043696172616e2047756c746e69656b73301e170d3130303732333137313032345a170d3337313230383137313032345a3071310b300906035504061302554b3110300e06035504081307556e6b6e6f776e3111300f0603550407130857657468657262793110300e060355040a1307556e6b6e6f776e3110300e060355040b1307556e6b6e6f776e311930170603550403131043696172616e2047756c746e69656b7330820122300d06092a864886f70d01010105000382010f003082010a028201010096d075e47c014e7822c89fd67f795d23203e2a8843f53ba4e6b1bf5f2fd0e225938267cfcae7fbf4fe596346afbaf4070fdb91f66fbcdf2348a3d92430502824f80517b156fab00809bdc8e631bfa9afd42d9045ab5fd6d28d9e140afc1300917b19b7c6c4df4a494cf1f7cb4a63c80d734265d735af9e4f09455f427aa65a53563f87b336ca2c19d244fcbba617ba0b19e56ed34afe0b253ab91e2fdb1271f1b9e3c3232027ed8862a112f0706e234cf236914b939bcf959821ecb2a6c18057e070de3428046d94b175e1d89bd795e535499a091f5bc65a79d539a8d43891ec504058acb28c08393b5718b57600a211e803f4a634e5c57f25b9b8c4422c6fd90203010001300d06092a864886f70d0101050500038201010008e4ef699e9807677ff56753da73efb2390d5ae2c17e4db691d5df7a7b60fc071ae509c5414be7d5da74df2811e83d3668c4a0b1abc84b9fa7d96b4cdf30bba68517ad2a93e233b042972ac0553a4801c9ebe07bf57ebe9a3b3d6d663965260e50f3b8f46db0531761e60340a2bddc3426098397fda54044a17e5244549f9869b460ca5e6e216b6f6a2db0580b480ca2afe6ec6b46eedacfa4aa45038809ece0c5978653d6c85f678e7f5a2156d1bedd8117751e64a4b0dcd140f3040b021821a8d93aed8d01ba36db6c82372211fed714d9a32607038cdfd565bd529ffc637212aaa2c224ef22b603eccefb5bf1e085c191d4b24fe742b17ab3f55d4e6f05ef"); + List fdroid1 = Arrays.asList("F-Droid Archive", "https://f-droid.org/archive", "The archive repository of the F-Droid client. This contains older versions of applications from the main repository.", + "13", "0", "2", "ignore", "3082035e30820246a00302010202044c49cd00300d06092a864886f70d01010505003071310b300906035504061302554b3110300e06035504081307556e6b6e6f776e3111300f0603550407130857657468657262793110300e060355040a1307556e6b6e6f776e3110300e060355040b1307556e6b6e6f776e311930170603550403131043696172616e2047756c746e69656b73301e170d3130303732333137313032345a170d3337313230383137313032345a3071310b300906035504061302554b3110300e06035504081307556e6b6e6f776e3111300f0603550407130857657468657262793110300e060355040a1307556e6b6e6f776e3110300e060355040b1307556e6b6e6f776e311930170603550403131043696172616e2047756c746e69656b7330820122300d06092a864886f70d01010105000382010f003082010a028201010096d075e47c014e7822c89fd67f795d23203e2a8843f53ba4e6b1bf5f2fd0e225938267cfcae7fbf4fe596346afbaf4070fdb91f66fbcdf2348a3d92430502824f80517b156fab00809bdc8e631bfa9afd42d9045ab5fd6d28d9e140afc1300917b19b7c6c4df4a494cf1f7cb4a63c80d734265d735af9e4f09455f427aa65a53563f87b336ca2c19d244fcbba617ba0b19e56ed34afe0b253ab91e2fdb1271f1b9e3c3232027ed8862a112f0706e234cf236914b939bcf959821ecb2a6c18057e070de3428046d94b175e1d89bd795e535499a091f5bc65a79d539a8d43891ec504058acb28c08393b5718b57600a211e803f4a634e5c57f25b9b8c4422c6fd90203010001300d06092a864886f70d0101050500038201010008e4ef699e9807677ff56753da73efb2390d5ae2c17e4db691d5df7a7b60fc071ae509c5414be7d5da74df2811e83d3668c4a0b1abc84b9fa7d96b4cdf30bba68517ad2a93e233b042972ac0553a4801c9ebe07bf57ebe9a3b3d6d663965260e50f3b8f46db0531761e60340a2bddc3426098397fda54044a17e5244549f9869b460ca5e6e216b6f6a2db0580b480ca2afe6ec6b46eedacfa4aa45038809ece0c5978653d6c85f678e7f5a2156d1bedd8117751e64a4b0dcd140f3040b021821a8d93aed8d01ba36db6c82372211fed714d9a32607038cdfd565bd529ffc637212aaa2c224ef22b603eccefb5bf1e085c191d4b24fe742b17ab3f55d4e6f05ef"); + List fdroid2 = Arrays.asList("Guardian Project", "https://guardianproject.info/fdroid/repo", "The official app repository of The Guardian Project. Applications in this repository are official binaries build by the original application developers and signed by the same key as the APKs that are released in the Google Play store.", + "13", "0", "3", "ignore", "308205d8308203c0020900a397b4da7ecda034300d06092a864886f70d01010505003081ad310b30090603550406130255533111300f06035504080c084e657720596f726b3111300f06035504070c084e657720596f726b31143012060355040b0c0b4644726f6964205265706f31193017060355040a0c10477561726469616e2050726f6a656374311d301b06035504030c14677561726469616e70726f6a6563742e696e666f3128302606092a864886f70d0109011619726f6f7440677561726469616e70726f6a6563742e696e666f301e170d3134303632363139333931385a170d3431313131303139333931385a3081ad310b30090603550406130255533111300f06035504080c084e657720596f726b3111300f06035504070c084e657720596f726b31143012060355040b0c0b4644726f6964205265706f31193017060355040a0c10477561726469616e2050726f6a656374311d301b06035504030c14677561726469616e70726f6a6563742e696e666f3128302606092a864886f70d0109011619726f6f7440677561726469616e70726f6a6563742e696e666f30820222300d06092a864886f70d01010105000382020f003082020a0282020100b3cd79121b9b883843be3c4482e320809106b0a23755f1dd3c7f46f7d315d7bb2e943486d61fc7c811b9294dcc6b5baac4340f8db2b0d5e14749e7f35e1fc211fdbc1071b38b4753db201c314811bef885bd8921ad86facd6cc3b8f74d30a0b6e2e6e576f906e9581ef23d9c03e926e06d1f033f28bd1e21cfa6a0e3ff5c9d8246cf108d82b488b9fdd55d7de7ebb6a7f64b19e0d6b2ab1380a6f9d42361770d1956701a7f80e2de568acd0bb4527324b1e0973e89595d91c8cc102d9248525ae092e2c9b69f7414f724195b81427f28b1d3d09a51acfe354387915fd9521e8c890c125fc41a12bf34d2a1b304067ab7251e0e9ef41833ce109e76963b0b256395b16b886bca21b831f1408f836146019e7908829e716e72b81006610a2af08301de5d067c9e114a1e5759db8a6be6a3cc2806bcfe6fafd41b5bc9ddddb3dc33d6f605b1ca7d8a9e0ecdd6390d38906649e68a90a717bea80fa220170eea0c86fc78a7e10dac7b74b8e62045a3ecca54e035281fdc9fe5920a855fde3c0be522e3aef0c087524f13d973dff3768158b01a5800a060c06b451ec98d627dd052eda804d0556f60dbc490d94e6e9dea62ffcafb5beffbd9fc38fb2f0d7050004fe56b4dda0a27bc47554e1e0a7d764e17622e71f83a475db286bc7862deee1327e2028955d978272ea76bf0b88e70a18621aba59ff0c5993ef5f0e5d6b6b98e68b70203010001300d06092a864886f70d0101050500038202010079c79c8ef408a20d243d8bd8249fb9a48350dc19663b5e0fce67a8dbcb7de296c5ae7bbf72e98a2020fb78f2db29b54b0e24b181aa1c1d333cc0303685d6120b03216a913f96b96eb838f9bff125306ae3120af838c9fc07ebb5100125436bd24ec6d994d0bff5d065221871f8410daf536766757239bf594e61c5432c9817281b985263bada8381292e543a49814061ae11c92a316e7dc100327b59e3da90302c5ada68c6a50201bda1fcce800b53f381059665dbabeeb0b50eb22b2d7d2d9b0aa7488ca70e67ac6c518adb8e78454a466501e89d81a45bf1ebc350896f2c3ae4b6679ecfbf9d32960d4f5b493125c7876ef36158562371193f600bc511000a67bdb7c664d018f99d9e589868d103d7e0994f166b2ba18ff7e67d8c4da749e44dfae1d930ae5397083a51675c409049dfb626a96246c0015ca696e94ebb767a20147834bf78b07fece3f0872b057c1c519ff882501995237d8206b0b3832f78753ebd8dcbd1d3d9f5ba733538113af6b407d960ec4353c50eb38ab29888238da843cd404ed8f4952f59e4bbc0035fc77a54846a9d419179c46af1b4a3b7fc98e4d312aaa29b9b7d79e739703dc0fa41c7280d5587709277ffa11c3620f5fba985b82c238ba19b17ebd027af9424be0941719919f620dd3bb3c3f11638363708aa11f858e153cf3a69bce69978b90e4a273836100aa1e617ba455cd00426847f"); + List fdroid3 = Arrays.asList("Guardian Project Archive", "https://guardianproject.info/fdroid/archive", "The official repository of The Guardian Project apps for use with F-Droid client. This contains older versions of applications from the main repository.", + "13", "0", "4", "ignore", "308205d8308203c0020900a397b4da7ecda034300d06092a864886f70d01010505003081ad310b30090603550406130255533111300f06035504080c084e657720596f726b3111300f06035504070c084e657720596f726b31143012060355040b0c0b4644726f6964205265706f31193017060355040a0c10477561726469616e2050726f6a656374311d301b06035504030c14677561726469616e70726f6a6563742e696e666f3128302606092a864886f70d0109011619726f6f7440677561726469616e70726f6a6563742e696e666f301e170d3134303632363139333931385a170d3431313131303139333931385a3081ad310b30090603550406130255533111300f06035504080c084e657720596f726b3111300f06035504070c084e657720596f726b31143012060355040b0c0b4644726f6964205265706f31193017060355040a0c10477561726469616e2050726f6a656374311d301b06035504030c14677561726469616e70726f6a6563742e696e666f3128302606092a864886f70d0109011619726f6f7440677561726469616e70726f6a6563742e696e666f30820222300d06092a864886f70d01010105000382020f003082020a0282020100b3cd79121b9b883843be3c4482e320809106b0a23755f1dd3c7f46f7d315d7bb2e943486d61fc7c811b9294dcc6b5baac4340f8db2b0d5e14749e7f35e1fc211fdbc1071b38b4753db201c314811bef885bd8921ad86facd6cc3b8f74d30a0b6e2e6e576f906e9581ef23d9c03e926e06d1f033f28bd1e21cfa6a0e3ff5c9d8246cf108d82b488b9fdd55d7de7ebb6a7f64b19e0d6b2ab1380a6f9d42361770d1956701a7f80e2de568acd0bb4527324b1e0973e89595d91c8cc102d9248525ae092e2c9b69f7414f724195b81427f28b1d3d09a51acfe354387915fd9521e8c890c125fc41a12bf34d2a1b304067ab7251e0e9ef41833ce109e76963b0b256395b16b886bca21b831f1408f836146019e7908829e716e72b81006610a2af08301de5d067c9e114a1e5759db8a6be6a3cc2806bcfe6fafd41b5bc9ddddb3dc33d6f605b1ca7d8a9e0ecdd6390d38906649e68a90a717bea80fa220170eea0c86fc78a7e10dac7b74b8e62045a3ecca54e035281fdc9fe5920a855fde3c0be522e3aef0c087524f13d973dff3768158b01a5800a060c06b451ec98d627dd052eda804d0556f60dbc490d94e6e9dea62ffcafb5beffbd9fc38fb2f0d7050004fe56b4dda0a27bc47554e1e0a7d764e17622e71f83a475db286bc7862deee1327e2028955d978272ea76bf0b88e70a18621aba59ff0c5993ef5f0e5d6b6b98e68b70203010001300d06092a864886f70d0101050500038202010079c79c8ef408a20d243d8bd8249fb9a48350dc19663b5e0fce67a8dbcb7de296c5ae7bbf72e98a2020fb78f2db29b54b0e24b181aa1c1d333cc0303685d6120b03216a913f96b96eb838f9bff125306ae3120af838c9fc07ebb5100125436bd24ec6d994d0bff5d065221871f8410daf536766757239bf594e61c5432c9817281b985263bada8381292e543a49814061ae11c92a316e7dc100327b59e3da90302c5ada68c6a50201bda1fcce800b53f381059665dbabeeb0b50eb22b2d7d2d9b0aa7488ca70e67ac6c518adb8e78454a466501e89d81a45bf1ebc350896f2c3ae4b6679ecfbf9d32960d4f5b493125c7876ef36158562371193f600bc511000a67bdb7c664d018f99d9e589868d103d7e0994f166b2ba18ff7e67d8c4da749e44dfae1d930ae5397083a51675c409049dfb626a96246c0015ca696e94ebb767a20147834bf78b07fece3f0872b057c1c519ff882501995237d8206b0b3832f78753ebd8dcbd1d3d9f5ba733538113af6b407d960ec4353c50eb38ab29888238da843cd404ed8f4952f59e4bbc0035fc77a54846a9d419179c46af1b4a3b7fc98e4d312aaa29b9b7d79e739703dc0fa41c7280d5587709277ffa11c3620f5fba985b82c238ba19b17ebd027af9424be0941719919f620dd3bb3c3f11638363708aa11f858e153cf3a69bce69978b90e4a273836100aa1e617ba455cd00426847f"); + + List shouldBeRepos = new LinkedList<>(); + shouldBeRepos + .addAll(oem0) + .addAll(oem1) + .addAll(fdroid0) + .addAll(fdroid1) + .addAll(fdroid2) + .addAll(fdroid3); + + for (int i = 0; i < defaultRepos.size(); i++) { + assertEquals(defaultRepos.get(i), shouldBeRepos.get(i)); + } + } + @Test public void canAddRepo() { From 27e0eaad9e511da90476d4df0e6b41948150b655 Mon Sep 17 00:00:00 2001 From: Dimitri Rusin Date: Tue, 7 Aug 2018 20:39:21 +0000 Subject: [PATCH 11/28] implemented creating xml file on oem partition; not sure whether it works cause gradle runs forever (>20min) --- .../java/org/fdroid/fdroid/data/DBHelper.java | 2 +- .../fdroid/fdroid/data/RepoProviderTest.java | 76 +++++++++++++++---- 2 files changed, 62 insertions(+), 16 deletions(-) diff --git a/app/src/main/java/org/fdroid/fdroid/data/DBHelper.java b/app/src/main/java/org/fdroid/fdroid/data/DBHelper.java index 661d77b4c..6edc1e281 100644 --- a/app/src/main/java/org/fdroid/fdroid/data/DBHelper.java +++ b/app/src/main/java/org/fdroid/fdroid/data/DBHelper.java @@ -274,7 +274,7 @@ public class DBHelper extends SQLiteOpenHelper { } } - private static List loadDefaultRepos(Context context) throws IllegalArgumentException { + public static List loadDefaultRepos(Context context) throws IllegalArgumentException { // Load additional repos first, then internal repos. This way, internal repos will be shown after the OEM-added ones on the Manage Repos screen. String packageName = context.getPackageName(); List defaultRepos = DBHelper.loadAdditionalRepos(packageName); diff --git a/app/src/test/java/org/fdroid/fdroid/data/RepoProviderTest.java b/app/src/test/java/org/fdroid/fdroid/data/RepoProviderTest.java index ffea1e2b8..02301f895 100644 --- a/app/src/test/java/org/fdroid/fdroid/data/RepoProviderTest.java +++ b/app/src/test/java/org/fdroid/fdroid/data/RepoProviderTest.java @@ -36,7 +36,9 @@ import org.robolectric.RobolectricTestRunner; import org.robolectric.annotation.Config; import java.util.Date; +import java.util.LinkedList; import java.util.List; +import java.util.Arrays; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; @@ -47,6 +49,7 @@ import static org.junit.Assert.assertNull; public class RepoProviderTest extends FDroidProviderTest { private static final String[] COLS = RepoTable.Cols.ALL; + private static final String TAG = "RepoProviderTest"; @Test public void countEnabledRepos() { @@ -176,11 +179,7 @@ public class RepoProviderTest extends FDroidProviderTest { @Test public void canAddAdditionalRepos() { - // TODO write to oem partition - - String packageName = context.getPackageName(); - Utils.debugLog(TAG, "canAddAdditionalRepos; packageName: " + packageName); - List defaultRepos = DBHelper.loadDefaultRepos(context); + /* Repo is structured as follows: 0) name @@ -192,10 +191,58 @@ public class RepoProviderTest extends FDroidProviderTest { 6) pushRequests 7) pubkey */ + + String packageName = context.getPackageName(); + Utils.debugLog(TAG, "canAddAdditionalRepos; packageName: " + packageName); + + FileOutputStream outputStream = new FileOutputStream("/oem/etc/" + packageName + "/additional_repos.xml"); + outputStream.write((" + + + + + oem0Name + + https://www.oem0.com/yeah/repo + + I'm the first oem repo. + + 22 + + 1 + + ignore + + fffff2313aaaaabcccc111 + + + oem1MyNameIs + + https://www.mynameis.com/rapper/repo + + Who is the first repo? + + 22 + + 0 + + ignore + + ddddddd2313aaaaabcccc111 + + + " + ).getBytes()); + outputStream.close(); + + // Load the actual repos + List defaultRepos = DBHelper.loadDefaultRepos(context); + + // Construct the repos that we should have loaded List oem0 = Arrays.asList("oem0Name", "https://www.oem0.com/yeah/repo", "I'm the first oem repo.", - "22", "1", "123", "ignore", "fffff2313aaaaabcccc111"); + "22", "1", "0", "ignore", "fffff2313aaaaabcccc111"); List oem1 = Arrays.asList("oem1MyNameIs", "https://www.mynameis.com/rapper/repo", "Who is the first repo?", - "22", "0", "123", "ignore", "ddddddd2313aaaaabcccc111"); + "22", "0", "0", "ignore", "ddddddd2313aaaaabcccc111"); List fdroid0 = Arrays.asList("F-Droid", "https://f-droid.org/repo", "The official F-Droid repository. Applications in this repository are mostly built directory from the source code. Some are official binaries built by the original application developers - these will be replaced by source-built versions over time.", "13", "1", "1", "ignore", "3082035e30820246a00302010202044c49cd00300d06092a864886f70d01010505003071310b300906035504061302554b3110300e06035504081307556e6b6e6f776e3111300f0603550407130857657468657262793110300e060355040a1307556e6b6e6f776e3110300e060355040b1307556e6b6e6f776e311930170603550403131043696172616e2047756c746e69656b73301e170d3130303732333137313032345a170d3337313230383137313032345a3071310b300906035504061302554b3110300e06035504081307556e6b6e6f776e3111300f0603550407130857657468657262793110300e060355040a1307556e6b6e6f776e3110300e060355040b1307556e6b6e6f776e311930170603550403131043696172616e2047756c746e69656b7330820122300d06092a864886f70d01010105000382010f003082010a028201010096d075e47c014e7822c89fd67f795d23203e2a8843f53ba4e6b1bf5f2fd0e225938267cfcae7fbf4fe596346afbaf4070fdb91f66fbcdf2348a3d92430502824f80517b156fab00809bdc8e631bfa9afd42d9045ab5fd6d28d9e140afc1300917b19b7c6c4df4a494cf1f7cb4a63c80d734265d735af9e4f09455f427aa65a53563f87b336ca2c19d244fcbba617ba0b19e56ed34afe0b253ab91e2fdb1271f1b9e3c3232027ed8862a112f0706e234cf236914b939bcf959821ecb2a6c18057e070de3428046d94b175e1d89bd795e535499a091f5bc65a79d539a8d43891ec504058acb28c08393b5718b57600a211e803f4a634e5c57f25b9b8c4422c6fd90203010001300d06092a864886f70d0101050500038201010008e4ef699e9807677ff56753da73efb2390d5ae2c17e4db691d5df7a7b60fc071ae509c5414be7d5da74df2811e83d3668c4a0b1abc84b9fa7d96b4cdf30bba68517ad2a93e233b042972ac0553a4801c9ebe07bf57ebe9a3b3d6d663965260e50f3b8f46db0531761e60340a2bddc3426098397fda54044a17e5244549f9869b460ca5e6e216b6f6a2db0580b480ca2afe6ec6b46eedacfa4aa45038809ece0c5978653d6c85f678e7f5a2156d1bedd8117751e64a4b0dcd140f3040b021821a8d93aed8d01ba36db6c82372211fed714d9a32607038cdfd565bd529ffc637212aaa2c224ef22b603eccefb5bf1e085c191d4b24fe742b17ab3f55d4e6f05ef"); List fdroid1 = Arrays.asList("F-Droid Archive", "https://f-droid.org/archive", "The archive repository of the F-Droid client. This contains older versions of applications from the main repository.", @@ -206,16 +253,15 @@ public class RepoProviderTest extends FDroidProviderTest { "13", "0", "4", "ignore", "308205d8308203c0020900a397b4da7ecda034300d06092a864886f70d01010505003081ad310b30090603550406130255533111300f06035504080c084e657720596f726b3111300f06035504070c084e657720596f726b31143012060355040b0c0b4644726f6964205265706f31193017060355040a0c10477561726469616e2050726f6a656374311d301b06035504030c14677561726469616e70726f6a6563742e696e666f3128302606092a864886f70d0109011619726f6f7440677561726469616e70726f6a6563742e696e666f301e170d3134303632363139333931385a170d3431313131303139333931385a3081ad310b30090603550406130255533111300f06035504080c084e657720596f726b3111300f06035504070c084e657720596f726b31143012060355040b0c0b4644726f6964205265706f31193017060355040a0c10477561726469616e2050726f6a656374311d301b06035504030c14677561726469616e70726f6a6563742e696e666f3128302606092a864886f70d0109011619726f6f7440677561726469616e70726f6a6563742e696e666f30820222300d06092a864886f70d01010105000382020f003082020a0282020100b3cd79121b9b883843be3c4482e320809106b0a23755f1dd3c7f46f7d315d7bb2e943486d61fc7c811b9294dcc6b5baac4340f8db2b0d5e14749e7f35e1fc211fdbc1071b38b4753db201c314811bef885bd8921ad86facd6cc3b8f74d30a0b6e2e6e576f906e9581ef23d9c03e926e06d1f033f28bd1e21cfa6a0e3ff5c9d8246cf108d82b488b9fdd55d7de7ebb6a7f64b19e0d6b2ab1380a6f9d42361770d1956701a7f80e2de568acd0bb4527324b1e0973e89595d91c8cc102d9248525ae092e2c9b69f7414f724195b81427f28b1d3d09a51acfe354387915fd9521e8c890c125fc41a12bf34d2a1b304067ab7251e0e9ef41833ce109e76963b0b256395b16b886bca21b831f1408f836146019e7908829e716e72b81006610a2af08301de5d067c9e114a1e5759db8a6be6a3cc2806bcfe6fafd41b5bc9ddddb3dc33d6f605b1ca7d8a9e0ecdd6390d38906649e68a90a717bea80fa220170eea0c86fc78a7e10dac7b74b8e62045a3ecca54e035281fdc9fe5920a855fde3c0be522e3aef0c087524f13d973dff3768158b01a5800a060c06b451ec98d627dd052eda804d0556f60dbc490d94e6e9dea62ffcafb5beffbd9fc38fb2f0d7050004fe56b4dda0a27bc47554e1e0a7d764e17622e71f83a475db286bc7862deee1327e2028955d978272ea76bf0b88e70a18621aba59ff0c5993ef5f0e5d6b6b98e68b70203010001300d06092a864886f70d0101050500038202010079c79c8ef408a20d243d8bd8249fb9a48350dc19663b5e0fce67a8dbcb7de296c5ae7bbf72e98a2020fb78f2db29b54b0e24b181aa1c1d333cc0303685d6120b03216a913f96b96eb838f9bff125306ae3120af838c9fc07ebb5100125436bd24ec6d994d0bff5d065221871f8410daf536766757239bf594e61c5432c9817281b985263bada8381292e543a49814061ae11c92a316e7dc100327b59e3da90302c5ada68c6a50201bda1fcce800b53f381059665dbabeeb0b50eb22b2d7d2d9b0aa7488ca70e67ac6c518adb8e78454a466501e89d81a45bf1ebc350896f2c3ae4b6679ecfbf9d32960d4f5b493125c7876ef36158562371193f600bc511000a67bdb7c664d018f99d9e589868d103d7e0994f166b2ba18ff7e67d8c4da749e44dfae1d930ae5397083a51675c409049dfb626a96246c0015ca696e94ebb767a20147834bf78b07fece3f0872b057c1c519ff882501995237d8206b0b3832f78753ebd8dcbd1d3d9f5ba733538113af6b407d960ec4353c50eb38ab29888238da843cd404ed8f4952f59e4bbc0035fc77a54846a9d419179c46af1b4a3b7fc98e4d312aaa29b9b7d79e739703dc0fa41c7280d5587709277ffa11c3620f5fba985b82c238ba19b17ebd027af9424be0941719919f620dd3bb3c3f11638363708aa11f858e153cf3a69bce69978b90e4a273836100aa1e617ba455cd00426847f"); List shouldBeRepos = new LinkedList<>(); - shouldBeRepos - .addAll(oem0) - .addAll(oem1) - .addAll(fdroid0) - .addAll(fdroid1) - .addAll(fdroid2) - .addAll(fdroid3); + shouldBeRepos.addAll(oem0); + shouldBeRepos.addAll(oem1); + shouldBeRepos.addAll(fdroid0); + shouldBeRepos.addAll(fdroid1); + shouldBeRepos.addAll(fdroid2); + shouldBeRepos.addAll(fdroid3); for (int i = 0; i < defaultRepos.size(); i++) { - assertEquals(defaultRepos.get(i), shouldBeRepos.get(i)); + assertEquals(shouldBeRepos.get(i), defaultRepos.get(i)); } } From 324cb2998b29816c7c9592c4d93c6192a8b91a99 Mon Sep 17 00:00:00 2001 From: Dimitri Rusin Date: Wed, 8 Aug 2018 11:32:15 +0000 Subject: [PATCH 12/28] minor style changes --- app/src/test/java/org/fdroid/fdroid/data/RepoProviderTest.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/app/src/test/java/org/fdroid/fdroid/data/RepoProviderTest.java b/app/src/test/java/org/fdroid/fdroid/data/RepoProviderTest.java index 02301f895..31320b73c 100644 --- a/app/src/test/java/org/fdroid/fdroid/data/RepoProviderTest.java +++ b/app/src/test/java/org/fdroid/fdroid/data/RepoProviderTest.java @@ -49,7 +49,6 @@ import static org.junit.Assert.assertNull; public class RepoProviderTest extends FDroidProviderTest { private static final String[] COLS = RepoTable.Cols.ALL; - private static final String TAG = "RepoProviderTest"; @Test public void countEnabledRepos() { @@ -193,8 +192,6 @@ public class RepoProviderTest extends FDroidProviderTest { */ String packageName = context.getPackageName(); - Utils.debugLog(TAG, "canAddAdditionalRepos; packageName: " + packageName); - FileOutputStream outputStream = new FileOutputStream("/oem/etc/" + packageName + "/additional_repos.xml"); outputStream.write((" From 59d0f7d6be82330198820bd96676f764a89921d2 Mon Sep 17 00:00:00 2001 From: Dimitri Rusin Date: Wed, 8 Aug 2018 11:33:43 +0000 Subject: [PATCH 13/28] some minor style changes --- .../org/fdroid/fdroid/data/RepoProviderTest.java | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/app/src/test/java/org/fdroid/fdroid/data/RepoProviderTest.java b/app/src/test/java/org/fdroid/fdroid/data/RepoProviderTest.java index 31320b73c..40e68a1e4 100644 --- a/app/src/test/java/org/fdroid/fdroid/data/RepoProviderTest.java +++ b/app/src/test/java/org/fdroid/fdroid/data/RepoProviderTest.java @@ -158,7 +158,6 @@ public class RepoProviderTest extends FDroidProviderTest { List defaultRepos = RepoProvider.Helper.all(context); assertEquals(defaultRepos.size(), 4); // based on app/src/main/res/default_repo.xml - String[] reposFromXml = context.getResources().getStringArray(R.array.default_repos); if (reposFromXml.length % DBHelper.REPO_XML_ARG_COUNT != 0) { throw new IllegalArgumentException( @@ -178,7 +177,6 @@ public class RepoProviderTest extends FDroidProviderTest { @Test public void canAddAdditionalRepos() { - /* Repo is structured as follows: 0) name @@ -190,7 +188,6 @@ public class RepoProviderTest extends FDroidProviderTest { 6) pushRequests 7) pubkey */ - String packageName = context.getPackageName(); FileOutputStream outputStream = new FileOutputStream("/oem/etc/" + packageName + "/additional_repos.xml"); outputStream.write((" @@ -236,17 +233,17 @@ public class RepoProviderTest extends FDroidProviderTest { List defaultRepos = DBHelper.loadDefaultRepos(context); // Construct the repos that we should have loaded - List oem0 = Arrays.asList("oem0Name", "https://www.oem0.com/yeah/repo", "I'm the first oem repo.", + List oem0 = Arrays.asList("oem0Name", "https://www.oem0.com/yeah/repo", "I'm the first oem repo.", "22", "1", "0", "ignore", "fffff2313aaaaabcccc111"); - List oem1 = Arrays.asList("oem1MyNameIs", "https://www.mynameis.com/rapper/repo", "Who is the first repo?", + List oem1 = Arrays.asList("oem1MyNameIs", "https://www.mynameis.com/rapper/repo", "Who is the first repo?", "22", "0", "0", "ignore", "ddddddd2313aaaaabcccc111"); - List fdroid0 = Arrays.asList("F-Droid", "https://f-droid.org/repo", "The official F-Droid repository. Applications in this repository are mostly built directory from the source code. Some are official binaries built by the original application developers - these will be replaced by source-built versions over time.", + List fdroid0 = Arrays.asList("F-Droid", "https://f-droid.org/repo", "The official F-Droid repository. Applications in this repository are mostly built directory from the source code. Some are official binaries built by the original application developers - these will be replaced by source-built versions over time.", "13", "1", "1", "ignore", "3082035e30820246a00302010202044c49cd00300d06092a864886f70d01010505003071310b300906035504061302554b3110300e06035504081307556e6b6e6f776e3111300f0603550407130857657468657262793110300e060355040a1307556e6b6e6f776e3110300e060355040b1307556e6b6e6f776e311930170603550403131043696172616e2047756c746e69656b73301e170d3130303732333137313032345a170d3337313230383137313032345a3071310b300906035504061302554b3110300e06035504081307556e6b6e6f776e3111300f0603550407130857657468657262793110300e060355040a1307556e6b6e6f776e3110300e060355040b1307556e6b6e6f776e311930170603550403131043696172616e2047756c746e69656b7330820122300d06092a864886f70d01010105000382010f003082010a028201010096d075e47c014e7822c89fd67f795d23203e2a8843f53ba4e6b1bf5f2fd0e225938267cfcae7fbf4fe596346afbaf4070fdb91f66fbcdf2348a3d92430502824f80517b156fab00809bdc8e631bfa9afd42d9045ab5fd6d28d9e140afc1300917b19b7c6c4df4a494cf1f7cb4a63c80d734265d735af9e4f09455f427aa65a53563f87b336ca2c19d244fcbba617ba0b19e56ed34afe0b253ab91e2fdb1271f1b9e3c3232027ed8862a112f0706e234cf236914b939bcf959821ecb2a6c18057e070de3428046d94b175e1d89bd795e535499a091f5bc65a79d539a8d43891ec504058acb28c08393b5718b57600a211e803f4a634e5c57f25b9b8c4422c6fd90203010001300d06092a864886f70d0101050500038201010008e4ef699e9807677ff56753da73efb2390d5ae2c17e4db691d5df7a7b60fc071ae509c5414be7d5da74df2811e83d3668c4a0b1abc84b9fa7d96b4cdf30bba68517ad2a93e233b042972ac0553a4801c9ebe07bf57ebe9a3b3d6d663965260e50f3b8f46db0531761e60340a2bddc3426098397fda54044a17e5244549f9869b460ca5e6e216b6f6a2db0580b480ca2afe6ec6b46eedacfa4aa45038809ece0c5978653d6c85f678e7f5a2156d1bedd8117751e64a4b0dcd140f3040b021821a8d93aed8d01ba36db6c82372211fed714d9a32607038cdfd565bd529ffc637212aaa2c224ef22b603eccefb5bf1e085c191d4b24fe742b17ab3f55d4e6f05ef"); - List fdroid1 = Arrays.asList("F-Droid Archive", "https://f-droid.org/archive", "The archive repository of the F-Droid client. This contains older versions of applications from the main repository.", + List fdroid1 = Arrays.asList("F-Droid Archive", "https://f-droid.org/archive", "The archive repository of the F-Droid client. This contains older versions of applications from the main repository.", "13", "0", "2", "ignore", "3082035e30820246a00302010202044c49cd00300d06092a864886f70d01010505003071310b300906035504061302554b3110300e06035504081307556e6b6e6f776e3111300f0603550407130857657468657262793110300e060355040a1307556e6b6e6f776e3110300e060355040b1307556e6b6e6f776e311930170603550403131043696172616e2047756c746e69656b73301e170d3130303732333137313032345a170d3337313230383137313032345a3071310b300906035504061302554b3110300e06035504081307556e6b6e6f776e3111300f0603550407130857657468657262793110300e060355040a1307556e6b6e6f776e3110300e060355040b1307556e6b6e6f776e311930170603550403131043696172616e2047756c746e69656b7330820122300d06092a864886f70d01010105000382010f003082010a028201010096d075e47c014e7822c89fd67f795d23203e2a8843f53ba4e6b1bf5f2fd0e225938267cfcae7fbf4fe596346afbaf4070fdb91f66fbcdf2348a3d92430502824f80517b156fab00809bdc8e631bfa9afd42d9045ab5fd6d28d9e140afc1300917b19b7c6c4df4a494cf1f7cb4a63c80d734265d735af9e4f09455f427aa65a53563f87b336ca2c19d244fcbba617ba0b19e56ed34afe0b253ab91e2fdb1271f1b9e3c3232027ed8862a112f0706e234cf236914b939bcf959821ecb2a6c18057e070de3428046d94b175e1d89bd795e535499a091f5bc65a79d539a8d43891ec504058acb28c08393b5718b57600a211e803f4a634e5c57f25b9b8c4422c6fd90203010001300d06092a864886f70d0101050500038201010008e4ef699e9807677ff56753da73efb2390d5ae2c17e4db691d5df7a7b60fc071ae509c5414be7d5da74df2811e83d3668c4a0b1abc84b9fa7d96b4cdf30bba68517ad2a93e233b042972ac0553a4801c9ebe07bf57ebe9a3b3d6d663965260e50f3b8f46db0531761e60340a2bddc3426098397fda54044a17e5244549f9869b460ca5e6e216b6f6a2db0580b480ca2afe6ec6b46eedacfa4aa45038809ece0c5978653d6c85f678e7f5a2156d1bedd8117751e64a4b0dcd140f3040b021821a8d93aed8d01ba36db6c82372211fed714d9a32607038cdfd565bd529ffc637212aaa2c224ef22b603eccefb5bf1e085c191d4b24fe742b17ab3f55d4e6f05ef"); - List fdroid2 = Arrays.asList("Guardian Project", "https://guardianproject.info/fdroid/repo", "The official app repository of The Guardian Project. Applications in this repository are official binaries build by the original application developers and signed by the same key as the APKs that are released in the Google Play store.", + List fdroid2 = Arrays.asList("Guardian Project", "https://guardianproject.info/fdroid/repo", "The official app repository of The Guardian Project. Applications in this repository are official binaries build by the original application developers and signed by the same key as the APKs that are released in the Google Play store.", "13", "0", "3", "ignore", "308205d8308203c0020900a397b4da7ecda034300d06092a864886f70d01010505003081ad310b30090603550406130255533111300f06035504080c084e657720596f726b3111300f06035504070c084e657720596f726b31143012060355040b0c0b4644726f6964205265706f31193017060355040a0c10477561726469616e2050726f6a656374311d301b06035504030c14677561726469616e70726f6a6563742e696e666f3128302606092a864886f70d0109011619726f6f7440677561726469616e70726f6a6563742e696e666f301e170d3134303632363139333931385a170d3431313131303139333931385a3081ad310b30090603550406130255533111300f06035504080c084e657720596f726b3111300f06035504070c084e657720596f726b31143012060355040b0c0b4644726f6964205265706f31193017060355040a0c10477561726469616e2050726f6a656374311d301b06035504030c14677561726469616e70726f6a6563742e696e666f3128302606092a864886f70d0109011619726f6f7440677561726469616e70726f6a6563742e696e666f30820222300d06092a864886f70d01010105000382020f003082020a0282020100b3cd79121b9b883843be3c4482e320809106b0a23755f1dd3c7f46f7d315d7bb2e943486d61fc7c811b9294dcc6b5baac4340f8db2b0d5e14749e7f35e1fc211fdbc1071b38b4753db201c314811bef885bd8921ad86facd6cc3b8f74d30a0b6e2e6e576f906e9581ef23d9c03e926e06d1f033f28bd1e21cfa6a0e3ff5c9d8246cf108d82b488b9fdd55d7de7ebb6a7f64b19e0d6b2ab1380a6f9d42361770d1956701a7f80e2de568acd0bb4527324b1e0973e89595d91c8cc102d9248525ae092e2c9b69f7414f724195b81427f28b1d3d09a51acfe354387915fd9521e8c890c125fc41a12bf34d2a1b304067ab7251e0e9ef41833ce109e76963b0b256395b16b886bca21b831f1408f836146019e7908829e716e72b81006610a2af08301de5d067c9e114a1e5759db8a6be6a3cc2806bcfe6fafd41b5bc9ddddb3dc33d6f605b1ca7d8a9e0ecdd6390d38906649e68a90a717bea80fa220170eea0c86fc78a7e10dac7b74b8e62045a3ecca54e035281fdc9fe5920a855fde3c0be522e3aef0c087524f13d973dff3768158b01a5800a060c06b451ec98d627dd052eda804d0556f60dbc490d94e6e9dea62ffcafb5beffbd9fc38fb2f0d7050004fe56b4dda0a27bc47554e1e0a7d764e17622e71f83a475db286bc7862deee1327e2028955d978272ea76bf0b88e70a18621aba59ff0c5993ef5f0e5d6b6b98e68b70203010001300d06092a864886f70d0101050500038202010079c79c8ef408a20d243d8bd8249fb9a48350dc19663b5e0fce67a8dbcb7de296c5ae7bbf72e98a2020fb78f2db29b54b0e24b181aa1c1d333cc0303685d6120b03216a913f96b96eb838f9bff125306ae3120af838c9fc07ebb5100125436bd24ec6d994d0bff5d065221871f8410daf536766757239bf594e61c5432c9817281b985263bada8381292e543a49814061ae11c92a316e7dc100327b59e3da90302c5ada68c6a50201bda1fcce800b53f381059665dbabeeb0b50eb22b2d7d2d9b0aa7488ca70e67ac6c518adb8e78454a466501e89d81a45bf1ebc350896f2c3ae4b6679ecfbf9d32960d4f5b493125c7876ef36158562371193f600bc511000a67bdb7c664d018f99d9e589868d103d7e0994f166b2ba18ff7e67d8c4da749e44dfae1d930ae5397083a51675c409049dfb626a96246c0015ca696e94ebb767a20147834bf78b07fece3f0872b057c1c519ff882501995237d8206b0b3832f78753ebd8dcbd1d3d9f5ba733538113af6b407d960ec4353c50eb38ab29888238da843cd404ed8f4952f59e4bbc0035fc77a54846a9d419179c46af1b4a3b7fc98e4d312aaa29b9b7d79e739703dc0fa41c7280d5587709277ffa11c3620f5fba985b82c238ba19b17ebd027af9424be0941719919f620dd3bb3c3f11638363708aa11f858e153cf3a69bce69978b90e4a273836100aa1e617ba455cd00426847f"); - List fdroid3 = Arrays.asList("Guardian Project Archive", "https://guardianproject.info/fdroid/archive", "The official repository of The Guardian Project apps for use with F-Droid client. This contains older versions of applications from the main repository.", + List fdroid3 = Arrays.asList("Guardian Project Archive", "https://guardianproject.info/fdroid/archive", "The official repository of The Guardian Project apps for use with F-Droid client. This contains older versions of applications from the main repository.", "13", "0", "4", "ignore", "308205d8308203c0020900a397b4da7ecda034300d06092a864886f70d01010505003081ad310b30090603550406130255533111300f06035504080c084e657720596f726b3111300f06035504070c084e657720596f726b31143012060355040b0c0b4644726f6964205265706f31193017060355040a0c10477561726469616e2050726f6a656374311d301b06035504030c14677561726469616e70726f6a6563742e696e666f3128302606092a864886f70d0109011619726f6f7440677561726469616e70726f6a6563742e696e666f301e170d3134303632363139333931385a170d3431313131303139333931385a3081ad310b30090603550406130255533111300f06035504080c084e657720596f726b3111300f06035504070c084e657720596f726b31143012060355040b0c0b4644726f6964205265706f31193017060355040a0c10477561726469616e2050726f6a656374311d301b06035504030c14677561726469616e70726f6a6563742e696e666f3128302606092a864886f70d0109011619726f6f7440677561726469616e70726f6a6563742e696e666f30820222300d06092a864886f70d01010105000382020f003082020a0282020100b3cd79121b9b883843be3c4482e320809106b0a23755f1dd3c7f46f7d315d7bb2e943486d61fc7c811b9294dcc6b5baac4340f8db2b0d5e14749e7f35e1fc211fdbc1071b38b4753db201c314811bef885bd8921ad86facd6cc3b8f74d30a0b6e2e6e576f906e9581ef23d9c03e926e06d1f033f28bd1e21cfa6a0e3ff5c9d8246cf108d82b488b9fdd55d7de7ebb6a7f64b19e0d6b2ab1380a6f9d42361770d1956701a7f80e2de568acd0bb4527324b1e0973e89595d91c8cc102d9248525ae092e2c9b69f7414f724195b81427f28b1d3d09a51acfe354387915fd9521e8c890c125fc41a12bf34d2a1b304067ab7251e0e9ef41833ce109e76963b0b256395b16b886bca21b831f1408f836146019e7908829e716e72b81006610a2af08301de5d067c9e114a1e5759db8a6be6a3cc2806bcfe6fafd41b5bc9ddddb3dc33d6f605b1ca7d8a9e0ecdd6390d38906649e68a90a717bea80fa220170eea0c86fc78a7e10dac7b74b8e62045a3ecca54e035281fdc9fe5920a855fde3c0be522e3aef0c087524f13d973dff3768158b01a5800a060c06b451ec98d627dd052eda804d0556f60dbc490d94e6e9dea62ffcafb5beffbd9fc38fb2f0d7050004fe56b4dda0a27bc47554e1e0a7d764e17622e71f83a475db286bc7862deee1327e2028955d978272ea76bf0b88e70a18621aba59ff0c5993ef5f0e5d6b6b98e68b70203010001300d06092a864886f70d0101050500038202010079c79c8ef408a20d243d8bd8249fb9a48350dc19663b5e0fce67a8dbcb7de296c5ae7bbf72e98a2020fb78f2db29b54b0e24b181aa1c1d333cc0303685d6120b03216a913f96b96eb838f9bff125306ae3120af838c9fc07ebb5100125436bd24ec6d994d0bff5d065221871f8410daf536766757239bf594e61c5432c9817281b985263bada8381292e543a49814061ae11c92a316e7dc100327b59e3da90302c5ada68c6a50201bda1fcce800b53f381059665dbabeeb0b50eb22b2d7d2d9b0aa7488ca70e67ac6c518adb8e78454a466501e89d81a45bf1ebc350896f2c3ae4b6679ecfbf9d32960d4f5b493125c7876ef36158562371193f600bc511000a67bdb7c664d018f99d9e589868d103d7e0994f166b2ba18ff7e67d8c4da749e44dfae1d930ae5397083a51675c409049dfb626a96246c0015ca696e94ebb767a20147834bf78b07fece3f0872b057c1c519ff882501995237d8206b0b3832f78753ebd8dcbd1d3d9f5ba733538113af6b407d960ec4353c50eb38ab29888238da843cd404ed8f4952f59e4bbc0035fc77a54846a9d419179c46af1b4a3b7fc98e4d312aaa29b9b7d79e739703dc0fa41c7280d5587709277ffa11c3620f5fba985b82c238ba19b17ebd027af9424be0941719919f620dd3bb3c3f11638363708aa11f858e153cf3a69bce69978b90e4a273836100aa1e617ba455cd00426847f"); List shouldBeRepos = new LinkedList<>(); From dc19b11ae1afeb1545a230e8721d6f4b7c53d738 Mon Sep 17 00:00:00 2001 From: Dimitri Rusin Date: Wed, 8 Aug 2018 12:43:52 +0000 Subject: [PATCH 14/28] finished additional repos test --- .../fdroid/fdroid/data/RepoProviderTest.java | 82 ++++++++++--------- 1 file changed, 44 insertions(+), 38 deletions(-) diff --git a/app/src/test/java/org/fdroid/fdroid/data/RepoProviderTest.java b/app/src/test/java/org/fdroid/fdroid/data/RepoProviderTest.java index 40e68a1e4..a7b0b190d 100644 --- a/app/src/test/java/org/fdroid/fdroid/data/RepoProviderTest.java +++ b/app/src/test/java/org/fdroid/fdroid/data/RepoProviderTest.java @@ -38,6 +38,7 @@ import org.robolectric.annotation.Config; import java.util.Date; import java.util.LinkedList; import java.util.List; +import java.io.FileOutputStream; import java.util.Arrays; import static org.junit.Assert.assertEquals; @@ -189,45 +190,50 @@ public class RepoProviderTest extends FDroidProviderTest { 7) pubkey */ String packageName = context.getPackageName(); - FileOutputStream outputStream = new FileOutputStream("/oem/etc/" + packageName + "/additional_repos.xml"); - outputStream.write((" - - + String filepath = "/oem/etc/" + packageName + "/additional_repos.xml"; + try { + FileOutputStream outputStream = new FileOutputStream(filepath); + outputStream.write(("" + + "" + + "" + +"" + +"oem0Name" + +"" + +"https://www.oem0.com/yeah/repo" + +"" + +"I'm the first oem repo." + +"" + +"22" + +"" + +"1" + +"" + +"ignore" + +"" + +"fffff2313aaaaabcccc111" - - oem0Name - - https://www.oem0.com/yeah/repo - - I'm the first oem repo. - - 22 - - 1 - - ignore - - fffff2313aaaaabcccc111 - - - oem1MyNameIs - - https://www.mynameis.com/rapper/repo - - Who is the first repo? - - 22 - - 0 - - ignore - - ddddddd2313aaaaabcccc111 - - - " - ).getBytes()); - outputStream.close(); + +"" + +"oem1MyNameIs" + +"" + +"https://www.mynameis.com/rapper/repo" + +"" + +"Who is the first repo?" + +"" + +"22" + +"" + +"0" + +"" + +"ignore" + +"" + +"ddddddd2313aaaaabcccc111" + +"" + +"" + ).getBytes()); + outputStream.close(); + } catch (Exception e) { + Utils.debugLog("RepoProviderTest::canAddAdditionalRepos()", "failed creating/writing file " + filepath); + Utils.debugLog("RepoProviderTest::canAddAdditionalRepos()", e.getMessage()); + return; + } // Load the actual repos List defaultRepos = DBHelper.loadDefaultRepos(context); From 5a6d2df3ac6ff3f5d1dcbb4b3c076b0eaf8408b4 Mon Sep 17 00:00:00 2001 From: Dimitri Rusin Date: Thu, 20 Sep 2018 12:19:35 +0000 Subject: [PATCH 15/28] removed stars from imports --- .../java/org/fdroid/fdroid/data/DBHelper.java | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/org/fdroid/fdroid/data/DBHelper.java b/app/src/main/java/org/fdroid/fdroid/data/DBHelper.java index 6edc1e281..f7942b2cd 100644 --- a/app/src/main/java/org/fdroid/fdroid/data/DBHelper.java +++ b/app/src/main/java/org/fdroid/fdroid/data/DBHelper.java @@ -42,10 +42,17 @@ import org.fdroid.fdroid.data.Schema.CatJoinTable; import org.fdroid.fdroid.data.Schema.InstalledAppTable; import org.fdroid.fdroid.data.Schema.PackageTable; import org.fdroid.fdroid.data.Schema.RepoTable; - -import java.util.*; -import java.io.*; -import org.xmlpull.v1.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.LinkedList; +import java.util.List; +import java.io.FileInputStream; +import java.io.InputStream; +import java.io.File; +import java.io.IOException; +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserFactory; +import org.xmlpull.v1.XmlPullParserException; /** * This is basically a singleton used to represent the database at the core From dd08655d43a7529988b9284a718adf2a27602000 Mon Sep 17 00:00:00 2001 From: Dimitri Rusin Date: Thu, 20 Sep 2018 19:12:14 +0000 Subject: [PATCH 16/28] changed the tests: now testing only DBHelper.parseXmlRepos() --- .../java/org/fdroid/fdroid/data/DBHelper.java | 2 +- .../org/fdroid/fdroid/data/DBHelperTest.java | 246 ++++++++++++++++++ .../fdroid/fdroid/data/RepoProviderTest.java | 89 ------- 3 files changed, 247 insertions(+), 90 deletions(-) create mode 100644 app/src/test/java/org/fdroid/fdroid/data/DBHelperTest.java diff --git a/app/src/main/java/org/fdroid/fdroid/data/DBHelper.java b/app/src/main/java/org/fdroid/fdroid/data/DBHelper.java index f7942b2cd..952a6af98 100644 --- a/app/src/main/java/org/fdroid/fdroid/data/DBHelper.java +++ b/app/src/main/java/org/fdroid/fdroid/data/DBHelper.java @@ -332,7 +332,7 @@ public class DBHelper extends SQLiteOpenHelper { /* * Take an xml file in the same format as the internal default_repos.xml and parse it into a list of items. */ - private static List parseXmlRepos(File defaultReposFile) throws IOException, XmlPullParserException { + public static List parseXmlRepos(File defaultReposFile) throws IOException, XmlPullParserException { List defaultRepos = new LinkedList<>(); InputStream xmlInputStream = null; xmlInputStream = new FileInputStream(defaultReposFile); diff --git a/app/src/test/java/org/fdroid/fdroid/data/DBHelperTest.java b/app/src/test/java/org/fdroid/fdroid/data/DBHelperTest.java new file mode 100644 index 000000000..82cabd5a1 --- /dev/null +++ b/app/src/test/java/org/fdroid/fdroid/data/DBHelperTest.java @@ -0,0 +1,246 @@ +package org.fdroid.fdroid.data; + +import android.app.Application; +import android.content.ContentValues; +import android.content.Context; +import android.net.Uri; +import android.support.annotation.Nullable; +import org.fdroid.fdroid.BuildConfig; +import org.fdroid.fdroid.R; +import org.fdroid.fdroid.Utils; +import org.fdroid.fdroid.data.Schema.RepoTable; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.annotation.Config; +import java.util.Date; +import java.util.LinkedList; +import java.io.FileOutputStream; +import java.util.Arrays; +import java.util.ArrayList; +import java.util.List; +import static org.junit.Assert.assertEquals; + +import java.io.FileInputStream; +import java.io.InputStream; +import java.io.File; +import java.io.IOException; +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserFactory; +import org.xmlpull.v1.XmlPullParserException; +import static org.fdroid.fdroid.Assert.assertCantDelete; +import static org.fdroid.fdroid.Assert.assertResultCount; +import static org.fdroid.fdroid.Assert.insertApp; +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.fail; + +public class DBHelperTest { + static final String TAG = "DBHelperTest"; + + private List parseXmlStringIntoRepos(String xml) throws IOException, XmlPullParserException { + String reposXmlPath = "/data/repos.xml"; + + FileOutputStream outputStream = new FileOutputStream(reposXmlPath); + outputStream.write(xml.getBytes()); + outputStream.close(); + + // Now parse that xml file + List additionalRepos = DBHelper.parseXmlRepos(new File(reposXmlPath)); + return additionalRepos; + } + + @Test + public void parseXmlReposNegativeTest() { + String wrongXml; + boolean success = false; + + // Try parsing invalid xml files + wrongXml = ""; + try { + parseXmlStringIntoRepos(wrongXml); + } catch (IOException io) { + fail("IOException: " + io.getMessage()); + } catch (XmlPullParserException xppe) { + // good + } + + wrongXml = "" + + "" + + "" + +"" + +"" + +"https://www.oem0.com/yeah/repo" + +"" + +"I'm the first oem repo." + +"" + +"22" + +"" + +"1" + +"" + +"ignore" + +"" + +"fffff2313aaaaabcccc111" + +"" + +""; + try { + parseXmlStringIntoRepos(wrongXml); + fail("Invalid xml read successfully --> Wrong"); + } catch (IOException io) { + fail("IOException: " + io.getMessage()); + } catch (XmlPullParserException xppe) { + // good + } + + wrongXml = "" + + "" + + "" + +"" + +"https://www.oem0.com/yeah/repo" + +"" + +"I'm the first oem repo." + +"" + +"22" + +"" + +"1" + +"" + +"ignore" + +"" + +"fffff2313aaaaabcccc111" + +"" + +""; + try { + parseXmlStringIntoRepos(wrongXml); + fail("Invalid xml read successfully --> Wrong"); + } catch (IOException io) { + fail("IOException: " + io.getMessage()); + } catch (XmlPullParserException xppe) { + // good + } + + wrongXml = "" + + "" + + "" + +""; + try { + parseXmlStringIntoRepos(wrongXml); + fail("Invalid xml read successfully --> Wrong"); + } catch (IOException io) { + fail("IOException: " + io.getMessage()); + } catch (XmlPullParserException xppe) { + // good + } + + wrongXml = "" + +"https://www.oem0.com/yeah/repo" + +"" + +"I'm the first oem repo." + +"" + +"22" + +"" + +"1" + +"" + +"ignore" + +"" + +"fffff2313aaaaabcccc111" + +"" + +""; + try { + parseXmlStringIntoRepos(wrongXml); + fail("Invalid xml read successfully --> Wrong"); + } catch (IOException io) { + fail("IOException: " + io.getMessage()); + } catch (XmlPullParserException xppe) { + // good + } + + // Parse valid xml but make sure that only tags are parsed + String validXml = "" + +"HAHA" + +"https://www.oem0.com/yeah/repo" + +"I'm the first oem repo." + +"22" + +"1" + +"ignore" + +"fffff2313aaaaabcccc111" + +""; + + List repos; + try { + repos = parseXmlStringIntoRepos(validXml); + assertEquals(repos.size(), 6); + assertEquals(repos.get(0), "https://www.oem0.com/yeah/repo"); + } catch (IOException io) { + fail("IOException. Valid xml did not get parsed!"); + } catch (XmlPullParserException xppe) { + fail("XmlPullParserException. Valid xml did not get parsed!"); + } + } + + @Test + public void parseXmlReposPositiveTest() { + // Parse valid xml file + String reposXmlContent = "" + + "" + + "" + +"" + +"oem0Name" + +"" + +"https://www.oem0.com/yeah/repo" + +"" + +"I'm the first oem repo." + +"" + +"22" + +"" + +"1" + +"" + +"ignore" + +"" + +"fffff2313aaaaabcccc111" + + +"" + +"oem1MyNameIs" + +"" + +"https://www.mynameis.com/rapper/repo" + +"" + +"Who is the first repo?" + +"" + +"22" + +"" + +"0" + +"" + +"ignore" + +"" + +"ddddddd2313aaaaabcccc111" + +"" + +""; + + // Now parse that xml file + List additionalRepos; + try { + additionalRepos = parseXmlStringIntoRepos(reposXmlContent); + } catch (IOException io) { + fail("IOException. Failed parsing xml string into repos."); + return; + } catch (XmlPullParserException xppe) { + fail("XmlPullParserException. Failed parsing xml string into repos."); + return; + } + + // We should have loaded these repos + List oem0 = Arrays.asList("oem0Name", "https://www.oem0.com/yeah/repo", "I'm the first oem repo.", + "22", "1", "ignore", "fffff2313aaaaabcccc111"); + List oem1 = Arrays.asList("oem1MyNameIs", "https://www.mynameis.com/rapper/repo", "Who is the first repo?", + "22", "0", "ignore", "ddddddd2313aaaaabcccc111"); + List shouldBeRepos = new LinkedList<>(); + shouldBeRepos.addAll(oem0); + shouldBeRepos.addAll(oem1); + + assertEquals(additionalRepos.size(), shouldBeRepos.size()); + for (int i = 0; i < additionalRepos.size(); i++) { + assertEquals(shouldBeRepos.get(i), additionalRepos.get(i)); + } + } +} diff --git a/app/src/test/java/org/fdroid/fdroid/data/RepoProviderTest.java b/app/src/test/java/org/fdroid/fdroid/data/RepoProviderTest.java index a7b0b190d..1ffec96f1 100644 --- a/app/src/test/java/org/fdroid/fdroid/data/RepoProviderTest.java +++ b/app/src/test/java/org/fdroid/fdroid/data/RepoProviderTest.java @@ -176,95 +176,6 @@ public class RepoProviderTest extends FDroidProviderTest { } } - @Test - public void canAddAdditionalRepos() { - /* - Repo is structured as follows: - 0) name - 1) address - 2) description - 3) version - 4) enabled - 5) priority (actually ignored in this use case) - 6) pushRequests - 7) pubkey - */ - String packageName = context.getPackageName(); - String filepath = "/oem/etc/" + packageName + "/additional_repos.xml"; - try { - FileOutputStream outputStream = new FileOutputStream(filepath); - outputStream.write(("" - + "" - + "" - +"" - +"oem0Name" - +"" - +"https://www.oem0.com/yeah/repo" - +"" - +"I'm the first oem repo." - +"" - +"22" - +"" - +"1" - +"" - +"ignore" - +"" - +"fffff2313aaaaabcccc111" - - +"" - +"oem1MyNameIs" - +"" - +"https://www.mynameis.com/rapper/repo" - +"" - +"Who is the first repo?" - +"" - +"22" - +"" - +"0" - +"" - +"ignore" - +"" - +"ddddddd2313aaaaabcccc111" - +"" - +"" - ).getBytes()); - outputStream.close(); - } catch (Exception e) { - Utils.debugLog("RepoProviderTest::canAddAdditionalRepos()", "failed creating/writing file " + filepath); - Utils.debugLog("RepoProviderTest::canAddAdditionalRepos()", e.getMessage()); - return; - } - - // Load the actual repos - List defaultRepos = DBHelper.loadDefaultRepos(context); - - // Construct the repos that we should have loaded - List oem0 = Arrays.asList("oem0Name", "https://www.oem0.com/yeah/repo", "I'm the first oem repo.", - "22", "1", "0", "ignore", "fffff2313aaaaabcccc111"); - List oem1 = Arrays.asList("oem1MyNameIs", "https://www.mynameis.com/rapper/repo", "Who is the first repo?", - "22", "0", "0", "ignore", "ddddddd2313aaaaabcccc111"); - List fdroid0 = Arrays.asList("F-Droid", "https://f-droid.org/repo", "The official F-Droid repository. Applications in this repository are mostly built directory from the source code. Some are official binaries built by the original application developers - these will be replaced by source-built versions over time.", - "13", "1", "1", "ignore", "3082035e30820246a00302010202044c49cd00300d06092a864886f70d01010505003071310b300906035504061302554b3110300e06035504081307556e6b6e6f776e3111300f0603550407130857657468657262793110300e060355040a1307556e6b6e6f776e3110300e060355040b1307556e6b6e6f776e311930170603550403131043696172616e2047756c746e69656b73301e170d3130303732333137313032345a170d3337313230383137313032345a3071310b300906035504061302554b3110300e06035504081307556e6b6e6f776e3111300f0603550407130857657468657262793110300e060355040a1307556e6b6e6f776e3110300e060355040b1307556e6b6e6f776e311930170603550403131043696172616e2047756c746e69656b7330820122300d06092a864886f70d01010105000382010f003082010a028201010096d075e47c014e7822c89fd67f795d23203e2a8843f53ba4e6b1bf5f2fd0e225938267cfcae7fbf4fe596346afbaf4070fdb91f66fbcdf2348a3d92430502824f80517b156fab00809bdc8e631bfa9afd42d9045ab5fd6d28d9e140afc1300917b19b7c6c4df4a494cf1f7cb4a63c80d734265d735af9e4f09455f427aa65a53563f87b336ca2c19d244fcbba617ba0b19e56ed34afe0b253ab91e2fdb1271f1b9e3c3232027ed8862a112f0706e234cf236914b939bcf959821ecb2a6c18057e070de3428046d94b175e1d89bd795e535499a091f5bc65a79d539a8d43891ec504058acb28c08393b5718b57600a211e803f4a634e5c57f25b9b8c4422c6fd90203010001300d06092a864886f70d0101050500038201010008e4ef699e9807677ff56753da73efb2390d5ae2c17e4db691d5df7a7b60fc071ae509c5414be7d5da74df2811e83d3668c4a0b1abc84b9fa7d96b4cdf30bba68517ad2a93e233b042972ac0553a4801c9ebe07bf57ebe9a3b3d6d663965260e50f3b8f46db0531761e60340a2bddc3426098397fda54044a17e5244549f9869b460ca5e6e216b6f6a2db0580b480ca2afe6ec6b46eedacfa4aa45038809ece0c5978653d6c85f678e7f5a2156d1bedd8117751e64a4b0dcd140f3040b021821a8d93aed8d01ba36db6c82372211fed714d9a32607038cdfd565bd529ffc637212aaa2c224ef22b603eccefb5bf1e085c191d4b24fe742b17ab3f55d4e6f05ef"); - List fdroid1 = Arrays.asList("F-Droid Archive", "https://f-droid.org/archive", "The archive repository of the F-Droid client. This contains older versions of applications from the main repository.", - "13", "0", "2", "ignore", "3082035e30820246a00302010202044c49cd00300d06092a864886f70d01010505003071310b300906035504061302554b3110300e06035504081307556e6b6e6f776e3111300f0603550407130857657468657262793110300e060355040a1307556e6b6e6f776e3110300e060355040b1307556e6b6e6f776e311930170603550403131043696172616e2047756c746e69656b73301e170d3130303732333137313032345a170d3337313230383137313032345a3071310b300906035504061302554b3110300e06035504081307556e6b6e6f776e3111300f0603550407130857657468657262793110300e060355040a1307556e6b6e6f776e3110300e060355040b1307556e6b6e6f776e311930170603550403131043696172616e2047756c746e69656b7330820122300d06092a864886f70d01010105000382010f003082010a028201010096d075e47c014e7822c89fd67f795d23203e2a8843f53ba4e6b1bf5f2fd0e225938267cfcae7fbf4fe596346afbaf4070fdb91f66fbcdf2348a3d92430502824f80517b156fab00809bdc8e631bfa9afd42d9045ab5fd6d28d9e140afc1300917b19b7c6c4df4a494cf1f7cb4a63c80d734265d735af9e4f09455f427aa65a53563f87b336ca2c19d244fcbba617ba0b19e56ed34afe0b253ab91e2fdb1271f1b9e3c3232027ed8862a112f0706e234cf236914b939bcf959821ecb2a6c18057e070de3428046d94b175e1d89bd795e535499a091f5bc65a79d539a8d43891ec504058acb28c08393b5718b57600a211e803f4a634e5c57f25b9b8c4422c6fd90203010001300d06092a864886f70d0101050500038201010008e4ef699e9807677ff56753da73efb2390d5ae2c17e4db691d5df7a7b60fc071ae509c5414be7d5da74df2811e83d3668c4a0b1abc84b9fa7d96b4cdf30bba68517ad2a93e233b042972ac0553a4801c9ebe07bf57ebe9a3b3d6d663965260e50f3b8f46db0531761e60340a2bddc3426098397fda54044a17e5244549f9869b460ca5e6e216b6f6a2db0580b480ca2afe6ec6b46eedacfa4aa45038809ece0c5978653d6c85f678e7f5a2156d1bedd8117751e64a4b0dcd140f3040b021821a8d93aed8d01ba36db6c82372211fed714d9a32607038cdfd565bd529ffc637212aaa2c224ef22b603eccefb5bf1e085c191d4b24fe742b17ab3f55d4e6f05ef"); - List fdroid2 = Arrays.asList("Guardian Project", "https://guardianproject.info/fdroid/repo", "The official app repository of The Guardian Project. Applications in this repository are official binaries build by the original application developers and signed by the same key as the APKs that are released in the Google Play store.", - "13", "0", "3", "ignore", "308205d8308203c0020900a397b4da7ecda034300d06092a864886f70d01010505003081ad310b30090603550406130255533111300f06035504080c084e657720596f726b3111300f06035504070c084e657720596f726b31143012060355040b0c0b4644726f6964205265706f31193017060355040a0c10477561726469616e2050726f6a656374311d301b06035504030c14677561726469616e70726f6a6563742e696e666f3128302606092a864886f70d0109011619726f6f7440677561726469616e70726f6a6563742e696e666f301e170d3134303632363139333931385a170d3431313131303139333931385a3081ad310b30090603550406130255533111300f06035504080c084e657720596f726b3111300f06035504070c084e657720596f726b31143012060355040b0c0b4644726f6964205265706f31193017060355040a0c10477561726469616e2050726f6a656374311d301b06035504030c14677561726469616e70726f6a6563742e696e666f3128302606092a864886f70d0109011619726f6f7440677561726469616e70726f6a6563742e696e666f30820222300d06092a864886f70d01010105000382020f003082020a0282020100b3cd79121b9b883843be3c4482e320809106b0a23755f1dd3c7f46f7d315d7bb2e943486d61fc7c811b9294dcc6b5baac4340f8db2b0d5e14749e7f35e1fc211fdbc1071b38b4753db201c314811bef885bd8921ad86facd6cc3b8f74d30a0b6e2e6e576f906e9581ef23d9c03e926e06d1f033f28bd1e21cfa6a0e3ff5c9d8246cf108d82b488b9fdd55d7de7ebb6a7f64b19e0d6b2ab1380a6f9d42361770d1956701a7f80e2de568acd0bb4527324b1e0973e89595d91c8cc102d9248525ae092e2c9b69f7414f724195b81427f28b1d3d09a51acfe354387915fd9521e8c890c125fc41a12bf34d2a1b304067ab7251e0e9ef41833ce109e76963b0b256395b16b886bca21b831f1408f836146019e7908829e716e72b81006610a2af08301de5d067c9e114a1e5759db8a6be6a3cc2806bcfe6fafd41b5bc9ddddb3dc33d6f605b1ca7d8a9e0ecdd6390d38906649e68a90a717bea80fa220170eea0c86fc78a7e10dac7b74b8e62045a3ecca54e035281fdc9fe5920a855fde3c0be522e3aef0c087524f13d973dff3768158b01a5800a060c06b451ec98d627dd052eda804d0556f60dbc490d94e6e9dea62ffcafb5beffbd9fc38fb2f0d7050004fe56b4dda0a27bc47554e1e0a7d764e17622e71f83a475db286bc7862deee1327e2028955d978272ea76bf0b88e70a18621aba59ff0c5993ef5f0e5d6b6b98e68b70203010001300d06092a864886f70d0101050500038202010079c79c8ef408a20d243d8bd8249fb9a48350dc19663b5e0fce67a8dbcb7de296c5ae7bbf72e98a2020fb78f2db29b54b0e24b181aa1c1d333cc0303685d6120b03216a913f96b96eb838f9bff125306ae3120af838c9fc07ebb5100125436bd24ec6d994d0bff5d065221871f8410daf536766757239bf594e61c5432c9817281b985263bada8381292e543a49814061ae11c92a316e7dc100327b59e3da90302c5ada68c6a50201bda1fcce800b53f381059665dbabeeb0b50eb22b2d7d2d9b0aa7488ca70e67ac6c518adb8e78454a466501e89d81a45bf1ebc350896f2c3ae4b6679ecfbf9d32960d4f5b493125c7876ef36158562371193f600bc511000a67bdb7c664d018f99d9e589868d103d7e0994f166b2ba18ff7e67d8c4da749e44dfae1d930ae5397083a51675c409049dfb626a96246c0015ca696e94ebb767a20147834bf78b07fece3f0872b057c1c519ff882501995237d8206b0b3832f78753ebd8dcbd1d3d9f5ba733538113af6b407d960ec4353c50eb38ab29888238da843cd404ed8f4952f59e4bbc0035fc77a54846a9d419179c46af1b4a3b7fc98e4d312aaa29b9b7d79e739703dc0fa41c7280d5587709277ffa11c3620f5fba985b82c238ba19b17ebd027af9424be0941719919f620dd3bb3c3f11638363708aa11f858e153cf3a69bce69978b90e4a273836100aa1e617ba455cd00426847f"); - List fdroid3 = Arrays.asList("Guardian Project Archive", "https://guardianproject.info/fdroid/archive", "The official repository of The Guardian Project apps for use with F-Droid client. This contains older versions of applications from the main repository.", - "13", "0", "4", "ignore", "308205d8308203c0020900a397b4da7ecda034300d06092a864886f70d01010505003081ad310b30090603550406130255533111300f06035504080c084e657720596f726b3111300f06035504070c084e657720596f726b31143012060355040b0c0b4644726f6964205265706f31193017060355040a0c10477561726469616e2050726f6a656374311d301b06035504030c14677561726469616e70726f6a6563742e696e666f3128302606092a864886f70d0109011619726f6f7440677561726469616e70726f6a6563742e696e666f301e170d3134303632363139333931385a170d3431313131303139333931385a3081ad310b30090603550406130255533111300f06035504080c084e657720596f726b3111300f06035504070c084e657720596f726b31143012060355040b0c0b4644726f6964205265706f31193017060355040a0c10477561726469616e2050726f6a656374311d301b06035504030c14677561726469616e70726f6a6563742e696e666f3128302606092a864886f70d0109011619726f6f7440677561726469616e70726f6a6563742e696e666f30820222300d06092a864886f70d01010105000382020f003082020a0282020100b3cd79121b9b883843be3c4482e320809106b0a23755f1dd3c7f46f7d315d7bb2e943486d61fc7c811b9294dcc6b5baac4340f8db2b0d5e14749e7f35e1fc211fdbc1071b38b4753db201c314811bef885bd8921ad86facd6cc3b8f74d30a0b6e2e6e576f906e9581ef23d9c03e926e06d1f033f28bd1e21cfa6a0e3ff5c9d8246cf108d82b488b9fdd55d7de7ebb6a7f64b19e0d6b2ab1380a6f9d42361770d1956701a7f80e2de568acd0bb4527324b1e0973e89595d91c8cc102d9248525ae092e2c9b69f7414f724195b81427f28b1d3d09a51acfe354387915fd9521e8c890c125fc41a12bf34d2a1b304067ab7251e0e9ef41833ce109e76963b0b256395b16b886bca21b831f1408f836146019e7908829e716e72b81006610a2af08301de5d067c9e114a1e5759db8a6be6a3cc2806bcfe6fafd41b5bc9ddddb3dc33d6f605b1ca7d8a9e0ecdd6390d38906649e68a90a717bea80fa220170eea0c86fc78a7e10dac7b74b8e62045a3ecca54e035281fdc9fe5920a855fde3c0be522e3aef0c087524f13d973dff3768158b01a5800a060c06b451ec98d627dd052eda804d0556f60dbc490d94e6e9dea62ffcafb5beffbd9fc38fb2f0d7050004fe56b4dda0a27bc47554e1e0a7d764e17622e71f83a475db286bc7862deee1327e2028955d978272ea76bf0b88e70a18621aba59ff0c5993ef5f0e5d6b6b98e68b70203010001300d06092a864886f70d0101050500038202010079c79c8ef408a20d243d8bd8249fb9a48350dc19663b5e0fce67a8dbcb7de296c5ae7bbf72e98a2020fb78f2db29b54b0e24b181aa1c1d333cc0303685d6120b03216a913f96b96eb838f9bff125306ae3120af838c9fc07ebb5100125436bd24ec6d994d0bff5d065221871f8410daf536766757239bf594e61c5432c9817281b985263bada8381292e543a49814061ae11c92a316e7dc100327b59e3da90302c5ada68c6a50201bda1fcce800b53f381059665dbabeeb0b50eb22b2d7d2d9b0aa7488ca70e67ac6c518adb8e78454a466501e89d81a45bf1ebc350896f2c3ae4b6679ecfbf9d32960d4f5b493125c7876ef36158562371193f600bc511000a67bdb7c664d018f99d9e589868d103d7e0994f166b2ba18ff7e67d8c4da749e44dfae1d930ae5397083a51675c409049dfb626a96246c0015ca696e94ebb767a20147834bf78b07fece3f0872b057c1c519ff882501995237d8206b0b3832f78753ebd8dcbd1d3d9f5ba733538113af6b407d960ec4353c50eb38ab29888238da843cd404ed8f4952f59e4bbc0035fc77a54846a9d419179c46af1b4a3b7fc98e4d312aaa29b9b7d79e739703dc0fa41c7280d5587709277ffa11c3620f5fba985b82c238ba19b17ebd027af9424be0941719919f620dd3bb3c3f11638363708aa11f858e153cf3a69bce69978b90e4a273836100aa1e617ba455cd00426847f"); - - List shouldBeRepos = new LinkedList<>(); - shouldBeRepos.addAll(oem0); - shouldBeRepos.addAll(oem1); - shouldBeRepos.addAll(fdroid0); - shouldBeRepos.addAll(fdroid1); - shouldBeRepos.addAll(fdroid2); - shouldBeRepos.addAll(fdroid3); - - for (int i = 0; i < defaultRepos.size(); i++) { - assertEquals(shouldBeRepos.get(i), defaultRepos.get(i)); - } - } - @Test public void canAddRepo() { From 95c375ac26ceb5ca2ed5ece08eaa0dee17b992b1 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Tue, 16 Oct 2018 16:47:54 +0200 Subject: [PATCH 17/28] fix DBHelperTest to actually load and parse additional_repos.xml --- .../org/fdroid/fdroid/data/DBHelperTest.java | 490 ++++++++++-------- .../fdroid/fdroid/data/RepoProviderTest.java | 3 - app/src/test/resources/additional_repos.xml | 34 ++ .../test/resources/ugly_additional_repos.xml | 31 ++ 4 files changed, 345 insertions(+), 213 deletions(-) create mode 100644 app/src/test/resources/additional_repos.xml create mode 100644 app/src/test/resources/ugly_additional_repos.xml diff --git a/app/src/test/java/org/fdroid/fdroid/data/DBHelperTest.java b/app/src/test/java/org/fdroid/fdroid/data/DBHelperTest.java index 82cabd5a1..0c7929036 100644 --- a/app/src/test/java/org/fdroid/fdroid/data/DBHelperTest.java +++ b/app/src/test/java/org/fdroid/fdroid/data/DBHelperTest.java @@ -1,246 +1,316 @@ package org.fdroid.fdroid.data; -import android.app.Application; -import android.content.ContentValues; import android.content.Context; -import android.net.Uri; -import android.support.annotation.Nullable; -import org.fdroid.fdroid.BuildConfig; -import org.fdroid.fdroid.R; -import org.fdroid.fdroid.Utils; -import org.fdroid.fdroid.data.Schema.RepoTable; +import android.support.test.InstrumentationRegistry; +import android.util.Log; +import org.apache.commons.io.IOUtils; +import org.fdroid.fdroid.TestUtils; +import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.robolectric.RobolectricTestRunner; -import org.robolectric.annotation.Config; -import java.util.Date; -import java.util.LinkedList; -import java.io.FileOutputStream; -import java.util.Arrays; -import java.util.ArrayList; -import java.util.List; -import static org.junit.Assert.assertEquals; - -import java.io.FileInputStream; -import java.io.InputStream; -import java.io.File; -import java.io.IOException; -import org.xmlpull.v1.XmlPullParser; -import org.xmlpull.v1.XmlPullParserFactory; import org.xmlpull.v1.XmlPullParserException; -import static org.fdroid.fdroid.Assert.assertCantDelete; -import static org.fdroid.fdroid.Assert.assertResultCount; -import static org.fdroid.fdroid.Assert.insertApp; -import static org.junit.Assert.assertArrayEquals; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.Arrays; +import java.util.LinkedList; +import java.util.List; + import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; import static org.junit.Assert.fail; +@RunWith(RobolectricTestRunner.class) public class DBHelperTest { - static final String TAG = "DBHelperTest"; + static final String TAG = "DBHelperTest"; - private List parseXmlStringIntoRepos(String xml) throws IOException, XmlPullParserException { - String reposXmlPath = "/data/repos.xml"; + private List getReposFromXml(String xml) throws IOException, XmlPullParserException { + File additionalReposXml = File.createTempFile("." + context.getPackageName() + "-DBHelperTest_", + "_additional_repos.xml"); + Log.i(TAG, "additionalReposXml: " + additionalReposXml); - FileOutputStream outputStream = new FileOutputStream(reposXmlPath); - outputStream.write(xml.getBytes()); - outputStream.close(); + FileOutputStream outputStream = new FileOutputStream(additionalReposXml); + outputStream.write(xml.getBytes()); + outputStream.close(); - // Now parse that xml file - List additionalRepos = DBHelper.parseXmlRepos(new File(reposXmlPath)); - return additionalRepos; + // Now parse that xml file + return DBHelper.parseXmlRepos(additionalReposXml); + } + + protected Context context; + + @Before + public final void setupBase() { + context = InstrumentationRegistry.getContext(); } @Test - public void parseXmlReposNegativeTest() { - String wrongXml; - boolean success = false; + public void parseAdditionalReposXmlAllOneLineTest() throws IOException, XmlPullParserException { + String oneRepoXml = "\n" + + "" + + "\n" + + "" + + "F-Droid" + + "" + + "https://f-droid.org/repo" + + "" + + "The official F-Droid repository. Applications in this repository are mostly built" + + "directory from the source code. Some are official binaries built by the original" + + "application developers - these will be replaced by source-built versions over time." + + "" + + "" + + "13" + + "" + + "1" + + "" + + "ignore" + + "" + + "" + + "3082035e30820246a00302010202044c49cd00300d06092a864886f70d01010505003071310b300906035504061302554b3110300e06035504081307556e6b6e6f776e3111300f0603550407130857657468657262793110300e060355040a1307556e6b6e6f776e3110300e060355040b1307556e6b6e6f776e311930170603550403131043696172616e2047756c746e69656b73301e170d3130303732333137313032345a170d3337313230383137313032345a3071310b300906035504061302554b3110300e06035504081307556e6b6e6f776e3111300f0603550407130857657468657262793110300e060355040a1307556e6b6e6f776e3110300e060355040b1307556e6b6e6f776e311930170603550403131043696172616e2047756c746e69656b7330820122300d06092a864886f70d01010105000382010f003082010a028201010096d075e47c014e7822c89fd67f795d23203e2a8843f53ba4e6b1bf5f2fd0e225938267cfcae7fbf4fe596346afbaf4070fdb91f66fbcdf2348a3d92430502824f80517b156fab00809bdc8e631bfa9afd42d9045ab5fd6d28d9e140afc1300917b19b7c6c4df4a494cf1f7cb4a63c80d734265d735af9e4f09455f427aa65a53563f87b336ca2c19d244fcbba617ba0b19e56ed34afe0b253ab91e2fdb1271f1b9e3c3232027ed8862a112f0706e234cf236914b939bcf959821ecb2a6c18057e070de3428046d94b175e1d89bd795e535499a091f5bc65a79d539a8d43891ec504058acb28c08393b5718b57600a211e803f4a634e5c57f25b9b8c4422c6fd90203010001300d06092a864886f70d0101050500038201010008e4ef699e9807677ff56753da73efb2390d5ae2c17e4db691d5df7a7b60fc071ae509c5414be7d5da74df2811e83d3668c4a0b1abc84b9fa7d96b4cdf30bba68517ad2a93e233b042972ac0553a4801c9ebe07bf57ebe9a3b3d6d663965260e50f3b8f46db0531761e60340a2bddc3426098397fda54044a17e5244549f9869b460ca5e6e216b6f6a2db0580b480ca2afe6ec6b46eedacfa4aa45038809ece0c5978653d6c85f678e7f5a2156d1bedd8117751e64a4b0dcd140f3040b021821a8d93aed8d01ba36db6c82372211fed714d9a32607038cdfd565bd529ffc637212aaa2c224ef22b603eccefb5bf1e085c191d4b24fe742b17ab3f55d4e6f05ef" + + "" + + "" + + ""; + List repos = getReposFromXml(oneRepoXml); + assertEquals("Should contain one repo's worth of items", DBHelper.REPO_XML_ARG_COUNT, repos.size()); + } - // Try parsing invalid xml files - wrongXml = ""; - try { - parseXmlStringIntoRepos(wrongXml); - } catch (IOException io) { - fail("IOException: " + io.getMessage()); - } catch (XmlPullParserException xppe) { - // good - } + @Test + public void parseAdditionalReposXmlIncludedPriorityTest() throws IOException, XmlPullParserException { + String wrongXml = "" + + "" + + "\n" + + "" + + "F-Droid" + + "" + + "https://f-droid.org/repo" + + "" + + "The official F-Droid repository. Applications in this repository are mostly built" + + "directory from the source code. Some are official binaries built by the original" + + "application developers - these will be replaced by source-built versions over time." + + "" + + "" + + "13" + + "" + + "1" + + "" + + "1" + + "" + + "ignore" + + "" + + "" + + "3082035e30820246a00302010202044c49cd00300d06092a864886f70d01010505003071310b300906035504061302554b3110300e06035504081307556e6b6e6f776e3111300f0603550407130857657468657262793110300e060355040a1307556e6b6e6f776e3110300e060355040b1307556e6b6e6f776e311930170603550403131043696172616e2047756c746e69656b73301e170d3130303732333137313032345a170d3337313230383137313032345a3071310b300906035504061302554b3110300e06035504081307556e6b6e6f776e3111300f0603550407130857657468657262793110300e060355040a1307556e6b6e6f776e3110300e060355040b1307556e6b6e6f776e311930170603550403131043696172616e2047756c746e69656b7330820122300d06092a864886f70d01010105000382010f003082010a028201010096d075e47c014e7822c89fd67f795d23203e2a8843f53ba4e6b1bf5f2fd0e225938267cfcae7fbf4fe596346afbaf4070fdb91f66fbcdf2348a3d92430502824f80517b156fab00809bdc8e631bfa9afd42d9045ab5fd6d28d9e140afc1300917b19b7c6c4df4a494cf1f7cb4a63c80d734265d735af9e4f09455f427aa65a53563f87b336ca2c19d244fcbba617ba0b19e56ed34afe0b253ab91e2fdb1271f1b9e3c3232027ed8862a112f0706e234cf236914b939bcf959821ecb2a6c18057e070de3428046d94b175e1d89bd795e535499a091f5bc65a79d539a8d43891ec504058acb28c08393b5718b57600a211e803f4a634e5c57f25b9b8c4422c6fd90203010001300d06092a864886f70d0101050500038201010008e4ef699e9807677ff56753da73efb2390d5ae2c17e4db691d5df7a7b60fc071ae509c5414be7d5da74df2811e83d3668c4a0b1abc84b9fa7d96b4cdf30bba68517ad2a93e233b042972ac0553a4801c9ebe07bf57ebe9a3b3d6d663965260e50f3b8f46db0531761e60340a2bddc3426098397fda54044a17e5244549f9869b460ca5e6e216b6f6a2db0580b480ca2afe6ec6b46eedacfa4aa45038809ece0c5978653d6c85f678e7f5a2156d1bedd8117751e64a4b0dcd140f3040b021821a8d93aed8d01ba36db6c82372211fed714d9a32607038cdfd565bd529ffc637212aaa2c224ef22b603eccefb5bf1e085c191d4b24fe742b17ab3f55d4e6f05ef" + + "" + + "" + + ""; + getReposFromXml(wrongXml); + List repos = getReposFromXml(wrongXml); + assertEquals("Should be empty", 0, repos.size()); + } - wrongXml = "" - + "" - + "" - +"" - +"" - +"https://www.oem0.com/yeah/repo" - +"" - +"I'm the first oem repo." - +"" - +"22" - +"" - +"1" - +"" - +"ignore" - +"" - +"fffff2313aaaaabcccc111" - +"" - +""; - try { - parseXmlStringIntoRepos(wrongXml); - fail("Invalid xml read successfully --> Wrong"); - } catch (IOException io) { - fail("IOException: " + io.getMessage()); - } catch (XmlPullParserException xppe) { - // good - } + @Test(expected = XmlPullParserException.class) + public void parseAdditionalReposXmlDoubleTagTest() throws IOException, XmlPullParserException { + String wrongXml = "" + + "" + + "" + + "" + + "https://www.oem0.com/yeah/repo" + + "" + + "I'm the first oem repo." + + "" + + "22" + + "" + + "1" + + "" + + "ignore" + + "" + + "fffff2313aaaaabcccc111" + + "" + + ""; + getReposFromXml(wrongXml); + fail("Invalid xml read successfully --> Wrong"); + } - wrongXml = "" - + "" - + "" - +"" - +"https://www.oem0.com/yeah/repo" - +"" - +"I'm the first oem repo." - +"" - +"22" - +"" - +"1" - +"" - +"ignore" - +"" - +"fffff2313aaaaabcccc111" - +"" - +""; - try { - parseXmlStringIntoRepos(wrongXml); - fail("Invalid xml read successfully --> Wrong"); - } catch (IOException io) { - fail("IOException: " + io.getMessage()); - } catch (XmlPullParserException xppe) { - // good - } + @Test(expected = XmlPullParserException.class) + public void parseAdditionalReposXmlMissingStartTagTest() throws IOException, XmlPullParserException { + String wrongXml = "" + + "https://www.oem0.com/yeah/repo" + + "" + + "I'm the first oem repo." + + "" + + "22" + + "" + + "1" + + "" + + "ignore" + + "" + + "fffff2313aaaaabcccc111" + + "" + + ""; + getReposFromXml(wrongXml); + fail("Invalid xml read successfully --> Wrong"); + } - wrongXml = "" - + "" - + "" - +""; - try { - parseXmlStringIntoRepos(wrongXml); - fail("Invalid xml read successfully --> Wrong"); - } catch (IOException io) { - fail("IOException: " + io.getMessage()); - } catch (XmlPullParserException xppe) { - // good - } + @Test + public void parseAdditionalReposXmlWrongCountTest() throws IOException, XmlPullParserException { + String wrongXml = "" + + "" + + "foo" + + ""; + List repos = getReposFromXml(wrongXml); + assertEquals("Should be empty", 0, repos.size()); + } - wrongXml = "" - +"https://www.oem0.com/yeah/repo" - +"" - +"I'm the first oem repo." - +"" - +"22" - +"" - +"1" - +"" - +"ignore" - +"" - +"fffff2313aaaaabcccc111" - +"" - +""; - try { - parseXmlStringIntoRepos(wrongXml); - fail("Invalid xml read successfully --> Wrong"); - } catch (IOException io) { - fail("IOException: " + io.getMessage()); - } catch (XmlPullParserException xppe) { - // good - } + /** + * Parse valid xml but make sure that only tags are parsed + */ + @Test + public void parseAdditionalReposXmlSloppyTest() throws IOException, XmlPullParserException { + InputStream input = TestUtils.class.getClassLoader().getResourceAsStream("ugly_additional_repos.xml"); + String validXml = IOUtils.toString(input, "UTF-8"); - // Parse valid xml but make sure that only tags are parsed - String validXml = "" - +"HAHA" - +"https://www.oem0.com/yeah/repo" - +"I'm the first oem repo." - +"22" - +"1" - +"ignore" - +"fffff2313aaaaabcccc111" - +""; + List repos = getReposFromXml(validXml); + assertEquals(2 * DBHelper.REPO_XML_ARG_COUNT, repos.size()); + assertEquals("Repo Name", repos.get(8)); + assertEquals("https://www.oem0.com/yeah/repo", repos.get(9)); + } - List repos; + @Test + public void parseAdditionalReposXmlPositiveTest() throws IOException { + InputStream input = TestUtils.class.getClassLoader().getResourceAsStream("additional_repos.xml"); + String reposXmlContent = IOUtils.toString(input, "UTF-8"); + + List additionalRepos; try { - repos = parseXmlStringIntoRepos(validXml); - assertEquals(repos.size(), 6); - assertEquals(repos.get(0), "https://www.oem0.com/yeah/repo"); + additionalRepos = getReposFromXml(reposXmlContent); } catch (IOException io) { - fail("IOException. Valid xml did not get parsed!"); + fail("IOException. Failed parsing xml string into repos."); + return; } catch (XmlPullParserException xppe) { - fail("XmlPullParserException. Valid xml did not get parsed!"); + fail("XmlPullParserException. Failed parsing xml string into repos."); + return; + } + + // We should have loaded these repos + List oem0 = Arrays.asList( + "oem0Name", + "https://www.oem0.com/yeah/repo", + "I'm the first oem repo.", + "22", + "1", + "0", // priority is inserted by DBHelper.parseAdditionalReposXml() + "ignore", + "fffff2313aaaaabcccc111"); + List oem1 = Arrays.asList( + "oem1MyNameIs", + "https://www.mynameis.com/rapper/repo", + "Who is the first repo?", + "22", + "0", + "0", // priority is inserted by DBHelper.parseAdditionalReposXml() + "ignore", + "ddddddd2313aaaaabcccc111"); + List shouldBeRepos = new LinkedList<>(); + shouldBeRepos.addAll(oem0); + shouldBeRepos.addAll(oem1); + + assertEquals(additionalRepos.size(), shouldBeRepos.size()); + for (int i = 0; i < additionalRepos.size(); i++) { + assertEquals(shouldBeRepos.get(i), additionalRepos.get(i)); } } + @Test - public void parseXmlReposPositiveTest() { - // Parse valid xml file - String reposXmlContent = "" - + "" - + "" - +"" - +"oem0Name" - +"" - +"https://www.oem0.com/yeah/repo" - +"" - +"I'm the first oem repo." - +"" - +"22" - +"" - +"1" - +"" - +"ignore" - +"" - +"fffff2313aaaaabcccc111" + public void canAddAdditionalRepos() throws IOException { + File oemEtcDir = new File("/oem/etc"); + File oemEtcPackageDir = new File(oemEtcDir, context.getPackageName()); + if (!oemEtcPackageDir.canWrite() || !oemEtcDir.canWrite()) { + if (oemEtcDir.canWrite() || new File("/").canWrite()) { + oemEtcPackageDir.mkdirs(); + } + if (!oemEtcPackageDir.isDirectory()) { + Log.e(TAG, "Cannot create " + oemEtcDir + ", skipping test!"); + return; + } + } - +"" - +"oem1MyNameIs" - +"" - +"https://www.mynameis.com/rapper/repo" - +"" - +"Who is the first repo?" - +"" - +"22" - +"" - +"0" - +"" - +"ignore" - +"" - +"ddddddd2313aaaaabcccc111" - +"" - +""; - - // Now parse that xml file - List additionalRepos; - try { - additionalRepos = parseXmlStringIntoRepos(reposXmlContent); - } catch (IOException io) { - fail("IOException. Failed parsing xml string into repos."); - return; - } catch (XmlPullParserException xppe) { - fail("XmlPullParserException. Failed parsing xml string into repos."); - return; - } + File additionalReposXmlFile = new File(oemEtcPackageDir, "additional_repos.xml"); + FileOutputStream outputStream = new FileOutputStream(additionalReposXmlFile); + outputStream.write(("" + + "" + + "" + + "" + + "oem0Name" + + "" + + "https://www.oem0.com/yeah/repo" + + "" + + "I'm the first oem repo." + + "" + + "22" + + "" + + "1" + + "" + + "ignore" + + "" + + "fffff2313aaaaabcccc111" - // We should have loaded these repos - List oem0 = Arrays.asList("oem0Name", "https://www.oem0.com/yeah/repo", "I'm the first oem repo.", - "22", "1", "ignore", "fffff2313aaaaabcccc111"); - List oem1 = Arrays.asList("oem1MyNameIs", "https://www.mynameis.com/rapper/repo", "Who is the first repo?", - "22", "0", "ignore", "ddddddd2313aaaaabcccc111"); - List shouldBeRepos = new LinkedList<>(); - shouldBeRepos.addAll(oem0); - shouldBeRepos.addAll(oem1); + + "" + + "oem1MyNameIs" + + "" + + "https://www.mynameis.com/rapper/repo" + + "" + + "Who is the first repo?" + + "" + + "22" + + "" + + "0" + + "" + + "ignore" + + "" + + "ddddddd2313aaaaabcccc111" + + "" + + "" + ). - assertEquals(additionalRepos.size(), shouldBeRepos.size()); - for (int i = 0; i < additionalRepos.size(); i++) { - assertEquals(shouldBeRepos.get(i), additionalRepos.get(i)); - } + getBytes()); + outputStream.close(); + + try { + List initialRepos = DBHelper.loadDefaultRepos(context); + + // Construct the repos that we should have loaded + List oem0 = Arrays.asList("oem0Name", "https://www.oem0.com/yeah/repo", "I'm the first oem repo.", + "22", "1", "0", "ignore", "fffff2313aaaaabcccc111"); + List oem1 = Arrays.asList("oem1MyNameIs", "https://www.mynameis.com/rapper/repo", "Who is the first repo?", + "22", "0", "0", "ignore", "ddddddd2313aaaaabcccc111"); + List fdroid0 = Arrays.asList("F-Droid", "https://f-droid.org/repo", "The official F-Droid repository. Applications in this repository are mostly built directory from the source code. Some are official binaries built by the original application developers - these will be replaced by source-built versions over time.", + "13", "1", "1", "ignore", "3082035e30820246a00302010202044c49cd00300d06092a864886f70d01010505003071310b300906035504061302554b3110300e06035504081307556e6b6e6f776e3111300f0603550407130857657468657262793110300e060355040a1307556e6b6e6f776e3110300e060355040b1307556e6b6e6f776e311930170603550403131043696172616e2047756c746e69656b73301e170d3130303732333137313032345a170d3337313230383137313032345a3071310b300906035504061302554b3110300e06035504081307556e6b6e6f776e3111300f0603550407130857657468657262793110300e060355040a1307556e6b6e6f776e3110300e060355040b1307556e6b6e6f776e311930170603550403131043696172616e2047756c746e69656b7330820122300d06092a864886f70d01010105000382010f003082010a028201010096d075e47c014e7822c89fd67f795d23203e2a8843f53ba4e6b1bf5f2fd0e225938267cfcae7fbf4fe596346afbaf4070fdb91f66fbcdf2348a3d92430502824f80517b156fab00809bdc8e631bfa9afd42d9045ab5fd6d28d9e140afc1300917b19b7c6c4df4a494cf1f7cb4a63c80d734265d735af9e4f09455f427aa65a53563f87b336ca2c19d244fcbba617ba0b19e56ed34afe0b253ab91e2fdb1271f1b9e3c3232027ed8862a112f0706e234cf236914b939bcf959821ecb2a6c18057e070de3428046d94b175e1d89bd795e535499a091f5bc65a79d539a8d43891ec504058acb28c08393b5718b57600a211e803f4a634e5c57f25b9b8c4422c6fd90203010001300d06092a864886f70d0101050500038201010008e4ef699e9807677ff56753da73efb2390d5ae2c17e4db691d5df7a7b60fc071ae509c5414be7d5da74df2811e83d3668c4a0b1abc84b9fa7d96b4cdf30bba68517ad2a93e233b042972ac0553a4801c9ebe07bf57ebe9a3b3d6d663965260e50f3b8f46db0531761e60340a2bddc3426098397fda54044a17e5244549f9869b460ca5e6e216b6f6a2db0580b480ca2afe6ec6b46eedacfa4aa45038809ece0c5978653d6c85f678e7f5a2156d1bedd8117751e64a4b0dcd140f3040b021821a8d93aed8d01ba36db6c82372211fed714d9a32607038cdfd565bd529ffc637212aaa2c224ef22b603eccefb5bf1e085c191d4b24fe742b17ab3f55d4e6f05ef"); + List fdroid1 = Arrays.asList("F-Droid Archive", "https://f-droid.org/archive", "The archive repository of the F-Droid client. This contains older versions of applications from the main repository.", + "13", "0", "2", "ignore", "3082035e30820246a00302010202044c49cd00300d06092a864886f70d01010505003071310b300906035504061302554b3110300e06035504081307556e6b6e6f776e3111300f0603550407130857657468657262793110300e060355040a1307556e6b6e6f776e3110300e060355040b1307556e6b6e6f776e311930170603550403131043696172616e2047756c746e69656b73301e170d3130303732333137313032345a170d3337313230383137313032345a3071310b300906035504061302554b3110300e06035504081307556e6b6e6f776e3111300f0603550407130857657468657262793110300e060355040a1307556e6b6e6f776e3110300e060355040b1307556e6b6e6f776e311930170603550403131043696172616e2047756c746e69656b7330820122300d06092a864886f70d01010105000382010f003082010a028201010096d075e47c014e7822c89fd67f795d23203e2a8843f53ba4e6b1bf5f2fd0e225938267cfcae7fbf4fe596346afbaf4070fdb91f66fbcdf2348a3d92430502824f80517b156fab00809bdc8e631bfa9afd42d9045ab5fd6d28d9e140afc1300917b19b7c6c4df4a494cf1f7cb4a63c80d734265d735af9e4f09455f427aa65a53563f87b336ca2c19d244fcbba617ba0b19e56ed34afe0b253ab91e2fdb1271f1b9e3c3232027ed8862a112f0706e234cf236914b939bcf959821ecb2a6c18057e070de3428046d94b175e1d89bd795e535499a091f5bc65a79d539a8d43891ec504058acb28c08393b5718b57600a211e803f4a634e5c57f25b9b8c4422c6fd90203010001300d06092a864886f70d0101050500038201010008e4ef699e9807677ff56753da73efb2390d5ae2c17e4db691d5df7a7b60fc071ae509c5414be7d5da74df2811e83d3668c4a0b1abc84b9fa7d96b4cdf30bba68517ad2a93e233b042972ac0553a4801c9ebe07bf57ebe9a3b3d6d663965260e50f3b8f46db0531761e60340a2bddc3426098397fda54044a17e5244549f9869b460ca5e6e216b6f6a2db0580b480ca2afe6ec6b46eedacfa4aa45038809ece0c5978653d6c85f678e7f5a2156d1bedd8117751e64a4b0dcd140f3040b021821a8d93aed8d01ba36db6c82372211fed714d9a32607038cdfd565bd529ffc637212aaa2c224ef22b603eccefb5bf1e085c191d4b24fe742b17ab3f55d4e6f05ef"); + List fdroid2 = Arrays.asList("Guardian Project", "https://guardianproject.info/fdroid/repo", "The official app repository of The Guardian Project. Applications in this repository are official binaries build by the original application developers and signed by the same key as the APKs that are released in the Google Play store.", + "13", "0", "3", "ignore", "308205d8308203c0020900a397b4da7ecda034300d06092a864886f70d01010505003081ad310b30090603550406130255533111300f06035504080c084e657720596f726b3111300f06035504070c084e657720596f726b31143012060355040b0c0b4644726f6964205265706f31193017060355040a0c10477561726469616e2050726f6a656374311d301b06035504030c14677561726469616e70726f6a6563742e696e666f3128302606092a864886f70d0109011619726f6f7440677561726469616e70726f6a6563742e696e666f301e170d3134303632363139333931385a170d3431313131303139333931385a3081ad310b30090603550406130255533111300f06035504080c084e657720596f726b3111300f06035504070c084e657720596f726b31143012060355040b0c0b4644726f6964205265706f31193017060355040a0c10477561726469616e2050726f6a656374311d301b06035504030c14677561726469616e70726f6a6563742e696e666f3128302606092a864886f70d0109011619726f6f7440677561726469616e70726f6a6563742e696e666f30820222300d06092a864886f70d01010105000382020f003082020a0282020100b3cd79121b9b883843be3c4482e320809106b0a23755f1dd3c7f46f7d315d7bb2e943486d61fc7c811b9294dcc6b5baac4340f8db2b0d5e14749e7f35e1fc211fdbc1071b38b4753db201c314811bef885bd8921ad86facd6cc3b8f74d30a0b6e2e6e576f906e9581ef23d9c03e926e06d1f033f28bd1e21cfa6a0e3ff5c9d8246cf108d82b488b9fdd55d7de7ebb6a7f64b19e0d6b2ab1380a6f9d42361770d1956701a7f80e2de568acd0bb4527324b1e0973e89595d91c8cc102d9248525ae092e2c9b69f7414f724195b81427f28b1d3d09a51acfe354387915fd9521e8c890c125fc41a12bf34d2a1b304067ab7251e0e9ef41833ce109e76963b0b256395b16b886bca21b831f1408f836146019e7908829e716e72b81006610a2af08301de5d067c9e114a1e5759db8a6be6a3cc2806bcfe6fafd41b5bc9ddddb3dc33d6f605b1ca7d8a9e0ecdd6390d38906649e68a90a717bea80fa220170eea0c86fc78a7e10dac7b74b8e62045a3ecca54e035281fdc9fe5920a855fde3c0be522e3aef0c087524f13d973dff3768158b01a5800a060c06b451ec98d627dd052eda804d0556f60dbc490d94e6e9dea62ffcafb5beffbd9fc38fb2f0d7050004fe56b4dda0a27bc47554e1e0a7d764e17622e71f83a475db286bc7862deee1327e2028955d978272ea76bf0b88e70a18621aba59ff0c5993ef5f0e5d6b6b98e68b70203010001300d06092a864886f70d0101050500038202010079c79c8ef408a20d243d8bd8249fb9a48350dc19663b5e0fce67a8dbcb7de296c5ae7bbf72e98a2020fb78f2db29b54b0e24b181aa1c1d333cc0303685d6120b03216a913f96b96eb838f9bff125306ae3120af838c9fc07ebb5100125436bd24ec6d994d0bff5d065221871f8410daf536766757239bf594e61c5432c9817281b985263bada8381292e543a49814061ae11c92a316e7dc100327b59e3da90302c5ada68c6a50201bda1fcce800b53f381059665dbabeeb0b50eb22b2d7d2d9b0aa7488ca70e67ac6c518adb8e78454a466501e89d81a45bf1ebc350896f2c3ae4b6679ecfbf9d32960d4f5b493125c7876ef36158562371193f600bc511000a67bdb7c664d018f99d9e589868d103d7e0994f166b2ba18ff7e67d8c4da749e44dfae1d930ae5397083a51675c409049dfb626a96246c0015ca696e94ebb767a20147834bf78b07fece3f0872b057c1c519ff882501995237d8206b0b3832f78753ebd8dcbd1d3d9f5ba733538113af6b407d960ec4353c50eb38ab29888238da843cd404ed8f4952f59e4bbc0035fc77a54846a9d419179c46af1b4a3b7fc98e4d312aaa29b9b7d79e739703dc0fa41c7280d5587709277ffa11c3620f5fba985b82c238ba19b17ebd027af9424be0941719919f620dd3bb3c3f11638363708aa11f858e153cf3a69bce69978b90e4a273836100aa1e617ba455cd00426847f"); + List fdroid3 = Arrays.asList("Guardian Project Archive", "https://guardianproject.info/fdroid/archive", "The official repository of The Guardian Project apps for use with F-Droid client. This contains older versions of applications from the main repository.", + "13", "0", "4", "ignore", "308205d8308203c0020900a397b4da7ecda034300d06092a864886f70d01010505003081ad310b30090603550406130255533111300f06035504080c084e657720596f726b3111300f06035504070c084e657720596f726b31143012060355040b0c0b4644726f6964205265706f31193017060355040a0c10477561726469616e2050726f6a656374311d301b06035504030c14677561726469616e70726f6a6563742e696e666f3128302606092a864886f70d0109011619726f6f7440677561726469616e70726f6a6563742e696e666f301e170d3134303632363139333931385a170d3431313131303139333931385a3081ad310b30090603550406130255533111300f06035504080c084e657720596f726b3111300f06035504070c084e657720596f726b31143012060355040b0c0b4644726f6964205265706f31193017060355040a0c10477561726469616e2050726f6a656374311d301b06035504030c14677561726469616e70726f6a6563742e696e666f3128302606092a864886f70d0109011619726f6f7440677561726469616e70726f6a6563742e696e666f30820222300d06092a864886f70d01010105000382020f003082020a0282020100b3cd79121b9b883843be3c4482e320809106b0a23755f1dd3c7f46f7d315d7bb2e943486d61fc7c811b9294dcc6b5baac4340f8db2b0d5e14749e7f35e1fc211fdbc1071b38b4753db201c314811bef885bd8921ad86facd6cc3b8f74d30a0b6e2e6e576f906e9581ef23d9c03e926e06d1f033f28bd1e21cfa6a0e3ff5c9d8246cf108d82b488b9fdd55d7de7ebb6a7f64b19e0d6b2ab1380a6f9d42361770d1956701a7f80e2de568acd0bb4527324b1e0973e89595d91c8cc102d9248525ae092e2c9b69f7414f724195b81427f28b1d3d09a51acfe354387915fd9521e8c890c125fc41a12bf34d2a1b304067ab7251e0e9ef41833ce109e76963b0b256395b16b886bca21b831f1408f836146019e7908829e716e72b81006610a2af08301de5d067c9e114a1e5759db8a6be6a3cc2806bcfe6fafd41b5bc9ddddb3dc33d6f605b1ca7d8a9e0ecdd6390d38906649e68a90a717bea80fa220170eea0c86fc78a7e10dac7b74b8e62045a3ecca54e035281fdc9fe5920a855fde3c0be522e3aef0c087524f13d973dff3768158b01a5800a060c06b451ec98d627dd052eda804d0556f60dbc490d94e6e9dea62ffcafb5beffbd9fc38fb2f0d7050004fe56b4dda0a27bc47554e1e0a7d764e17622e71f83a475db286bc7862deee1327e2028955d978272ea76bf0b88e70a18621aba59ff0c5993ef5f0e5d6b6b98e68b70203010001300d06092a864886f70d0101050500038202010079c79c8ef408a20d243d8bd8249fb9a48350dc19663b5e0fce67a8dbcb7de296c5ae7bbf72e98a2020fb78f2db29b54b0e24b181aa1c1d333cc0303685d6120b03216a913f96b96eb838f9bff125306ae3120af838c9fc07ebb5100125436bd24ec6d994d0bff5d065221871f8410daf536766757239bf594e61c5432c9817281b985263bada8381292e543a49814061ae11c92a316e7dc100327b59e3da90302c5ada68c6a50201bda1fcce800b53f381059665dbabeeb0b50eb22b2d7d2d9b0aa7488ca70e67ac6c518adb8e78454a466501e89d81a45bf1ebc350896f2c3ae4b6679ecfbf9d32960d4f5b493125c7876ef36158562371193f600bc511000a67bdb7c664d018f99d9e589868d103d7e0994f166b2ba18ff7e67d8c4da749e44dfae1d930ae5397083a51675c409049dfb626a96246c0015ca696e94ebb767a20147834bf78b07fece3f0872b057c1c519ff882501995237d8206b0b3832f78753ebd8dcbd1d3d9f5ba733538113af6b407d960ec4353c50eb38ab29888238da843cd404ed8f4952f59e4bbc0035fc77a54846a9d419179c46af1b4a3b7fc98e4d312aaa29b9b7d79e739703dc0fa41c7280d5587709277ffa11c3620f5fba985b82c238ba19b17ebd027af9424be0941719919f620dd3bb3c3f11638363708aa11f858e153cf3a69bce69978b90e4a273836100aa1e617ba455cd00426847f"); + + List shouldBeRepos = new LinkedList<>(); + shouldBeRepos.addAll(oem0); + shouldBeRepos.addAll(oem1); + shouldBeRepos.addAll(fdroid0); + shouldBeRepos.addAll(fdroid1); + shouldBeRepos.addAll(fdroid2); + shouldBeRepos.addAll(fdroid3); + + for (int i = 0; i < initialRepos.size(); i++) { + assertEquals(shouldBeRepos.get(i), initialRepos.get(i)); + } + } finally { + for (Repo repo : RepoProvider.Helper.all(context, new String[]{Schema.RepoTable.Cols._ID})) { + RepoProvider.Helper.remove(context, repo.getId()); + } + additionalReposXmlFile.delete(); + DBHelper.clearDbHelperSingleton(); + } } } diff --git a/app/src/test/java/org/fdroid/fdroid/data/RepoProviderTest.java b/app/src/test/java/org/fdroid/fdroid/data/RepoProviderTest.java index 1ffec96f1..378ef8cfa 100644 --- a/app/src/test/java/org/fdroid/fdroid/data/RepoProviderTest.java +++ b/app/src/test/java/org/fdroid/fdroid/data/RepoProviderTest.java @@ -36,10 +36,7 @@ import org.robolectric.RobolectricTestRunner; import org.robolectric.annotation.Config; import java.util.Date; -import java.util.LinkedList; import java.util.List; -import java.io.FileOutputStream; -import java.util.Arrays; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; diff --git a/app/src/test/resources/additional_repos.xml b/app/src/test/resources/additional_repos.xml new file mode 100644 index 000000000..da6fa4c1c --- /dev/null +++ b/app/src/test/resources/additional_repos.xml @@ -0,0 +1,34 @@ + + + + + oem0Name + + https://www.oem0.com/yeah/repo + + I'm the first oem repo. + + 22 + + 1 + + ignore + + fffff2313aaaaabcccc111 + + + oem1MyNameIs + + https://www.mynameis.com/rapper/repo + + Who is the first repo? + + 22 + + 0 + + ignore + + ddddddd2313aaaaabcccc111 + + diff --git a/app/src/test/resources/ugly_additional_repos.xml b/app/src/test/resources/ugly_additional_repos.xml new file mode 100644 index 000000000..a91932d88 --- /dev/null +++ b/app/src/test/resources/ugly_additional_repos.xml @@ -0,0 +1,31 @@ + + + + + FTW + + https://f-droid.org/repo + + I'm the first oem repo. + + 22 + + 1 + + prompt + + fffff2313aaaaabcccc111 + + + SHOULD BE IGNORED + Repo Name + https://www.oem0.com/yeah/repo + I'm the second oem repo. + 22 + 1 + SHOULD BE IGNORED + SHOULD BE IGNORED + always + fffff2313aaaaabcccc111 + + From b529e10c4aec6eff6b7dd5d89513386d9789fb4d Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Tue, 16 Oct 2018 16:48:50 +0200 Subject: [PATCH 18/28] priority is NOT ignored, just additional_repos.xml is not allowed to set --- app/src/main/java/org/fdroid/fdroid/data/DBHelper.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/org/fdroid/fdroid/data/DBHelper.java b/app/src/main/java/org/fdroid/fdroid/data/DBHelper.java index 952a6af98..3602e98e1 100644 --- a/app/src/main/java/org/fdroid/fdroid/data/DBHelper.java +++ b/app/src/main/java/org/fdroid/fdroid/data/DBHelper.java @@ -274,7 +274,7 @@ public class DBHelper extends SQLiteOpenHelper { defaultRepos.get(i + 2), // description defaultRepos.get(i + 3), // version defaultRepos.get(i + 4), // enabled - Integer.toString(i), // priority; currently ignored + defaultRepos.get(i + 5), // priority defaultRepos.get(i + 6), // pushRequests defaultRepos.get(i + 7) // pubkey ); From 7eb53518aa8ce83774a2c21dc3aa0a0a0879546f Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Tue, 16 Oct 2018 16:55:37 +0200 Subject: [PATCH 19/28] move comments to javadoc --- .../java/org/fdroid/fdroid/data/DBHelper.java | 43 +++++++++---------- 1 file changed, 21 insertions(+), 22 deletions(-) diff --git a/app/src/main/java/org/fdroid/fdroid/data/DBHelper.java b/app/src/main/java/org/fdroid/fdroid/data/DBHelper.java index 3602e98e1..0b967a48e 100644 --- a/app/src/main/java/org/fdroid/fdroid/data/DBHelper.java +++ b/app/src/main/java/org/fdroid/fdroid/data/DBHelper.java @@ -281,14 +281,16 @@ public class DBHelper extends SQLiteOpenHelper { } } + /** + * Load additional repos first, then internal repos. This way, internal repos will be shown after the OEM-added + * ones on the Manage Repos screen. + */ public static List loadDefaultRepos(Context context) throws IllegalArgumentException { - // Load additional repos first, then internal repos. This way, internal repos will be shown after the OEM-added ones on the Manage Repos screen. String packageName = context.getPackageName(); List defaultRepos = DBHelper.loadAdditionalRepos(packageName); List internalRepos = Arrays.asList(context.getResources().getStringArray(R.array.default_repos)); defaultRepos.addAll(internalRepos); - // Insert all the repos into the database if (defaultRepos.size() % REPO_XML_ARG_COUNT != 0) { throw new IllegalArgumentException( "At least one of the internally or externally loaded default repos does not have " + REPO_XML_ARG_COUNT + " entries."); @@ -297,16 +299,17 @@ public class DBHelper extends SQLiteOpenHelper { return defaultRepos; } - /* - * Look for external repositories under { "/system", "/vendor", "/odm", "/oem" } - * If ROOT is one of those paths and 'packageName' is the name of the package - * that contains this class, then we look under 'root'/etc/'packageName'/additional_repos.xml - */ + /** + * Look for additional, initial repositories from the device's filesystem. + * These can be added as part of the ROM ({@code /system} or included later + * by vendors/OEMs ({@code /vendor}, {@code /odm}, {@code /oem}). These are + * always added at a lower priority than the repos embedded in the APK via + * {@code default_repos.xml}. + *

+ * ROM has the lowest priority, then Vendor, ODM, and OEM. + */ private static List loadAdditionalRepos(String packageName) { - // First, take the built-in repos. List externalRepos = new LinkedList<>(); - - // Second, take the external repos. We will later prioritize the repos according their order in the list externalRepos. for (String root : Arrays.asList("/system", "/vendor", "/odm", "/oem")) { String additionalReposPath = root + "/etc/" + packageName + "/additional_repos.xml"; try { @@ -329,9 +332,14 @@ public class DBHelper extends SQLiteOpenHelper { return externalRepos; } - /* - * Take an xml file in the same format as the internal default_repos.xml and parse it into a list of items. - */ + /** + * Parse {@code additional_repos.xml} into a list of items. Walk through + * all TEXT pieces of the xml file and put them into a single list of repo + * elements. Each repo is defined as eight elements in that list. + * {@code additional_repos.xml} has seven elements per repo because it is + * not allowed to set the priority since that would give it the power to + * override {@code default_repos.xml}. + */ public static List parseXmlRepos(File defaultReposFile) throws IOException, XmlPullParserException { List defaultRepos = new LinkedList<>(); InputStream xmlInputStream = null; @@ -341,28 +349,19 @@ public class DBHelper extends SQLiteOpenHelper { XmlPullParser parser = factory.newPullParser(); parser.setInput(xmlInputStream, "UTF-8"); - // Type of piece of xml file, can be END_DOCUMENT, TEXT, END_TAG, START_TAG, ... int eventType = parser.getEventType(); - - /* Walk through all TEXT pieces of the xml file and put them into our list of default repos. - * This could be improved by structuring the content for example into a list of lists where each contained list represents a repository, but - * we do it the traditional way. - */ boolean isItem = false; while (eventType != XmlPullParser.END_DOCUMENT) { String tagname = parser.getName(); switch (eventType) { - // If an item starts, remember that in isItem case XmlPullParser.START_TAG: if (tagname.equals("item")) { isItem = true; } break; - // If an item ends, also remember that in isItem case XmlPullParser.END_TAG: isItem = false; break; - // If this is a textblock of an item tag, extract that into defaultRepos case XmlPullParser.TEXT: if (isItem) { defaultRepos.add(new String(parser.getText())); // This is a piece of real information in the xml file From b9b7dab2c46f48b75102c19c670d509df437fb70 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Tue, 16 Oct 2018 17:08:32 +0200 Subject: [PATCH 20/28] fix additional_repos.xml handling to be properly parsed additional_repos.xml has 7 elements per repo, while default_repos.xml has 8. The difference is that additional_repos.xml does not have the "priority" since it is not allowed to override anything that is set in default_repos.xml. see spec in !705 --- .../java/org/fdroid/fdroid/data/DBHelper.java | 60 ++++++++++--------- 1 file changed, 33 insertions(+), 27 deletions(-) diff --git a/app/src/main/java/org/fdroid/fdroid/data/DBHelper.java b/app/src/main/java/org/fdroid/fdroid/data/DBHelper.java index 0b967a48e..43bba9b7d 100644 --- a/app/src/main/java/org/fdroid/fdroid/data/DBHelper.java +++ b/app/src/main/java/org/fdroid/fdroid/data/DBHelper.java @@ -42,17 +42,18 @@ import org.fdroid.fdroid.data.Schema.CatJoinTable; import org.fdroid.fdroid.data.Schema.InstalledAppTable; import org.fdroid.fdroid.data.Schema.PackageTable; import org.fdroid.fdroid.data.Schema.RepoTable; +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; +import org.xmlpull.v1.XmlPullParserFactory; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; import java.util.ArrayList; import java.util.Arrays; import java.util.LinkedList; import java.util.List; -import java.io.FileInputStream; -import java.io.InputStream; -import java.io.File; -import java.io.IOException; -import org.xmlpull.v1.XmlPullParser; -import org.xmlpull.v1.XmlPullParserFactory; -import org.xmlpull.v1.XmlPullParserException; /** * This is basically a singleton used to represent the database at the core @@ -282,8 +283,11 @@ public class DBHelper extends SQLiteOpenHelper { } /** - * Load additional repos first, then internal repos. This way, internal repos will be shown after the OEM-added - * ones on the Manage Repos screen. + * Load additional repos first, then internal repos. This way, internal + * repos will be shown after the OEM-added ones on the Manage Repos + * screen. This throws a hard {@code Exception} on parse errors since + * this file is built into the APK. So it should fail as hard and fast + * as possible so the developer catches the problem. */ public static List loadDefaultRepos(Context context) throws IllegalArgumentException { String packageName = context.getPackageName(); @@ -292,8 +296,8 @@ public class DBHelper extends SQLiteOpenHelper { defaultRepos.addAll(internalRepos); if (defaultRepos.size() % REPO_XML_ARG_COUNT != 0) { - throw new IllegalArgumentException( - "At least one of the internally or externally loaded default repos does not have " + REPO_XML_ARG_COUNT + " entries."); + throw new IllegalArgumentException("default_repos.xml has wrong item count: " + + defaultRepos.size() + " % REPO_XML_ARG_COUNT(" + REPO_XML_ARG_COUNT + ") != 0"); } return defaultRepos; @@ -311,24 +315,16 @@ public class DBHelper extends SQLiteOpenHelper { private static List loadAdditionalRepos(String packageName) { List externalRepos = new LinkedList<>(); for (String root : Arrays.asList("/system", "/vendor", "/odm", "/oem")) { - String additionalReposPath = root + "/etc/" + packageName + "/additional_repos.xml"; + File defaultReposFile = new File(root + "/etc/" + packageName + "/additional_repos.xml"); try { - File defaultReposFile = new File(additionalReposPath); - if (defaultReposFile.exists() && defaultReposFile.isFile()) { + if (defaultReposFile.isFile()) { externalRepos.addAll(DBHelper.parseXmlRepos(defaultReposFile)); } } catch (Exception e) { - Utils.debugLog(TAG, "Error loading " + additionalReposPath); - Utils.debugLog(TAG, "Exception: " + e.getMessage()); - continue; + Log.e(TAG, "Error loading " + defaultReposFile + ": " + e.getMessage()); } } - final int PRIORITY_INDEX = 5; - for (int i = PRIORITY_INDEX; i < externalRepos.size(); i += REPO_XML_ARG_COUNT) { - externalRepos.add(i, "0"); - } - return externalRepos; } @@ -342,8 +338,7 @@ public class DBHelper extends SQLiteOpenHelper { */ public static List parseXmlRepos(File defaultReposFile) throws IOException, XmlPullParserException { List defaultRepos = new LinkedList<>(); - InputStream xmlInputStream = null; - xmlInputStream = new FileInputStream(defaultReposFile); + InputStream xmlInputStream = new FileInputStream(additionalReposFile); XmlPullParserFactory factory = XmlPullParserFactory.newInstance(); factory.setNamespaceAware(true); XmlPullParser parser = factory.newPullParser(); @@ -364,15 +359,26 @@ public class DBHelper extends SQLiteOpenHelper { break; case XmlPullParser.TEXT: if (isItem) { - defaultRepos.add(new String(parser.getText())); // This is a piece of real information in the xml file + defaultRepos.add(parser.getText()); } break; } eventType = parser.next(); } - xmlInputStream.close(); - return defaultRepos; + + final int PRIORITY_INDEX = 5; + for (int i = PRIORITY_INDEX; i < defaultRepos.size(); i += REPO_XML_ARG_COUNT) { + defaultRepos.add(i, "0"); + } + + if (defaultRepos.size() % REPO_XML_ARG_COUNT == 0) { + return defaultRepos; + } + + Log.e(TAG, "Ignoring " + additionalReposFile + ", wrong number of items: " + + defaultRepos.size() + " % " + (REPO_XML_ARG_COUNT - 1) + " != 0"); + return new LinkedList<>(); } @Override From e8264d7dbb6a0448c2a20b62048a1def420ddf88 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Tue, 16 Oct 2018 17:10:11 +0200 Subject: [PATCH 21/28] rename REPO_XML_ARG_COUNT to REPO_XML_ITEM_COUNT --- .../java/org/fdroid/fdroid/data/DBHelper.java | 26 +++++++++---------- .../org/fdroid/fdroid/data/DBHelperTest.java | 4 +-- .../fdroid/fdroid/data/RepoProviderTest.java | 6 ++--- 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/app/src/main/java/org/fdroid/fdroid/data/DBHelper.java b/app/src/main/java/org/fdroid/fdroid/data/DBHelper.java index 43bba9b7d..a79618823 100644 --- a/app/src/main/java/org/fdroid/fdroid/data/DBHelper.java +++ b/app/src/main/java/org/fdroid/fdroid/data/DBHelper.java @@ -65,7 +65,7 @@ import java.util.List; public class DBHelper extends SQLiteOpenHelper { private static final String TAG = "DBHelper"; - public static final int REPO_XML_ARG_COUNT = 8; + public static final int REPO_XML_ITEM_COUNT = 8; private static DBHelper instance; private static final String DATABASE_NAME = "fdroid"; @@ -267,7 +267,7 @@ public class DBHelper extends SQLiteOpenHelper { List defaultRepos = DBHelper.loadDefaultRepos(context); - for (int i = 0; i < defaultRepos.size(); i += REPO_XML_ARG_COUNT) { + for (int i = 0; i < defaultRepos.size(); i += REPO_XML_ITEM_COUNT) { insertRepo( db, defaultRepos.get(i), // name @@ -295,9 +295,9 @@ public class DBHelper extends SQLiteOpenHelper { List internalRepos = Arrays.asList(context.getResources().getStringArray(R.array.default_repos)); defaultRepos.addAll(internalRepos); - if (defaultRepos.size() % REPO_XML_ARG_COUNT != 0) { + if (defaultRepos.size() % REPO_XML_ITEM_COUNT != 0) { throw new IllegalArgumentException("default_repos.xml has wrong item count: " + - defaultRepos.size() + " % REPO_XML_ARG_COUNT(" + REPO_XML_ARG_COUNT + ") != 0"); + defaultRepos.size() + " % REPO_XML_ARG_COUNT(" + REPO_XML_ITEM_COUNT + ") != 0"); } return defaultRepos; @@ -368,16 +368,16 @@ public class DBHelper extends SQLiteOpenHelper { xmlInputStream.close(); final int PRIORITY_INDEX = 5; - for (int i = PRIORITY_INDEX; i < defaultRepos.size(); i += REPO_XML_ARG_COUNT) { + for (int i = PRIORITY_INDEX; i < defaultRepos.size(); i += REPO_XML_ITEM_COUNT) { defaultRepos.add(i, "0"); } - if (defaultRepos.size() % REPO_XML_ARG_COUNT == 0) { + if (defaultRepos.size() % REPO_XML_ITEM_COUNT == 0) { return defaultRepos; } Log.e(TAG, "Ignoring " + additionalReposFile + ", wrong number of items: " - + defaultRepos.size() + " % " + (REPO_XML_ARG_COUNT - 1) + " != 0"); + + defaultRepos.size() + " % " + (REPO_XML_ITEM_COUNT - 1) + " != 0"); return new LinkedList<>(); } @@ -703,10 +703,10 @@ public class DBHelper extends SQLiteOpenHelper { String[] defaultRepos = context.getResources().getStringArray(R.array.default_repos); String fdroidPubKey = defaultRepos[7]; String fdroidAddress = defaultRepos[1]; - String fdroidArchiveAddress = defaultRepos[REPO_XML_ARG_COUNT + 1]; - String gpPubKey = defaultRepos[REPO_XML_ARG_COUNT * 2 + 7]; - String gpAddress = defaultRepos[REPO_XML_ARG_COUNT * 2 + 1]; - String gpArchiveAddress = defaultRepos[REPO_XML_ARG_COUNT * 3 + 1]; + String fdroidArchiveAddress = defaultRepos[REPO_XML_ITEM_COUNT + 1]; + String gpPubKey = defaultRepos[REPO_XML_ITEM_COUNT * 2 + 7]; + String gpAddress = defaultRepos[REPO_XML_ITEM_COUNT * 2 + 1]; + String gpArchiveAddress = defaultRepos[REPO_XML_ITEM_COUNT * 3 + 1]; updateRepoPriority(db, fdroidPubKey, fdroidAddress, 1); updateRepoPriority(db, fdroidPubKey, fdroidArchiveAddress, 2); @@ -957,8 +957,8 @@ public class DBHelper extends SQLiteOpenHelper { } String[] defaultRepos = context.getResources().getStringArray(R.array.default_repos); - for (int i = 0; i < defaultRepos.length / REPO_XML_ARG_COUNT; i++) { - int offset = i * REPO_XML_ARG_COUNT; + for (int i = 0; i < defaultRepos.length / REPO_XML_ITEM_COUNT; i++) { + int offset = i * REPO_XML_ITEM_COUNT; insertNameAndDescription(db, defaultRepos[offset], // name defaultRepos[offset + 1], // address diff --git a/app/src/test/java/org/fdroid/fdroid/data/DBHelperTest.java b/app/src/test/java/org/fdroid/fdroid/data/DBHelperTest.java index 0c7929036..8a24c5466 100644 --- a/app/src/test/java/org/fdroid/fdroid/data/DBHelperTest.java +++ b/app/src/test/java/org/fdroid/fdroid/data/DBHelperTest.java @@ -73,7 +73,7 @@ public class DBHelperTest { "" + ""; List repos = getReposFromXml(oneRepoXml); - assertEquals("Should contain one repo's worth of items", DBHelper.REPO_XML_ARG_COUNT, repos.size()); + assertEquals("Should contain one repo's worth of items", DBHelper.REPO_XML_ITEM_COUNT, repos.size()); } @Test @@ -171,7 +171,7 @@ public class DBHelperTest { String validXml = IOUtils.toString(input, "UTF-8"); List repos = getReposFromXml(validXml); - assertEquals(2 * DBHelper.REPO_XML_ARG_COUNT, repos.size()); + assertEquals(2 * DBHelper.REPO_XML_ITEM_COUNT, repos.size()); assertEquals("Repo Name", repos.get(8)); assertEquals("https://www.oem0.com/yeah/repo", repos.get(9)); } diff --git a/app/src/test/java/org/fdroid/fdroid/data/RepoProviderTest.java b/app/src/test/java/org/fdroid/fdroid/data/RepoProviderTest.java index 378ef8cfa..5bd1abbae 100644 --- a/app/src/test/java/org/fdroid/fdroid/data/RepoProviderTest.java +++ b/app/src/test/java/org/fdroid/fdroid/data/RepoProviderTest.java @@ -157,12 +157,12 @@ public class RepoProviderTest extends FDroidProviderTest { assertEquals(defaultRepos.size(), 4); // based on app/src/main/res/default_repo.xml String[] reposFromXml = context.getResources().getStringArray(R.array.default_repos); - if (reposFromXml.length % DBHelper.REPO_XML_ARG_COUNT != 0) { + if (reposFromXml.length % DBHelper.REPO_XML_ITEM_COUNT != 0) { throw new IllegalArgumentException( "default_repo.xml array does not have the right number of elements"); } - for (int i = 0; i < reposFromXml.length / DBHelper.REPO_XML_ARG_COUNT; i++) { - int offset = i * DBHelper.REPO_XML_ARG_COUNT; + for (int i = 0; i < reposFromXml.length / DBHelper.REPO_XML_ITEM_COUNT; i++) { + int offset = i * DBHelper.REPO_XML_ITEM_COUNT; assertRepo( defaultRepos.get(i), reposFromXml[offset + 1], // address From aace086da42fa3d9be3b313a379a3d12bd749b5e Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Tue, 16 Oct 2018 17:16:33 +0200 Subject: [PATCH 22/28] separate defaultRepos from initialRepos, which includes additionalRepos --- .../java/org/fdroid/fdroid/data/DBHelper.java | 43 ++++++++++--------- .../org/fdroid/fdroid/data/DBHelperTest.java | 2 +- 2 files changed, 24 insertions(+), 21 deletions(-) diff --git a/app/src/main/java/org/fdroid/fdroid/data/DBHelper.java b/app/src/main/java/org/fdroid/fdroid/data/DBHelper.java index a79618823..1e4ff4b84 100644 --- a/app/src/main/java/org/fdroid/fdroid/data/DBHelper.java +++ b/app/src/main/java/org/fdroid/fdroid/data/DBHelper.java @@ -265,42 +265,45 @@ public class DBHelper extends SQLiteOpenHelper { db.execSQL(CREATE_TABLE_APK_ANTI_FEATURE_JOIN); ensureIndexes(db); - List defaultRepos = DBHelper.loadDefaultRepos(context); + List initialRepos = DBHelper.loadInitialRepos(context); - for (int i = 0; i < defaultRepos.size(); i += REPO_XML_ITEM_COUNT) { + for (int i = 0; i < initialRepos.size(); i += REPO_XML_ITEM_COUNT) { insertRepo( db, - defaultRepos.get(i), // name - defaultRepos.get(i + 1), // address - defaultRepos.get(i + 2), // description - defaultRepos.get(i + 3), // version - defaultRepos.get(i + 4), // enabled - defaultRepos.get(i + 5), // priority - defaultRepos.get(i + 6), // pushRequests - defaultRepos.get(i + 7) // pubkey + initialRepos.get(i), // name + initialRepos.get(i + 1), // address + initialRepos.get(i + 2), // description + initialRepos.get(i + 3), // version + initialRepos.get(i + 4), // enabled + initialRepos.get(i + 5), // priority + initialRepos.get(i + 6), // pushRequests + initialRepos.get(i + 7) // pubkey ); } } /** - * Load additional repos first, then internal repos. This way, internal - * repos will be shown after the OEM-added ones on the Manage Repos + * Load Additional Repos first, then Default Repos. This way, Default + * Repos will be shown after the OEM-added ones on the Manage Repos * screen. This throws a hard {@code Exception} on parse errors since - * this file is built into the APK. So it should fail as hard and fast + * Default Repos are built into the APK. So it should fail as hard and fast * as possible so the developer catches the problem. + *

+ * Additional Repos ({@code additional_repos.xml}) come from the ROM, + * while Default Repos ({@code default_repos.xml} is built into the APK. */ - public static List loadDefaultRepos(Context context) throws IllegalArgumentException { + public static List loadInitialRepos(Context context) throws IllegalArgumentException { String packageName = context.getPackageName(); - List defaultRepos = DBHelper.loadAdditionalRepos(packageName); - List internalRepos = Arrays.asList(context.getResources().getStringArray(R.array.default_repos)); - defaultRepos.addAll(internalRepos); + List initialRepos = DBHelper.loadAdditionalRepos(packageName); + List defaultRepos = Arrays.asList(context.getResources().getStringArray(R.array.default_repos)); + initialRepos.addAll(defaultRepos); - if (defaultRepos.size() % REPO_XML_ITEM_COUNT != 0) { + if (initialRepos.size() % REPO_XML_ITEM_COUNT != 0) { throw new IllegalArgumentException("default_repos.xml has wrong item count: " + - defaultRepos.size() + " % REPO_XML_ARG_COUNT(" + REPO_XML_ITEM_COUNT + ") != 0"); + initialRepos.size() + " % REPO_XML_ARG_COUNT(" + REPO_XML_ITEM_COUNT + ") != 0"); } - return defaultRepos; + return initialRepos; } /** diff --git a/app/src/test/java/org/fdroid/fdroid/data/DBHelperTest.java b/app/src/test/java/org/fdroid/fdroid/data/DBHelperTest.java index 8a24c5466..024d69796 100644 --- a/app/src/test/java/org/fdroid/fdroid/data/DBHelperTest.java +++ b/app/src/test/java/org/fdroid/fdroid/data/DBHelperTest.java @@ -278,7 +278,7 @@ public class DBHelperTest { outputStream.close(); try { - List initialRepos = DBHelper.loadDefaultRepos(context); + List initialRepos = DBHelper.loadInitialRepos(context); // Construct the repos that we should have loaded List oem0 = Arrays.asList("oem0Name", "https://www.oem0.com/yeah/repo", "I'm the first oem repo.", From 9f3a32d986f20faddb566609f8fca907b799127d Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Tue, 16 Oct 2018 17:18:05 +0200 Subject: [PATCH 23/28] rename defaultReposFile to additionalReposFile --- app/src/main/java/org/fdroid/fdroid/data/DBHelper.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/org/fdroid/fdroid/data/DBHelper.java b/app/src/main/java/org/fdroid/fdroid/data/DBHelper.java index 1e4ff4b84..1eef3c190 100644 --- a/app/src/main/java/org/fdroid/fdroid/data/DBHelper.java +++ b/app/src/main/java/org/fdroid/fdroid/data/DBHelper.java @@ -318,13 +318,13 @@ public class DBHelper extends SQLiteOpenHelper { private static List loadAdditionalRepos(String packageName) { List externalRepos = new LinkedList<>(); for (String root : Arrays.asList("/system", "/vendor", "/odm", "/oem")) { - File defaultReposFile = new File(root + "/etc/" + packageName + "/additional_repos.xml"); + File additionalReposFile = new File(root + "/etc/" + packageName + "/additional_repos.xml"); try { - if (defaultReposFile.isFile()) { - externalRepos.addAll(DBHelper.parseXmlRepos(defaultReposFile)); + if (additionalReposFile.isFile()) { + externalRepos.addAll(DBHelper.parseXmlRepos(additionalReposFile)); } } catch (Exception e) { - Log.e(TAG, "Error loading " + defaultReposFile + ": " + e.getMessage()); + Log.e(TAG, "Error loading " + additionalReposFile + ": " + e.getMessage()); } } From ec5814137915a023b8f4717104a53f4a892bd4f5 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Tue, 16 Oct 2018 17:20:46 +0200 Subject: [PATCH 24/28] rename item lists to repoItems --- .../java/org/fdroid/fdroid/data/DBHelper.java | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/app/src/main/java/org/fdroid/fdroid/data/DBHelper.java b/app/src/main/java/org/fdroid/fdroid/data/DBHelper.java index 1eef3c190..987bad4d1 100644 --- a/app/src/main/java/org/fdroid/fdroid/data/DBHelper.java +++ b/app/src/main/java/org/fdroid/fdroid/data/DBHelper.java @@ -316,19 +316,19 @@ public class DBHelper extends SQLiteOpenHelper { * ROM has the lowest priority, then Vendor, ODM, and OEM. */ private static List loadAdditionalRepos(String packageName) { - List externalRepos = new LinkedList<>(); + List repoItems = new LinkedList<>(); for (String root : Arrays.asList("/system", "/vendor", "/odm", "/oem")) { File additionalReposFile = new File(root + "/etc/" + packageName + "/additional_repos.xml"); try { if (additionalReposFile.isFile()) { - externalRepos.addAll(DBHelper.parseXmlRepos(additionalReposFile)); + repoItems.addAll(DBHelper.parseXmlRepos(additionalReposFile)); } } catch (Exception e) { Log.e(TAG, "Error loading " + additionalReposFile + ": " + e.getMessage()); } } - return externalRepos; + return repoItems; } /** @@ -340,7 +340,7 @@ public class DBHelper extends SQLiteOpenHelper { * override {@code default_repos.xml}. */ public static List parseXmlRepos(File defaultReposFile) throws IOException, XmlPullParserException { - List defaultRepos = new LinkedList<>(); + List repoItems = new LinkedList<>(); InputStream xmlInputStream = new FileInputStream(additionalReposFile); XmlPullParserFactory factory = XmlPullParserFactory.newInstance(); factory.setNamespaceAware(true); @@ -362,7 +362,7 @@ public class DBHelper extends SQLiteOpenHelper { break; case XmlPullParser.TEXT: if (isItem) { - defaultRepos.add(parser.getText()); + repoItems.add(parser.getText()); } break; } @@ -371,16 +371,16 @@ public class DBHelper extends SQLiteOpenHelper { xmlInputStream.close(); final int PRIORITY_INDEX = 5; - for (int i = PRIORITY_INDEX; i < defaultRepos.size(); i += REPO_XML_ITEM_COUNT) { - defaultRepos.add(i, "0"); + for (int i = PRIORITY_INDEX; i < repoItems.size(); i += REPO_XML_ITEM_COUNT) { + repoItems.add(i, "0"); } - if (defaultRepos.size() % REPO_XML_ITEM_COUNT == 0) { - return defaultRepos; + if (repoItems.size() % REPO_XML_ITEM_COUNT == 0) { + return repoItems; } Log.e(TAG, "Ignoring " + additionalReposFile + ", wrong number of items: " - + defaultRepos.size() + " % " + (REPO_XML_ITEM_COUNT - 1) + " != 0"); + + repoItems.size() + " % " + (REPO_XML_ITEM_COUNT - 1) + " != 0"); return new LinkedList<>(); } From 17885462676dd050e4393603c5dad8be3bc5af3b Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Tue, 16 Oct 2018 17:21:07 +0200 Subject: [PATCH 25/28] rename parseXmlRepos to parseAdditionalReposXml --- app/src/main/java/org/fdroid/fdroid/data/DBHelper.java | 5 +++-- app/src/test/java/org/fdroid/fdroid/data/DBHelperTest.java | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/org/fdroid/fdroid/data/DBHelper.java b/app/src/main/java/org/fdroid/fdroid/data/DBHelper.java index 987bad4d1..74c0355ec 100644 --- a/app/src/main/java/org/fdroid/fdroid/data/DBHelper.java +++ b/app/src/main/java/org/fdroid/fdroid/data/DBHelper.java @@ -321,7 +321,7 @@ public class DBHelper extends SQLiteOpenHelper { File additionalReposFile = new File(root + "/etc/" + packageName + "/additional_repos.xml"); try { if (additionalReposFile.isFile()) { - repoItems.addAll(DBHelper.parseXmlRepos(additionalReposFile)); + repoItems.addAll(DBHelper.parseAdditionalReposXml(additionalReposFile)); } } catch (Exception e) { Log.e(TAG, "Error loading " + additionalReposFile + ": " + e.getMessage()); @@ -339,7 +339,8 @@ public class DBHelper extends SQLiteOpenHelper { * not allowed to set the priority since that would give it the power to * override {@code default_repos.xml}. */ - public static List parseXmlRepos(File defaultReposFile) throws IOException, XmlPullParserException { + public static List parseAdditionalReposXml(File additionalReposFile) + throws IOException, XmlPullParserException { List repoItems = new LinkedList<>(); InputStream xmlInputStream = new FileInputStream(additionalReposFile); XmlPullParserFactory factory = XmlPullParserFactory.newInstance(); diff --git a/app/src/test/java/org/fdroid/fdroid/data/DBHelperTest.java b/app/src/test/java/org/fdroid/fdroid/data/DBHelperTest.java index 024d69796..34b5ec97b 100644 --- a/app/src/test/java/org/fdroid/fdroid/data/DBHelperTest.java +++ b/app/src/test/java/org/fdroid/fdroid/data/DBHelperTest.java @@ -36,7 +36,7 @@ public class DBHelperTest { outputStream.close(); // Now parse that xml file - return DBHelper.parseXmlRepos(additionalReposXml); + return DBHelper.parseAdditionalReposXml(additionalReposXml); } protected Context context; From 6dd4523d3c916cfff96bf56455897f98cbcb24b2 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Tue, 16 Oct 2018 17:31:33 +0200 Subject: [PATCH 26/28] clean up whitespace in repo descriptions This cleans up the whitespace in the description item, since the XML parsing will include the linefeeds and indenting in the description. --- app/src/main/java/org/fdroid/fdroid/data/DBHelper.java | 9 +++++++++ .../java/org/fdroid/fdroid/data/RepoProviderTest.java | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/org/fdroid/fdroid/data/DBHelper.java b/app/src/main/java/org/fdroid/fdroid/data/DBHelper.java index 74c0355ec..fb463e5b9 100644 --- a/app/src/main/java/org/fdroid/fdroid/data/DBHelper.java +++ b/app/src/main/java/org/fdroid/fdroid/data/DBHelper.java @@ -291,6 +291,9 @@ public class DBHelper extends SQLiteOpenHelper { *

* Additional Repos ({@code additional_repos.xml}) come from the ROM, * while Default Repos ({@code default_repos.xml} is built into the APK. + *

+ * This also cleans up the whitespace in the description item, since the + * XML parsing will include the linefeeds and indenting in the description. */ public static List loadInitialRepos(Context context) throws IllegalArgumentException { String packageName = context.getPackageName(); @@ -303,6 +306,12 @@ public class DBHelper extends SQLiteOpenHelper { initialRepos.size() + " % REPO_XML_ARG_COUNT(" + REPO_XML_ITEM_COUNT + ") != 0"); } + final int DESCRIPTION_INDEX = 2; + for (int i = DESCRIPTION_INDEX; i < initialRepos.size(); i += REPO_XML_ITEM_COUNT) { + String description = initialRepos.get(i); + initialRepos.set(i, description.replaceAll("\\s+", " ")); + } + return initialRepos; } diff --git a/app/src/test/java/org/fdroid/fdroid/data/RepoProviderTest.java b/app/src/test/java/org/fdroid/fdroid/data/RepoProviderTest.java index 5bd1abbae..e2a726abc 100644 --- a/app/src/test/java/org/fdroid/fdroid/data/RepoProviderTest.java +++ b/app/src/test/java/org/fdroid/fdroid/data/RepoProviderTest.java @@ -166,7 +166,7 @@ public class RepoProviderTest extends FDroidProviderTest { assertRepo( defaultRepos.get(i), reposFromXml[offset + 1], // address - reposFromXml[offset + 2], // description + reposFromXml[offset + 2].replaceAll("\\s+", " "), // description Utils.calcFingerprint(reposFromXml[offset + 7]), // pubkey reposFromXml[offset] // name ); From 409846e1990ca580a6b196756ea6de878c72891e Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Tue, 16 Oct 2018 18:39:01 +0200 Subject: [PATCH 27/28] force DBHelperTest.canAddAdditionalRepos() to run on CI --- app/src/test/java/org/fdroid/fdroid/data/DBHelperTest.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/src/test/java/org/fdroid/fdroid/data/DBHelperTest.java b/app/src/test/java/org/fdroid/fdroid/data/DBHelperTest.java index 34b5ec97b..ce48faf56 100644 --- a/app/src/test/java/org/fdroid/fdroid/data/DBHelperTest.java +++ b/app/src/test/java/org/fdroid/fdroid/data/DBHelperTest.java @@ -2,6 +2,7 @@ package org.fdroid.fdroid.data; import android.content.Context; import android.support.test.InstrumentationRegistry; +import android.text.TextUtils; import android.util.Log; import org.apache.commons.io.IOUtils; import org.fdroid.fdroid.TestUtils; @@ -230,7 +231,7 @@ public class DBHelperTest { if (oemEtcDir.canWrite() || new File("/").canWrite()) { oemEtcPackageDir.mkdirs(); } - if (!oemEtcPackageDir.isDirectory()) { + if (TextUtils.isEmpty(System.getenv("CI")) && !oemEtcPackageDir.isDirectory()) { Log.e(TAG, "Cannot create " + oemEtcDir + ", skipping test!"); return; } From eb023887a58a013e7f34063bfd3ac29ce63346e9 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Tue, 16 Oct 2018 22:18:41 +0200 Subject: [PATCH 28/28] fix checkstyle complaints * LocalFinalVariableName * EqualsAvoidNull * EmptyLineSeparator * SeparatorWrap * LineLength --- .../main/java/org/fdroid/fdroid/data/DBHelper.java | 10 +++++----- .../java/org/fdroid/fdroid/data/DBHelperTest.java | 11 ++++------- 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/app/src/main/java/org/fdroid/fdroid/data/DBHelper.java b/app/src/main/java/org/fdroid/fdroid/data/DBHelper.java index fb463e5b9..9eaad2d44 100644 --- a/app/src/main/java/org/fdroid/fdroid/data/DBHelper.java +++ b/app/src/main/java/org/fdroid/fdroid/data/DBHelper.java @@ -306,8 +306,8 @@ public class DBHelper extends SQLiteOpenHelper { initialRepos.size() + " % REPO_XML_ARG_COUNT(" + REPO_XML_ITEM_COUNT + ") != 0"); } - final int DESCRIPTION_INDEX = 2; - for (int i = DESCRIPTION_INDEX; i < initialRepos.size(); i += REPO_XML_ITEM_COUNT) { + final int descriptionIndex = 2; + for (int i = descriptionIndex; i < initialRepos.size(); i += REPO_XML_ITEM_COUNT) { String description = initialRepos.get(i); initialRepos.set(i, description.replaceAll("\\s+", " ")); } @@ -363,7 +363,7 @@ public class DBHelper extends SQLiteOpenHelper { String tagname = parser.getName(); switch (eventType) { case XmlPullParser.START_TAG: - if (tagname.equals("item")) { + if ("item".equals(tagname)) { isItem = true; } break; @@ -380,8 +380,8 @@ public class DBHelper extends SQLiteOpenHelper { } xmlInputStream.close(); - final int PRIORITY_INDEX = 5; - for (int i = PRIORITY_INDEX; i < repoItems.size(); i += REPO_XML_ITEM_COUNT) { + final int priorityIndex = 5; + for (int i = priorityIndex; i < repoItems.size(); i += REPO_XML_ITEM_COUNT) { repoItems.add(i, "0"); } diff --git a/app/src/test/java/org/fdroid/fdroid/data/DBHelperTest.java b/app/src/test/java/org/fdroid/fdroid/data/DBHelperTest.java index ce48faf56..2159a709b 100644 --- a/app/src/test/java/org/fdroid/fdroid/data/DBHelperTest.java +++ b/app/src/test/java/org/fdroid/fdroid/data/DBHelperTest.java @@ -69,7 +69,7 @@ public class DBHelperTest { "ignore" + "" + "" + - "3082035e30820246a00302010202044c49cd00300d06092a864886f70d01010505003071310b300906035504061302554b3110300e06035504081307556e6b6e6f776e3111300f0603550407130857657468657262793110300e060355040a1307556e6b6e6f776e3110300e060355040b1307556e6b6e6f776e311930170603550403131043696172616e2047756c746e69656b73301e170d3130303732333137313032345a170d3337313230383137313032345a3071310b300906035504061302554b3110300e06035504081307556e6b6e6f776e3111300f0603550407130857657468657262793110300e060355040a1307556e6b6e6f776e3110300e060355040b1307556e6b6e6f776e311930170603550403131043696172616e2047756c746e69656b7330820122300d06092a864886f70d01010105000382010f003082010a028201010096d075e47c014e7822c89fd67f795d23203e2a8843f53ba4e6b1bf5f2fd0e225938267cfcae7fbf4fe596346afbaf4070fdb91f66fbcdf2348a3d92430502824f80517b156fab00809bdc8e631bfa9afd42d9045ab5fd6d28d9e140afc1300917b19b7c6c4df4a494cf1f7cb4a63c80d734265d735af9e4f09455f427aa65a53563f87b336ca2c19d244fcbba617ba0b19e56ed34afe0b253ab91e2fdb1271f1b9e3c3232027ed8862a112f0706e234cf236914b939bcf959821ecb2a6c18057e070de3428046d94b175e1d89bd795e535499a091f5bc65a79d539a8d43891ec504058acb28c08393b5718b57600a211e803f4a634e5c57f25b9b8c4422c6fd90203010001300d06092a864886f70d0101050500038201010008e4ef699e9807677ff56753da73efb2390d5ae2c17e4db691d5df7a7b60fc071ae509c5414be7d5da74df2811e83d3668c4a0b1abc84b9fa7d96b4cdf30bba68517ad2a93e233b042972ac0553a4801c9ebe07bf57ebe9a3b3d6d663965260e50f3b8f46db0531761e60340a2bddc3426098397fda54044a17e5244549f9869b460ca5e6e216b6f6a2db0580b480ca2afe6ec6b46eedacfa4aa45038809ece0c5978653d6c85f678e7f5a2156d1bedd8117751e64a4b0dcd140f3040b021821a8d93aed8d01ba36db6c82372211fed714d9a32607038cdfd565bd529ffc637212aaa2c224ef22b603eccefb5bf1e085c191d4b24fe742b17ab3f55d4e6f05ef" + + "3082035e30820246a00302010202044c49cd00300d06092a864886f70d01010505003071310b30090603550406130255" + "" + "" + ""; @@ -101,7 +101,7 @@ public class DBHelperTest { "ignore" + "" + "" + - "3082035e30820246a00302010202044c49cd00300d06092a864886f70d01010505003071310b300906035504061302554b3110300e06035504081307556e6b6e6f776e3111300f0603550407130857657468657262793110300e060355040a1307556e6b6e6f776e3110300e060355040b1307556e6b6e6f776e311930170603550403131043696172616e2047756c746e69656b73301e170d3130303732333137313032345a170d3337313230383137313032345a3071310b300906035504061302554b3110300e06035504081307556e6b6e6f776e3111300f0603550407130857657468657262793110300e060355040a1307556e6b6e6f776e3110300e060355040b1307556e6b6e6f776e311930170603550403131043696172616e2047756c746e69656b7330820122300d06092a864886f70d01010105000382010f003082010a028201010096d075e47c014e7822c89fd67f795d23203e2a8843f53ba4e6b1bf5f2fd0e225938267cfcae7fbf4fe596346afbaf4070fdb91f66fbcdf2348a3d92430502824f80517b156fab00809bdc8e631bfa9afd42d9045ab5fd6d28d9e140afc1300917b19b7c6c4df4a494cf1f7cb4a63c80d734265d735af9e4f09455f427aa65a53563f87b336ca2c19d244fcbba617ba0b19e56ed34afe0b253ab91e2fdb1271f1b9e3c3232027ed8862a112f0706e234cf236914b939bcf959821ecb2a6c18057e070de3428046d94b175e1d89bd795e535499a091f5bc65a79d539a8d43891ec504058acb28c08393b5718b57600a211e803f4a634e5c57f25b9b8c4422c6fd90203010001300d06092a864886f70d0101050500038201010008e4ef699e9807677ff56753da73efb2390d5ae2c17e4db691d5df7a7b60fc071ae509c5414be7d5da74df2811e83d3668c4a0b1abc84b9fa7d96b4cdf30bba68517ad2a93e233b042972ac0553a4801c9ebe07bf57ebe9a3b3d6d663965260e50f3b8f46db0531761e60340a2bddc3426098397fda54044a17e5244549f9869b460ca5e6e216b6f6a2db0580b480ca2afe6ec6b46eedacfa4aa45038809ece0c5978653d6c85f678e7f5a2156d1bedd8117751e64a4b0dcd140f3040b021821a8d93aed8d01ba36db6c82372211fed714d9a32607038cdfd565bd529ffc637212aaa2c224ef22b603eccefb5bf1e085c191d4b24fe742b17ab3f55d4e6f05ef" + + "3082035e30820246a00302010202044c49cd00300d06092a864886f70d01010505003071310b3009060355040613025" + "" + "" + ""; @@ -222,7 +222,7 @@ public class DBHelperTest { } } - + @SuppressWarnings("LineLength") @Test public void canAddAdditionalRepos() throws IOException { File oemEtcDir = new File("/oem/etc"); @@ -272,10 +272,7 @@ public class DBHelperTest { + "" + "ddddddd2313aaaaabcccc111" + "" - + "" - ). - - getBytes()); + + "").getBytes()); outputStream.close(); try {