Skip to content

Commit 388bfe3

Browse files
paulrougetMortimerGoro
authored andcommitted
Servo support enabled via user.properties (Igalia#498)
1 parent 7e614e7 commit 388bfe3

20 files changed

+723
-5
lines changed

README.md

+4
Original file line numberDiff line numberDiff line change
@@ -93,4 +93,8 @@ geckoViewLocalX86=/path/to/your/build/geckoview-nightly-x86-64.0.20180924100359.
9393
- You can use `adb shell setprop debug.oculus.enableVideoCapture 1`to record videos on the Oculus Go. Remember to disable it when your video is ready.
9494

9595

96+
## Experimental Servo support
97+
98+
To compile with Servo support, create a file called `user.properties` in the top-level project directory and add `enableServo=1`. Then to enable Servo in Firefox Reality, go the Developer Options panel in the Settings, and toggle the Servo option. Then a new button will be added to the navigation bar. Clicking that button will reload the current page with Servo.
99+
96100
[![Task Status](https://github.taskcluster.net/v1/repository/MozillaReality/FirefoxReality/master/badge.svg)](https://github.taskcluster.net/v1/repository/MozillaReality/FirefoxReality/master/latest) [Build results](https://github.taskcluster.net/v1/repository/MozillaReality/FirefoxReality/master/latest)

app/build.gradle

+12-1
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,10 @@ android {
3535
} else {
3636
project.archivesBaseName = "FirefoxReality"
3737
}
38+
compileOptions {
39+
sourceCompatibility JavaVersion.VERSION_1_8
40+
targetCompatibility JavaVersion.VERSION_1_8
41+
}
3842
buildTypes {
3943
release {
4044
minifyEnabled true
@@ -231,6 +235,13 @@ dependencies {
231235
implementation "com.github.mozilla:mozillaspeechlibrary:1.0.4"
232236
}
233237

238+
if (findProject(':servo')) {
239+
dependencies {
240+
oculusvrImplementation project(':servo')
241+
googlevrImplementation project(':servo')
242+
}
243+
}
244+
234245
if (findProject(':wavesdk')) {
235246
dependencies {
236247
wavevrImplementation project(':wavesdk')
@@ -288,4 +299,4 @@ android.applicationVariants.all { variant ->
288299
println("Build type: " + buildType)
289300
println("Flavor: " + variant.flavorName)
290301
println("Version code: " + variant.mergedFlavor.versionCode)
291-
}
302+
}

app/src/common/shared/org/mozilla/vrbrowser/browser/SessionStore.java

+37-1
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@
4343
import java.util.List;
4444
import java.util.Map;
4545

46+
import static org.mozilla.vrbrowser.utils.ServoUtils.*;
47+
4648
public class SessionStore implements GeckoSession.NavigationDelegate, GeckoSession.ProgressDelegate,
4749
GeckoSession.ContentDelegate, GeckoSession.TextInputDelegate, GeckoSession.TrackingProtectionDelegate,
4850
GeckoSession.PromptDelegate {
@@ -78,6 +80,7 @@ class SessionSettings {
7880
boolean trackingProtection = true;
7981
boolean suspendMediaWhenInactive = true;
8082
int userAgentMode = SettingsStore.getInstance(mContext).getUaMode();
83+
boolean servo = false;
8184
}
8285

8386
class State {
@@ -307,7 +310,17 @@ public int createSession() {
307310
int createSession(SessionSettings aSettings) {
308311
State state = new State();
309312
state.mSettings = aSettings;
310-
state.mSession = new GeckoSession();
313+
314+
if (aSettings.servo) {
315+
if (isServoAvailable()) {
316+
state.mSession = createServoSession(mContext);
317+
} else {
318+
Log.e(LOGTAG, "Attempt to create a ServoSession. Servo hasn't been enable at build time. Using a GeckoSession instead.");
319+
state.mSession = new GeckoSession();
320+
}
321+
} else {
322+
state.mSession = new GeckoSession();
323+
}
311324

312325
int result = state.mSession.hashCode();
313326
mSessions.put(result, state);
@@ -555,6 +568,20 @@ public void loadUri(String aUri) {
555568
mCurrentSession.loadUri(aUri);
556569
}
557570

571+
public void toggleServo() {
572+
if (mCurrentSession == null) {
573+
return;
574+
}
575+
576+
boolean was_servo = isInstanceOfServoSession(mCurrentSession);
577+
String uri = getCurrentUri();
578+
SessionStore.SessionSettings settings = new SessionStore.SessionSettings();
579+
settings.servo = !was_servo;
580+
int id = createSession(settings);
581+
setCurrentSession(id);
582+
loadUri(uri);
583+
}
584+
558585
public boolean isInFullScreen() {
559586
if (mCurrentSession == null) {
560587
return false;
@@ -714,6 +741,15 @@ public void setMaxWindowSize(int width, int height) {
714741
GeckoAppShell.setScreenSizeOverride(new Rect(0, 0, width, height));
715742
}
716743

744+
public void setServo(final boolean enabled) {
745+
if (!enabled && mCurrentSession != null && isInstanceOfServoSession(mCurrentSession)) {
746+
String uri = getCurrentUri();
747+
int id = createSession();
748+
setCurrentSession(id);
749+
loadUri(uri);
750+
}
751+
}
752+
717753
public void setMultiprocess(final boolean enabled) {
718754
if (mCurrentSession != null) {
719755
final GeckoResult<GeckoSession.SessionState> state = mCurrentSession.saveState();

app/src/common/shared/org/mozilla/vrbrowser/browser/SettingsStore.java

+12
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import org.mozilla.vrbrowser.R;
1212
import org.mozilla.vrbrowser.telemetry.TelemetryWrapper;
1313

14+
import static org.mozilla.vrbrowser.utils.ServoUtils.isServoAvailable;
1415

1516
public class SettingsStore {
1617

@@ -35,6 +36,7 @@ SettingsStore getInstance(final @NonNull Context aContext) {
3536
public final static boolean CONSOLE_LOGS_DEFAULT = false;
3637
public final static boolean ENV_OVERRIDE_DEFAULT = false;
3738
public final static boolean MULTIPROCESS_DEFAULT = false;
39+
public final static boolean SERVO_DEFAULT = false;
3840
public final static int UA_MODE_DEFAULT = 0;
3941
public final static int INPUT_MODE_DEFAULT = 1;
4042
public final static float DISPLAY_DENSITY_DEFAULT = 1.0f;
@@ -148,6 +150,16 @@ public void setMultiprocessEnabled(boolean isEnabled) {
148150
editor.commit();
149151
}
150152

153+
public boolean isServoEnabled() {
154+
return isServoAvailable() && mPrefs.getBoolean(mContext.getString(R.string.settings_key_servo), SERVO_DEFAULT);
155+
}
156+
157+
public void setServoEnabled(boolean isEnabled) {
158+
SharedPreferences.Editor editor = mPrefs.edit();
159+
editor.putBoolean(mContext.getString(R.string.settings_key_servo), isEnabled);
160+
editor.commit();
161+
}
162+
151163
public int getUaMode() {
152164
return mPrefs.getInt(
153165
mContext.getString(R.string.settings_key_desktop_version), UA_MODE_DEFAULT);

app/src/common/shared/org/mozilla/vrbrowser/ui/widgets/DeveloperOptionsWidget.java

+32
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
import org.mozilla.vrbrowser.ui.settings.RadioGroupSetting;
2323
import org.mozilla.vrbrowser.ui.settings.SwitchSetting;
2424

25+
import static org.mozilla.vrbrowser.utils.ServoUtils.isServoAvailable;
26+
2527
public class DeveloperOptionsWidget extends UIWidget {
2628

2729
private static final String LOGTAG = "VRB";
@@ -33,6 +35,7 @@ public class DeveloperOptionsWidget extends UIWidget {
3335
private SwitchSetting mConsoleLogsSwitch;
3436
private SwitchSetting mEnvOverrideSwitch;
3537
private SwitchSetting mMultiprocessSwitch;
38+
private SwitchSetting mServoSwitch;
3639

3740
private RadioGroupSetting mEnvironmentsRadio;
3841
private RadioGroupSetting mPointerColorRadio;
@@ -97,6 +100,14 @@ public void onClick(View view) {
97100
mMultiprocessSwitch.setOnCheckedChangeListener(mMultiprocessListener);
98101
setMultiprocess(SettingsStore.getInstance(getContext()).isMultiprocessEnabled(), false);
99102

103+
mServoSwitch = findViewById(R.id.servo_switch);
104+
if (!isServoAvailable()) {
105+
mServoSwitch.setVisibility(View.GONE);
106+
} else {
107+
mServoSwitch.setOnCheckedChangeListener(mServoListener);
108+
setServo(SettingsStore.getInstance(getContext()).isServoEnabled(), false);
109+
}
110+
100111
String env = SettingsStore.getInstance(getContext()).getEnvironment();
101112
mEnvironmentsRadio = findViewById(R.id.environment_radio);
102113
mEnvironmentsRadio.setOnCheckedChangeListener(mEnvsListener);
@@ -218,6 +229,14 @@ public void onCheckedChanged(CompoundButton compoundButton, boolean value, boole
218229
}
219230
};
220231

232+
private SwitchSetting.OnCheckedChangeListener mServoListener = new SwitchSetting.OnCheckedChangeListener() {
233+
@Override
234+
public void onCheckedChanged(CompoundButton compoundButton, boolean b, boolean doApply) {
235+
setServo(b, true);
236+
}
237+
};
238+
239+
221240
private RadioGroupSetting.OnCheckedChangeListener mUaModeListener = new RadioGroupSetting.OnCheckedChangeListener() {
222241
@Override
223242
public void onCheckedChanged(RadioGroup radioGroup, int checkedId, boolean doApply) {
@@ -303,6 +322,7 @@ public void onClick(View view) {
303322

304323
setConsoleLogs(SettingsStore.CONSOLE_LOGS_DEFAULT, true);
305324
setMultiprocess(SettingsStore.MULTIPROCESS_DEFAULT, true);
325+
setServo(SettingsStore.SERVO_DEFAULT, true);
306326

307327
if (mEnvOverrideSwitch.isChecked() != SettingsStore.ENV_OVERRIDE_DEFAULT) {
308328
setEnvOverride(SettingsStore.ENV_OVERRIDE_DEFAULT);
@@ -373,6 +393,18 @@ private void setMultiprocess(boolean value, boolean doApply) {
373393
}
374394
}
375395

396+
private void setServo(boolean value, boolean doApply) {
397+
mServoSwitch.setOnCheckedChangeListener(null);
398+
mServoSwitch.setValue(value, false);
399+
mServoSwitch.setOnCheckedChangeListener(mServoListener);
400+
401+
SettingsStore.getInstance(getContext()).setServoEnabled(value);
402+
403+
if (doApply) {
404+
SessionStore.get().setServo(value);
405+
}
406+
}
407+
376408
private void setUaMode(int checkId, boolean doApply) {
377409
mUaModeRadio.setOnCheckedChangeListener(null);
378410
mUaModeRadio.setChecked(checkId, doApply);

app/src/common/shared/org/mozilla/vrbrowser/ui/widgets/NavigationBarWidget.java

+41-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@
66
package org.mozilla.vrbrowser.ui.widgets;
77

88
import android.content.Context;
9+
import android.content.SharedPreferences;
910
import android.net.Uri;
11+
import android.preference.PreferenceManager;
1012
import android.support.annotation.NonNull;
1113
import android.util.AttributeSet;
1214
import android.util.Log;
@@ -33,7 +35,8 @@
3335
public class NavigationBarWidget extends UIWidget implements GeckoSession.NavigationDelegate,
3436
GeckoSession.ProgressDelegate, GeckoSession.ContentDelegate,
3537
WidgetManagerDelegate.UpdateListener, SessionStore.SessionChangeListener,
36-
NavigationURLBar.NavigationURLBarDelegate, VoiceSearchWidget.VoiceSearchDelegate {
38+
NavigationURLBar.NavigationURLBarDelegate, VoiceSearchWidget.VoiceSearchDelegate,
39+
SharedPreferences.OnSharedPreferenceChangeListener {
3740

3841
private static final String LOGTAG = "VRB";
3942

@@ -42,6 +45,7 @@ public class NavigationBarWidget extends UIWidget implements GeckoSession.Naviga
4245
private UIButton mForwardButton;
4346
private UIButton mReloadButton;
4447
private UIButton mHomeButton;
48+
private UIButton mServoButton;
4549
private NavigationURLBar mURLBar;
4650
private ViewGroup mNavigationContainer;
4751
private ViewGroup mFocusModeContainer;
@@ -60,6 +64,8 @@ public class NavigationBarWidget extends UIWidget implements GeckoSession.Naviga
6064
private ArrayList<CustomUIButton> mButtons;
6165
private int mURLBarLayoutIndex;
6266
private VoiceSearchWidget mVoiceSearchWidget;
67+
private Context mAppContext;
68+
private SharedPreferences mPrefs;
6369

6470
public NavigationBarWidget(Context aContext) {
6571
super(aContext);
@@ -77,12 +83,14 @@ public NavigationBarWidget(Context aContext, AttributeSet aAttrs, int aDefStyle)
7783
}
7884

7985
private void initialize(Context aContext) {
86+
mAppContext = aContext.getApplicationContext();
8087
inflate(aContext, R.layout.navigation_bar, this);
8188
mAudio = AudioEngine.fromContext(aContext);
8289
mBackButton = findViewById(R.id.backButton);
8390
mForwardButton = findViewById(R.id.forwardButton);
8491
mReloadButton = findViewById(R.id.reloadButton);
8592
mHomeButton = findViewById(R.id.homeButton);
93+
mServoButton = findViewById(R.id.servoButton);
8694
mURLBar = findViewById(R.id.urlBar);
8795
mNavigationContainer = findViewById(R.id.navigationBarContainer);
8896
mFocusModeContainer = findViewById(R.id.focusModeContainer);
@@ -147,6 +155,17 @@ public void onClick(View v) {
147155
}
148156
});
149157

158+
mServoButton.setOnClickListener(new OnClickListener() {
159+
@Override
160+
public void onClick(View v) {
161+
v.requestFocusFromTouch();
162+
SessionStore.get().toggleServo();
163+
if (mAudio != null) {
164+
mAudio.playSound(AudioEngine.Sound.CLICK);
165+
}
166+
}
167+
});
168+
150169
mResizeEnterButton = findViewById(R.id.resizeEnterButton);
151170
mResizeExitButton = findViewById(R.id.resizeExitButton);
152171
mPreset0 = findViewById(R.id.resizePreset0);
@@ -223,7 +242,7 @@ public void onClick(View view) {
223242
mButtons = new ArrayList<>();
224243
mButtons.addAll(Arrays.<CustomUIButton>asList(
225244
mBackButton, mForwardButton, mReloadButton, mHomeButton, mResizeEnterButton, mResizeExitButton,
226-
mPreset0, mPreset1, mPreset2, mPreset3));
245+
mServoButton, mPreset0, mPreset1, mPreset2, mPreset3));
227246

228247
mURLBar.setDelegate(this);
229248

@@ -236,11 +255,16 @@ public void onClick(View view) {
236255
mVoiceSearchWidget.setDelegate(this);
237256

238257
SessionStore.get().addSessionChangeListener(this);
258+
259+
mPrefs = PreferenceManager.getDefaultSharedPreferences(mAppContext);
260+
mPrefs.registerOnSharedPreferenceChangeListener(this);
261+
updateServoButton();
239262
}
240263

241264
@Override
242265
public void releaseWidget() {
243266
mWidgetManager.removeUpdateListener(this);
267+
mPrefs.unregisterOnSharedPreferenceChangeListener(this);
244268
SessionStore.get().removeNavigationListener(this);
245269
SessionStore.get().removeProgressListener(this);
246270
SessionStore.get().removeContentListener(this);
@@ -365,6 +389,14 @@ public void showVoiceSearch() {
365389
mURLBar.showVoiceSearch(true);
366390
}
367391

392+
public void updateServoButton() {
393+
if (SettingsStore.getInstance(mAppContext).isServoEnabled()) {
394+
mServoButton.setVisibility(View.VISIBLE);
395+
} else {
396+
mServoButton.setVisibility(View.GONE);
397+
}
398+
}
399+
368400
@Override
369401
public GeckoResult<GeckoSession> onNewSession(@NonNull GeckoSession aSession, @NonNull String aUri) {
370402
return null;
@@ -606,4 +638,11 @@ public void OnVoiceSearchCanceled() {
606638
public void OnVoiceSearchError() {
607639
// Nothing to do yet
608640
}
641+
642+
@Override
643+
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
644+
if (key == mAppContext.getString(R.string.settings_key_servo)) {
645+
updateServoButton();
646+
}
647+
}
609648
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package org.mozilla.vrbrowser.utils;
2+
3+
import android.content.Context;
4+
import android.util.Log;
5+
6+
import org.mozilla.geckoview.GeckoSession;
7+
8+
import java.lang.reflect.Constructor;
9+
10+
public class ServoUtils {
11+
private static final String CLASSNAME = "org.mozilla.servo.ServoSession";
12+
private static final String LOGTAG = "ServoUtils";
13+
14+
public static boolean isServoAvailable() {
15+
try {
16+
Class.forName(CLASSNAME);
17+
return true;
18+
} catch (ClassNotFoundException e) {
19+
return false;
20+
}
21+
}
22+
23+
public static boolean isInstanceOfServoSession(Object obj) {
24+
try {
25+
return Class.forName(CLASSNAME).isInstance(obj);
26+
} catch (ClassNotFoundException e) {
27+
return false;
28+
}
29+
}
30+
31+
public static GeckoSession createServoSession(Context context) {
32+
try {
33+
Class servoClass = Class.forName(CLASSNAME);
34+
Constructor<?> constructor = servoClass.getConstructor(Context.class);
35+
return (GeckoSession) constructor.newInstance(context);
36+
} catch (Exception e) {
37+
Log.e(LOGTAG, "Can't load or instanciate ServoSession: " + e);
38+
return null;
39+
}
40+
}
41+
}
273 KB
Loading

0 commit comments

Comments
 (0)