Skip to content
Open
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions catroid/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@ android {
buildConfigField "boolean", "FEATURE_NFC_ENABLED", "true"
buildConfigField "boolean", "FEATURE_POCKETMUSIC_ENABLED", "true"
buildConfigField "boolean", "FEATURE_RASPI_ENABLED", "true"
buildConfigField "boolean", "FEATURE_MQTT_ENABLED", "true"
buildConfigField "boolean", "FEATURE_SCRATCH_CONVERTER_ENABLED", "true"
buildConfigField "boolean", "FEATURE_USER_REPORTERS_ENABLED", "true"
buildConfigField "boolean", "FEATURE_MULTIPLAYER_VARIABLES_ENABLED", "true"
Expand Down Expand Up @@ -420,6 +421,9 @@ dependencies {
implementation 'com.google.guava:guava:28.2-android'
implementation 'com.google.code.gson:gson:2.8.7'

// MQTT
implementation 'org.eclipse.paho:org.eclipse.paho.client.mqttv3:1.2.5'

implementation 'com.koushikdutta.async:androidasync:2.2.1'
implementation 'com.squareup.picasso:picasso:2.71828'
implementation 'ar.com.hjg:pngj:2.1.0'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@
import static org.catrobat.catroid.ui.settingsfragments.SettingsFragment.SETTINGS_SHOW_PHIRO_BRICKS_CHECKBOX_PREFERENCE;
import static org.catrobat.catroid.ui.settingsfragments.SettingsFragment.SETTINGS_SHOW_PLOT_BRICKS;
import static org.catrobat.catroid.ui.settingsfragments.SettingsFragment.SETTINGS_SHOW_RASPI_BRICKS;
import static org.catrobat.catroid.ui.settingsfragments.SettingsFragment.SETTINGS_SHOW_MQTT_BRICKS;
import static org.hamcrest.Matchers.hasToString;
import static org.hamcrest.Matchers.instanceOf;
import static org.hamcrest.core.AllOf.allOf;
Expand Down Expand Up @@ -123,7 +124,7 @@ public class SettingsFragmentTest {
SETTINGS_CAST_GLOBALLY_ENABLED, SETTINGS_SHOW_AI_SPEECH_RECOGNITION_SENSORS,
SETTINGS_SHOW_AI_SPEECH_SYNTHETIZATION_SENSORS,
SETTINGS_SHOW_AI_FACE_DETECTION_SENSORS, SETTINGS_SHOW_AI_POSE_DETECTION_SENSORS,
SETTINGS_SHOW_AI_TEXT_RECOGNITION_SENSORS));
SETTINGS_SHOW_AI_TEXT_RECOGNITION_SENSORS, SETTINGS_SHOW_MQTT_BRICKS));
private Map<String, Boolean> initialSettings = new HashMap<>();
private Matcher<Intent> expectedBrowserIntent;

Expand Down Expand Up @@ -258,6 +259,15 @@ public void rasPiSettingsTest() {
checkPreference(R.string.preference_title_enable_raspi_bricks, SETTINGS_SHOW_RASPI_BRICKS);
}

@Category({Cat.AppUi.class, Level.Smoke.class, Cat.Gadgets.class})
@Test
public void mqttSettingsTest() {
onData(PreferenceMatchers.withTitle(R.string.preference_title_enable_mqtt_bricks))
.perform(click());

checkPreference(R.string.preference_title_enable_mqtt_bricks, SETTINGS_SHOW_MQTT_BRICKS);
}

