Add support for proxy restrictions
Implement enforcement of the following chromium proxy restrictions:
ProxyMode, ProxyServer, ProxyBypassList
Originally cherry picked from 556a3ba3bb9dae768810181ace1e0b07fd5824c2.
Includes fix for search restriction unit test failures when
including proxy restrictions code.
Also added some logging for functional verification.
Change-Id: If7fc1d8be36fa600a3d974d6b584d504ed2faf71
diff --git a/src/com/android/browser/BrowserSettings.java b/src/com/android/browser/BrowserSettings.java
index b5db3af..ed21c8d 100644
--- a/src/com/android/browser/BrowserSettings.java
+++ b/src/com/android/browser/BrowserSettings.java
@@ -32,6 +32,7 @@
import com.android.browser.R;
import com.android.browser.homepages.HomeProvider;
+import com.android.browser.mdm.ProxyRestriction;
import com.android.browser.mdm.SearchEngineRestriction;
import com.android.browser.platformsupport.Browser;
import com.android.browser.provider.BrowserProvider;
@@ -133,6 +134,9 @@
if (mNeedsSharedSync) {
syncSharedSettings();
}
+ // Instantiate ProxyRestriction after engine initialization
+ // to ensure ProxyChangeListener is already created.
+ ProxyRestriction.getInstance();
}
public void startManagingSettings(final WebSettings settings) {
diff --git a/src/com/android/browser/mdm/ProxyRestriction.java b/src/com/android/browser/mdm/ProxyRestriction.java
new file mode 100644
index 0000000..be08254
--- /dev/null
+++ b/src/com/android/browser/mdm/ProxyRestriction.java
@@ -0,0 +1,151 @@
+/*
+ * Copyright (c) 2015, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+package com.android.browser.mdm;
+
+import android.net.Uri;
+import android.os.Bundle;
+import android.util.Log;
+
+import com.android.browser.PreferenceKeys;
+
+import org.chromium.net.ProxyChangeListener;
+import org.chromium.net.ProxyChangeListener.ProxyConfig;
+
+public class ProxyRestriction extends Restriction implements PreferenceKeys {
+
+ private final static String TAG = "ProxyRestriction";
+
+ private static ProxyRestriction sInstance;
+
+ private ProxyRestriction() {
+ super();
+ }
+
+ public static ProxyRestriction getInstance() {
+ synchronized (ProxyRestriction.class) {
+ if (sInstance == null) {
+ sInstance = new ProxyRestriction();
+ }
+ }
+ return sInstance;
+ }
+
+ @Override
+ public void enable(boolean enable) {
+ super.enable(enable);
+ // Ensure any previously set proxy restriction is revoked
+ if (!enable) {
+ ProxyChangeListener.setMdmProxy(null, null);
+ }
+ }
+
+ @Override
+ public void enforce(Bundle restrictions) {
+ String proxyMode = restrictions.getString(ProxyChangeListener.PROXY_MODE);
+
+ // Leaving ProxyMode not set lifts any managed profile proxy restrictions, allowing users to
+ // choose the proxy settings on their own.
+ if (proxyMode == null) {
+ Log.v(TAG, "enforce: proxyMode is null, disabling.");
+ enable(false);
+ }
+
+ // If policy is to not use the proxy and always connect directly, then all other options
+ // are ignored.
+ else if (proxyMode.equals(ProxyChangeListener.MODE_DIRECT)) {
+ Log.v(TAG, "enforce: proxyMode is MODE_DIRECT, enabling and passing to ProxyChangeListener.");
+ enable(true);
+ ProxyChangeListener.setMdmProxy(proxyMode, null);
+ }
+
+ // If you choose to use system proxy settings or auto detect the proxy server,
+ // all other options are ignored.
+ else if (proxyMode.equals(ProxyChangeListener.MODE_SYSTEM) ||
+ proxyMode.equals(ProxyChangeListener.MODE_AUTO_DETECT)) {
+ //TODO: Disable for now. Needs more investigation.
+ Log.v(TAG, "enforce: proxyMode is [" + proxyMode.toString() + "]. Not supported. disabling.");
+ enable(false);
+ }
+
+ // If you choose fixed server proxy mode, you can specify further options in 'Address or URL
+ // of proxy server' and 'Comma-separated list of proxy bypass rules'.
+ else if (proxyMode.equals(ProxyChangeListener.MODE_FIXED_SERVERS)) {
+ String host;
+ int port;
+ try {
+ Uri proxyServerUri = Uri.parse(restrictions.getString(ProxyChangeListener.PROXY_SERVER));
+ host = proxyServerUri.getHost();
+ // Bail out if host is not present
+ if (host == null) {
+ Log.e(TAG, "enforce: host - nul while processing MODE_FIXED_SERVERS");
+ enable(false);
+ return;
+ }
+ port = proxyServerUri.getPort();
+ } catch (Exception e) {
+ // Bail out if ProxyServer string is missing
+ Log.e(TAG,"enforce: Exception caught while processing MODE_FIXED_SERVERS");
+ enable(false);
+ return;
+ }
+ String proxyBypassList = restrictions.getString(ProxyChangeListener.PROXY_BYPASS_LIST);
+ Log.v(TAG,"enforce: saving MODE_FIXED_SERVERS proxy config: ");
+ Log.v(TAG," - host : " + host.toString());
+ Log.v(TAG," - port : " + port);
+// Log.v(TAG," - bypassList : " + proxyBypassList != null ? proxyBypassList.toString() : "NULL");
+
+ saveProxyConfig(proxyMode, host, port, null, proxyBypassList);
+ }
+
+ // This policy only takes effect if you have selected manual proxy settings at 'Choose how
+ // to specify proxy server settings'. You should leave this policy not set if you have
+ // selected any other mode for setting proxy policies.
+ else if (proxyMode.equals(ProxyChangeListener.MODE_PAC_SCRIPT)) {
+ String proxyPacUrl = restrictions.getString(ProxyChangeListener.PROXY_PAC_URL);
+ // Bail out if ProxyPacUrl string is missing
+ if (proxyPacUrl == null) {
+ Log.v(TAG, "enforce: MODE_PAC_SCRIPT. proxyPacUrl is null. disabling");
+ enable(false);
+ } else {
+ Log.v(TAG, "enforce: MODE_PAC_SCRIPT. proxyPacUrl ["+proxyPacUrl.toString() +
+ "]. sending and enabling");
+ saveProxyConfig(proxyMode, null, -1, null, proxyPacUrl);
+ }
+ }
+ }
+
+ private void saveProxyConfig(String proxyMode, String host, int port, String proxyPacUrl, String proxyBypassList) {
+ ProxyChangeListener.setMdmProxy(proxyMode, new ProxyConfig(host, port, proxyPacUrl,
+ (proxyBypassList != null) ? proxyBypassList.split(",") : new String[0]));
+ enable(true);
+ }
+
+}
diff --git a/src/com/android/browser/mdm/Restriction.java b/src/com/android/browser/mdm/Restriction.java
index 5d9fbf9..ab21c03 100644
--- a/src/com/android/browser/mdm/Restriction.java
+++ b/src/com/android/browser/mdm/Restriction.java
@@ -42,7 +42,7 @@
*/
public abstract class Restriction {
- private static boolean mEnabled = false;
+ private boolean mEnabled = false;
public Restriction() {
// Register observer for restrictions