diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml
index e4411d8e9..8d805f038 100644
--- a/android/app/src/main/AndroidManifest.xml
+++ b/android/app/src/main/AndroidManifest.xml
@@ -7,6 +7,9 @@
android:label="@string/app_name"
android:networkSecurityConfig="@xml/network_security_config"
android:theme="@style/AppTheme">
+
entries = manager.getManifestRestrictions(
+ getApplicationContext().getPackageName());
+ for (RestrictionEntry restrictionEntry : entries) {
+ String key = restrictionEntry.getKey();
+ if (RESTRICTION_SERVER_URL.equals(key)) {
+ // If restrictions are passed to the application.
+ if (restrictions != null &&
+ restrictions.containsKey(RESTRICTION_SERVER_URL)) {
+ defaultURL = restrictions.getString(RESTRICTION_SERVER_URL);
+ configurationByRestrictions = true;
+ // Otherwise use default URL from app-restrictions.xml.
+ } else {
+ defaultURL = restrictionEntry.getSelectedString();
+ configurationByRestrictions = false;
+ }
+ }
+ }
}
@Override
diff --git a/android/app/src/main/res/values/strings.xml b/android/app/src/main/res/values/strings.xml
index ebde5be0c..bd1265237 100644
--- a/android/app/src/main/res/values/strings.xml
+++ b/android/app/src/main/res/values/strings.xml
@@ -1,3 +1,5 @@
Jitsi Meet
+ URL of Jitsi Meet server instance to connect to
+ Server URL
diff --git a/android/app/src/main/res/xml/app_restrictions.xml b/android/app/src/main/res/xml/app_restrictions.xml
new file mode 100644
index 000000000..150c4c7ca
--- /dev/null
+++ b/android/app/src/main/res/xml/app_restrictions.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
diff --git a/react/features/app/components/App.native.js b/react/features/app/components/App.native.js
index f0343253e..5b692ac18 100644
--- a/react/features/app/components/App.native.js
+++ b/react/features/app/components/App.native.js
@@ -4,7 +4,7 @@ import React from 'react';
import { setColorScheme } from '../../base/color-scheme';
import { DialogContainer } from '../../base/dialog';
-import { CALL_INTEGRATION_ENABLED, updateFlags } from '../../base/flags';
+import { CALL_INTEGRATION_ENABLED, SERVER_URL_CHANGE_ENABLED, updateFlags } from '../../base/flags';
import { Platform } from '../../base/react';
import { DimensionsDetector, clientResized } from '../../base/responsive-ui';
import { updateSettings } from '../../base/settings';
@@ -86,6 +86,20 @@ export class App extends AbstractApp {
// We set these early enough so then we avoid any unnecessary re-renders.
const { dispatch } = this.state.store;
+ // Check if serverURL is configured externally and not allowed to change.
+ const serverURLChangeEnabled = this.props.flags[SERVER_URL_CHANGE_ENABLED];
+
+ if (!serverURLChangeEnabled) {
+ // As serverURL is provided externally, so we push it to settings.
+ if (typeof this.props.url !== 'undefined') {
+ const { serverURL } = this.props.url;
+
+ if (typeof serverURL !== 'undefined') {
+ dispatch(updateSettings({ serverURL }));
+ }
+ }
+ }
+
dispatch(setColorScheme(this.props.colorScheme));
dispatch(updateFlags(this.props.flags));
dispatch(updateSettings(this.props.userInfo || {}));
diff --git a/react/features/base/flags/constants.js b/react/features/base/flags/constants.js
index dfad73667..bc94c382d 100644
--- a/react/features/base/flags/constants.js
+++ b/react/features/base/flags/constants.js
@@ -81,6 +81,12 @@ export const RAISE_HAND_ENABLED = 'raise-hand.enabled';
*/
export const RECORDING_ENABLED = 'recording.enabled';
+/**
+ * Flag indicating if server URL change is enabled.
+ * Default: enabled (true)
+ */
+export const SERVER_URL_CHANGE_ENABLED = 'server-url-change.enabled';
+
/**
* Flag indicating if tile view feature should be enabled.
* Default: enabled.
diff --git a/react/features/settings/components/native/SettingsView.js b/react/features/settings/components/native/SettingsView.js
index cfa8fedf7..c5decf726 100644
--- a/react/features/settings/components/native/SettingsView.js
+++ b/react/features/settings/components/native/SettingsView.js
@@ -7,11 +7,11 @@ import { translate } from '../../../base/i18n';
import { JitsiModal } from '../../../base/modal';
import { connect } from '../../../base/redux';
import { SETTINGS_VIEW_ID } from '../../constants';
-import { normalizeUserInputURL } from '../../functions';
+import { normalizeUserInputURL, isServerURLChangeEnabled } from '../../functions';
import {
AbstractSettingsView,
_mapStateToProps as _abstractMapStateToProps,
- type Props
+ type Props as AbstractProps
} from '../AbstractSettingsView';
import FormRow from './FormRow';
@@ -70,6 +70,20 @@ type State = {
startWithVideoMuted: boolean,
}
+/**
+ * The type of the React {@code Component} props of
+ * {@link SettingsView}.
+ */
+type Props = AbstractProps & {
+
+ /**
+ * Flag indicating if URL can be changed by user.
+ *
+ * @protected
+ */
+ _serverURLChangeEnabled: boolean
+}
+
/**
* The native container rendering the app settings page.
*
@@ -168,6 +182,7 @@ class SettingsView extends AbstractSettingsView {
{
*/
function _mapStateToProps(state) {
return {
- ..._abstractMapStateToProps(state)
+ ..._abstractMapStateToProps(state),
+ _serverURLChangeEnabled: isServerURLChangeEnabled(state)
};
}
diff --git a/react/features/settings/functions.js b/react/features/settings/functions.js
index 4dfd58e24..dcf6f6ee0 100644
--- a/react/features/settings/functions.js
+++ b/react/features/settings/functions.js
@@ -1,4 +1,6 @@
// @flow
+
+import { SERVER_URL_CHANGE_ENABLED, getFeatureFlag } from '../base/flags';
import { i18next, DEFAULT_LANGUAGE, LANGUAGES } from '../base/i18n';
import { createLocalTrack } from '../base/lib-jitsi-meet/functions';
import {
@@ -23,6 +25,20 @@ export function isSettingEnabled(settingName: string) {
return interfaceConfig.SETTINGS_SECTIONS.includes(settingName);
}
+/**
+ * Returns true if user is allowed to change Server URL.
+ *
+ * @param {(Function|Object)} stateful - The (whole) redux state, or redux's
+ * {@code getState} function to be used to retrieve the state.
+ * @returns {boolean} True to indicate that user can change Server URL, false otherwise.
+ */
+export function isServerURLChangeEnabled(stateful: Object | Function) {
+ const state = toState(stateful);
+ const flag = getFeatureFlag(state, SERVER_URL_CHANGE_ENABLED, true);
+
+ return flag;
+}
+
/**
* Normalizes a URL entered by the user.
* FIXME: Consider adding this to base/util/uri.