@Category({Cat.AppUi.class, Level.Smoke.class, Cat.Gadgets.class})
@Test
public void aiSettingsTest() {
Expand Down
2 changes: 1 addition & 1 deletion catroid/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Catroid: An on-device visual programming system for Android devices
~ Copyright (C) 2010-2025 The Catrobat Team
~ Copyright (C) 2010-2026 The Catrobat Team
~ (<http://developer.catrobat.org/credits>)
~
~ This program is free software: you can redistribute it and/or modify
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
/*
* Catroid: An on-device visual programming system for Android devices
* Copyright (C) 2010-2026 The Catrobat Team
* (<http://developer.catrobat.org/credits>)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* An additional term exception under section 7 of the GNU Affero
* General Public License, version 3, is available at
* http://developer.catrobat.org/license_additional_term
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

package org.catrobat.catroid.ui.settingsfragments

import android.os.Bundle
import android.preference.CheckBoxPreference
import android.preference.EditTextPreference
import android.preference.Preference
import android.preference.PreferenceCategory
import android.preference.PreferenceFragment
import android.widget.Toast
import androidx.annotation.VisibleForTesting
import androidx.appcompat.app.AppCompatActivity
import org.catrobat.catroid.R
import org.catrobat.catroid.ui.settingsfragments.SettingsFragment.MQTT_CONNECTION_SETTINGS_CATEGORY
import org.catrobat.catroid.ui.settingsfragments.SettingsFragment.MQTT_CLIENT_ID
import org.catrobat.catroid.ui.settingsfragments.SettingsFragment.MQTT_HOST
import org.catrobat.catroid.ui.settingsfragments.SettingsFragment.MQTT_PASSWORD
import org.catrobat.catroid.ui.settingsfragments.SettingsFragment.MQTT_PORT
import org.catrobat.catroid.ui.settingsfragments.SettingsFragment.MQTT_USERNAME
import org.catrobat.catroid.ui.settingsfragments.SettingsFragment.SETTINGS_SHOW_MQTT_BRICKS

class MqttSettingsFragment : PreferenceFragment() {

override fun onResume() {
super.onResume()
(activity as AppCompatActivity).supportActionBar?.title = preferenceScreen.title
}

override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
SettingsFragment.setToChosenLanguage(activity)
addPreferencesFromResource(R.xml.mqtt_preferences)

val mqttCheckBoxPreference = findPreference(SETTINGS_SHOW_MQTT_BRICKS) as CheckBoxPreference
val mqttConnectionSettings = findPreference(MQTT_CONNECTION_SETTINGS_CATEGORY) as PreferenceCategory
mqttConnectionSettings.isEnabled = mqttCheckBoxPreference.isChecked

mqttCheckBoxPreference.onPreferenceChangeListener = Preference.OnPreferenceChangeListener { _, isChecked ->
mqttConnectionSettings.isEnabled = isChecked as Boolean
true
}

bindSummaryToValue(findPreference(MQTT_HOST) as EditTextPreference)
bindSummaryToValue(findPreference(MQTT_USERNAME) as EditTextPreference)
bindSummaryToValue(findPreference(MQTT_CLIENT_ID) as EditTextPreference)

val portPreference = findPreference(MQTT_PORT) as EditTextPreference
portPreference.summary = portPreference.text
portPreference.onPreferenceChangeListener = Preference.OnPreferenceChangeListener { _, newValue ->
if (!isValidPort(newValue.toString())) {
Toast.makeText(activity, R.string.preference_mqtt_port_invalid, Toast.LENGTH_SHORT).show()
return@OnPreferenceChangeListener false
}
portPreference.summary = newValue.toString()
true
}

val passwordPreference = findPreference(MQTT_PASSWORD) as EditTextPreference
passwordPreference.onPreferenceChangeListener = Preference.OnPreferenceChangeListener { _, _ -> true }
}

private fun bindSummaryToValue(preference: EditTextPreference) {
preference.summary = preference.text
preference.onPreferenceChangeListener = Preference.OnPreferenceChangeListener { pref, newValue ->
(pref as EditTextPreference).summary = newValue.toString()
true
}
}

companion object {
private const val MIN_PORT = 1
private const val MAX_PORT = 65_535

@JvmField val TAG: String = MqttSettingsFragment::class.java.simpleName

@VisibleForTesting
@JvmStatic
fun isValidPort(value: String): Boolean {
val port = value.toIntOrNull() ?: return false
return port in MIN_PORT..MAX_PORT
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,17 @@
public static final String RASPI_PORT = "setting_raspi_port_preference";
public static final String RASPI_VERSION_SPINNER = "setting_raspi_version_preference";

public static final String MQTT_SCREEN_KEY = "settings_mqtt_screen";
public static final String SETTINGS_SHOW_MQTT_BRICKS = "setting_mqtt_bricks";
public static final String MQTT_CONNECTION_SETTINGS_CATEGORY = "setting_mqtt_category";
public static final String MQTT_HOST = "setting_mqtt_host";
public static final String MQTT_PORT = "setting_mqtt_port";
public static final String MQTT_TLS = "setting_mqtt_tls";
public static final String MQTT_USERNAME = "setting_mqtt_username";
public static final String MQTT_PASSWORD = "setting_mqtt_password";
public static final String MQTT_CLIENT_ID = "setting_mqtt_client_id";

Check warning

Code scanning / Checkstyle

Maximum of blank lines is 1 Warning

Maximum of blank lines is 1
Comment thread
github-advanced-security[bot] marked this conversation as resolved.
Fixed


public static final String SETTINGS_CRASH_REPORTS = "setting_enable_crash_reports";
public static final String TAG = SettingsFragment.class.getSimpleName();

Expand Down Expand Up @@ -210,6 +221,12 @@
screen.removePreference(testPreference);
}

if (!BuildConfig.FEATURE_MQTT_ENABLED) {
PreferenceScreen mqttPreference = (PreferenceScreen) findPreference(MQTT_SCREEN_KEY);
mqttPreference.setEnabled(false);
screen.removePreference(mqttPreference);
}

setCorrectPreferenceViewForEmbroidery();
setCorrectPreferenceViewForPhiro();
}
Expand Down Expand Up @@ -262,6 +279,12 @@
.addToBackStack(RaspberryPiSettingsFragment.TAG)
.commit();
break;
case MQTT_SCREEN_KEY:
getFragmentManager().beginTransaction()
.replace(R.id.content_frame, new MqttSettingsFragment(), MqttSettingsFragment.TAG)
.addToBackStack(MqttSettingsFragment.TAG)
.commit();
break;
}
return super.onPreferenceTreeClick(preferenceScreen, preference);
}
Expand Down Expand Up @@ -408,6 +431,38 @@
return getBooleanSharedPreference(false, SETTINGS_SHOW_RASPI_BRICKS, context);
}

public static boolean isMqttSharedPreferenceEnabled(Context context) {
return getBooleanSharedPreference(false, SETTINGS_SHOW_MQTT_BRICKS, context);
}

public static String getMqttHost(Context context) {
return getSharedPreferences(context).getString(MQTT_HOST, "");
Comment thread
Paras-ydv marked this conversation as resolved.
Outdated
}

public static int getMqttPort(Context context) {
try {
return Integer.parseInt(getSharedPreferences(context).getString(MQTT_PORT, "1883"));
} catch (NumberFormatException e) {
return 1883;
}
}

public static boolean isMqttTlsEnabled(Context context) {
return getBooleanSharedPreference(false, MQTT_TLS, context);
}

public static String getMqttUsername(Context context) {
return getSharedPreferences(context).getString(MQTT_USERNAME, "");
}

public static String getMqttPassword(Context context) {
return getSharedPreferences(context).getString(MQTT_PASSWORD, "");
}

public static String getMqttClientId(Context context) {
return getSharedPreferences(context).getString(MQTT_CLIENT_ID, "");
}

public static boolean isNfcSharedPreferenceEnabled(Context context) {
return getBooleanSharedPreference(false, SETTINGS_SHOW_NFC_BRICKS, context);
}
Expand Down
17 changes: 17 additions & 0 deletions catroid/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1531,6 +1531,23 @@ needs read and write access to it. You can always change permissions through you
<string formatted="false" name="error_connecting_to">Error: Could not connect to %s : %d</string>
<!-- -->

<!-- MQTT Settings -->
<string formatted="false" name="preference_title_enable_mqtt_bricks">MQTT extension</string>
<string formatted="false" name="preference_description_mqtt_bricks">Allow the app to connect to MQTT brokers</string>
<string formatted="false" name="preference_title_mqtt_enabled">Enable MQTT bricks</string>
<string formatted="false" name="preference_description_mqtt_enabled">Enable bricks and sensors for MQTT</string>
<string formatted="false" name="preference_title_mqtt_category">MQTT settings</string>
<string formatted="false" name="preference_title_mqtt_broker_host">Broker host</string>
<string formatted="false" name="preference_description_mqtt_broker_host">IP address or hostname of the MQTT broker</string>
<string formatted="false" name="preference_title_mqtt_broker_port">Broker port</string>
<string formatted="false" name="preference_description_mqtt_broker_port">Port number of the MQTT broker (1–65535)</string>
<string formatted="false" name="preference_title_mqtt_use_tls">Use TLS</string>
<string formatted="false" name="preference_title_mqtt_username">Username</string>
<string formatted="false" name="preference_title_mqtt_password">Password</string>
<string formatted="false" name="preference_title_mqtt_client_id">Client ID</string>
<string formatted="false" name="preference_mqtt_port_invalid">Port must be a number between 1 and 65535</string>
<!-- -->

<!-- Lego Mindstorms Strings -->
<string formatted="false" name="nxt_brick_motor_move">Set NXT motor</string>
<string formatted="false" name="nxt_motor_speed_to">to</string>
Expand Down
76 changes: 76 additions & 0 deletions catroid/src/main/res/xml/mqtt_preferences.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Catroid: An on-device visual programming system for Android devices
~ Copyright (C) 2010-2025 The Catrobat Team
~ (<http://developer.catrobat.org/credits>)
~
~ This program is free software: you can redistribute it and/or modify
~ it under the terms of the GNU Affero General Public License as
~ published by the Free Software Foundation, either version 3 of the
~ License, or (at your option) any later version.
~
~ An additional term exception under section 7 of the GNU Affero
~ General Public License, version 3, is available at
~ http://developer.catrobat.org/license_additional_term
~
~ This program is distributed in the hope that it will be useful,
~ but WITHOUT ANY WARRANTY; without even the implied warranty of
~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
~ GNU Affero General Public License for more details.
~
~ You should have received a copy of the GNU Affero General Public License
~ along with this program. If not, see <http://www.gnu.org/licenses/>.
-->
<PreferenceScreen
android:key="settings_mqtt_screen"
android:summary="@string/preference_description_mqtt_bricks"
android:title="@string/preference_title_enable_mqtt_bricks"
xmlns:android="http://schemas.android.com/apk/res/android">

<CheckBoxPreference
android:defaultValue="false"
android:key="setting_mqtt_bricks"
android:summary="@string/preference_description_mqtt_enabled"
android:title="@string/preference_title_mqtt_enabled" />

<PreferenceCategory
android:key="setting_mqtt_category"
android:title="@string/preference_title_mqtt_category">

<EditTextPreference
android:defaultValue="192.168.0.1"
android:key="setting_mqtt_host"
android:summary="@string/preference_description_mqtt_broker_host"
android:title="@string/preference_title_mqtt_broker_host" />

<EditTextPreference
android:defaultValue="1883"
android:inputType="number"
android:key="setting_mqtt_port"
android:summary="@string/preference_description_mqtt_broker_port"
android:title="@string/preference_title_mqtt_broker_port" />

<CheckBoxPreference
android:defaultValue="false"
android:key="setting_mqtt_tls"
android:title="@string/preference_title_mqtt_use_tls" />

<EditTextPreference
android:defaultValue=""
android:key="setting_mqtt_username"
android:title="@string/preference_title_mqtt_username" />

<EditTextPreference
android:defaultValue=""
android:inputType="textPassword"
android:key="setting_mqtt_password"
android:title="@string/preference_title_mqtt_password" />

<EditTextPreference
android:defaultValue=""
android:key="setting_mqtt_client_id"
android:title="@string/preference_title_mqtt_client_id" />

</PreferenceCategory>

</PreferenceScreen>
5 changes: 5 additions & 0 deletions catroid/src/main/res/xml/preferences.xml
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,11 @@
android:summary="@string/preference_description_raspi_bricks"
android:title="@string/preference_title_enable_raspi_bricks" />

<PreferenceScreen
android:key="settings_mqtt_screen"
android:summary="@string/preference_description_mqtt_bricks"
android:title="@string/preference_title_enable_mqtt_bricks" />

<Preference
android:key="setting_enable_phiro_bricks_preference"
android:summary="@string/preference_description_phiro_bricks"
Expand Down
Loading
Loading