Skip to content

Commit

Permalink
Only show servo button for few websites (MozillaReality#632)
Browse files Browse the repository at this point in the history
  • Loading branch information
paulrouget committed Oct 25, 2018
1 parent c1cc17c commit f40cf90
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 6 deletions.
Expand Up @@ -30,6 +30,7 @@
import org.mozilla.vrbrowser.ui.views.NavigationURLBar;
import org.mozilla.vrbrowser.ui.views.UIButton;
import org.mozilla.vrbrowser.ui.views.UITextButton;
import org.mozilla.vrbrowser.utils.ServoUtils;

import java.util.ArrayList;
import java.util.Arrays;
Expand Down Expand Up @@ -392,7 +393,19 @@ public void showVoiceSearch() {
}

public void updateServoButton() {
if (SettingsStore.getInstance(mAppContext).isServoEnabled()) {
// We show the Servo button if:
// 1. the current session is using Servo. No matter what, we need the toggle button to go back to Gecko.
// 2. Or, if the pref is enabled and the current url is white listed.
boolean show = false;
GeckoSession currentSession = SessionStore.get().getCurrentSession();
if (currentSession != null) {
String currentUri = SessionStore.get().getCurrentUri();
boolean isPrefEnabled = SettingsStore.getInstance(mAppContext).isServoEnabled();
boolean isServoSession = ServoUtils.isInstanceOfServoSession(currentSession);
boolean isUrlWhiteListed = ServoUtils.isUrlInServoWhiteList(mAppContext, currentUri);
show = isServoSession || (isPrefEnabled && isUrlWhiteListed);
}
if (show) {
mServoButton.setVisibility(View.VISIBLE);
} else {
mServoButton.setVisibility(View.GONE);
Expand Down Expand Up @@ -421,6 +434,7 @@ public void onLocationChange(GeckoSession session, String url) {
mURLBar.setURL(url);
mReloadButton.setEnabled(true);
}
updateServoButton();
}

@Override
Expand Down
32 changes: 27 additions & 5 deletions app/src/common/shared/org/mozilla/vrbrowser/utils/ServoUtils.java
Expand Up @@ -6,14 +6,17 @@
import org.mozilla.geckoview.GeckoSession;

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;

public class ServoUtils {
private static final String CLASSNAME = "org.mozilla.servo.ServoSession";
private static final String SESSION_CLASSNAME = "org.mozilla.servo.ServoSession";
private static final String WHITELIST_CLASSNAME = "org.mozilla.servo.ServoWhiteList";
private static final String LOGTAG = "ServoUtils";
private static Object mServoWhiteList = null;

public static boolean isServoAvailable() {
try {
Class.forName(CLASSNAME);
Class.forName(SESSION_CLASSNAME);
return true;
} catch (ClassNotFoundException e) {
return false;
Expand All @@ -22,20 +25,39 @@ public static boolean isServoAvailable() {

public static boolean isInstanceOfServoSession(Object obj) {
try {
return Class.forName(CLASSNAME).isInstance(obj);
return Class.forName(SESSION_CLASSNAME).isInstance(obj);
} catch (ClassNotFoundException e) {
return false;
}
}

public static GeckoSession createServoSession(Context context) {
try {
Class servoClass = Class.forName(CLASSNAME);
Constructor<?> constructor = servoClass.getConstructor(Context.class);
Class clazz = Class.forName(SESSION_CLASSNAME);
Constructor<?> constructor = clazz.getConstructor(Context.class);
return (GeckoSession) constructor.newInstance(context);
} catch (Exception e) {
Log.e(LOGTAG, "Can't load or instanciate ServoSession: " + e);
return null;
}
}

public static boolean isUrlInServoWhiteList(Context context, String url) {
if (isServoAvailable()) {
try {
Class clazz = Class.forName(WHITELIST_CLASSNAME);
if (mServoWhiteList == null) {
Constructor<?> constructor = clazz.getConstructor(Context.class);
mServoWhiteList = constructor.newInstance(context);
}
Method isAllowed = clazz.getMethod("isAllowed", String.class);
return (boolean) isAllowed.invoke(mServoWhiteList, url);
} catch (Exception e) {
Log.e(LOGTAG, "Failed to call ServoWhiteList::isAllowed: " + e);
return false;
}
} else {
return false;
}
}
}
23 changes: 23 additions & 0 deletions servo/src/main/java/org/mozilla/servo/ServoWhiteList.java
@@ -0,0 +1,23 @@
package org.mozilla.servo;

import android.content.Context;
import android.content.res.Resources;
import android.util.Log;

import java.util.Arrays;
import java.util.regex.Pattern;
import java.util.stream.Stream;

public class ServoWhiteList {
private final Pattern[] mRules;

public ServoWhiteList(Context context) {
Resources res = context.getResources();
Stream<String> rules = Stream.of(res.getStringArray(R.array.servo_white_list));
mRules = rules.map(Pattern::compile).toArray(Pattern[]::new);
}

public boolean isAllowed(String url) {
return url != null && Stream.of(mRules).anyMatch(r -> r.matcher(url).matches());
}
}
20 changes: 20 additions & 0 deletions servo/src/main/res/values/servo_white_list.xml
@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array name="servo_white_list">
<!--
Matches:
https://servo.org
https://download.servo.org
https://download.servo.org
https://servo.org/
https://servo.org/ddd
Doesn't match:
https://.servo.org/ddd
https://servo.orgd
http://servo.org
-->
<item>https:\/\/(.+\.)?servo\.org(\/.*)?$</item>
<!-- All examples hosted under threejs.org/examples/ -->
<item>https:\/\/threejs\.org\/examples\/.*</item>
</string-array>
</resources>

0 comments on commit f40cf90

Please sign in to comment.