Bug 1355870 - Allow a system preference to determine distribution dir. r=nalexander
authorMichael Kaply <mozilla@kaply.com>
Thu, 13 Apr 2017 20:04:41 -0500
changeset 353046 74c853a70973239b637d8c4b0aa2e2345443c0f8
parent 353045 d09c1172a183133f2df462325fe939c44980e9d3
child 353047 13941e8c1b9d3901377d760c53c93403c451c457
push id31655
push userihsiao@mozilla.com
push dateFri, 14 Apr 2017 09:07:09 +0000
treeherdermozilla-central@8f806306fb83 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnalexander
bugs1355870
milestone55.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1355870 - Allow a system preference to determine distribution dir. r=nalexander
mobile/android/base/java/org/mozilla/gecko/distribution/Distribution.java
--- 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