Bug #1355870 - Allow a system preference to determine distribution dir. r=nalexander
draft
Bug #1355870 - Allow a system preference to determine distribution dir. r=nalexander
MozReview-Commit-ID: GmD6CGsKX5h
--- a/mobile/android/base/java/org/mozilla/gecko/distribution/Distribution.java
+++ b/mobile/android/base/java/org/mozilla/gecko/distribution/Distribution.java
@@ -7,16 +7,17 @@ package org.mozilla.gecko.distribution;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
+import java.lang.reflect.Method;
import java.net.HttpURLConnection;
import java.net.ProtocolException;
import java.net.SocketException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.UnknownHostException;
import java.util.Collections;
import java.util.Enumeration;
@@ -83,17 +84,20 @@ public class Distribution {
/**
* Telemetry constants.
*/
private static final String HISTOGRAM_REFERRER_INVALID = "FENNEC_DISTRIBUTION_REFERRER_INVALID";
private static final String HISTOGRAM_DOWNLOAD_TIME_MS = "FENNEC_DISTRIBUTION_DOWNLOAD_TIME_MS";
private static final String HISTOGRAM_CODE_CATEGORY = "FENNEC_DISTRIBUTION_CODE_CATEGORY";
+ // This is the name of the system property used to discover a custom distribution directory.
+ private static final String SYSPROP_DISTRIBUTIONDIR = "ro.org.mozilla.distributiondir";
/**
+ *
* Success/failure codes. Don't exceed the maximum listed in Histograms.json.
*/
private static final int CODE_CATEGORY_STATUS_OUT_OF_RANGE = 0;
// HTTP status 'codes' run from 1 to 5.
private static final int CODE_CATEGORY_OFFLINE = 6;
private static final int CODE_CATEGORY_FETCH_EXCEPTION = 7;
// It's a post-fetch exception if we were able to download, but not
@@ -930,25 +934,67 @@ public class Distribution {
System.arraycopy(dataDirectories, 0, directories, 0, dataDirectories.length);
System.arraycopy(systemDirectories, 0, directories, dataDirectories.length, systemDirectories.length);
return directories;
}
/**
+ * This function checks to see if a custom distribution directory has
+ * been set as a system property and returns it if it exists. The path
+ * returned will always have a single trailing slash.
+ *
+ * The system property is readonly, so it can only be set by vendors or
+ * someone with a rooted device.
+ *
+ * The mechanism to obtain the property is necessary because retrieval
+ * methods are not exposed in the SDK.
+ */
+ private static String getDistributionDirectoryFromSystemProperty() {
+ try {
+ @SuppressWarnings("rawtypes")
+ Class clazz = Class.forName("android.os.SystemProperties");
+ @SuppressWarnings("unchecked")
+ Method method = clazz.getDeclaredMethod("get", String.class);
+ String distDirName = (String)method.invoke(null, SYSPROP_DISTRIBUTIONDIR);
+ if (!distDirName.isEmpty()) {
+ Log.d(LOGTAG, "System property " + SYSPROP_DISTRIBUTIONDIR + " found with value " + distDirName);
+ // Add a trailing slash if it isn't there
+ if (distDirName.charAt(distDirName.length() - 1) != '/') {
+ distDirName += '/';
+ }
+ File distDir = new File(distDirName);
+ if (distDir.exists() && distDir.isDirectory()) {
+ Log.d(LOGTAG, "Custom distribution directory found at " + distDirName);
+ return distDirName;
+ }
+ }
+ } catch (Exception e) {
+ Log.e(LOGTAG, "Error getting system property " + SYSPROP_DISTRIBUTIONDIR, e);
+ }
+ Log.d(LOGTAG, "Custom distribution directory not found.");
+ return null;
+ }
+ /**
* Get a list of system distribution folder candidates.
*
* /system/<package>/distribution/<mcc>/<mnc> - For bundled distributions for specific network providers
* /system/<package>/distribution/<mcc> - For bundled distributions for specific countries
* /system/<package>/distribution/default - For bundled distributions with no matching mcc/mnc
* /system/<package>/distribution - Default non-bundled system distribution
*/
private static String[] getSystemDistributionDirectories(Context context) {
- final String baseDirectory = "/system/" + context.getPackageName() + "/distribution";
+ final String systemPropertyBaseDirectory = getDistributionDirectoryFromSystemProperty();
+ final String baseDirectory;
+ if (systemPropertyBaseDirectory != null) {
+ baseDirectory = systemPropertyBaseDirectory + context.getPackageName() + "/distribution";
+ } else {
+ baseDirectory = "/system/" + context.getPackageName() + "/distribution";
+ }
return getDistributionDirectoriesFromBaseDirectory(context, baseDirectory);
}
/**
* Get a list of data distribution folder candidates.
*
* <dataDir>/distribution/<mcc>/<mnc> - For bundled distributions for specific network providers
* <dataDir>/distribution/<mcc> - For bundled distributions for specific countries